Skip to content

Commit

Permalink
adding dereference of refs in anyOfs (#207)
Browse files Browse the repository at this point in the history
  • Loading branch information
hazam committed Feb 4, 2020
1 parent b4e7e06 commit 913cc2d
Show file tree
Hide file tree
Showing 2 changed files with 163 additions and 0 deletions.
15 changes: 15 additions & 0 deletions index.js
Expand Up @@ -904,12 +904,26 @@ function buildArrayTypeCondition (type, accessor) {
return condition
}

function dereferenceAnyOfRefs (schema, externalSchema, fullSchema) {
schema.anyOf.forEach((s, index) => {
// follow the refs
while (s.$ref) {
schema.anyOf[index] = refFinder(s.$ref, fullSchema, externalSchema)
s = schema.anyOf[index]
}
})
}

function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKey) {
var code = ''
var funcName

subKey = subKey || ''

if (schema.$ref) {
schema = refFinder(schema.$ref, fullSchema, externalSchema)
}

if (schema.type === undefined) {
var inferedType = inferTypeByKeyword(schema)
if (inferedType) {
Expand Down Expand Up @@ -955,6 +969,7 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKe
break
case undefined:
if ('anyOf' in schema) {
dereferenceAnyOfRefs(schema, externalSchema, fullSchema)
schema.anyOf.forEach((s, index) => {
var nestedResult = nested(laterCode, name, key, s, externalSchema, fullSchema, subKey !== '' ? subKey : 'i' + index)
code += `
Expand Down
148 changes: 148 additions & 0 deletions test/anyof.test.js
Expand Up @@ -248,3 +248,151 @@ test('null value in schema', (t) => {
t.fail()
}
})

test('anyOf and $ref together', (t) => {
t.plan(2)

const schema = {
type: 'object',
properties: {
cs: {
anyOf: [
{
$ref: '#/definitions/Option'
},
{
type: 'boolean'
}
]
}
},
definitions: {
Option: {
type: 'string'
}
}
}

const stringify = build(schema)

try {
const value = stringify({
cs: 'franco'
})
t.is(value, '{"cs":"franco"}')
} catch (e) {
t.fail()
}

try {
const value = stringify({
cs: true
})
t.is(value, '{"cs":true}')
} catch (e) {
t.fail()
}
})

test('anyOf and $ref: 2 levels are fine', (t) => {
t.plan(1)

const schema = {
type: 'object',
properties: {
cs: {
anyOf: [
{
$ref: '#/definitions/Option'
},
{
type: 'boolean'
}
]
}
},
definitions: {
Option: {
anyOf: [
{
type: 'number'
},
{
type: 'boolean'
}
]
}
}
}

const stringify = build(schema)
try {
const value = stringify({
cs: 3
})
t.is(value, '{"cs":3}')
} catch (e) {
t.fail()
}
})

test('anyOf and $ref: multiple levels should throw at build.', (t) => {
t.plan(3)

const schema = {
type: 'object',
properties: {
cs: {
anyOf: [
{
$ref: '#/definitions/Option'
},
{
type: 'boolean'
}
]
}
},
definitions: {
Option: {
anyOf: [
{
$ref: '#/definitions/Option2'
},
{
type: 'string'
}
]
},
Option2: {
type: 'number'
}
}
}

const stringify = build(schema)
try {
const value = stringify({
cs: 3
})
t.is(value, '{"cs":3}')
} catch (e) {
t.fail(e)
}
try {
const value = stringify({
cs: true
})
t.is(value, '{"cs":true}')
} catch (e) {
t.fail(e)
}
try {
const value = stringify({
cs: 'pippo'
})
t.is(value, '{"cs":"pippo"}')
} catch (e) {
t.fail(e)
}
})

0 comments on commit 913cc2d

Please sign in to comment.