fast-json-stringify 2.7.9 → 2.7.13

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.
@@ -2,6 +2,10 @@ version: 2
2
2
  updates:
3
3
  - package-ecosystem: github-actions
4
4
  directory: '/'
5
+ ignore:
6
+ - dependency-name: "actions/*"
7
+ update-types:
8
+ ["version-update:semver-minor", "version-update:semver-patch"]
5
9
  schedule:
6
10
  interval: daily
7
11
  open-pull-requests-limit: 10
@@ -0,0 +1,111 @@
1
+ name: Benchmark
2
+
3
+ on:
4
+ pull_request_target:
5
+ types: [labeled]
6
+
7
+ jobs:
8
+ benchmark:
9
+ if: ${{ github.event.label.name == 'benchmark' }}
10
+ runs-on: ubuntu-latest
11
+ outputs:
12
+ PR-BENCH-12: ${{ steps.benchmark-pr.outputs.BENCH_RESULT12 }}
13
+ PR-BENCH-14: ${{ steps.benchmark-pr.outputs.BENCH_RESULT14 }}
14
+ PR-BENCH-16: ${{ steps.benchmark-pr.outputs.BENCH_RESULT16 }}
15
+ MAIN-BENCH-12: ${{ steps.benchmark-main.outputs.BENCH_RESULT12 }}
16
+ MAIN-BENCH-14: ${{ steps.benchmark-main.outputs.BENCH_RESULT14 }}
17
+ MAIN-BENCH-16: ${{ steps.benchmark-main.outputs.BENCH_RESULT16 }}
18
+ strategy:
19
+ matrix:
20
+ node-version: [12, 14, 16]
21
+ steps:
22
+ - uses: actions/checkout@v2
23
+ with:
24
+ ref: ${{github.event.pull_request.head.ref}}
25
+ repository: ${{github.event.pull_request.head.repo.full_name}}
26
+
27
+ - uses: actions/setup-node@v2
28
+ with:
29
+ node-version: ${{ matrix.node-version }}
30
+
31
+ - name: Install
32
+ run: |
33
+ npm install --ignore-scripts
34
+
35
+ - name: Run benchmark
36
+ id: benchmark-pr
37
+ run: |
38
+ npm run --silent benchmark > ./bench-result
39
+ content=$(cat ./bench-result)
40
+ content="${content//'%'/'%25'}"
41
+ content="${content//$'\n'/'%0A'}"
42
+ content="${content//$'\r'/'%0D'}"
43
+ echo "::set-output name=BENCH_RESULT${{matrix.node-version}}::$content"
44
+
45
+ # main benchmark
46
+ - uses: actions/checkout@v2
47
+ with:
48
+ ref: 'master'
49
+
50
+ - name: Install
51
+ run: |
52
+ npm install --ignore-scripts
53
+
54
+ - name: Run benchmark
55
+ id: benchmark-master
56
+ run: |
57
+ npm run --silent benchmark > ./bench-result
58
+ content=$(cat ./bench-result)
59
+ content="${content//'%'/'%25'}"
60
+ content="${content//$'\n'/'%0A'}"
61
+ content="${content//$'\r'/'%0D'}"
62
+ echo "::set-output name=BENCH_RESULT${{matrix.node-version}}::$content"
63
+
64
+ output-benchmark:
65
+ needs: [benchmark]
66
+ runs-on: ubuntu-latest
67
+ steps:
68
+ - name: Comment PR
69
+ uses: thollander/actions-comment-pull-request@v1
70
+ with:
71
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
72
+ message: |
73
+ **Node**: 12
74
+ **PR**:
75
+ ```
76
+ ${{ needs.benchmark.outputs.PR-BENCH-12 }}
77
+ ```
78
+ **MAIN**:
79
+ ```
80
+ ${{ needs.benchmark.outputs.MAIN-BENCH-12 }}
81
+ ```
82
+
83
+ ---
84
+
85
+ **Node**: 14
86
+ **PR**:
87
+ ```
88
+ ${{ needs.benchmark.outputs.PR-BENCH-14 }}
89
+ ```
90
+ **MAIN**:
91
+ ```
92
+ ${{ needs.benchmark.outputs.MAIN-BENCH-14 }}
93
+ ```
94
+
95
+ ---
96
+
97
+ **Node**: 16
98
+ **PR**:
99
+ ```
100
+ ${{ needs.benchmark.outputs.PR-BENCH-16 }}
101
+ ```
102
+ **MAIN**:
103
+ ```
104
+ ${{ needs.benchmark.outputs.MAIN-BENCH-16 }}
105
+ ```
106
+
107
+ - uses: actions-ecosystem/action-remove-labels@v1
108
+ with:
109
+ labels: |
110
+ benchmark
111
+ github_token: ${{ secrets.GITHUB_TOKEN }}
@@ -19,10 +19,10 @@ jobs:
19
19
  os: [macos-latest, ubuntu-latest, windows-latest]
20
20
 
21
21
  steps:
22
- - uses: actions/checkout@v2.3.4
22
+ - uses: actions/checkout@v2
23
23
 
24
24
  - name: Use Node.js
25
- uses: actions/setup-node@v2.4.0
25
+ uses: actions/setup-node@v2
26
26
  with:
27
27
  node-version: ${{ matrix.node-version }}
28
28
 
@@ -38,6 +38,6 @@ jobs:
38
38
  needs: test
39
39
  runs-on: ubuntu-latest
40
40
  steps:
41
- - uses: fastify/github-action-merge-dependabot@v2.4.0
41
+ - uses: fastify/github-action-merge-dependabot@v2.7.1
42
42
  with:
43
43
  github-token: ${{ secrets.GITHUB_TOKEN }}
package/README.md CHANGED
@@ -12,22 +12,25 @@ __fast-json-stringify__ is significantly faster than `JSON.stringify()` for smal
12
12
  ##### Benchmarks
13
13
 
14
14
  - Machine: `EX41S-SSD, Intel Core i7, 4Ghz, 64GB RAM, 4C/8T, SSD`.
15
- - Node.js `v12.16.2`
15
+ - Node.js `v16.9.1`
16
16
 
17
17
  ```
18
- FJS creation x 59,805 ops/sec ±0.23% (91 runs sampled)
18
+ FJS creation x 6,040 ops/sec ±1.17% (91 runs sampled)
19
19
 
20
- JSON.stringify array x 5,330 ops/sec ±0.54% (97 runs sampled)
21
- fast-json-stringify array x 6,995 ops/sec ±0.24% (94 runs sampled)
20
+ JSON.stringify array x 5,519 ops/sec ±0.08% (99 runs sampled)
21
+ fast-json-stringify array x 7,143 ops/sec ±0.14% (97 runs sampled)
22
22
 
23
- JSON.stringify long string x 15,108 ops/sec ±0.13% (100 runs sampled)
24
- fast-json-stringify long string x 15,089 ops/sec ±0.15% (98 runs sampled)
23
+ JSON.stringify long string x 16,438 ops/sec ±0.32% (98 runs sampled)
24
+ fast-json-stringify long string x 16,457 ops/sec ±0.09% (97 runs sampled)
25
25
 
26
- JSON.stringify short string x 13,214,696 ops/sec ±0.19% (97 runs sampled)
27
- fast-json-stringify short string x 33,378,500 ops/sec ±0.27% (95 runs sampled)
26
+ JSON.stringify short string x 12,061,258 ops/sec ±0.32% (97 runs sampled)
27
+ fast-json-stringify short string x 35,531,071 ops/sec ±0.17% (94 runs sampled)
28
28
 
29
- JSON.stringify obj x 3,172,653 ops/sec ±0.15% (98 runs sampled)
30
- fast-json-stringify obj x 13,537,123 ops/sec ±0.19% (95 runs sampled)
29
+ JSON.stringify obj x 3,079,746 ops/sec ±0.09% (95 runs sampled)
30
+ fast-json-stringify obj x 7,721,569 ops/sec ±0.12% (98 runs sampled)
31
+
32
+ JSON stringify date x 1,149,786 ops/sec ±0.10% (99 runs sampled)
33
+ fast-json-stringify date format x 1,674,498 ops/sec ±0.12% (99 runs sampled)
31
34
  ```
32
35
 
33
36
  #### Table of contents:
package/bench.js CHANGED
@@ -50,22 +50,38 @@ const arraySchemaCJS = {
50
50
  items: schemaCJS
51
51
  }
52
52
 
53
+ const dateFormatSchema = {
54
+ description: 'Date of birth',
55
+ type: 'string',
56
+ format: 'date'
57
+ }
58
+
59
+ const dateFormatSchemaCJS = {
60
+ description: 'Date of birth',
61
+ type: 'string',
62
+ format: 'date'
63
+ }
64
+
53
65
  const obj = {
54
66
  firstName: 'Matteo',
55
67
  lastName: 'Collina',
56
68
  age: 32
57
69
  }
58
70
 
71
+ const date = new Date()
72
+
59
73
  const multiArray = []
60
74
 
61
75
  const CJS = require('compile-json-stringify')
62
76
  const CJSStringify = CJS(schemaCJS)
63
77
  const CJSStringifyArray = CJS(arraySchemaCJS)
78
+ const CJSStringifyDate = CJS(dateFormatSchemaCJS)
64
79
  const CJSStringifyString = CJS({ type: 'string' })
65
80
 
66
81
  const FJS = require('.')
67
82
  const stringify = FJS(schema)
68
83
  const stringifyArray = FJS(arraySchema)
84
+ const stringifyDate = FJS(dateFormatSchema)
69
85
  const stringifyString = FJS({ type: 'string' })
70
86
  let str = ''
71
87
 
@@ -138,6 +154,18 @@ suite.add('compile-json-stringify obj', function () {
138
154
  CJSStringify(obj)
139
155
  })
140
156
 
157
+ suite.add('JSON stringify date', function () {
158
+ JSON.stringify(date)
159
+ })
160
+
161
+ suite.add('fast-json-stringify date format', function () {
162
+ stringifyDate(date)
163
+ })
164
+
165
+ suite.add('compile-json-stringify date format', function () {
166
+ CJSStringifyDate(date)
167
+ })
168
+
141
169
  suite.on('cycle', cycle)
142
170
 
143
171
  suite.run()
package/index.js CHANGED
@@ -47,7 +47,12 @@ function mergeLocation (source, dest) {
47
47
  }
48
48
  }
49
49
 
50
+ const arrayItemsReferenceSerializersMap = new Map()
51
+ const objectReferenceSerializersMap = new Map()
52
+
50
53
  function build (schema, options) {
54
+ arrayItemsReferenceSerializersMap.clear()
55
+ objectReferenceSerializersMap.clear()
51
56
  options = options || {}
52
57
  isValidSchema(schema)
53
58
  if (options.schema) {
@@ -144,6 +149,9 @@ function build (schema, options) {
144
149
  return dependenciesName
145
150
  }
146
151
 
152
+ arrayItemsReferenceSerializersMap.clear()
153
+ objectReferenceSerializersMap.clear()
154
+
147
155
  return (Function.apply(null, dependenciesName).apply(null, dependencies))
148
156
  }
149
157
 
@@ -285,10 +293,7 @@ function $asDatetime (date, skipQuotes) {
285
293
  function $asDate (date, skipQuotes) {
286
294
  const quotes = skipQuotes === true ? '' : '"'
287
295
  if (date instanceof Date) {
288
- const year = new Intl.DateTimeFormat('en', { year: 'numeric' }).format(date)
289
- const month = new Intl.DateTimeFormat('en', { month: '2-digit' }).format(date)
290
- const day = new Intl.DateTimeFormat('en', { day: '2-digit' }).format(date)
291
- return quotes + year + '-' + month + '-' + day + quotes
296
+ return quotes + new Date(date.getTime() - (date.getTimezoneOffset() * 60000 )).toISOString().slice(0, 10) + quotes
292
297
  } else if (date && typeof date.format === 'function') {
293
298
  return quotes + date.format('YYYY-MM-DD') + quotes
294
299
  } else {
@@ -397,51 +402,60 @@ function addPatternProperties (location) {
397
402
  } catch (err) {
398
403
  throw new Error(`${err.message}. Found at ${regex} matching ${JSON.stringify(pp[regex])}`)
399
404
  }
400
- code += `
401
- if (/${regex.replace(/\\*\//g, '\\/')}/.test(keys[i])) {
402
- `
405
+
406
+ const ifPpKeyExists = `if (/${regex.replace(/\\*\//g, '\\/')}/.test(keys[i])) {`
407
+
403
408
  if (type === 'object') {
404
409
  code += `${buildObject(ppLocation, '', 'buildObjectPP' + index)}
410
+ ${ifPpKeyExists}
405
411
  ${addComma}
406
412
  json += $asString(keys[i]) + ':' + buildObjectPP${index}(obj[keys[i]])
407
413
  `
408
414
  } else if (type === 'array') {
409
415
  code += `${buildArray(ppLocation, '', 'buildArrayPP' + index)}
416
+ ${ifPpKeyExists}
410
417
  ${addComma}
411
418
  json += $asString(keys[i]) + ':' + buildArrayPP${index}(obj[keys[i]])
412
419
  `
413
420
  } else if (type === 'null') {
414
421
  code += `
422
+ ${ifPpKeyExists}
415
423
  ${addComma}
416
424
  json += $asString(keys[i]) +':null'
417
425
  `
418
426
  } else if (type === 'string') {
419
427
  code += `
428
+ ${ifPpKeyExists}
420
429
  ${addComma}
421
430
  json += $asString(keys[i]) + ':' + ${stringSerializer}(obj[keys[i]])
422
431
  `
423
432
  } else if (type === 'integer') {
424
433
  code += `
434
+ ${ifPpKeyExists}
425
435
  ${addComma}
426
436
  json += $asString(keys[i]) + ':' + $asInteger(obj[keys[i]])
427
437
  `
428
438
  } else if (type === 'number') {
429
439
  code += `
440
+ ${ifPpKeyExists}
430
441
  ${addComma}
431
442
  json += $asString(keys[i]) + ':' + $asNumber(obj[keys[i]])
432
443
  `
433
444
  } else if (type === 'boolean') {
434
445
  code += `
446
+ ${ifPpKeyExists}
435
447
  ${addComma}
436
448
  json += $asString(keys[i]) + ':' + $asBoolean(obj[keys[i]])
437
449
  `
438
450
  } else if (type === undefined) {
439
451
  code += `
452
+ ${ifPpKeyExists}
440
453
  ${addComma}
441
454
  json += $asString(keys[i]) + ':' + $asAny(obj[keys[i]])
442
455
  `
443
456
  } else {
444
457
  code += `
458
+ ${ifPpKeyExists}
445
459
  throw new Error('Cannot coerce ' + obj[keys[i]] + ' to ' + ${JSON.stringify(type)})
446
460
  `
447
461
  }
@@ -805,6 +819,12 @@ function buildCode (location, code, laterCode, name) {
805
819
  `
806
820
  }
807
821
 
822
+ if (schema.allOf) {
823
+ const builtCode = buildCodeWithAllOfs(location, code, laterCode, name)
824
+ code = builtCode.code
825
+ laterCode = builtCode.laterCode
826
+ }
827
+
808
828
  return { code: code, laterCode: laterCode }
809
829
  }
810
830
 
@@ -920,6 +940,16 @@ function buildObject (location, code, name) {
920
940
  }
921
941
  `
922
942
  }
943
+
944
+ if (objectReferenceSerializersMap.has(schema)) {
945
+ code += `
946
+ return ${objectReferenceSerializersMap.get(schema)}(input)
947
+ }
948
+ `
949
+ return code
950
+ }
951
+ objectReferenceSerializersMap.set(schema, name)
952
+
923
953
  code += `
924
954
  var obj = ${toJSON('input')}
925
955
  var json = '{'
@@ -959,9 +989,6 @@ function buildArray (location, code, name, key = null) {
959
989
  }
960
990
  `
961
991
  }
962
- code += `
963
- var json = '['
964
- `
965
992
  const laterCode = ''
966
993
 
967
994
  // default to any items type
@@ -975,8 +1002,18 @@ function buildArray (location, code, name, key = null) {
975
1002
  schema = location.schema
976
1003
  schema[fjsCloned] = true
977
1004
  }
1005
+
978
1006
  location = refFinder(schema.items.$ref, location)
979
1007
  schema.items = location.schema
1008
+
1009
+ if (arrayItemsReferenceSerializersMap.has(schema.items)) {
1010
+ code += `
1011
+ return ${arrayItemsReferenceSerializersMap.get(schema.items)}(obj)
1012
+ }
1013
+ `
1014
+ return code
1015
+ }
1016
+ arrayItemsReferenceSerializersMap.set(schema.items, name)
980
1017
  }
981
1018
 
982
1019
  let result = { code: '', laterCode: '' }
@@ -1023,17 +1060,17 @@ function buildArray (location, code, name, key = null) {
1023
1060
 
1024
1061
  code += `
1025
1062
  var l = obj.length
1026
-
1063
+ var jsonOutput= ''
1027
1064
  for (var i = 0; i < l; i++) {
1028
- var jsonLastChar = json[json.length - 1]
1065
+ var json = ''
1066
+ ${result.code}
1067
+ jsonOutput += json
1029
1068
 
1030
- if (i > 0 && jsonLastChar !== '[' && jsonLastChar !== ',') {
1031
- json += ','
1069
+ if (json.length > 0 && i < l - 1) {
1070
+ jsonOutput += ','
1032
1071
  }
1033
- ${result.code}
1034
1072
  }
1035
- json += ']'
1036
- return json
1073
+ return \`[\${jsonOutput}]\`
1037
1074
  }
1038
1075
  ${result.laterCode}
1039
1076
  `
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fast-json-stringify",
3
- "version": "2.7.9",
3
+ "version": "2.7.13",
4
4
  "description": "Stringify your JSON at max speed",
5
5
  "main": "index.js",
6
6
  "types": "index.d.ts",
@@ -277,6 +277,58 @@ test('object with multiple $refs in allOf', (t) => {
277
277
  t.equal(value, '{"id1":1,"id2":2}')
278
278
  })
279
279
 
280
+ test('allOf with nested allOf in $ref', (t) => {
281
+ t.plan(1)
282
+
283
+ const schema = {
284
+ title: 'allOf with nested allOf in $ref',
285
+ type: 'object',
286
+ definitions: {
287
+ group: {
288
+ type: 'object',
289
+ allOf: [{
290
+ properties: {
291
+ id2: {
292
+ type: 'integer'
293
+ }
294
+ }
295
+ }, {
296
+ properties: {
297
+ id3: {
298
+ type: 'integer'
299
+ }
300
+ }
301
+ }]
302
+ }
303
+ },
304
+ allOf: [
305
+ {
306
+ type: 'object',
307
+ properties: {
308
+ id1: {
309
+ type: 'integer'
310
+ }
311
+ },
312
+ required: [
313
+ 'id1'
314
+ ]
315
+ },
316
+ {
317
+ $ref: '#/definitions/group'
318
+ }
319
+ ]
320
+ }
321
+
322
+ const stringify = build(schema)
323
+ const value = stringify({
324
+ id1: 1,
325
+ id2: 2,
326
+ id3: 3,
327
+ id4: 4 // extra prop shouldn't be in result
328
+ })
329
+ t.equal(value, '{"id1":1,"id2":2,"id3":3}')
330
+ })
331
+
280
332
  test('object with external $refs in allOf', (t) => {
281
333
  t.plan(1)
282
334
 
@@ -0,0 +1,180 @@
1
+ 'use strict'
2
+
3
+ const test = require('tap').test
4
+ const build = require('..')
5
+
6
+ test('can stringify recursive directory tree (issue #181)', (t) => {
7
+ t.plan(1)
8
+
9
+ const schema = {
10
+ definitions: {
11
+ directory: {
12
+ type: 'object',
13
+ properties: {
14
+ name: { type: 'string' },
15
+ subDirectories: {
16
+ type: 'array',
17
+ items: { $ref: '#/definitions/directory' },
18
+ default: []
19
+ }
20
+ }
21
+ }
22
+ },
23
+ type: 'array',
24
+ items: { $ref: '#/definitions/directory' }
25
+ }
26
+ const stringify = build(schema)
27
+
28
+ t.equal(stringify([
29
+ { name: 'directory 1', subDirectories: [] },
30
+ {
31
+ name: 'directory 2',
32
+ subDirectories: [
33
+ { name: 'directory 2.1', subDirectories: [] },
34
+ { name: 'directory 2.2', subDirectories: [] }
35
+ ]
36
+ }
37
+ ]), '[{"name":"directory 1","subDirectories":[]},{"name":"directory 2","subDirectories":[{"name":"directory 2.1","subDirectories":[]},{"name":"directory 2.2","subDirectories":[]}]}]')
38
+ })
39
+
40
+ test('can stringify when recursion in external schema', t => {
41
+ t.plan(1)
42
+
43
+ const referenceSchema = {
44
+ $id: 'person',
45
+ type: 'object',
46
+ properties: {
47
+ name: { type: 'string' },
48
+ children: {
49
+ type: 'array',
50
+ items: { $ref: '#' }
51
+ }
52
+ }
53
+ }
54
+
55
+ const schema = {
56
+ $id: 'mainSchema',
57
+ type: 'object',
58
+ properties: {
59
+ people: {
60
+ $ref: 'person'
61
+ }
62
+ }
63
+ }
64
+ const stringify = build(schema, {
65
+ schema: {
66
+ [referenceSchema.$id]: referenceSchema
67
+ }
68
+ })
69
+
70
+ const value = stringify({ people: { name: 'Elizabeth', children: [{ name: 'Charles' }] } })
71
+ t.equal(value, '{"people":{"name":"Elizabeth","children":[{"name":"Charles"}]}}')
72
+ })
73
+
74
+ test('use proper serialize function', t => {
75
+ t.plan(1)
76
+
77
+ const personSchema = {
78
+ $id: 'person',
79
+ type: 'object',
80
+ properties: {
81
+ name: { type: 'string' },
82
+ children: {
83
+ type: 'array',
84
+ items: { $ref: '#' }
85
+ }
86
+ }
87
+ }
88
+
89
+ const directorySchema = {
90
+ $id: 'directory',
91
+ type: 'object',
92
+ properties: {
93
+ name: { type: 'string' },
94
+ subDirectories: {
95
+ type: 'array',
96
+ items: { $ref: '#' },
97
+ default: []
98
+ }
99
+ }
100
+ }
101
+
102
+ const schema = {
103
+ $id: 'mainSchema',
104
+ type: 'object',
105
+ properties: {
106
+ people: { $ref: 'person' },
107
+ directory: { $ref: 'directory' }
108
+ }
109
+ }
110
+ const stringify = build(schema, {
111
+ schema: {
112
+ [personSchema.$id]: personSchema,
113
+ [directorySchema.$id]: directorySchema
114
+ }
115
+ })
116
+
117
+ const value = stringify({
118
+ people: {
119
+ name: 'Elizabeth',
120
+ children: [{
121
+ name: 'Charles',
122
+ children: [{ name: 'William', children: [{ name: 'George' }, { name: 'Charlotte' }] }, { name: 'Harry' }]
123
+ }]
124
+ },
125
+ directory: {
126
+ name: 'directory 1',
127
+ subDirectories: [
128
+ { name: 'directory 1.1', subDirectories: [] },
129
+ {
130
+ name: 'directory 1.2',
131
+ subDirectories: [{ name: 'directory 1.2.1' }, { name: 'directory 1.2.2' }]
132
+ }
133
+ ]
134
+ }
135
+ })
136
+ t.equal(value, '{"people":{"name":"Elizabeth","children":[{"name":"Charles","children":[{"name":"William","children":[{"name":"George"},{"name":"Charlotte"}]},{"name":"Harry"}]}]},"directory":{"name":"directory 1","subDirectories":[{"name":"directory 1.1","subDirectories":[]},{"name":"directory 1.2","subDirectories":[{"name":"directory 1.2.1","subDirectories":[]},{"name":"directory 1.2.2","subDirectories":[]}]}]}}')
137
+ })
138
+
139
+ test('can stringify recursive references in object types (issue #365)', t => {
140
+ t.plan(1)
141
+
142
+ const schema = {
143
+ type: 'object',
144
+ definitions: {
145
+ parentCategory: {
146
+ type: 'object',
147
+ properties: {
148
+ parent: {
149
+ $ref: '#/definitions/parentCategory'
150
+ }
151
+ }
152
+ }
153
+ },
154
+ properties: {
155
+ category: {
156
+ type: 'object',
157
+ properties: {
158
+ parent: {
159
+ $ref: '#/definitions/parentCategory'
160
+ }
161
+ }
162
+ }
163
+ }
164
+ }
165
+
166
+ const stringify = build(schema)
167
+ const data = {
168
+ category: {
169
+ parent: {
170
+ parent: {
171
+ parent: {
172
+ parent: {}
173
+ }
174
+ }
175
+ }
176
+ }
177
+ }
178
+ const value = stringify(data)
179
+ t.equal(value, '{"category":{"parent":{"parent":{"parent":{"parent":{}}}}}}')
180
+ })