fix(sample-gen): first oneOf or anyOf should be combined with schema (#6775)

* fix(sample-gen): oneOf and anyOf should be merge into schema

when there was oneOf or anyOf defined it just used the first schema of it to generate the samples.
Now, the first oneOf or anyOf is combined with the schema to generate samples.

* test(sample-gen): oneOf and anyOf should be combined with schema
This commit is contained in:
Mahtis Michel
2021-01-07 20:26:34 +01:00
committed by GitHub
parent 2564625f3d
commit 0f541a1ab0
2 changed files with 121 additions and 14 deletions

View File

@@ -48,12 +48,62 @@ const liftSampleHelper = (oldSchema, target) => {
if(target.xml === undefined && oldSchema.xml !== undefined) { if(target.xml === undefined && oldSchema.xml !== undefined) {
target.xml = oldSchema.xml target.xml = oldSchema.xml
} }
if(target.type === undefined && oldSchema.type !== undefined) {
target.type = oldSchema.type
}
return target return target
} }
export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = undefined, respectXML = false) => { export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = undefined, respectXML = false) => {
schema = objectify(schema)
let usePlainValue = exampleOverride !== undefined || schema.example !== undefined || schema && schema.default !== undefined
// first check if there is the need of combining this schema with others required by allOf
const hasOneOf = !usePlainValue && schema && schema.oneOf && schema.oneOf.length > 0
const hasAnyOf = !usePlainValue && schema && schema.anyOf && schema.anyOf.length > 0
if(!usePlainValue && (hasOneOf || hasAnyOf)) {
const schemaToAdd = objectify(hasOneOf
? schema.oneOf[0]
: schema.anyOf[0]
)
liftSampleHelper(schemaToAdd, schema)
if(!schema.xml && schemaToAdd.xml) {
schema.xml = schemaToAdd.xml
}
if(schema.example !== undefined && schemaToAdd.example !== undefined) {
usePlainValue = true
} else if(schemaToAdd.properties) {
if(!schema.properties) {
schema.properties = {}
}
let props = objectify(schemaToAdd.properties)
for (let propName in props) {
if (!props.hasOwnProperty(propName)) {
continue
}
if ( props[propName] && props[propName].deprecated ) {
continue
}
if ( props[propName] && props[propName].readOnly && !config.includeReadOnly ) {
continue
}
if ( props[propName] && props[propName].writeOnly && !config.includeWriteOnly ) {
continue
}
if(!schema.properties[propName]) {
schema.properties[propName] = props[propName]
if(!schemaToAdd.required && Array.isArray(schemaToAdd.required) && schemaToAdd.required.indexOf(propName) !== -1) {
if(!schema.required) {
schema.required = [propName]
} else {
schema.required.push(propName)
}
}
}
}
}
}
const _attr = {} const _attr = {}
let { xml, type, example, properties, additionalProperties, items } = objectify(schema) let { xml, type, example, properties, additionalProperties, items } = schema
let { includeReadOnly, includeWriteOnly } = config let { includeReadOnly, includeWriteOnly } = config
xml = xml || {} xml = xml || {}
let { name, prefix, namespace } = xml let { name, prefix, namespace } = xml
@@ -77,18 +127,6 @@ export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = und
res[displayName] = [] res[displayName] = []
} }
const usePlainValue = exampleOverride !== undefined || example !== undefined || schema && schema.default !== undefined
const hasOneOf = !usePlainValue && schema && schema.oneOf && schema.oneOf.length > 0
const hasAnyOf = !usePlainValue && schema && schema.anyOf && schema.anyOf.length > 0
if(!usePlainValue && (hasOneOf || hasAnyOf)) {
const someSchema = hasOneOf
? schema.oneOf[0]
: schema.anyOf[0]
liftSampleHelper(schema, someSchema)
return sampleFromSchemaGeneric(someSchema, config, undefined, respectXML)
}
// try recover missing type // try recover missing type
if(schema && !type) { if(schema && !type) {
if(properties || additionalProperties) { if(properties || additionalProperties) {
@@ -105,6 +143,7 @@ export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = und
let addPropertyToResult let addPropertyToResult
if(respectXML) { if(respectXML) {
addPropertyToResult = (propName, overrideE = undefined) => { addPropertyToResult = (propName, overrideE = undefined) => {
if(schema) { if(schema) {
// case it is an xml attribute // case it is an xml attribute
props[propName].xml = props[propName].xml || {} props[propName].xml = props[propName].xml || {}
@@ -139,9 +178,11 @@ export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = und
} }
} }
} else { } else {
addPropertyToResult = (propName, overrideE) => addPropertyToResult = (propName, overrideE) => {
res[propName] = sampleFromSchemaGeneric(props[propName], config, overrideE, respectXML) res[propName] = sampleFromSchemaGeneric(props[propName], config, overrideE, respectXML)
} }
}
// check for plain value and if found use it to generate sample from it // check for plain value and if found use it to generate sample from it
if(usePlainValue) { if(usePlainValue) {

View File

@@ -29,6 +29,72 @@ describe("sampleFromSchema", () => {
expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected) expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected)
}) })
it("combine first oneOf or anyOf with schema's definitions", function () {
let definition = {
type: "object",
anyOf: [
{
type: "object",
properties: {
test2: {
type: "string",
example: "anyOf"
},
test: {
type: "string",
example: "anyOf"
}
}
}
],
properties: {
test: {
type: "string",
example: "schema"
}
}
}
let expected = {
test: "schema",
test2: "anyOf"
}
expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected)
definition = {
type: "object",
oneOf: [
{
type: "object",
properties: {
test2: {
type: "string",
example: "oneOf"
},
test: {
type: "string",
example: "oneOf"
}
}
}
],
properties: {
test: {
type: "string",
example: "schema"
}
}
}
expected = {
test: "schema",
test2: "oneOf"
}
expect(sampleFromSchema(definition, { includeReadOnly: false })).toEqual(expected)
})
it("returns object with no readonly fields for parameter", function () { it("returns object with no readonly fields for parameter", function () {
let definition = { let definition = {
type: "object", type: "object",