fix(schema example): xml gen should follow json gen behavior (#6555)

* ref: #6470 
* fixes: #6540
* fixes: #4943 

* add example override option to json
* add example override option to xml
* added basic oneOf and anyOf support
* fix anyof|oneof
* only lift xml to items


Co-authored-by: Tim Lai <timothy.lai@gmail.com>
This commit is contained in:
Mahtis Michel
2020-11-03 19:58:59 +01:00
committed by GitHub
parent 64ae7af565
commit 288c89bdbb
8 changed files with 488 additions and 228 deletions

View File

@@ -4,7 +4,7 @@ import ImPropTypes from "react-immutable-proptypes"
import cx from "classnames" import cx from "classnames"
import { fromJS, Seq, Iterable, List, Map } from "immutable" import { fromJS, Seq, Iterable, List, Map } from "immutable"
import { getExtensions, getSampleSchema, fromJSOrdered, stringify } from "core/utils" import { getExtensions, getSampleSchema, fromJSOrdered, stringify } from "core/utils"
import { isFunc } from "../utils"
const getExampleComponent = ( sampleResponse, HighlightCode, getConfigs ) => { const getExampleComponent = ( sampleResponse, HighlightCode, getConfigs ) => {
if ( if (
@@ -121,21 +121,6 @@ export default class Response extends React.Component {
specPathWithPossibleSchema = response.has("schema") ? specPath.push("schema") : specPath specPathWithPossibleSchema = response.has("schema") ? specPath.push("schema") : specPath
} }
const overrideSchemaExample = (oldSchema, newExample) => {
if(newExample === undefined)
return oldSchema
if(!oldSchema)
oldSchema = { }
if(isFunc(oldSchema.toJS))
oldSchema = oldSchema.toJS()
oldSchema.example = newExample && isFunc(newExample.toJS)
? newExample.toJS()
: newExample
return oldSchema
}
let mediaTypeExample let mediaTypeExample
let shouldOverrideSchemaExample = false let shouldOverrideSchemaExample = false
let sampleSchema let sampleSchema
@@ -170,13 +155,12 @@ export default class Response extends React.Component {
} }
} }
const schemaForSampleGeneration = shouldOverrideSchemaExample const sampleResponse = getSampleSchema(
? overrideSchemaExample(sampleSchema, mediaTypeExample) sampleSchema,
: sampleSchema activeContentType,
sampleGenConfig,
const sampleResponse = schemaForSampleGeneration shouldOverrideSchemaExample ? mediaTypeExample : undefined
? getSampleSchema(schemaForSampleGeneration, activeContentType, sampleGenConfig) )
: null
let example = getExampleComponent( sampleResponse, HighlightCode, getConfigs ) let example = getExampleComponent( sampleResponse, HighlightCode, getConfigs )

View File

@@ -1,7 +1,7 @@
import { objectify, isFunc, normalizeArray, deeplyStripKey } from "core/utils" import { objectify, isFunc, normalizeArray, deeplyStripKey } from "core/utils"
import XML from "@kyleshockey/xml" import XML from "@kyleshockey/xml"
import memoizee from "memoizee" import memoizee from "memoizee"
import deepAssign from "@kyleshockey/object-assign-deep" import isEmpty from "lodash/isEmpty"
const primitives = { const primitives = {
"string": () => "string", "string": () => "string",
@@ -30,82 +30,291 @@ const primitive = (schema) => {
return "Unknown Type: " + schema.type return "Unknown Type: " + schema.type
} }
// do a couple of quick sanity tests to ensure the value
// looks like a $$ref that swagger-client generates.
const sanitizeRef = (value) => deeplyStripKey(value, "$$ref", (val) =>
typeof val === "string" && val.indexOf("#") > -1)
export const sampleFromSchema = (schema, config={}) => { const liftSampleHelper = (oldSchema, target) => {
let { type, example, properties, additionalProperties, items } = objectify(schema) if(target.example === undefined && oldSchema.example !== undefined) {
target.example = oldSchema.example
}
if(target.default === undefined && oldSchema.default !== undefined) {
target.default = oldSchema.default
}
if(target.enum === undefined && oldSchema.enum !== undefined) {
target.enum = oldSchema.enum
}
if(target.xml === undefined && oldSchema.xml !== undefined) {
target.xml = oldSchema.xml
}
return target
}
export const sampleFromSchemaGeneric = (schema, config={}, exampleOverride = undefined, respectXML = false) => {
const _attr = {}
let { xml, type, example, properties, additionalProperties, items } = objectify(schema)
let { includeReadOnly, includeWriteOnly } = config let { includeReadOnly, includeWriteOnly } = config
xml = xml || {}
let { name, prefix, namespace } = xml
let displayName
let res = {}
// set xml naming and attributes
if(example !== undefined) { if(respectXML) {
return deeplyStripKey(example, "$$ref", (val) => { name = name || "notagname"
// do a couple of quick sanity tests to ensure the value // add prefix to name if exists
// looks like a $$ref that swagger-client generates. displayName = (prefix ? prefix + ":" : "") + name
return typeof val === "string" && val.indexOf("#") > -1 if ( namespace ) {
}) //add prefix to namespace if exists
let namespacePrefix = prefix ? ( "xmlns:" + prefix ) : "xmlns"
_attr[namespacePrefix] = namespace
}
} }
if(!type) { // init xml default response sample obj
if(properties) { if(respectXML) {
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
if(schema && !type) {
if(properties || additionalProperties) {
type = "object" type = "object"
} else if(items) { } else if(items) {
type = "array" type = "array"
} else { } else if(!usePlainValue){
return return
} }
} }
// add to result helper init for xml or json
const props = objectify(properties)
let addPropertyToResult
if(respectXML) {
addPropertyToResult = (propName, overrideE = undefined) => {
if(schema) {
// case it is an xml attribute
props[propName].xml = props[propName].xml || {}
if (props[propName].xml.attribute) {
const enumAttrVal = Array.isArray(props[propName].enum)
? props[propName].enum[0]
: undefined
const attrExample = props[propName].example
const attrDefault = props[propName].default
if(attrExample !== undefined) {
_attr[props[propName].xml.name || propName] = attrExample
} else if(attrDefault !== undefined) {
_attr[props[propName].xml.name || propName] = attrDefault
} else if(enumAttrVal !== undefined) {
_attr[props[propName].xml.name || propName] = enumAttrVal
} else {
_attr[props[propName].xml.name || propName] = primitive(props[propName])
}
return
}
props[propName].xml.name = props[propName].xml.name || propName
}
let t = sampleFromSchemaGeneric(schema && props[propName] || undefined, config, overrideE, respectXML)
if (Array.isArray(t)) {
res[displayName] = res[displayName].concat(t)
} else {
res[displayName].push(t)
}
}
} else {
addPropertyToResult = (propName, overrideE) =>
res[propName] = sampleFromSchemaGeneric(props[propName], config, overrideE, respectXML)
}
// check for plain value and if found use it to generate sample from it
if(usePlainValue) {
let sample
if(exampleOverride !== undefined) {
sample = sanitizeRef(exampleOverride)
} else if(example !== undefined) {
sample = sanitizeRef(example)
} else {
sample = sanitizeRef(schema.default)
}
// if json just return
if(!respectXML) {
return sample
}
// recover missing type
if(!schema) {
type = Array.isArray(sample) ? "array" : typeof sample
}
// generate xml sample recursively for array case
if(type === "array") {
if (!Array.isArray(sample)) {
sample = [sample]
}
const itemSchema = schema
? schema.items
: undefined
if(itemSchema) {
itemSchema.xml = itemSchema.xml || xml || {}
itemSchema.xml.name = itemSchema.xml.name || xml.name
}
const itemSamples = sample
.map(s => sampleFromSchemaGeneric(itemSchema, config, s, respectXML))
if(xml.wrapped) {
res[displayName] = itemSamples
if (!isEmpty(_attr)) {
res[displayName].push({_attr: _attr})
}
}
else {
res = itemSamples
}
return res
}
// generate xml sample recursively for object case
if(type === "object") {
for (let propName in sample) {
if (!sample.hasOwnProperty(propName)) {
continue
}
if (schema && props[propName] && props[propName].readOnly && !includeReadOnly) {
continue
}
if (schema && props[propName] && props[propName].writeOnly && !includeWriteOnly) {
continue
}
if (schema && props[propName] && props[propName].xml && props[propName].xml.attribute) {
_attr[props[propName].xml.name || propName] = example[propName]
continue
}
addPropertyToResult(propName, sample[propName])
}
if (!isEmpty(_attr)) {
res[displayName].push({_attr: _attr})
}
return res
}
res[displayName] = !isEmpty(_attr) ? [{_attr: _attr}, sample] : sample
return res
}
// use schema to generate sample
if(type === "object") { if(type === "object") {
let props = objectify(properties) for (let propName in props) {
let obj = {} if (!props.hasOwnProperty(propName)) {
for (var name in props) {
if ( props[name] && props[name].deprecated ) {
continue continue
} }
if ( props[name] && props[name].readOnly && !includeReadOnly ) { if ( props[propName] && props[propName].deprecated ) {
continue continue
} }
if ( props[name] && props[name].writeOnly && !includeWriteOnly ) { if ( props[propName] && props[propName].readOnly && !includeReadOnly ) {
continue continue
} }
obj[name] = sampleFromSchema(props[name], config) if ( props[propName] && props[propName].writeOnly && !includeWriteOnly ) {
continue
}
addPropertyToResult(propName)
} }
if ( additionalProperties === true ) { if ( additionalProperties === true ) {
obj.additionalProp1 = {} if(respectXML) {
res[displayName].push({additionalProp: "Anything can be here"})
} else {
res.additionalProp1 = {}
}
} else if ( additionalProperties ) { } else if ( additionalProperties ) {
let additionalProps = objectify(additionalProperties) const additionalProps = objectify(additionalProperties)
let additionalPropVal = sampleFromSchema(additionalProps, config) const additionalPropSample = sampleFromSchemaGeneric(additionalProps, config, undefined, respectXML)
for (let i = 1; i < 4; i++) { if(respectXML && additionalProps.xml && additionalProps.xml.name && additionalProps.xml.name !== "notagname")
obj["additionalProp" + i] = additionalPropVal {
res[displayName].push(additionalPropSample)
} else {
for (let i = 1; i < 4; i++) {
if(respectXML) {
const temp = {}
temp["additionalProp" + i] = additionalPropSample["notagname"]
res[displayName].push(temp)
} else {
res["additionalProp" + i] = additionalPropSample
}
}
} }
} }
return obj if (respectXML && _attr) {
res[displayName].push({_attr: _attr})
}
return res
} }
if(type === "array") { if(type === "array") {
let sampleArray
if(respectXML) {
items.xml = items.xml || schema.xml || {}
items.xml.name = items.xml.name || xml.name
}
if(Array.isArray(items.anyOf)) { if(Array.isArray(items.anyOf)) {
return items.anyOf.map(i => sampleFromSchema(i, config)) sampleArray = items.anyOf.map(i => sampleFromSchemaGeneric(liftSampleHelper(items, i), config, undefined, respectXML))
} else if(Array.isArray(items.oneOf)) {
sampleArray = items.oneOf.map(i => sampleFromSchemaGeneric(liftSampleHelper(items, i), config, undefined, respectXML))
} else if(!respectXML || respectXML && xml.wrapped) {
sampleArray = [sampleFromSchemaGeneric(items, config, undefined, respectXML)]
} else {
return sampleFromSchemaGeneric(items, config, undefined, respectXML)
} }
if(respectXML && xml.wrapped) {
if(Array.isArray(items.oneOf)) { res[displayName] = sampleArray
return items.oneOf.map(i => sampleFromSchema(i, config)) if (!isEmpty(_attr)) {
res[displayName].push({_attr: _attr})
}
return res
} }
return sampleArray
return [ sampleFromSchema(items, config) ]
} }
if(schema["enum"]) { let value
if(schema["default"]) if (schema && Array.isArray(schema.enum)) {
return schema["default"] //display enum first value
return normalizeArray(schema["enum"])[0] value = normalizeArray(schema.enum)[0]
} else if(schema) {
// display schema default
value = primitive(schema)
} else {
return
} }
if (type === "file") { if (type === "file") {
return return
} }
return primitive(schema) if(respectXML) {
res[displayName] = !isEmpty(_attr) ? [{_attr: _attr}, value] : value
return res
}
return value
} }
export const inferSchema = (thing) => { export const inferSchema = (thing) => {
@@ -119,162 +328,16 @@ export const inferSchema = (thing) => {
return thing // Hopefully this will have something schema like in it... `type` for example return thing // Hopefully this will have something schema like in it... `type` for example
} }
export const createXMLExample = (schema, config={}, o) => {
export const sampleXmlFromSchema = (schema, config={}) => { const json = sampleFromSchemaGeneric(schema, config, o, true)
let objectifySchema = deepAssign({}, objectify(schema))
let { type, properties, additionalProperties, items, example } = objectifySchema
let { includeReadOnly, includeWriteOnly } = config
let defaultValue = objectifySchema.default
let res = {}
let _attr = {}
let { xml } = schema
let { name, prefix, namespace } = xml
let enumValue = objectifySchema.enum
let displayName, value
if(!type) {
if(properties || additionalProperties) {
type = "object"
} else if(items) {
type = "array"
} else {
return
}
}
name = name || "notagname"
// add prefix to name if exists
displayName = (prefix ? prefix + ":" : "") + name
if ( namespace ) {
//add prefix to namespace if exists
let namespacePrefix = prefix ? ( "xmlns:" + prefix ) : "xmlns"
_attr[namespacePrefix] = namespace
}
if (type === "array") {
if (items) {
items.xml = items.xml || xml || {}
items.xml.name = items.xml.name || xml.name
if (xml.wrapped) {
res[displayName] = []
if (Array.isArray(example)) {
example.forEach((v)=>{
items.example = v
res[displayName].push(sampleXmlFromSchema(items, config))
})
} else if (Array.isArray(defaultValue)) {
defaultValue.forEach((v)=>{
items.default = v
res[displayName].push(sampleXmlFromSchema(items, config))
})
} else {
res[displayName] = [sampleXmlFromSchema(items, config)]
}
if (_attr) {
res[displayName].push({_attr: _attr})
}
return res
}
let _res = []
if (Array.isArray(example)) {
example.forEach((v)=>{
items.example = v
_res.push(sampleXmlFromSchema(items, config))
})
return _res
} else if (Array.isArray(defaultValue)) {
defaultValue.forEach((v)=>{
items.default = v
_res.push(sampleXmlFromSchema(items, config))
})
return _res
}
return sampleXmlFromSchema(items, config)
}
}
if (type === "object") {
let props = objectify(properties)
res[displayName] = []
example = example || {}
for (let propName in props) {
if (!props.hasOwnProperty(propName)) {
continue
}
if ( props[propName].readOnly && !includeReadOnly ) {
continue
}
if ( props[propName].writeOnly && !includeWriteOnly ) {
continue
}
props[propName].xml = props[propName].xml || {}
if (props[propName].xml.attribute) {
let enumAttrVal = Array.isArray(props[propName].enum) && props[propName].enum[0]
let attrExample = props[propName].example
let attrDefault = props[propName].default
_attr[props[propName].xml.name || propName] = attrExample!== undefined && attrExample
|| example[propName] !== undefined && example[propName] || attrDefault !== undefined && attrDefault
|| enumAttrVal || primitive(props[propName])
} else {
props[propName].xml.name = props[propName].xml.name || propName
if(props[propName].example === undefined && example[propName] !== undefined) {
props[propName].example = example[propName]
}
let t = sampleXmlFromSchema(props[propName])
if (Array.isArray(t)) {
res[displayName] = res[displayName].concat(t)
} else {
res[displayName].push(t)
}
}
}
if (additionalProperties === true) {
res[displayName].push({additionalProp: "Anything can be here"})
} else if (additionalProperties) {
res[displayName].push({additionalProp: primitive(additionalProperties)})
}
if (_attr) {
res[displayName].push({_attr: _attr})
}
return res
}
if (example !== undefined) {
value = example
} else if (defaultValue !== undefined) {
//display example if exists
value = defaultValue
} else if (Array.isArray(enumValue)) {
//display enum first value
value = enumValue[0]
} else {
//set default value
value = primitive(schema)
}
res[displayName] = _attr ? [{_attr: _attr}, value] : value
return res
}
export function createXMLExample(schema, config) {
let json = sampleXmlFromSchema(schema, config)
if (!json) { return } if (!json) { return }
return XML(json, { declaration: true, indent: "\t" }) return XML(json, { declaration: true, indent: "\t" })
} }
export const sampleFromSchema = (schema, config={}, o) =>
sampleFromSchemaGeneric(schema, config, o, false)
export const memoizedCreateXMLExample = memoizee(createXMLExample) export const memoizedCreateXMLExample = memoizee(createXMLExample)
export const memoizedSampleFromSchema = memoizee(sampleFromSchema) export const memoizedSampleFromSchema = memoizee(sampleFromSchema)

View File

@@ -541,8 +541,8 @@ export const validateParam = (param, value, { isOAS3 = false, bypassRequiredChec
return errors return errors
} }
const getXmlSampleSchema = (schema, config) => { const getXmlSampleSchema = (schema, config, exampleOverride) => {
if (!schema.xml || !schema.xml.name) { if (schema && (!schema.xml || !schema.xml.name)) {
schema.xml = schema.xml || {} schema.xml = schema.xml || {}
if (schema.$$ref) { if (schema.$$ref) {
@@ -554,7 +554,7 @@ const getXmlSampleSchema = (schema, config) => {
return null return null
} }
} }
return memoizedCreateXMLExample(schema, config) return memoizedCreateXMLExample(schema, config, exampleOverride)
} }
const shouldStringifyTypesConfig = [ const shouldStringifyTypesConfig = [
@@ -566,8 +566,8 @@ const shouldStringifyTypesConfig = [
const defaultStringifyTypes = ["object"] const defaultStringifyTypes = ["object"]
const getStringifiedSampleForSchema = (schema, config, contentType) => { const getStringifiedSampleForSchema = (schema, config, contentType, exampleOverride) => {
const res = memoizedSampleFromSchema(schema, config) const res = memoizedSampleFromSchema(schema, config, exampleOverride)
const resType = typeof res const resType = typeof res
const typesToStringify = shouldStringifyTypesConfig.reduce( const typesToStringify = shouldStringifyTypesConfig.reduce(
@@ -581,12 +581,17 @@ const getStringifiedSampleForSchema = (schema, config, contentType) => {
: res : res
} }
export const getSampleSchema = (schema, contentType="", config={}) => { export const getSampleSchema = (schema, contentType="", config={}, exampleOverride = undefined) => {
if(schema && isFunc(schema.toJS))
schema = schema.toJS()
if(exampleOverride && isFunc(exampleOverride.toJS))
exampleOverride = exampleOverride.toJS()
if (/xml/.test(contentType)) { if (/xml/.test(contentType)) {
return getXmlSampleSchema(schema, config) return getXmlSampleSchema(schema, config, exampleOverride)
} }
return getStringifiedSampleForSchema(schema, config, contentType) return getStringifiedSampleForSchema(schema, config, contentType, exampleOverride)
} }
export const parseSearch = () => { export const parseSearch = () => {

View File

@@ -0,0 +1,43 @@
openapi: 3.0.0
info:
description: Test API
version: v1
title: Test API
tags:
- name: Test
description: Test API
servers:
- url: /v1
paths:
/test:
post:
tags:
- Test
summary: Test endpoint
description: Test
operationId: postTest
responses:
'200':
description: Returns response
content:
application/xml:
schema:
$ref: '#/components/schemas/test'
components:
schemas:
test:
type: object
properties:
a:
type: string
b:
type: integer
c:
oneOf:
- type: object
- type: array
items:
type: string
- type: boolean
- type: integer
- type: number

View File

@@ -0,0 +1,85 @@
openapi: 3.0.0
info:
description: Test API
version: v1
title: Test API
tags:
- name: Test
description: Test API
servers:
- url: /v1
paths:
/test:
post:
tags:
- Test
summary: Test endpoint
description: Test
operationId: postTest
responses:
'200':
description: Returns response
content:
application/xml:
schema:
$ref: '#/components/schemas/test'
components:
schemas:
test:
type: object
properties:
a:
type: string
b:
type: integer
c:
type: array
items:
$ref: '#/components/schemas/Things'
d:
type: array
items:
anyOf:
- $ref: '#/components/schemas/TextObject'
- $ref: '#/components/schemas/ImageObject'
Things:
type: object
oneOf:
- $ref: '#/components/schemas/TextObject'
- $ref: '#/components/schemas/ImageObject'
TextObject:
required:
- data
type: object
properties:
objectType:
type: string
example: Text
xml:
name: ObjectType
data:
type: string
example: This is a text
xml:
name: Data
description: Contains a text
ImageObject:
required:
- data
type: object
properties:
objectType:
type: string
example: image
xml:
name: ObjectType
data:
type: string
example: This is a image
xml:
name: Data
description: Contains a image

View File

@@ -0,0 +1,20 @@
describe("#4943: XML example not rendered correctly with oneOf", () => {
it("should render integer property correctly", () => {
cy
.visit("/?url=/documents/bugs/4943.yaml")
.get("#operations-Test-postTest")
.click()
.get(".microlight")
.contains("<b>0</b>")
})
it("should render oneOf property correctly", () => {
cy
.visit("/?url=/documents/bugs/4943.yaml")
.get("#operations-Test-postTest")
.click()
.get(".try-out__btn")
.click()
.get(".microlight")
.contains("<c>\n\t</c>")
})
})

View File

@@ -0,0 +1,11 @@
describe("#6540: XML example not rendered correctly with oneOf", () => {
it("should render xml like json", () => {
const expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<test>\n\t<a>string</a>\n\t<b>0</b>\n\t<c>\n\t\t<ObjectType>Text</ObjectType>\n\t\t<Data>This is a text</Data>\n\t</c>\n\t<c>\n\t\t<ObjectType>image</ObjectType>\n\t\t<Data>This is a image</Data>\n\t</c>\n\t<d>\n\t\t<ObjectType>Text</ObjectType>\n\t\t<Data>This is a text</Data>\n\t</d>\n\t<d>\n\t\t<ObjectType>image</ObjectType>\n\t\t<Data>This is a image</Data>\n\t</d>\n</test>"
cy
.visit("/?url=/documents/bugs/6540.yaml")
.get("#operations-Test-postTest")
.click()
.get(".microlight")
.contains(expected)
})
})

View File

@@ -512,6 +512,26 @@ describe("sampleFromSchema", () => {
expect(sampleFromSchema(definition)).toEqual(expected) expect(sampleFromSchema(definition)).toEqual(expected)
}) })
}) })
it("should use overrideExample when defined", () => {
const definition = {
type: "object",
properties: {
foo: {
type: "string"
}
},
example: {
foo: null
}
}
const expected = {
foo: "override"
}
expect(sampleFromSchema(definition, {}, expected)).toEqual(expected)
})
}) })
describe("createXMLExample", function () { describe("createXMLExample", function () {
@@ -1337,7 +1357,7 @@ describe("createXMLExample", function () {
}) })
it("returns object with additional props", function () { it("returns object with additional props", function () {
let expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<dog>string</dog>\n\t<additionalProp>string</additionalProp>\n</animals>" let expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<dog>string</dog>\n\t<additionalProp1>string</additionalProp1>\n\t<additionalProp2>string</additionalProp2>\n\t<additionalProp3>string</additionalProp3>\n</animals>"
let definition = { let definition = {
type: "object", type: "object",
properties: { properties: {
@@ -1394,7 +1414,7 @@ describe("createXMLExample", function () {
}) })
it("returns object with additional props with no type passed", function () { it("returns object with additional props with no type passed", function () {
let expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<additionalProp>string</additionalProp>\n</animals>" let expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<animals>\n\t<additionalProp1>string</additionalProp1>\n\t<additionalProp2>string</additionalProp2>\n\t<additionalProp3>string</additionalProp3>\n</animals>"
let definition = { let definition = {
additionalProperties: { additionalProperties: {
type: "string" type: "string"
@@ -1406,5 +1426,34 @@ describe("createXMLExample", function () {
expect(sut(definition)).toEqual(expected) expect(sut(definition)).toEqual(expected)
}) })
it("should use overrideExample when defined", () => {
const expected = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<bar>\n\t<foo>override</foo>\n</bar>"
const definition = {
type: "object",
properties: {
foo: {
type: "string",
xml: {
name: "foo"
}
}
},
example: {
foo: null
},
xml: {
name: "bar"
}
}
const overrideExample = {
foo: "override"
}
expect(sut(definition, {}, overrideExample)).toEqual(expected)
})
}) })
}) })