fast-json-stringify 3.2.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/test/date.test.js CHANGED
@@ -1,7 +1,7 @@
1
1
  'use strict'
2
2
 
3
3
  const test = require('tap').test
4
- const moment = require('moment')
4
+ const { DateTime } = require('luxon')
5
5
  const validator = require('is-my-json-valid')
6
6
  const build = require('..')
7
7
 
@@ -40,13 +40,14 @@ test('render a date in a string when format is date-format as ISOString', (t) =>
40
40
  t.ok(validate(JSON.parse(output)), 'valid schema')
41
41
  })
42
42
 
43
- test('render a date in a string when format is date as YYYY-MM-DD', (t) => {
43
+ test('render a nullable date in a string when format is date-format as ISOString', (t) => {
44
44
  t.plan(2)
45
45
 
46
46
  const schema = {
47
47
  title: 'a date in a string',
48
48
  type: 'string',
49
- format: 'date'
49
+ format: 'date-time',
50
+ nullable: true
50
51
  }
51
52
  const toStringify = new Date()
52
53
 
@@ -54,11 +55,11 @@ test('render a date in a string when format is date as YYYY-MM-DD', (t) => {
54
55
  const stringify = build(schema)
55
56
  const output = stringify(toStringify)
56
57
 
57
- t.equal(output, `"${moment(toStringify).format('YYYY-MM-DD')}"`)
58
+ t.equal(output, JSON.stringify(toStringify))
58
59
  t.ok(validate(JSON.parse(output)), 'valid schema')
59
60
  })
60
61
 
61
- test('verify padding for rendered date in a string when format is date', (t) => {
62
+ test('render a date in a string when format is date as YYYY-MM-DD', (t) => {
62
63
  t.plan(2)
63
64
 
64
65
  const schema = {
@@ -66,23 +67,24 @@ test('verify padding for rendered date in a string when format is date', (t) =>
66
67
  type: 'string',
67
68
  format: 'date'
68
69
  }
69
- const toStringify = new Date(2020, 0, 1, 0, 0, 0, 0)
70
+ const toStringify = new Date()
70
71
 
71
72
  const validate = validator(schema)
72
73
  const stringify = build(schema)
73
74
  const output = stringify(toStringify)
74
75
 
75
- t.equal(output, `"${moment(toStringify).format('YYYY-MM-DD')}"`)
76
+ t.equal(output, `"${DateTime.fromJSDate(toStringify).toISODate()}"`)
76
77
  t.ok(validate(JSON.parse(output)), 'valid schema')
77
78
  })
78
79
 
79
- test('render a date in a string when format is time as kk:mm:ss', (t) => {
80
- t.plan(3)
80
+ test('render a nullable date in a string when format is date as YYYY-MM-DD', (t) => {
81
+ t.plan(2)
81
82
 
82
83
  const schema = {
83
84
  title: 'a date in a string',
84
85
  type: 'string',
85
- format: 'time'
86
+ format: 'date',
87
+ nullable: true
86
88
  }
87
89
  const toStringify = new Date()
88
90
 
@@ -90,14 +92,29 @@ test('render a date in a string when format is time as kk:mm:ss', (t) => {
90
92
  const stringify = build(schema)
91
93
  const output = stringify(toStringify)
92
94
 
93
- validate(JSON.parse(output))
94
- t.equal(validate.errors, null)
95
+ t.equal(output, `"${DateTime.fromJSDate(toStringify).toISODate()}"`)
96
+ t.ok(validate(JSON.parse(output)), 'valid schema')
97
+ })
95
98
 
96
- t.equal(output, `"${moment(toStringify).format('HH:mm:ss')}"`)
99
+ test('verify padding for rendered date in a string when format is date', (t) => {
100
+ t.plan(2)
101
+
102
+ const schema = {
103
+ title: 'a date in a string',
104
+ type: 'string',
105
+ format: 'date'
106
+ }
107
+ const toStringify = new Date(2020, 0, 1, 0, 0, 0, 0)
108
+
109
+ const validate = validator(schema)
110
+ const stringify = build(schema)
111
+ const output = stringify(toStringify)
112
+
113
+ t.equal(output, `"${DateTime.fromJSDate(toStringify).toISODate()}"`)
97
114
  t.ok(validate(JSON.parse(output)), 'valid schema')
98
115
  })
99
116
 
100
- test('verify padding for rendered date in a string when format is time', (t) => {
117
+ test('render a date in a string when format is time as kk:mm:ss', (t) => {
101
118
  t.plan(3)
102
119
 
103
120
  const schema = {
@@ -105,7 +122,7 @@ test('verify padding for rendered date in a string when format is time', (t) =>
105
122
  type: 'string',
106
123
  format: 'time'
107
124
  }
108
- const toStringify = new Date(2020, 0, 1, 1, 1, 1, 1)
125
+ const toStringify = new Date()
109
126
 
110
127
  const validate = validator(schema)
111
128
  const stringify = build(schema)
@@ -114,61 +131,71 @@ test('verify padding for rendered date in a string when format is time', (t) =>
114
131
  validate(JSON.parse(output))
115
132
  t.equal(validate.errors, null)
116
133
 
117
- t.equal(output, `"${moment(toStringify).format('HH:mm:ss')}"`)
134
+ t.equal(output, `"${DateTime.fromJSDate(toStringify).toFormat('HH:mm:ss')}"`)
118
135
  t.ok(validate(JSON.parse(output)), 'valid schema')
119
136
  })
120
137
 
121
- test('render a moment.js instance in a string when format is date-time as ISOString', (t) => {
122
- t.plan(2)
138
+ test('render a nullable date in a string when format is time as kk:mm:ss', (t) => {
139
+ t.plan(3)
123
140
 
124
141
  const schema = {
125
- title: 'a moment.js object in a string',
142
+ title: 'a date in a string',
126
143
  type: 'string',
127
- format: 'date-time'
144
+ format: 'time',
145
+ nullable: true
128
146
  }
129
- const toStringify = moment()
147
+ const toStringify = new Date()
130
148
 
131
149
  const validate = validator(schema)
132
150
  const stringify = build(schema)
133
151
  const output = stringify(toStringify)
134
152
 
135
- t.equal(output, JSON.stringify(toStringify))
153
+ validate(JSON.parse(output))
154
+ t.equal(validate.errors, null)
155
+
156
+ t.equal(output, `"${DateTime.fromJSDate(toStringify).toFormat('HH:mm:ss')}"`)
136
157
  t.ok(validate(JSON.parse(output)), 'valid schema')
137
158
  })
138
159
 
139
- test('render a moment.js instance in a string when format is date as YYYY-MM-DD', (t) => {
140
- t.plan(2)
160
+ test('render a midnight time', (t) => {
161
+ t.plan(3)
141
162
 
142
163
  const schema = {
143
- title: 'a moment.js object in a string',
164
+ title: 'a date in a string',
144
165
  type: 'string',
145
- format: 'date'
166
+ format: 'time'
146
167
  }
147
- const toStringify = moment()
168
+ const midnight = new Date(new Date().setHours(24))
148
169
 
149
170
  const validate = validator(schema)
150
171
  const stringify = build(schema)
151
- const output = stringify(toStringify)
172
+ const output = stringify(midnight)
152
173
 
153
- t.equal(output, `"${toStringify.format('YYYY-MM-DD')}"`)
174
+ validate(JSON.parse(output))
175
+ t.equal(validate.errors, null)
176
+
177
+ t.equal(output, `"${DateTime.fromJSDate(midnight).toFormat('HH:mm:ss')}"`)
154
178
  t.ok(validate(JSON.parse(output)), 'valid schema')
155
179
  })
156
180
 
157
- test('render a moment.js instance in a string when format is time as HH:mm:ss', (t) => {
158
- t.plan(2)
181
+ test('verify padding for rendered date in a string when format is time', (t) => {
182
+ t.plan(3)
159
183
 
160
184
  const schema = {
161
- title: 'a moment.js object in a string',
185
+ title: 'a date in a string',
162
186
  type: 'string',
163
187
  format: 'time'
164
188
  }
165
- const toStringify = moment()
189
+ const toStringify = new Date(2020, 0, 1, 1, 1, 1, 1)
166
190
 
167
191
  const validate = validator(schema)
168
192
  const stringify = build(schema)
169
193
  const output = stringify(toStringify)
170
194
 
171
- t.equal(output, `"${toStringify.format('HH:mm:ss')}"`)
195
+ validate(JSON.parse(output))
196
+ t.equal(validate.errors, null)
197
+
198
+ t.equal(output, `"${DateTime.fromJSDate(toStringify).toFormat('HH:mm:ss')}"`)
172
199
  t.ok(validate(JSON.parse(output)), 'valid schema')
173
200
  })
174
201
 
@@ -185,7 +212,7 @@ test('render a nested object in a string when type is date-format as ISOString',
185
212
  }
186
213
  }
187
214
  }
188
- const toStringify = { date: moment() }
215
+ const toStringify = { date: new Date() }
189
216
 
190
217
  const validate = validator(schema)
191
218
  const stringify = build(schema)
@@ -98,5 +98,5 @@ test('to string auto-consistent with ajv-formats', t => {
98
98
  const compiled = fjs.restore(debugMode)
99
99
  const tobe = JSON.stringify({ str: 'foo@bar.com' })
100
100
  t.same(compiled({ str: 'foo@bar.com' }), tobe)
101
- t.same(compiled({ str: 'foo' }), JSON.stringify({ str: null }), 'invalid format is ignored')
101
+ t.throws(() => compiled({ str: 'foo' }))
102
102
  })
@@ -30,3 +30,34 @@ test('nested objects with same properties', (t) => {
30
30
  })
31
31
  t.equal(value, '{"stringProperty":"string1","objectProperty":{"stringProperty":"string2","numberProperty":42}}')
32
32
  })
33
+
34
+ test('names collision', (t) => {
35
+ t.plan(1)
36
+
37
+ const schema = {
38
+ title: 'nested objects with same properties',
39
+ type: 'object',
40
+ properties: {
41
+ test: {
42
+ type: 'object',
43
+ properties: {
44
+ a: { type: 'string' }
45
+ }
46
+ },
47
+ tes: {
48
+ type: 'object',
49
+ properties: {
50
+ b: { type: 'string' },
51
+ t: { type: 'object' }
52
+ }
53
+ }
54
+ }
55
+ }
56
+ const stringify = build(schema)
57
+ const data = {
58
+ test: { a: 'a' },
59
+ tes: { b: 'b', t: {} }
60
+ }
61
+
62
+ t.equal(stringify(data), JSON.stringify(data))
63
+ })
@@ -116,3 +116,331 @@ Object.keys(testSet).forEach(key => {
116
116
  t.same(JSON.parse(result), expected)
117
117
  })
118
118
  })
119
+
120
+ test('handle nullable number correctly', (t) => {
121
+ t.plan(2)
122
+
123
+ const schema = {
124
+ type: 'number',
125
+ nullable: true
126
+ }
127
+ const stringify = build(schema)
128
+
129
+ const data = null
130
+ const result = stringify(data)
131
+
132
+ t.same(result, JSON.stringify(data))
133
+ t.same(JSON.parse(result), data)
134
+ })
135
+
136
+ test('handle nullable integer correctly', (t) => {
137
+ t.plan(2)
138
+
139
+ const schema = {
140
+ type: 'integer',
141
+ nullable: true
142
+ }
143
+ const stringify = build(schema)
144
+
145
+ const data = null
146
+ const result = stringify(data)
147
+
148
+ t.same(result, JSON.stringify(data))
149
+ t.same(JSON.parse(result), data)
150
+ })
151
+
152
+ test('handle nullable boolean correctly', (t) => {
153
+ t.plan(2)
154
+
155
+ const schema = {
156
+ type: 'boolean',
157
+ nullable: true
158
+ }
159
+ const stringify = build(schema)
160
+
161
+ const data = null
162
+ const result = stringify(data)
163
+
164
+ t.same(result, JSON.stringify(data))
165
+ t.same(JSON.parse(result), data)
166
+ })
167
+
168
+ test('handle nullable string correctly', (t) => {
169
+ t.plan(2)
170
+
171
+ const schema = {
172
+ type: 'string',
173
+ nullable: true
174
+ }
175
+ const stringify = build(schema)
176
+
177
+ const data = null
178
+ const result = stringify(data)
179
+
180
+ t.same(result, JSON.stringify(data))
181
+ t.same(JSON.parse(result), data)
182
+ })
183
+
184
+ test('handle nullable date-time correctly', (t) => {
185
+ t.plan(2)
186
+
187
+ const schema = {
188
+ type: 'string',
189
+ format: 'date-time',
190
+ nullable: true
191
+ }
192
+ const stringify = build(schema)
193
+
194
+ const data = null
195
+ const result = stringify(data)
196
+
197
+ t.same(result, JSON.stringify(data))
198
+ t.same(JSON.parse(result), data)
199
+ })
200
+
201
+ test('handle nullable date correctly', (t) => {
202
+ t.plan(2)
203
+
204
+ const schema = {
205
+ type: 'string',
206
+ format: 'date',
207
+ nullable: true
208
+ }
209
+ const stringify = build(schema)
210
+
211
+ const data = null
212
+ const result = stringify(data)
213
+
214
+ t.same(result, JSON.stringify(data))
215
+ t.same(JSON.parse(result), data)
216
+ })
217
+
218
+ test('handle nullable time correctly', (t) => {
219
+ t.plan(2)
220
+
221
+ const schema = {
222
+ type: 'string',
223
+ format: 'time',
224
+ nullable: true
225
+ }
226
+ const stringify = build(schema)
227
+
228
+ const data = null
229
+ const result = stringify(data)
230
+
231
+ t.same(result, JSON.stringify(data))
232
+ t.same(JSON.parse(result), data)
233
+ })
234
+
235
+ test('large array of nullable strings with default mechanism', (t) => {
236
+ t.plan(2)
237
+
238
+ const schema = {
239
+ type: 'object',
240
+ properties: {
241
+ ids: {
242
+ type: 'array',
243
+ items: {
244
+ type: 'string',
245
+ nullable: true
246
+ }
247
+ }
248
+ }
249
+ }
250
+
251
+ const options = {
252
+ largeArraySize: 2e4,
253
+ largeArrayMechanism: 'default'
254
+ }
255
+
256
+ const stringify = build(schema, options)
257
+
258
+ const data = { ids: new Array(2e4).fill(null) }
259
+ const result = stringify(data)
260
+
261
+ t.same(result, JSON.stringify(data))
262
+ t.same(JSON.parse(result), data)
263
+ })
264
+
265
+ test('large array of nullable date-time strings with default mechanism', (t) => {
266
+ t.plan(2)
267
+
268
+ const schema = {
269
+ type: 'object',
270
+ properties: {
271
+ ids: {
272
+ type: 'array',
273
+ items: {
274
+ type: 'string',
275
+ format: 'date-time',
276
+ nullable: true
277
+ }
278
+ }
279
+ }
280
+ }
281
+
282
+ const options = {
283
+ largeArraySize: 2e4,
284
+ largeArrayMechanism: 'default'
285
+ }
286
+
287
+ const stringify = build(schema, options)
288
+
289
+ const data = { ids: new Array(2e4).fill(null) }
290
+ const result = stringify(data)
291
+
292
+ t.same(result, JSON.stringify(data))
293
+ t.same(JSON.parse(result), data)
294
+ })
295
+
296
+ test('large array of nullable date-time strings with default mechanism', (t) => {
297
+ t.plan(2)
298
+
299
+ const schema = {
300
+ type: 'object',
301
+ properties: {
302
+ ids: {
303
+ type: 'array',
304
+ items: {
305
+ type: 'string',
306
+ format: 'date',
307
+ nullable: true
308
+ }
309
+ }
310
+ }
311
+ }
312
+
313
+ const options = {
314
+ largeArraySize: 2e4,
315
+ largeArrayMechanism: 'default'
316
+ }
317
+
318
+ const stringify = build(schema, options)
319
+
320
+ const data = { ids: new Array(2e4).fill(null) }
321
+ const result = stringify(data)
322
+
323
+ t.same(result, JSON.stringify(data))
324
+ t.same(JSON.parse(result), data)
325
+ })
326
+
327
+ test('large array of nullable date-time strings with default mechanism', (t) => {
328
+ t.plan(2)
329
+
330
+ const schema = {
331
+ type: 'object',
332
+ properties: {
333
+ ids: {
334
+ type: 'array',
335
+ items: {
336
+ type: 'string',
337
+ format: 'time',
338
+ nullable: true
339
+ }
340
+ }
341
+ }
342
+ }
343
+
344
+ const options = {
345
+ largeArraySize: 2e4,
346
+ largeArrayMechanism: 'default'
347
+ }
348
+
349
+ const stringify = build(schema, options)
350
+
351
+ const data = { ids: new Array(2e4).fill(null) }
352
+ const result = stringify(data)
353
+
354
+ t.same(result, JSON.stringify(data))
355
+ t.same(JSON.parse(result), data)
356
+ })
357
+
358
+ test('large array of nullable numbers with default mechanism', (t) => {
359
+ t.plan(2)
360
+
361
+ const schema = {
362
+ type: 'object',
363
+ properties: {
364
+ ids: {
365
+ type: 'array',
366
+ items: {
367
+ type: 'number',
368
+ nullable: true
369
+ }
370
+ }
371
+ }
372
+ }
373
+
374
+ const options = {
375
+ largeArraySize: 2e4,
376
+ largeArrayMechanism: 'default'
377
+ }
378
+
379
+ const stringify = build(schema, options)
380
+
381
+ const data = { ids: new Array(2e4).fill(null) }
382
+ const result = stringify(data)
383
+
384
+ t.same(result, JSON.stringify(data))
385
+ t.same(JSON.parse(result), data)
386
+ })
387
+
388
+ test('large array of nullable integers with default mechanism', (t) => {
389
+ t.plan(2)
390
+
391
+ const schema = {
392
+ type: 'object',
393
+ properties: {
394
+ ids: {
395
+ type: 'array',
396
+ items: {
397
+ type: 'integer',
398
+ nullable: true
399
+ }
400
+ }
401
+ }
402
+ }
403
+
404
+ const options = {
405
+ largeArraySize: 2e4,
406
+ largeArrayMechanism: 'default'
407
+ }
408
+
409
+ const stringify = build(schema, options)
410
+
411
+ const data = { ids: new Array(2e4).fill(null) }
412
+ const result = stringify(data)
413
+
414
+ t.same(result, JSON.stringify(data))
415
+ t.same(JSON.parse(result), data)
416
+ })
417
+
418
+ test('large array of nullable booleans with default mechanism', (t) => {
419
+ t.plan(2)
420
+
421
+ const schema = {
422
+ type: 'object',
423
+ properties: {
424
+ ids: {
425
+ type: 'array',
426
+ items: {
427
+ type: 'boolean',
428
+ nullable: true
429
+ }
430
+ }
431
+ }
432
+ }
433
+
434
+ const options = {
435
+ largeArraySize: 2e4,
436
+ largeArrayMechanism: 'default'
437
+ }
438
+
439
+ const stringify = build(schema, options)
440
+
441
+ const data = { ids: new Array(2e4).fill(null) }
442
+ const result = stringify(data)
443
+
444
+ t.same(result, JSON.stringify(data))
445
+ t.same(JSON.parse(result), data)
446
+ })
@@ -104,11 +104,7 @@ test('object with field of type string and coercion disable ', (t) => {
104
104
  }
105
105
  }
106
106
  const stringify = build(schema)
107
-
108
- const value = stringify({
109
- str: 1
110
- })
111
- t.equal(value, '{"str":null}')
107
+ t.throws(() => stringify({ str: 1 }))
112
108
  })
113
109
 
114
110
  test('object with field of type string and coercion enable ', (t) => {
@@ -403,7 +399,7 @@ test('oneOf object with field of type string with format or null', (t) => {
403
399
  })
404
400
 
405
401
  test('one array item match oneOf types', (t) => {
406
- t.plan(1)
402
+ t.plan(3)
407
403
 
408
404
  const schema = {
409
405
  type: 'object',
@@ -429,15 +425,13 @@ test('one array item match oneOf types', (t) => {
429
425
 
430
426
  const stringify = build(schema)
431
427
 
432
- const responseWithMappedType = stringify({
433
- data: [false, 'foo']
434
- })
435
-
436
- t.equal('{"data":["foo"]}', responseWithMappedType)
428
+ t.equal(stringify({ data: ['foo'] }), '{"data":["foo"]}')
429
+ t.equal(stringify({ data: [1] }), '{"data":[1]}')
430
+ t.throws(() => stringify({ data: [false, 'foo'] }))
437
431
  })
438
432
 
439
433
  test('some array items match oneOf types', (t) => {
440
- t.plan(1)
434
+ t.plan(2)
441
435
 
442
436
  const schema = {
443
437
  type: 'object',
@@ -463,11 +457,8 @@ test('some array items match oneOf types', (t) => {
463
457
 
464
458
  const stringify = build(schema)
465
459
 
466
- const responseWithMappedTypes = stringify({
467
- data: [false, 'foo', true, 5]
468
- })
469
-
470
- t.equal('{"data":["foo",5]}', responseWithMappedTypes)
460
+ t.equal(stringify({ data: ['foo', 5] }), '{"data":["foo",5]}')
461
+ t.throws(() => stringify({ data: [false, 'foo', true, 5] }))
471
462
  })
472
463
 
473
464
  test('all array items does not match oneOf types', (t) => {
@@ -497,9 +488,5 @@ test('all array items does not match oneOf types', (t) => {
497
488
 
498
489
  const stringify = build(schema)
499
490
 
500
- const emptyResponse = stringify({
501
- data: [null, false, true, undefined, [], {}]
502
- })
503
-
504
- t.equal('{"data":[]}', emptyResponse)
491
+ t.throws(() => stringify({ data: [null, false, true, undefined, [], {}] }))
505
492
  })
@@ -63,7 +63,7 @@ test('patternProperties - string coerce', (t) => {
63
63
  })
64
64
 
65
65
  test('patternProperties - number coerce', (t) => {
66
- t.plan(1)
66
+ t.plan(2)
67
67
  const stringify = build({
68
68
  title: 'check number coerce',
69
69
  type: 'object',
@@ -75,8 +75,16 @@ test('patternProperties - number coerce', (t) => {
75
75
  }
76
76
  })
77
77
 
78
- const obj = { foo: true, ofoo: '42', xfoo: 'string', arrfoo: [1, 2], objfoo: { num: 42 } }
79
- t.equal(stringify(obj), '{"foo":1,"ofoo":42,"xfoo":null,"arrfoo":null,"objfoo":null}')
78
+ const coercibleValues = { foo: true, ofoo: '42' }
79
+ t.equal(stringify(coercibleValues), '{"foo":1,"ofoo":42}')
80
+
81
+ const incoercibleValues = { xfoo: 'string', arrfoo: [1, 2], objfoo: { num: 42 } }
82
+ try {
83
+ stringify(incoercibleValues)
84
+ t.fail('should throw an error')
85
+ } catch (err) {
86
+ t.ok(err)
87
+ }
80
88
  })
81
89
 
82
90
  test('patternProperties - boolean coerce', (t) => {
@@ -119,7 +127,7 @@ test('patternProperties - object coerce', (t) => {
119
127
  })
120
128
 
121
129
  test('patternProperties - array coerce', (t) => {
122
- t.plan(1)
130
+ t.plan(2)
123
131
  const stringify = build({
124
132
  title: 'check array coerce',
125
133
  type: 'object',
@@ -134,6 +142,9 @@ test('patternProperties - array coerce', (t) => {
134
142
  }
135
143
  })
136
144
 
137
- const obj = { foo: 'true', ofoo: 0, arrfoo: [1, 2], objfoo: { tyrion: 'lannister' } }
138
- t.equal(stringify(obj), '{"foo":["t","r","u","e"],"ofoo":[],"arrfoo":["1","2"],"objfoo":[]}')
145
+ const coercibleValues = { arrfoo: [1, 2] }
146
+ t.equal(stringify(coercibleValues), '{"arrfoo":["1","2"]}')
147
+
148
+ const incoercibleValues = { foo: 'true', ofoo: 0, objfoo: { tyrion: 'lannister' } }
149
+ t.throws(() => stringify(incoercibleValues))
139
150
  })