You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							322 lines
						
					
					
						
							5.6 KiB
						
					
					
				
			
		
		
	
	
							322 lines
						
					
					
						
							5.6 KiB
						
					
					
				'use strict'
 | 
						|
 | 
						|
const moment = require('moment')
 | 
						|
const test = require('tap').test
 | 
						|
const validator = require('is-my-json-valid')
 | 
						|
const build = require('..')
 | 
						|
 | 
						|
function buildTest (schema, toStringify) {
 | 
						|
  test(`render a ${schema.title} as JSON`, (t) => {
 | 
						|
    t.plan(3)
 | 
						|
 | 
						|
    const validate = validator(schema)
 | 
						|
    const stringify = build(schema)
 | 
						|
    const output = stringify(toStringify)
 | 
						|
 | 
						|
    t.same(JSON.parse(output), toStringify)
 | 
						|
    t.equal(output, JSON.stringify(toStringify))
 | 
						|
    t.ok(validate(JSON.parse(output)), 'valid schema')
 | 
						|
  })
 | 
						|
}
 | 
						|
 | 
						|
buildTest({
 | 
						|
  title: 'string array',
 | 
						|
  type: 'object',
 | 
						|
  properties: {
 | 
						|
    ids: {
 | 
						|
      type: 'array',
 | 
						|
      items: {
 | 
						|
        type: 'string'
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}, {
 | 
						|
  ids: ['test']
 | 
						|
})
 | 
						|
 | 
						|
buildTest({
 | 
						|
  title: 'number array',
 | 
						|
  type: 'object',
 | 
						|
  properties: {
 | 
						|
    ids: {
 | 
						|
      type: 'array',
 | 
						|
      items: {
 | 
						|
        type: 'number'
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}, {
 | 
						|
  ids: [1]
 | 
						|
})
 | 
						|
 | 
						|
buildTest({
 | 
						|
  title: 'mixed array',
 | 
						|
  type: 'object',
 | 
						|
  properties: {
 | 
						|
    ids: {
 | 
						|
      type: 'array',
 | 
						|
      items: [
 | 
						|
        {
 | 
						|
          type: 'null'
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: 'string'
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: 'integer'
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: 'number'
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: 'boolean'
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: 'object',
 | 
						|
          properties: {
 | 
						|
            a: {
 | 
						|
              type: 'string'
 | 
						|
            }
 | 
						|
          }
 | 
						|
        },
 | 
						|
        {
 | 
						|
          type: 'array',
 | 
						|
          items: {
 | 
						|
            type: 'string'
 | 
						|
          }
 | 
						|
        }
 | 
						|
      ]
 | 
						|
    }
 | 
						|
  }
 | 
						|
}, {
 | 
						|
  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 }] })
 | 
						|
 | 
						|
buildTest({
 | 
						|
  title: 'array with weird key',
 | 
						|
  type: 'object',
 | 
						|
  properties: {
 | 
						|
    '@data': {
 | 
						|
      type: 'array',
 | 
						|
      items: {
 | 
						|
        type: 'string'
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
}, {
 | 
						|
  '@data': ['test']
 | 
						|
})
 | 
						|
 | 
						|
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'] }))
 | 
						|
})
 | 
						|
 | 
						|
test('moment array', (t) => {
 | 
						|
  t.plan(1)
 | 
						|
  const schema = {
 | 
						|
    type: 'object',
 | 
						|
    properties: {
 | 
						|
      times: {
 | 
						|
        type: 'array',
 | 
						|
        items: {
 | 
						|
          type: 'string',
 | 
						|
          format: 'date-time'
 | 
						|
        }
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
  const stringify = build(schema)
 | 
						|
  const value = stringify({
 | 
						|
    times: [moment('2018-04-21T07:52:31.017Z')]
 | 
						|
  })
 | 
						|
  t.equal(value, '{"times":["2018-04-21T07:52:31.017Z"]}')
 | 
						|
})
 | 
						|
 | 
						|
buildTest({
 | 
						|
  title: 'item types in array default to any',
 | 
						|
  type: 'object',
 | 
						|
  properties: {
 | 
						|
    foo: {
 | 
						|
      type: 'array'
 | 
						|
    }
 | 
						|
  }
 | 
						|
}, {
 | 
						|
  foo: [1, 'string', {}, null]
 | 
						|
})
 | 
						|
 | 
						|
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'
 | 
						|
          }
 | 
						|
        ],
 | 
						|
        additionalItems: true
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const stringify = build(schema)
 | 
						|
  const result = stringify({
 | 
						|
    foo: [
 | 
						|
      'foo',
 | 
						|
      'bar',
 | 
						|
      1
 | 
						|
    ]
 | 
						|
  })
 | 
						|
 | 
						|
  t.equal(result, '{"foo":["foo","bar",1]}')
 | 
						|
})
 | 
						|
 | 
						|
test('array items is a list of schema and additionalItems is false', (t) => {
 | 
						|
  t.plan(1)
 | 
						|
 | 
						|
  const schema = {
 | 
						|
    type: 'object',
 | 
						|
    properties: {
 | 
						|
      foo: {
 | 
						|
        type: 'array',
 | 
						|
        items: [
 | 
						|
          {
 | 
						|
            type: 'string'
 | 
						|
          }
 | 
						|
        ],
 | 
						|
        additionalItems: false
 | 
						|
      }
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  const stringify = build(schema)
 | 
						|
 | 
						|
  try {
 | 
						|
    stringify({
 | 
						|
      foo: [
 | 
						|
        'foo',
 | 
						|
        'bar'
 | 
						|
      ]
 | 
						|
    })
 | 
						|
    t.fail()
 | 
						|
  } catch (error) {
 | 
						|
    t.ok(/does not match schema definition./.test(error.message))
 | 
						|
  }
 | 
						|
})
 | 
						|
 | 
						|
// https://github.com/fastify/fast-json-stringify/issues/279
 | 
						|
test('object array with anyOf and symbol', (t) => {
 | 
						|
  t.plan(1)
 | 
						|
  const ArrayKind = Symbol('ArrayKind')
 | 
						|
  const ObjectKind = Symbol('LiteralKind')
 | 
						|
  const UnionKind = Symbol('UnionKind')
 | 
						|
  const LiteralKind = Symbol('LiteralKind')
 | 
						|
  const StringKind = Symbol('StringKind')
 | 
						|
 | 
						|
  const schema = {
 | 
						|
    kind: ArrayKind,
 | 
						|
    type: 'array',
 | 
						|
    items: {
 | 
						|
      kind: ObjectKind,
 | 
						|
      type: 'object',
 | 
						|
      properties: {
 | 
						|
        name: {
 | 
						|
          kind: StringKind,
 | 
						|
          type: 'string'
 | 
						|
        },
 | 
						|
        option: {
 | 
						|
          kind: UnionKind,
 | 
						|
          anyOf: [
 | 
						|
            {
 | 
						|
              kind: LiteralKind,
 | 
						|
              type: 'string',
 | 
						|
              enum: ['Foo']
 | 
						|
            },
 | 
						|
            {
 | 
						|
              kind: LiteralKind,
 | 
						|
              type: 'string',
 | 
						|
              enum: ['Bar']
 | 
						|
            }
 | 
						|
          ]
 | 
						|
        }
 | 
						|
      },
 | 
						|
      required: ['name', 'option']
 | 
						|
    }
 | 
						|
  }
 | 
						|
  const stringify = build(schema)
 | 
						|
  const value = stringify([
 | 
						|
    { name: 'name-0', option: 'Foo' },
 | 
						|
    { name: 'name-1', option: 'Bar' }
 | 
						|
  ])
 | 
						|
  t.equal(value, '[{"name":"name-0","option":"Foo"},{"name":"name-1","option":"Bar"}]')
 | 
						|
})
 |