diff --git a/index.js b/index.js index 32f6f194..946abf12 100644 --- a/index.js +++ b/index.js @@ -407,41 +407,46 @@ function buildArray (schema, code, name, externalSchema, fullSchema) { result = schema.items.reduce((res, item, i) => { var accessor = '[i]' const tmpRes = nested(laterCode, name, accessor, item, externalSchema, fullSchema, i) - var condition + var condition = `i === ${i} && ` switch (item.type) { case 'null': - condition = `obj${accessor} === null` + condition += `obj${accessor} === null` break case 'string': - condition = `typeof obj${accessor} === 'string'` + condition += `typeof obj${accessor} === 'string'` break case 'integer': - condition = `Number.isInteger(obj${accessor})` + condition += `Number.isInteger(obj${accessor})` break case 'number': - condition = `!Number.isInteger(obj${accessor}) && Number.isFinite(obj${accessor})` + condition += `Number.isFinite(obj${accessor})` break case 'boolean': - condition = `typeof obj${accessor} === 'boolean'` + condition += `typeof obj${accessor} === 'boolean'` break case 'object': - condition = `obj${accessor} && typeof obj${accessor} === 'object' && obj${accessor}.constructor === Object` + condition += `obj${accessor} && typeof obj${accessor} === 'object' && obj${accessor}.constructor === Object` break case 'array': - condition = `Array.isArray(obj${accessor})` + condition += `Array.isArray(obj${accessor})` break default: throw new Error(`${item.type} unsupported`) } return { code: `${res.code} - if (${condition}) { + ${i > 0 ? 'else' : ''} if (${condition}) { ${tmpRes.code} }`, laterCode: `${res.laterCode} ${tmpRes.laterCode}` } }, result) + result.code += ` + else { + throw new Error(\`Item at $\{i} does not match schema definition.\`) + } + ` } else { result = nested(laterCode, name, '[i]', schema.items, externalSchema, fullSchema) } diff --git a/test/array.test.js b/test/array.test.js index f130368d..9223a8bd 100644 --- a/test/array.test.js +++ b/test/array.test.js @@ -94,3 +94,73 @@ buildTest({ }, { ids: [null, 'test', 1, 1.1, true, {a: 'test'}, ['test']] }) + +buildTest({ + 'title': 'repeated types', + 'type': 'object', + 'properties': { + 'ids': { + 'type': 'array', + 'items': [ + { + type: 'number' + }, + { + type: 'number' + } + ] + } + } +}, {ids: [1, 2]}) + +buildTest({ + 'title': 'pattern properties array', + 'type': 'object', + 'properties': { + 'args': { + 'type': 'array', + 'items': [ + { + 'type': 'object', + 'patternProperties': { + '.*': { + 'type': 'string' + } + } + }, + { + 'type': 'object', + 'patternProperties': { + '.*': { + 'type': 'number' + } + } + } + ] + } + } +}, {args: [{a: 'test'}, {b: 1}]}) + +test('invalid items throw', (t) => { + t.plan(1) + const schema = { + 'type': 'object', + 'properties': { + 'args': { + 'type': 'array', + 'items': [ + { + 'type': 'object', + 'patternProperties': { + '.*': { + 'type': 'string' + } + } + } + ] + } + } + } + const stringify = build(schema) + t.throws(() => stringify({args: ['invalid']})) +})