diff --git a/docs/usage/configuration.md b/docs/usage/configuration.md
index 21533af781b..9cfeb274233 100644
--- a/docs/usage/configuration.md
+++ b/docs/usage/configuration.md
@@ -58,6 +58,7 @@ Parameter name | Docker variable | Description
`operationsSorter` | _Unavailable_ | `Function=(a => a)`. Apply a sort to the operation list of each API. It can be 'alpha' (sort by paths alphanumerically), 'method' (sort by HTTP method) or a function (see Array.prototype.sort() to know how sort function works). Default is the order returned by the server unchanged.
`showExtensions` | `SHOW_EXTENSIONS` | `Boolean=false`. Controls the display of vendor extension (`x-`) fields and values for Operations, Parameters, and Schema.
`showCommonExtensions` | `SHOW_COMMON_EXTENSIONS` | `Boolean=false`. Controls the display of extensions (`pattern`, `maxLength`, `minLength`, `maximum`, `minimum`) fields and values for Parameters.
+ `showAlternativeSchemaExample` | _Unavailable_ | `Boolean=false`. Controls the display of alternative schemas (oneOf/anyOf) in the Example View.
`tagsSorter` | _Unavailable_ | `Function=(a => a)`. Apply a sort to the tag list of each API. It can be 'alpha' (sort by paths alphanumerically) or a function (see [Array.prototype.sort()](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort) to learn how to write a sort function). Two tag name strings are passed to the sorter for each pass. Default is the order determined by Swagger UI.
`useUnsafeMarkdown` | `USE_UNSAFE_MARKDOWN` | `Boolean=false`. When enabled, sanitizer will leave `style`, `class` and `data-*` attributes untouched on all HTML Elements declared inside markdown strings. This parameter is **Deprecated** and will be removed in `4.0.0`.
`onComplete` | _Unavailable_ | `Function=NOOP`. Provides a mechanism to be notified when Swagger UI has finished rendering a newly provided definition.
diff --git a/src/core/components/alternative-schema-select.jsx b/src/core/components/alternative-schema-select.jsx
new file mode 100644
index 00000000000..ff4387dbf76
--- /dev/null
+++ b/src/core/components/alternative-schema-select.jsx
@@ -0,0 +1,91 @@
+import React, { Component } from "react"
+import PropTypes from "prop-types"
+
+export default class AlternativeSchemaSelect extends Component {
+
+ static propTypes = {
+ alternativeSchemaSelections: PropTypes.object.isRequired,
+ onSelectionChanged: PropTypes.func.isRequired,
+ isManualMode: PropTypes.bool.isRequired,
+ alternativeSchemas: PropTypes.object.isRequired
+ }
+
+ constructor(props) {
+ super(props)
+ this.onModeChange = this.onModeChange.bind(this)
+ this.oneOfChange = this.oneOfChange.bind(this)
+ this.selectOneOfComponent = this.selectOneOfComponent.bind(this)
+ this.state = {
+ isManualMode: false,
+ alternativeSchemaSelections: {}
+ }
+ }
+
+ onModeChange(e) {
+ var { onSelectionChanged } = this.props
+ var { alternativeSchemaSelections } = this.state
+
+ onSelectionChanged( (e.target.dataset.name === "MANUAL" ? alternativeSchemaSelections :{}))
+ this.setState({isManualMode: e.target.dataset.name === "MANUAL"})
+ }
+
+ oneOfChange(e, id) {
+ var { onSelectionChanged } = this.props
+ var { alternativeSchemaSelections } = this.state
+
+ alternativeSchemaSelections[id] = parseInt(e.target.value)
+
+ onSelectionChanged( alternativeSchemaSelections )
+ }
+
+ selectOneOfComponent(attributePath, options, defaultOption, type) {
+ if (options) {
+ return (
+
+
+ Choose {type} {attributePath}:
+
+
this.oneOfChange(e, attributePath)}
+ >
+ {""}
+ {Object.keys(options).map((key, index) => {
+ return {options[key]}
+ })}
+
+
+ )
+ }
+ return null
+ }
+
+ render() {
+
+ const { alternativeSchemas } = this.props
+ const { isManualMode } = this.state
+
+ var oneOfComponents = []
+ if (isManualMode && alternativeSchemas) {
+ alternativeSchemas.map((attribute) => {
+ oneOfComponents.push(this.selectOneOfComponent(attribute.key, attribute.options, attribute.selectedIndex, attribute.type))
+ return true
+ })
+ }
+ return (
+
+ )
+ }
+}
\ No newline at end of file
diff --git a/src/core/components/model-example.jsx b/src/core/components/model-example.jsx
index b7498ebdbef..13b42588fcf 100644
--- a/src/core/components/model-example.jsx
+++ b/src/core/components/model-example.jsx
@@ -13,6 +13,9 @@ export default class ModelExample extends React.Component {
specPath: ImPropTypes.list.isRequired,
includeReadOnly: PropTypes.bool,
includeWriteOnly: PropTypes.bool,
+ alternativeSchemas: PropTypes.object,
+ onSelectedAlternativeOptionChanged: PropTypes.func,
+ onChange: PropTypes.func,
}
constructor(props, context) {
@@ -54,10 +57,11 @@ export default class ModelExample extends React.Component {
}
render() {
- let { getComponent, specSelectors, schema, example, isExecute, getConfigs, specPath, includeReadOnly, includeWriteOnly } = this.props
+ let { getComponent, specSelectors, schema, example, isExecute, getConfigs, specPath, includeReadOnly, includeWriteOnly, alternativeSchemas, onChange } = this.props
let { defaultModelExpandDepth } = getConfigs()
const ModelWrapper = getComponent("ModelWrapper")
const HighlightCode = getComponent("highlightCode")
+ const AlternativeSchemaSelect = getComponent("alternativeSchemaSelect")
let isOAS3 = specSelectors.isOAS3()
@@ -80,6 +84,14 @@ export default class ModelExample extends React.Component {
)
) : null
}
+ {
+ this.state.activeTab === "example" && alternativeSchemas && onChange ? (
+
+ ) : null
+ }
{
this.state.activeTab === "model" && {
+ this.setState({alternativeSchemaSelections: alternativeSchemaSelections})
+ }}
onChangeIncludeEmpty={(name, value) => {
oas3Actions.setRequestBodyInclusion({
pathMethod,
diff --git a/src/core/components/response.jsx b/src/core/components/response.jsx
index 2e078c99dd6..efc8f72b762 100644
--- a/src/core/components/response.jsx
+++ b/src/core/components/response.jsx
@@ -22,6 +22,7 @@ export default class Response extends React.Component {
this.state = {
responseContentType: "",
+ alternativeSchemaSelections: {}
}
}
@@ -40,7 +41,8 @@ export default class Response extends React.Component {
contentType: PropTypes.string,
activeExamplesKey: PropTypes.string,
controlsAcceptHeader: PropTypes.bool,
- onContentTypeChange: PropTypes.func
+ onContentTypeChange: PropTypes.func,
+ alternativeSchemaSelections: PropTypes.object
}
static defaultProps = {
@@ -57,6 +59,10 @@ export default class Response extends React.Component {
})
}
+ _onAlternativeSchemaChanged = (alternativeSchemaSelections) =>{
+ this.setState({alternativeSchemaSelections: alternativeSchemaSelections})
+ }
+
getTargetExamplesKey = () => {
const { response, contentType, activeExamplesKey } = this.props
@@ -85,6 +91,8 @@ export default class Response extends React.Component {
oas3Actions,
} = this.props
+ const { showAlternativeSchemaExample } = getConfigs()
+
let { inferSchema } = fn
let isOAS3 = specSelectors.isOAS3()
@@ -131,8 +139,11 @@ export default class Response extends React.Component {
sampleResponse = stringify(activeMediaType.get("example"))
} else {
// use an example value generated based on the schema
+ var alternativeSchemas = showAlternativeSchemaExample === true ? [] : undefined
sampleResponse = getSampleSchema(oas3SchemaForContentType.toJS(), this.state.responseContentType, {
- includeReadOnly: true
+ includeReadOnly: true,
+ alternativeSchemas: alternativeSchemas,
+ alternativeSchemaSelections: this.state.alternativeSchemaSelections || {}
})
}
} else {
@@ -219,7 +230,10 @@ export default class Response extends React.Component {
specSelectors={ specSelectors }
schema={ fromJSOrdered(schema) }
example={ example }
- includeReadOnly={ true }/>
+ includeReadOnly={ true }
+ alternativeSchemas= { alternativeSchemas }
+ onChange = { this._onAlternativeSchemaChanged }/>
+
) : null }
{ isOAS3 && examplesForMediaType ? (
diff --git a/src/core/index.js b/src/core/index.js
index 057586216d9..268f3df9544 100644
--- a/src/core/index.js
+++ b/src/core/index.js
@@ -50,6 +50,7 @@ export default function SwaggerUI(opts) {
defaultModelsExpandDepth: 1,
showExtensions: false,
showCommonExtensions: false,
+ showAlternativeSchemaExample: false,
withCredentials: undefined,
supportedSubmitMethods: [
"get",
diff --git a/src/core/plugins/oas3/components/request-body.jsx b/src/core/plugins/oas3/components/request-body.jsx
index 05aa3dd0fcd..614e6158e55 100644
--- a/src/core/plugins/oas3/components/request-body.jsx
+++ b/src/core/plugins/oas3/components/request-body.jsx
@@ -4,7 +4,7 @@ import ImPropTypes from "react-immutable-proptypes"
import { Map, OrderedMap, List } from "immutable"
import { getCommonExtensions, getSampleSchema, stringify, isEmptyValue } from "core/utils"
-function getDefaultRequestBodyValue(requestBody, mediaType, activeExamplesKey) {
+function getDefaultRequestBodyValue(requestBody, mediaType, activeExamplesKey, alternativeSchemas, alternativeSchemaSelections) {
let mediaTypeValue = requestBody.getIn(["content", mediaType])
let schema = mediaTypeValue.get("schema").toJS()
let example =
@@ -25,7 +25,9 @@ function getDefaultRequestBodyValue(requestBody, mediaType, activeExamplesKey) {
return stringify(
example ||
getSampleSchema(schema, mediaType, {
- includeWriteOnly: true
+ includeWriteOnly: true,
+ alternativeSchemas: alternativeSchemas,
+ alternativeSchemaSelections: alternativeSchemaSelections
}) ||
""
)
@@ -50,6 +52,8 @@ const RequestBody = ({
onChangeIncludeEmpty,
activeExamplesKey,
updateActiveExamplesKey,
+ alternativeSchemaSelections,
+ onAlternativeSchemaChange,
}) => {
const handleFile = (e) => {
onChange(e.target.files[0])
@@ -76,7 +80,7 @@ const RequestBody = ({
const Example = getComponent("Example")
const ParameterIncludeEmpty = getComponent("ParameterIncludeEmpty")
- const { showCommonExtensions } = getConfigs()
+ const { showCommonExtensions, showAlternativeSchemaExample } = getConfigs()
const requestBodyDescription = (requestBody && requestBody.get("description")) || null
const requestBodyContent = (requestBody && requestBody.get("content")) || new OrderedMap()
@@ -206,6 +210,8 @@ const RequestBody = ({
}
+ var alternativeSchemas = showAlternativeSchemaExample === true ? [] : undefined
+
return
{ requestBodyDescription &&
@@ -239,6 +245,7 @@ const RequestBody = ({
/>
) : (
+
}
@@ -288,6 +299,8 @@ RequestBody.propTypes = {
specPath: PropTypes.array.isRequired,
activeExamplesKey: PropTypes.string,
updateActiveExamplesKey: PropTypes.func,
+ alternativeSchemaSelections: PropTypes.object,
+ onAlternativeSchemaChange: PropTypes.func,
}
export default RequestBody
diff --git a/src/core/plugins/samples/fn.js b/src/core/plugins/samples/fn.js
index 401ba329141..8fd15dbd26a 100644
--- a/src/core/plugins/samples/fn.js
+++ b/src/core/plugins/samples/fn.js
@@ -30,11 +30,73 @@ const primitive = (schema) => {
return "Unknown Type: " + schema.type
}
+const extractDiscriminatorMappingValues = (discriminator) => {
+ var discriminatorMappingValues
+ if (discriminator && discriminator.propertyName && discriminator.mapping){
+ discriminatorMappingValues ={}
+ Object.keys(discriminator.mapping).map(function(key) {
+ var mappingKey = discriminator.mapping[key]
+ if(mappingKey){
+ var mappingName = mappingKey.split("#")
+ discriminatorMappingValues[mappingName[mappingName.length-1]] = key
+ }
+ })
+ }
+ return discriminatorMappingValues
+}
-export const sampleFromSchema = (schema, config={}) => {
- let { type, example, properties, additionalProperties, items } = objectify(schema)
- let { includeReadOnly, includeWriteOnly } = config
+const evaluateOptionName = (valueObj) => {
+ if (valueObj.title){
+ return valueObj.title
+ } else if (valueObj.$$ref){
+ return valueObj.$$ref.split("/").pop(-1)
+ } else if (valueObj.properties){
+ let attr = Object.keys(valueObj.properties)
+ return "Item " + (attr.length == 1 ? "(" + attr[0] + ")": attr.length > 1 ? "(" + attr[0] + ", ...)": "" )
+ } else {
+ return "Item"
+ }
+}
+const extractAlternativeSchema = (oneOfSchema, config, path, type, discriminator) => {
+ if ( Array.isArray(oneOfSchema) && oneOfSchema.length > 0) {
+
+ let { alternativeSchemas, alternativeSchemaSelections } = config
+
+ let index = 0
+ let options = {}
+ let discriminatorMappingValues = extractDiscriminatorMappingValues(discriminator)
+
+ oneOfSchema.map(valueObj => {
+ options["#" + index++] = "#" + index + ": " + evaluateOptionName(valueObj)
+
+ if (discriminatorMappingValues && valueObj.properties && valueObj.$$ref){
+ var discriminatorProperty = valueObj.properties[discriminator.propertyName]
+ if (discriminatorProperty && !discriminatorProperty["example"]) {
+ var mappingNane = valueObj.$$ref.split("#")
+ var example = discriminatorMappingValues[mappingNane[mappingNane.length-1]]
+ if(example){
+ discriminatorProperty["example"] = example
+ }
+ }
+ }
+ return true
+ })
+
+ let selectedIndex = alternativeSchemaSelections[path] || 0
+ if ( selectedIndex >= oneOfSchema.length || selectedIndex < -1) {
+ selectedIndex = 0
+ }
+ alternativeSchemas.push({ key: path, options: options, selectedIndex: selectedIndex, type})
+
+ return selectedIndex >-1 ? oneOfSchema[selectedIndex] : undefined
+ }
+ return
+}
+
+export const sampleFromSchema = (schema, config={}, path="#") => {
+ let { type, example, properties, additionalProperties, items, oneOf, anyOf, discriminator } = objectify(schema)
+ let { includeReadOnly, includeWriteOnly, alternativeSchemas } = config
if(example !== undefined) {
return deeplyStripKey(example, "$$ref", (val) => {
@@ -44,10 +106,31 @@ export const sampleFromSchema = (schema, config={}) => {
})
}
- if(!type) {
- if(properties) {
+ if (alternativeSchemas && !items) {
+ if (oneOf) {
+ let oneOfSchema = extractAlternativeSchema(oneOf, config, path, "one of", discriminator)
+ oneOfSchema = Object.assign({}, schema, oneOfSchema)
+ if (schema.properties) {
+ Object.assign(oneOfSchema.properties, schema.properties)
+ }
+ delete oneOfSchema.oneOf
+ return sampleFromSchema(oneOfSchema, config, path)
+ }
+ if (anyOf) {
+ let anyOfSchema = extractAlternativeSchema(anyOf, config, path, "any of", discriminator)
+ anyOfSchema = Object.assign({}, schema, anyOfSchema)
+ if (schema.properties) {
+ Object.assign(anyOfSchema.properties, schema.properties)
+ }
+ delete anyOfSchema.anyOf
+ return sampleFromSchema(anyOfSchema, config, path)
+ }
+ }
+
+ if (!type) {
+ if (properties) {
type = "object"
- } else if(items) {
+ } else if (items) {
type = "array"
} else {
return
@@ -56,6 +139,7 @@ export const sampleFromSchema = (schema, config={}) => {
if(type === "object") {
let props = objectify(properties)
+
let obj = {}
for (var name in props) {
if ( props[name] && props[name].deprecated ) {
@@ -67,7 +151,7 @@ export const sampleFromSchema = (schema, config={}) => {
if ( props[name] && props[name].writeOnly && !includeWriteOnly ) {
continue
}
- obj[name] = sampleFromSchema(props[name], config)
+ obj[name] = sampleFromSchema(props[name], config, path + "/" + name)
}
if ( additionalProperties === true ) {
@@ -85,14 +169,14 @@ export const sampleFromSchema = (schema, config={}) => {
if(type === "array") {
if(Array.isArray(items.anyOf)) {
- return items.anyOf.map(i => sampleFromSchema(i, config))
+ return items.anyOf.map(i => sampleFromSchema(i, config, path + "[]"))
}
- if(Array.isArray(items.oneOf)) {
- return items.oneOf.map(i => sampleFromSchema(i, config))
+ if(Array.isArray(items.oneOf) && !alternativeSchemas) {
+ return items.oneOf.map(i => sampleFromSchema(i, config, path + "[]"))
}
- return [ sampleFromSchema(items, config) ]
+ return [ sampleFromSchema(items, config, path + "[]") ]
}
if(schema["enum"]) {
diff --git a/src/core/presets/base.js b/src/core/presets/base.js
index 6fe8f43c618..9fa50d05890 100644
--- a/src/core/presets/base.js
+++ b/src/core/presets/base.js
@@ -68,6 +68,7 @@ import Schemes from "core/components/schemes"
import SchemesContainer from "core/containers/schemes"
import ModelCollapse from "core/components/model-collapse"
import ModelExample from "core/components/model-example"
+import AlternativeSchemaSelect from "core/components/alternative-schema-select"
import ModelWrapper from "core/components/model-wrapper"
import Model from "core/components/model"
import Models from "core/components/models"
@@ -134,6 +135,7 @@ export default function() {
schemes: Schemes,
SchemesContainer,
modelExample: ModelExample,
+ alternativeSchemaSelect: AlternativeSchemaSelect,
ModelWrapper,
ModelCollapse,
Model,
diff --git a/src/style/_layout.scss b/src/style/_layout.scss
index 91493496fee..ea9f8afa8bd 100644
--- a/src/style/_layout.scss
+++ b/src/style/_layout.scss
@@ -824,6 +824,14 @@
}
}
+.response-control-alternative-examples {
+ font-size: 12px;
+ &__title {
+ display: block;
+ margin-bottom: 0.2em;
+ }
+}
+
@keyframes blinker
{
50%
diff --git a/test/mocha/components/response.jsx b/test/mocha/components/response.jsx
index 0cbde9ecb3a..d688865c2e8 100644
--- a/test/mocha/components/response.jsx
+++ b/test/mocha/components/response.jsx
@@ -16,6 +16,7 @@ describe(" ", function () {
operationLink: dummyComponent,
contentType: dummyComponent
}
+
const props = {
getComponent: c => components[c],
specSelectors: {
@@ -29,6 +30,7 @@ describe(" ", function () {
contentType: "application/json",
className: "for-test",
specPath: List(),
+ getConfigs: function(){ return {showAlternativeSchemaExample: undefined}},
response: fromJS({
schema: {
type: "object",
diff --git a/test/mocha/core/plugins/samples/fn.js b/test/mocha/core/plugins/samples/fn.js
index 496adafd7ca..d3173e7a7b3 100644
--- a/test/mocha/core/plugins/samples/fn.js
+++ b/test/mocha/core/plugins/samples/fn.js
@@ -512,7 +512,536 @@ describe("sampleFromSchema", function() {
expect(sampleFromSchema(definition)).toEqual(expected)
})
+ }),
+
+ describe("alternative schema (oneOf/anyOf)", function() {
+ var definition = {
+ "type": "object",
+ "properties": {
+ "address": {
+ "type": "string"
+ },
+ "options": {
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "shipping": {
+ "type": "string",
+ "enum": [
+ "FAST",
+ "STANDARD"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "properties": {
+ "remarks": {
+ "type": "string"
+ },
+ "comment": {
+ "type": "string",
+ "example": "My comment"
+ },
+ "count": {
+ "type": "integer",
+ "example": 99
+ }
+ }
+ }
+ ]
+ }
+ }
+ }
+
+ it("returns first `oneOf` item as example", function() {
+
+ var expected = {
+ "address": "string",
+ "options": {
+ "remarks": "string",
+ "comment": "My comment",
+ "count": 99
+ }
+ }
+
+ var alternativeSchemas= []
+ var alternativeSchemaSelections= {"#/options": 1}
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#/options": 1} })
+ expect(result).toEqual(expected)
+ })
+
+ it("extracts `oneOf` options", function() {
+
+ var expected = [
+ {
+ "selectedIndex": 1,
+ "key": "#/options",
+ "options": {
+ "#0": "#1: Item (shipping)",
+ "#1": "#2: Item (remarks, ...)"
+ },
+ "type": "one of"
+ }
+ ]
+
+ var alternativeSchemas= []
+ var alternativeSchemaSelections= {"#/options": 1}
+
+ sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: alternativeSchemaSelections })
+ expect(alternativeSchemas).toEqual(expected)
+ })
+
+ it("extracts `oneOf` options and adapted selection ", function() {
+
+ var expected = [
+ {
+ "selectedIndex": 0,
+ "key": "#/options",
+ "options": {
+ "#0": "#1: Item (shipping)",
+ "#1": "#2: Item (remarks, ...)"
+ },
+ "type": "one of"
+ }
+ ]
+
+ var alternativeSchemas= []
+
+ sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#/options": 99999} })
+ expect(alternativeSchemas).toEqual(expected)
+ })
+
+ it("extracts `oneOf` options and select first element ", function() {
+
+ var expected = [
+ {
+ "selectedIndex": 0,
+ "key": "#/options",
+ "options": {
+ "#0": "#1: Item (shipping)",
+ "#1": "#2: Item (remarks, ...)"
+ },
+ "type": "one of"
+ }
+ ]
+
+ var alternativeSchemas= []
+
+ sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections:{} })
+ expect(alternativeSchemas).toEqual(expected)
+ })
+
+ it("returns example without and alternative schema as undefined ()", function() {
+
+ var expected = {
+ "address": "string",
+ "options": undefined
+ }
+
+ let result = sampleFromSchema(definition)
+ expect(result).toEqual(expected)
+ }
+ )}
+ )
+
+ describe("alternative schema (oneOf/anyOf) attribute", function() {
+ var definition = {
+
+ "oneOf": [
+ {
+ "type": "string",
+ "example": "first"
+ },
+ {
+ "type": "integer",
+ "example": 99
+ }
+ ]
+ }
+
+ it("returns first `oneOf` attribute as example", function() {
+
+ var expected = "first"
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 0} })
+ expect(result).toEqual(expected)
+ })
+
+ it("returns second `oneOf` attribute as example", function() {
+
+ var expected = 99
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 1} })
+ expect(result).toEqual(expected)
+ })
+
+ it("extracts `oneOf` options", function() {
+
+ var expected = [
+ {
+ "selectedIndex": 1,
+ "key": "#",
+ "options": {
+ "#0": "#1: Item",
+ "#1": "#2: Item"
+ },
+ "type": "one of"
+ }
+ ]
+
+ var alternativeSchemas= []
+ var alternativeSchemaSelections= {"#": 1}
+
+ sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: alternativeSchemaSelections })
+ expect(alternativeSchemas).toEqual(expected)
+ })
+
+ })
+
+ describe("alternative schema on object level (oneOf/anyOf)", function() {
+ var definition = {
+ "type": "object",
+ "properties": {
+ "emailAddress": {
+ "type": "string"
+ },
+ },
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "shipping": {
+ "type": "string",
+ "enum": [
+ "FAST",
+ "STANDARD"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "title": "My Title",
+ "properties": {
+ "remarks": {
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+
+ it("returns first `oneOf` item as example", function() {
+
+ var expected = {
+ "emailAddress": "string",
+ "shipping": "FAST"
+ }
+
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#/options": 1} })
+ expect(result).toEqual(expected)
+ })
+
+ it("extracts `oneOf` options", function() {
+
+ var expected = [
+ {
+ "selectedIndex": 1,
+ "key": "#",
+ "options": {
+ "#0": "#1: Item (shipping, ...)",
+ "#1": "#2: My Title"
+ },
+ "type": "one of"
+ }
+ ]
+
+ var alternativeSchemas= []
+
+ sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 1} })
+ expect(alternativeSchemas).toEqual(expected)
+ })
+
+ it("extracts `oneOf` options and adapted selection ", function() {
+
+ var expected = [
+ {
+ "selectedIndex": 0,
+ "key": "#",
+ "options": {
+ "#0": "#1: Item (shipping, ...)",
+ "#1": "#2: My Title"
+ },
+ "type": "one of"
+ }
+ ]
+
+ var alternativeSchemas= []
+
+ sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 99999} })
+ expect(alternativeSchemas).toEqual(expected)
+ })
+
+ it("extracts `oneOf` options and select first element ", function() {
+
+ var expected = [
+ {
+ "selectedIndex": 0,
+ "key": "#",
+ "options": {
+ "#0": "#1: Item (shipping, ...)",
+ "#1": "#2: My Title"
+ },
+ "type": "one of"
+ }
+ ]
+
+ var alternativeSchemas= []
+
+ sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections:{} })
+ expect(alternativeSchemas).toEqual(expected)
+ })
+
+ it("returns example without and alternative schema as undefined ()", function() {
+
+ var expected = {
+ "emailAddress": "string"
+ }
+
+ let result = sampleFromSchema(definition)
+ expect(result).toEqual(expected)
+ }
+ )}
+ )
+
+ describe("alternative schema (oneOf/anyOf) with discriminator", function() {
+ var definition = {
+ "type": "object",
+ "properties": {
+ "emailAddress": {
+ "type": "string"
+ },
+ },
+ "oneOf": [
+ {
+ "$$ref": "swagger.yaml#/components/schemas/AnObjectA",
+ "type": "object",
+ "properties": {
+ "objectType": {
+ "type": "string",
+ },
+ "shipping": {
+ "type": "string",
+ "enum": [
+ "FAST",
+ "STANDARD"
+ ]
+ }
+ }
+ },
+ {
+ "$$ref": "#/components/schemas/AnObjectB",
+ "type": "object",
+ "properties": {
+ "objectType": {
+ "type": "string",
+ },
+ "remarks": {
+ "type": "string",
+ "example": "A remark"
+ }
+ }
+ },
+ {
+ "$$ref": "#/components/schemas/AnObjectC",
+ "type": "object",
+ "properties": {
+ "objectType": {
+ "type": "string",
+ },
+ "comment": {
+ "type": "string"
+ }
+ }
+ }
+ ],
+ "discriminator": {
+ "propertyName": "objectType",
+ "mapping": {
+ "objA": "#/components/schemas/AnObjectA",
+ "objB": "#/components/schemas/AnObjectB",
+ "objD": "#/components/schemas/NotMatching"
+ }
+ }
+ }
+
+ it("returns first `oneOf` item with objectType A", function() {
+
+ var expected = {
+ "emailAddress": "string",
+ "shipping": "FAST",
+ "objectType": "objA"
+ }
+
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 0} })
+ expect(result).toEqual(expected)
+ })
+
+ it("returns second `oneOf` item with objectType B", function() {
+
+ var expected = {
+ "emailAddress": "string",
+ "remarks": "A remark",
+ "objectType": "objB"
+ }
+
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 1} })
+ expect(result).toEqual(expected)
+ })
+
+ it("returns second `oneOf` item with objectType C", function() {
+
+ var expected = {
+ "emailAddress": "string",
+ "comment": "string",
+ "objectType": "string"
+ }
+
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 2} })
+ expect(result).toEqual(expected)
+ })
})
+
+ describe("alternative schema (oneOf) of array type", function() {
+ var definition = {
+ "type": "array",
+ "items": {
+ "type": "object",
+ "properties": {
+ "emailAddress": {
+ "type": "string"
+ }
+ },
+ "oneOf": [
+ {
+ "type": "object",
+ "properties": {
+ "shipping": {
+ "type": "string",
+ "enum": [
+ "FAST",
+ "STANDARD"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "properties": {
+ "remarks": {
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+
+ it("returns first `oneOf` item with objectType A", function() {
+
+ var expected = [{
+ "emailAddress": "string",
+ "shipping": "FAST"
+ }]
+
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 0} })
+ expect(result).toEqual(expected)
+ })
+
+ it("returns second `oneOf` item with objectType B", function() {
+
+ var expected = [{
+ "emailAddress": "string",
+ "remarks": "string"
+ }]
+
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#[]": 1} })
+ expect(result).toEqual(expected)
+ })
+ })
+
+ describe("alternative schema (anyOf) of array type", function() {
+ var definition = {
+ "type": "array",
+ "items": {
+ "anyOf": [
+ {
+ "type": "object",
+ "properties": {
+ "shipping": {
+ "type": "string",
+ "enum": [
+ "FAST",
+ "STANDARD"
+ ]
+ }
+ }
+ },
+ {
+ "type": "object",
+ "properties": {
+ "remarks": {
+ "type": "string"
+ }
+ }
+ }
+ ]
+ }
+ }
+
+ it("returns all `anyOf` items", function() {
+
+ var expected = [
+ {"shipping": "FAST"},
+ {"remarks": "string"}
+ ]
+
+ var alternativeSchemas= []
+
+ var result = sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 0} })
+ expect(result).toEqual(expected)
+ })
+
+ it("alternativeSchemaSelections shows allItems", function() {
+
+ var expected = []
+
+ var alternativeSchemas= []
+
+ sampleFromSchema(definition, {alternativeSchemas: alternativeSchemas, alternativeSchemaSelections: {"#": 0} })
+ expect(alternativeSchemas).toEqual(expected)
+ })
+
+ })
+
})
describe("createXMLExample", function () {