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.
		
		
		
		
		
			
		
			
				
					
					
						
							1252 lines
						
					
					
						
							22 KiB
						
					
					
				
			
		
		
	
	
							1252 lines
						
					
					
						
							22 KiB
						
					
					
				| 'use strict'
 | |
| 
 | |
| const test = require('tap').test
 | |
| const build = require('..')
 | |
| 
 | |
| test('ref internal - properties', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     definitions: {
 | |
|       def: {
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           str: {
 | |
|             type: 'string'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     type: 'object',
 | |
|     properties: {
 | |
|       obj: {
 | |
|         $ref: '#/definitions/def'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     obj: {
 | |
|       str: 'test'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"obj":{"str":"test"}}')
 | |
| })
 | |
| 
 | |
| test('ref internal - items', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'array with $ref',
 | |
|     definitions: {
 | |
|       def: {
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           str: {
 | |
|             type: 'string'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     type: 'array',
 | |
|     items: { $ref: '#/definitions/def' }
 | |
|   }
 | |
| 
 | |
|   const array = [{
 | |
|     str: 'test'
 | |
|   }]
 | |
| 
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(array)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '[{"str":"test"}]')
 | |
| })
 | |
| 
 | |
| test('ref external - properties', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     first: require('./ref.json'),
 | |
|     second: {
 | |
|       definitions: {
 | |
|         num: {
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             int: {
 | |
|               type: 'integer'
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     third: {
 | |
|       type: 'string'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     type: 'object',
 | |
|     properties: {
 | |
|       obj: {
 | |
|         $ref: 'first#/definitions/def'
 | |
|       },
 | |
|       num: {
 | |
|         $ref: 'second#/definitions/num'
 | |
|       },
 | |
|       strPlain: {
 | |
|         $ref: 'third'
 | |
|       },
 | |
|       strHash: {
 | |
|         $ref: 'third#'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     obj: {
 | |
|       str: 'test'
 | |
|     },
 | |
|     num: {
 | |
|       int: 42
 | |
|     },
 | |
|     strPlain: 'test',
 | |
|     strHash: 'test'
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"obj":{"str":"test"},"num":{"int":42},"strPlain":"test","strHash":"test"}')
 | |
| })
 | |
| 
 | |
| test('ref internal - patternProperties', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     definitions: {
 | |
|       def: {
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           str: {
 | |
|             type: 'string'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     type: 'object',
 | |
|     properties: {},
 | |
|     patternProperties: {
 | |
|       obj: {
 | |
|         $ref: '#/definitions/def'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     obj: {
 | |
|       str: 'test'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"obj":{"str":"test"}}')
 | |
| })
 | |
| 
 | |
| test('ref internal - additionalProperties', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     definitions: {
 | |
|       def: {
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           str: {
 | |
|             type: 'string'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     type: 'object',
 | |
|     properties: {},
 | |
|     additionalProperties: {
 | |
|       $ref: '#/definitions/def'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     obj: {
 | |
|       str: 'test'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"obj":{"str":"test"}}')
 | |
| })
 | |
| 
 | |
| test('ref internal - pattern-additional Properties', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     definitions: {
 | |
|       def: {
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           str: {
 | |
|             type: 'string'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     type: 'object',
 | |
|     properties: {},
 | |
|     patternProperties: {
 | |
|       reg: {
 | |
|         $ref: '#/definitions/def'
 | |
|       }
 | |
|     },
 | |
|     additionalProperties: {
 | |
|       $ref: '#/definitions/def'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     reg: {
 | |
|       str: 'test'
 | |
|     },
 | |
|     obj: {
 | |
|       str: 'test'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"reg":{"str":"test"},"obj":{"str":"test"}}')
 | |
| })
 | |
| 
 | |
| test('ref external - pattern-additional Properties', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     first: require('./ref.json'),
 | |
|     second: {
 | |
|       definitions: {
 | |
|         num: {
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             int: {
 | |
|               type: 'integer'
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     type: 'object',
 | |
|     properties: {},
 | |
|     patternProperties: {
 | |
|       reg: {
 | |
|         $ref: 'first#/definitions/def'
 | |
|       }
 | |
|     },
 | |
|     additionalProperties: {
 | |
|       $ref: 'second#/definitions/num'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     reg: {
 | |
|       str: 'test'
 | |
|     },
 | |
|     obj: {
 | |
|       int: 42
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"reg":{"str":"test"},"obj":{"int":42}}')
 | |
| })
 | |
| 
 | |
| test('ref internal - deepObject schema', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     definitions: {
 | |
|       def: {
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           coming: {
 | |
|             type: 'object',
 | |
|             properties: {
 | |
|               where: {
 | |
|                 type: 'string'
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     type: 'object',
 | |
|     properties: {
 | |
|       winter: {
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           is: {
 | |
|             $ref: '#/definitions/def'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     winter: {
 | |
|       is: {
 | |
|         coming: {
 | |
|           where: 'to town'
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"winter":{"is":{"coming":{"where":"to town"}}}}')
 | |
| })
 | |
| 
 | |
| test('ref internal - plain name fragment', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     definitions: {
 | |
|       def: {
 | |
|         $id: '#uri',
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           str: {
 | |
|             type: 'string'
 | |
|           }
 | |
|         },
 | |
|         required: ['str']
 | |
|       }
 | |
|     },
 | |
|     type: 'object',
 | |
|     properties: {
 | |
|       obj: {
 | |
|         $ref: '#uri'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     obj: {
 | |
|       str: 'test'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"obj":{"str":"test"}}')
 | |
| })
 | |
| 
 | |
| test('ref external - plain name fragment', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     first: {
 | |
|       $id: '#first-schema',
 | |
|       type: 'object',
 | |
|       properties: {
 | |
|         str: {
 | |
|           type: 'string'
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     second: {
 | |
|       definitions: {
 | |
|         second: {
 | |
|           $id: '#second-schema',
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             int: {
 | |
|               type: 'integer'
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref to external plain name fragment',
 | |
|     type: 'object',
 | |
|     properties: {
 | |
|       first: {
 | |
|         $ref: '#first-schema'
 | |
|       },
 | |
|       second: {
 | |
|         $ref: '#second-schema'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     first: {
 | |
|       str: 'test'
 | |
|     },
 | |
|     second: {
 | |
|       int: 42
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"first":{"str":"test"},"second":{"int":42}}')
 | |
| })
 | |
| 
 | |
| test('ref external - duplicate plain name fragment', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     external: {
 | |
|       $id: '#duplicateSchema',
 | |
|       type: 'object',
 | |
|       properties: {
 | |
|         prop: {
 | |
|           type: 'boolean'
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     other: {
 | |
|       $id: '#otherSchema',
 | |
|       type: 'object',
 | |
|       properties: {
 | |
|         prop: {
 | |
|           type: 'integer'
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref to plain name fragment',
 | |
|     type: 'object',
 | |
|     definitions: {
 | |
|       duplicate: {
 | |
|         $id: '#duplicateSchema',
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           prop: {
 | |
|             type: 'string'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     properties: {
 | |
|       local: {
 | |
|         $ref: '#duplicateSchema'
 | |
|       },
 | |
|       external: {
 | |
|         $ref: 'external#duplicateSchema'
 | |
|       },
 | |
|       other: {
 | |
|         $ref: '#otherSchema'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     local: {
 | |
|       prop: 'test'
 | |
|     },
 | |
|     external: {
 | |
|       prop: true
 | |
|     },
 | |
|     other: {
 | |
|       prop: 42
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"local":{"prop":"test"},"external":{"prop":true},"other":{"prop":42}}')
 | |
| })
 | |
| 
 | |
| test('ref external - explicit external plain name fragment must not fallback to other external schemas', (t) => {
 | |
|   t.plan(1)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     first: {
 | |
|       $id: '#target',
 | |
|       type: 'object',
 | |
|       properties: {
 | |
|         prop: {
 | |
|           type: 'string'
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     second: {
 | |
|       $id: '#wrong',
 | |
|       type: 'object',
 | |
|       properties: {
 | |
|         prop: {
 | |
|           type: 'integer'
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref to plain name fragment',
 | |
|     type: 'object',
 | |
|     definitions: {
 | |
|       third: {
 | |
|         $id: '#wrong',
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           prop: {
 | |
|             type: 'boolean'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     properties: {
 | |
|       target: {
 | |
|         $ref: 'first#wrong'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     target: {
 | |
|       prop: 'test'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   try {
 | |
|     const stringify = build(schema, { schema: externalSchema })
 | |
|     const output = stringify(object)
 | |
|     JSON.parse(output)
 | |
|     t.fail()
 | |
|   } catch (e) {
 | |
|     t.pass()
 | |
|   }
 | |
| })
 | |
| 
 | |
| test('ref internal - multiple $ref format', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     type: 'object',
 | |
|     definitions: {
 | |
|       one: {
 | |
|         type: 'string',
 | |
|         definitions: {
 | |
|           two: {
 | |
|             $id: '#twos',
 | |
|             type: 'string'
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     properties: {
 | |
|       zero: {
 | |
|         $id: '#three',
 | |
|         type: 'string'
 | |
|       },
 | |
|       a: { $ref: '#/definitions/one' },
 | |
|       b: { $ref: '#three' },
 | |
|       c: { $ref: '#/properties/zero' },
 | |
|       d: { $ref: '#twos' },
 | |
|       e: { $ref: '#/definitions/one/definitions/two' }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     zero: 'test',
 | |
|     a: 'test',
 | |
|     b: 'test',
 | |
|     c: 'test',
 | |
|     d: 'test',
 | |
|     e: 'test'
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"zero":"test","a":"test","b":"test","c":"test","d":"test","e":"test"}')
 | |
| })
 | |
| 
 | |
| test('ref external - external schema with internal ref (object property)', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     external: {
 | |
|       definitions: {
 | |
|         internal: { type: 'string' },
 | |
|         def: {
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             prop: { $ref: '#/definitions/internal' }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     type: 'object',
 | |
|     properties: {
 | |
|       obj: {
 | |
|         $ref: 'external#/definitions/def'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     obj: {
 | |
|       prop: 'test'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"obj":{"prop":"test"}}')
 | |
| })
 | |
| 
 | |
| test('ref external - external schema with internal ref (array items)', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     external: {
 | |
|       definitions: {
 | |
|         internal: { type: 'string' },
 | |
|         def: {
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             prop: { $ref: '#/definitions/internal' }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     type: 'object',
 | |
|     properties: {
 | |
|       arr: {
 | |
|         type: 'array',
 | |
|         items: {
 | |
|           $ref: 'external#/definitions/def'
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     arr: [{
 | |
|       prop: 'test'
 | |
|     }]
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"arr":[{"prop":"test"}]}')
 | |
| })
 | |
| 
 | |
| test('ref external - external schema with internal ref (root)', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     external: {
 | |
|       definitions: {
 | |
|         internal: { type: 'string' },
 | |
|         def: {
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             prop: { $ref: '#/definitions/internal' }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     $ref: 'external#/definitions/def'
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     prop: 'test'
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"prop":"test"}')
 | |
| })
 | |
| 
 | |
| test('ref external - external schema with internal ref (pattern properties)', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     external: {
 | |
|       definitions: {
 | |
|         internal: { type: 'string' },
 | |
|         def: {
 | |
|           type: 'object',
 | |
|           patternProperties: {
 | |
|             '^p': { $ref: '#/definitions/internal' }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref',
 | |
|     type: 'object',
 | |
|     patternProperties: {
 | |
|       '^o': {
 | |
|         $ref: 'external#/definitions/def'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = {
 | |
|     obj: {
 | |
|       prop: 'test'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"obj":{"prop":"test"}}')
 | |
| })
 | |
| 
 | |
| test('ref in root internal', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref in root schema',
 | |
|     $ref: '#/definitions/num',
 | |
|     definitions: {
 | |
|       num: {
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           int: {
 | |
|             $ref: '#/definitions/int'
 | |
|           }
 | |
|         }
 | |
|       },
 | |
|       int: {
 | |
|         type: 'integer'
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = { int: 42 }
 | |
|   const stringify = build(schema)
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"int":42}')
 | |
| })
 | |
| 
 | |
| test('ref in root external', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     numbers: {
 | |
|       $id: 'numbers',
 | |
|       definitions: {
 | |
|         num: {
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             int: {
 | |
|               type: 'integer'
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref in root schema',
 | |
|     type: 'object',
 | |
|     $ref: 'numbers#/definitions/num'
 | |
|   }
 | |
| 
 | |
|   const object = { int: 42 }
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"int":42}')
 | |
| })
 | |
| 
 | |
| test('ref in root external multiple times', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     numbers: {
 | |
|       $id: 'numbers',
 | |
|       $ref: 'subnumbers#/definitions/num'
 | |
|     },
 | |
|     subnumbers: {
 | |
|       $id: 'subnumbers',
 | |
|       definitions: {
 | |
|         num: {
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             int: {
 | |
|               type: 'integer'
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     title: 'object with $ref in root schema',
 | |
|     type: 'object',
 | |
|     $ref: 'numbers#/definitions/num'
 | |
|   }
 | |
| 
 | |
|   const object = { int: 42 }
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"int":42}')
 | |
| })
 | |
| 
 | |
| test('ref external to relative definition', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     'relative:to:local': {
 | |
|       $id: 'relative:to:local',
 | |
|       type: 'object',
 | |
|       properties: {
 | |
|         foo: { $ref: '#/definitions/foo' }
 | |
|       },
 | |
|       definitions: {
 | |
|         foo: { type: 'string' }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     type: 'object',
 | |
|     required: ['fooParent'],
 | |
|     properties: {
 | |
|       fooParent: { $ref: 'relative:to:local' }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = { fooParent: { foo: 'bar' } }
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"fooParent":{"foo":"bar"}}')
 | |
| })
 | |
| 
 | |
| test('ref to nested ref definition', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     'a:b:c1': {
 | |
|       $id: 'a:b:c1',
 | |
|       type: 'object',
 | |
|       definitions: {
 | |
|         foo: { $ref: 'a:b:c2#/definitions/foo' }
 | |
|       }
 | |
|     },
 | |
|     'a:b:c2': {
 | |
|       $id: 'a:b:c2',
 | |
|       type: 'object',
 | |
|       definitions: {
 | |
|         foo: { type: 'string' }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     type: 'object',
 | |
|     required: ['foo'],
 | |
|     properties: {
 | |
|       foo: { $ref: 'a:b:c1#/definitions/foo' }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = { foo: 'foo' }
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"foo":"foo"}')
 | |
| })
 | |
| 
 | |
| test('ref in definition with exact match', (t) => {
 | |
|   t.plan(2)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     '#/definitions/foo': {
 | |
|       type: 'string'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     type: 'object',
 | |
|     properties: {
 | |
|       foo: { $ref: '#/definitions/foo' }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const object = { foo: 'foo' }
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify(object)
 | |
| 
 | |
|   JSON.parse(output)
 | |
|   t.pass()
 | |
| 
 | |
|   t.equal(output, '{"foo":"foo"}')
 | |
| })
 | |
| 
 | |
| test('Bad key', t => {
 | |
|   t.test('Find match', t => {
 | |
|     t.plan(1)
 | |
|     try {
 | |
|       build({
 | |
|         definitions: {
 | |
|           projectId: {
 | |
|             type: 'object',
 | |
|             properties: {
 | |
|               id: { type: 'integer' }
 | |
|             }
 | |
|           }
 | |
|         },
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           data: {
 | |
|             $ref: '#/definitions/porjectId'
 | |
|           }
 | |
|         }
 | |
|       })
 | |
|       t.fail('Should throw')
 | |
|     } catch (err) {
 | |
|       t.equal(err.message, 'Cannot find reference "porjectId", did you mean "projectId"?')
 | |
|     }
 | |
|   })
 | |
| 
 | |
|   t.test('No match', t => {
 | |
|     t.plan(1)
 | |
|     try {
 | |
|       build({
 | |
|         definitions: {
 | |
|           projectId: {
 | |
|             type: 'object',
 | |
|             properties: {
 | |
|               id: { type: 'integer' }
 | |
|             }
 | |
|           }
 | |
|         },
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           data: {
 | |
|             $ref: '#/definitions/foobar'
 | |
|           }
 | |
|         }
 | |
|       })
 | |
|       t.fail('Should throw')
 | |
|     } catch (err) {
 | |
|       t.equal(err.message, 'Cannot find reference "foobar"')
 | |
|     }
 | |
|   })
 | |
| 
 | |
|   t.test('Find match (external schema)', t => {
 | |
|     t.plan(1)
 | |
|     try {
 | |
|       build({
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           data: {
 | |
|             $ref: 'external#/definitions/porjectId'
 | |
|           }
 | |
|         }
 | |
|       }, {
 | |
|         schema: {
 | |
|           external: {
 | |
|             definitions: {
 | |
|               projectId: {
 | |
|                 type: 'object',
 | |
|                 properties: {
 | |
|                   id: { type: 'integer' }
 | |
|                 }
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       })
 | |
|       t.fail('Should throw')
 | |
|     } catch (err) {
 | |
|       t.equal(err.message, 'Cannot find reference "porjectId", did you mean "projectId"?')
 | |
|     }
 | |
|   })
 | |
| 
 | |
|   t.test('No match (external schema)', t => {
 | |
|     t.plan(1)
 | |
|     try {
 | |
|       build({
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           data: {
 | |
|             $ref: 'external#/definitions/foobar'
 | |
|           }
 | |
|         }
 | |
|       }, {
 | |
|         schema: {
 | |
|           external: {
 | |
|             definitions: {
 | |
|               projectId: {
 | |
|                 type: 'object',
 | |
|                 properties: {
 | |
|                   id: { type: 'integer' }
 | |
|                 }
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       })
 | |
|       t.fail('Should throw')
 | |
|     } catch (err) {
 | |
|       t.equal(err.message, 'Cannot find reference "foobar"')
 | |
|     }
 | |
|   })
 | |
| 
 | |
|   t.test('Find match (external definitions typo)', t => {
 | |
|     t.plan(1)
 | |
|     try {
 | |
|       build({
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           data: {
 | |
|             $ref: 'external#/deifnitions/projectId'
 | |
|           }
 | |
|         }
 | |
|       }, {
 | |
|         schema: {
 | |
|           external: {
 | |
|             definitions: {
 | |
|               projectId: {
 | |
|                 type: 'object',
 | |
|                 properties: {
 | |
|                   id: { type: 'integer' }
 | |
|                 }
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       })
 | |
|       t.fail('Should throw')
 | |
|     } catch (err) {
 | |
|       t.equal(err.message, 'Cannot find reference "deifnitions", did you mean "definitions"?')
 | |
|     }
 | |
|   })
 | |
| 
 | |
|   t.test('Find match (definitions typo)', t => {
 | |
|     t.plan(1)
 | |
|     try {
 | |
|       build({
 | |
|         definitions: {
 | |
|           projectId: {
 | |
|             type: 'object',
 | |
|             properties: {
 | |
|               id: { type: 'integer' }
 | |
|             }
 | |
|           }
 | |
|         },
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           data: {
 | |
|             $ref: '#/deifnitions/projectId'
 | |
|           }
 | |
|         }
 | |
|       })
 | |
|       t.fail('Should throw')
 | |
|     } catch (err) {
 | |
|       t.equal(err.message, 'Cannot find reference "deifnitions", did you mean "definitions"?')
 | |
|     }
 | |
|   })
 | |
| 
 | |
|   t.test('Find match (external schema typo)', t => {
 | |
|     t.plan(1)
 | |
|     try {
 | |
|       build({
 | |
|         type: 'object',
 | |
|         properties: {
 | |
|           data: {
 | |
|             $ref: 'extrenal#/definitions/projectId'
 | |
|           }
 | |
|         }
 | |
|       }, {
 | |
|         schema: {
 | |
|           external: {
 | |
|             definitions: {
 | |
|               projectId: {
 | |
|                 type: 'object',
 | |
|                 properties: {
 | |
|                   id: { type: 'integer' }
 | |
|                 }
 | |
|               }
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       })
 | |
|       t.fail('Should throw')
 | |
|     } catch (err) {
 | |
|       t.equal(err.message, 'Cannot find reference "extrenal", did you mean "external"?')
 | |
|     }
 | |
|   })
 | |
| 
 | |
|   t.end()
 | |
| })
 | |
| 
 | |
| test('Regression 2.5.2', t => {
 | |
|   t.plan(1)
 | |
| 
 | |
|   const externalSchema = {
 | |
|     '/models/Bar': {
 | |
|       $id: '/models/Bar',
 | |
|       $schema: 'http://json-schema.org/schema#',
 | |
|       definitions: {
 | |
|         entity: {
 | |
|           type: 'object',
 | |
|           properties: { field: { type: 'string' } }
 | |
|         }
 | |
|       }
 | |
|     },
 | |
|     '/models/Foo': {
 | |
|       $id: '/models/Foo',
 | |
|       $schema: 'http://json-schema.org/schema#',
 | |
|       definitions: {
 | |
|         entity: {
 | |
|           type: 'object',
 | |
|           properties: {
 | |
|             field: { type: 'string' },
 | |
|             sub: {
 | |
|               oneOf: [
 | |
|                 { $ref: '/models/Bar#/definitions/entity' },
 | |
|                 { type: 'null' }
 | |
|               ]
 | |
|             }
 | |
|           }
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const schema = {
 | |
|     type: 'array',
 | |
|     items: {
 | |
|       $ref: '/models/Foo#/definitions/entity'
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   const stringify = build(schema, { schema: externalSchema })
 | |
|   const output = stringify([{ field: 'parent', sub: { field: 'joined' } }])
 | |
| 
 | |
|   t.equal(output, '[{"field":"parent","sub":{"field":"joined"}}]')
 | |
| })
 |