Skip to content

Commit

Permalink
fix: non-nullable schema receiving null input does not coerce for def…
Browse files Browse the repository at this point in the history
…ault types on object and arrays (#670)
  • Loading branch information
rhighs authored Jan 5, 2024
1 parent 6de8c6c commit 721c599
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 6 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,8 @@ Otherwise, instead of raising an error, null values will be coerced as follows:
- `number` -> `0`
- `string` -> `""`
- `boolean` -> `false`
- `object` -> `{}`
- `array` -> `[]`

<a name="largearrays"></a>
#### Large Arrays
Expand Down
5 changes: 5 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -560,10 +560,13 @@ function buildObject (context, location) {
let functionCode = `
`

const nullable = schema.nullable === true
functionCode += `
// ${schemaRef}
function ${functionName} (input) {
const obj = ${toJSON('input')}
${!nullable ? 'if (obj === null) return \'{}\'' : ''}
${buildInnerObject(context, location)}
}
`
Expand Down Expand Up @@ -601,7 +604,9 @@ function buildArray (context, location) {
// ${schemaRef}
`

const nullable = schema.nullable === true
functionCode += `
${!nullable ? 'if (obj === null) return \'[]\'' : ''}
if (!Array.isArray(obj)) {
throw new TypeError(\`The value of '${schemaRef}' does not match schema definition.\`)
}
Expand Down
37 changes: 33 additions & 4 deletions test/toJSON.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ test('not fail on null sub-object declared nullable', (t) => {
t.equal('{"product":null}', stringify(object))
})

test('throw an error on non nullable null sub-object', (t) => {
test('on non nullable null sub-object it should coerce to {}', (t) => {
t.plan(1)

const stringify = build({
Expand All @@ -148,10 +148,12 @@ test('throw an error on non nullable null sub-object', (t) => {
const object = {
product: null
}
t.throws(() => { stringify(object) })

const result = stringify(object)
t.equal(result, JSON.stringify({ product: {} }))
})

test('throw an error on non nullable null object', (t) => {
test('on non nullable null object it should coerce to {}', (t) => {
t.plan(1)

const stringify = build({
Expand All @@ -170,5 +172,32 @@ test('throw an error on non nullable null object', (t) => {
}
}
})
t.throws(() => { stringify(null) })

const result = stringify(null)
t.equal(result, '{}')
})

test('on non-nullable null object it should skip rendering, skipping required fields checks', (t) => {
t.plan(1)

const stringify = build({
title: 'simple object',
nullable: false,
type: 'object',
properties: {
product: {
nullable: false,
type: 'object',
properties: {
name: {
type: 'string'
}
}
}
},
required: ['product']
})

const result = stringify(null)
t.equal(result, '{}')
})
5 changes: 3 additions & 2 deletions test/typesArray.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -467,7 +467,7 @@ test('class instance that is simultaneously a string and a json', (t) => {
t.equal(valueObj, '{"simultaneously":{"foo":"hello"}}')
})

test('should throw an error when type is array and object is null', (t) => {
test('should not throw an error when type is array and object is null, it should instead coerce to []', (t) => {
t.plan(1)
const schema = {
type: 'object',
Expand All @@ -482,7 +482,8 @@ test('should throw an error when type is array and object is null', (t) => {
}

const stringify = build(schema)
t.throws(() => stringify({ arr: null }), new TypeError('The value of \'#/properties/arr\' does not match schema definition.'))
const result = stringify({ arr: null })
t.equal(result, JSON.stringify({ arr: [] }))
})

test('should throw an error when type is array and object is not an array', (t) => {
Expand Down

0 comments on commit 721c599

Please sign in to comment.