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"}]')
 | |
| })
 |