Skip to content

Commit 913cc2d

Browse files
authored
adding dereference of refs in anyOfs (#207)
1 parent b4e7e06 commit 913cc2d

File tree

2 files changed

+163
-0
lines changed

2 files changed

+163
-0
lines changed

index.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -904,12 +904,26 @@ function buildArrayTypeCondition (type, accessor) {
904904
return condition
905905
}
906906

907+
function dereferenceAnyOfRefs (schema, externalSchema, fullSchema) {
908+
schema.anyOf.forEach((s, index) => {
909+
// follow the refs
910+
while (s.$ref) {
911+
schema.anyOf[index] = refFinder(s.$ref, fullSchema, externalSchema)
912+
s = schema.anyOf[index]
913+
}
914+
})
915+
}
916+
907917
function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKey) {
908918
var code = ''
909919
var funcName
910920

911921
subKey = subKey || ''
912922

923+
if (schema.$ref) {
924+
schema = refFinder(schema.$ref, fullSchema, externalSchema)
925+
}
926+
913927
if (schema.type === undefined) {
914928
var inferedType = inferTypeByKeyword(schema)
915929
if (inferedType) {
@@ -955,6 +969,7 @@ function nested (laterCode, name, key, schema, externalSchema, fullSchema, subKe
955969
break
956970
case undefined:
957971
if ('anyOf' in schema) {
972+
dereferenceAnyOfRefs(schema, externalSchema, fullSchema)
958973
schema.anyOf.forEach((s, index) => {
959974
var nestedResult = nested(laterCode, name, key, s, externalSchema, fullSchema, subKey !== '' ? subKey : 'i' + index)
960975
code += `

test/anyof.test.js

Lines changed: 148 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,3 +248,151 @@ test('null value in schema', (t) => {
248248
t.fail()
249249
}
250250
})
251+
252+
test('anyOf and $ref together', (t) => {
253+
t.plan(2)
254+
255+
const schema = {
256+
type: 'object',
257+
properties: {
258+
cs: {
259+
anyOf: [
260+
{
261+
$ref: '#/definitions/Option'
262+
},
263+
{
264+
type: 'boolean'
265+
}
266+
]
267+
}
268+
},
269+
definitions: {
270+
Option: {
271+
type: 'string'
272+
}
273+
}
274+
}
275+
276+
const stringify = build(schema)
277+
278+
try {
279+
const value = stringify({
280+
cs: 'franco'
281+
})
282+
t.is(value, '{"cs":"franco"}')
283+
} catch (e) {
284+
t.fail()
285+
}
286+
287+
try {
288+
const value = stringify({
289+
cs: true
290+
})
291+
t.is(value, '{"cs":true}')
292+
} catch (e) {
293+
t.fail()
294+
}
295+
})
296+
297+
test('anyOf and $ref: 2 levels are fine', (t) => {
298+
t.plan(1)
299+
300+
const schema = {
301+
type: 'object',
302+
properties: {
303+
cs: {
304+
anyOf: [
305+
{
306+
$ref: '#/definitions/Option'
307+
},
308+
{
309+
type: 'boolean'
310+
}
311+
]
312+
}
313+
},
314+
definitions: {
315+
Option: {
316+
anyOf: [
317+
{
318+
type: 'number'
319+
},
320+
{
321+
type: 'boolean'
322+
}
323+
]
324+
}
325+
}
326+
}
327+
328+
const stringify = build(schema)
329+
try {
330+
const value = stringify({
331+
cs: 3
332+
})
333+
t.is(value, '{"cs":3}')
334+
} catch (e) {
335+
t.fail()
336+
}
337+
})
338+
339+
test('anyOf and $ref: multiple levels should throw at build.', (t) => {
340+
t.plan(3)
341+
342+
const schema = {
343+
type: 'object',
344+
properties: {
345+
cs: {
346+
anyOf: [
347+
{
348+
$ref: '#/definitions/Option'
349+
},
350+
{
351+
type: 'boolean'
352+
}
353+
]
354+
}
355+
},
356+
definitions: {
357+
Option: {
358+
anyOf: [
359+
{
360+
$ref: '#/definitions/Option2'
361+
},
362+
{
363+
type: 'string'
364+
}
365+
]
366+
},
367+
Option2: {
368+
type: 'number'
369+
}
370+
}
371+
}
372+
373+
const stringify = build(schema)
374+
try {
375+
const value = stringify({
376+
cs: 3
377+
})
378+
t.is(value, '{"cs":3}')
379+
} catch (e) {
380+
t.fail(e)
381+
}
382+
try {
383+
const value = stringify({
384+
cs: true
385+
})
386+
t.is(value, '{"cs":true}')
387+
} catch (e) {
388+
t.fail(e)
389+
}
390+
try {
391+
const value = stringify({
392+
cs: 'pippo'
393+
})
394+
t.is(value, '{"cs":"pippo"}')
395+
} catch (e) {
396+
t.fail(e)
397+
}
398+
})

0 commit comments

Comments
 (0)