Skip to content

Commit

Permalink
refactor: buildArray function (#457)
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-tymoshenko authored Jun 10, 2022
1 parent 658411c commit 310325b
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 41 deletions.
96 changes: 55 additions & 41 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -754,45 +754,21 @@ function buildArray (location, locationPath) {
`
}

let result = { code: '' }
const accessor = '[i]'
if (Array.isArray(schema.items)) {
result = schema.items.reduce((res, item, i) => {
const tmpRes = buildValue(locationPath + accessor + i, 'obj[i]', mergeLocation(location, { schema: item }))
const condition = `i === ${i} && ${buildArrayTypeCondition(item.type, accessor)}`
return {
code: `${res.code}
${i > 0 ? 'else' : ''} if (${condition}) {
${tmpRes}
}`
}
}, result)

if (schema.additionalItems) {
const tmpRes = buildValue(locationPath + accessor, 'obj[i]', mergeLocation(location, { schema: schema.items }))
result.code += `
else if (i >= ${schema.items.length}) {
${tmpRes}
}
`
}

result.code += `
else {
throw new Error(\`Item at $\{i} does not match schema definition.\`)
}
`
} else {
result.code = buildValue(locationPath + accessor, 'obj[i]', mergeLocation(location, { schema: schema.items }))
}

functionCode += `
if (!Array.isArray(obj)) {
throw new TypeError(\`The value '$\{obj}' does not match schema definition.\`)
}
const arrayLength = obj.length
`

functionCode += 'const arrayLength = obj.length\n'
if (!schema.additionalItems) {
functionCode += `
if (arrayLength > ${schema.items.length}) {
throw new Error(\`Item at ${schema.items.length} does not match schema definition.\`)
}
`
}

if (largeArrayMechanism !== 'default') {
if (largeArrayMechanism === 'json-stringify') {
functionCode += `if (arrayLength && arrayLength >= ${largeArraySize}) return JSON.stringify(obj)\n`
Expand All @@ -802,16 +778,54 @@ function buildArray (location, locationPath) {
}

functionCode += `
let jsonOutput= ''
for (let i = 0; i < arrayLength; i++) {
let json = ''
${result.code}
jsonOutput += json
let jsonOutput = ''
`

if (json.length > 0 && i < arrayLength - 1) {
jsonOutput += ','
}
const accessor = '[i]'
if (Array.isArray(schema.items)) {
for (let i = 0; i < schema.items.length; i++) {
const item = schema.items[i]
const tmpRes = buildValue(locationPath + accessor + i, `obj[${i}]`, mergeLocation(location, { schema: item }))
functionCode += `
if (${i} < arrayLength) {
if (${buildArrayTypeCondition(item.type, `[${i}]`)}) {
let json = ''
${tmpRes}
jsonOutput += json
if (${i} < arrayLength - 1) {
jsonOutput += ','
}
} else {
throw new Error(\`Item at ${i} does not match schema definition.\`)
}
}
`
}

if (schema.additionalItems) {
functionCode += `
for (let i = ${schema.items.length}; i < arrayLength; i++) {
let json = JSON.stringify(obj[i])
jsonOutput += json
if (i < arrayLength - 1) {
jsonOutput += ','
}
}`
}
} else {
const code = buildValue(locationPath + accessor, 'obj[i]', mergeLocation(location, { schema: schema.items }))
functionCode += `
for (let i = 0; i < arrayLength; i++) {
let json = ''
${code}
jsonOutput += json
if (i < arrayLength - 1) {
jsonOutput += ','
}
}`
}

functionCode += `
return \`[\${jsonOutput}]\`
}`

Expand Down
29 changes: 29 additions & 0 deletions test/array.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,35 @@ test('array items is a list of schema and additionalItems is true, just the desc
t.equal(result, '{"foo":["foo","bar",1]}')
})

test('array items is a list of schema and additionalItems is true, just the described item is validated', (t) => {
t.plan(1)

const schema = {
type: 'object',
properties: {
foo: {
type: 'array',
items: [
{
type: 'string'
},
{
type: 'number'
}
],
additionalItems: true
}
}
}

const stringify = build(schema)
const result = stringify({
foo: ['foo']
})

t.equal(result, '{"foo":["foo"]}')
})

test('array items is a list of schema and additionalItems is false', (t) => {
t.plan(1)

Expand Down

0 comments on commit 310325b

Please sign in to comment.