added unit testing, and started implementing unit tests...phew
This commit is contained in:
8
node_modules/fast-safe-stringify/.travis.yml
generated
vendored
Normal file
8
node_modules/fast-safe-stringify/.travis.yml
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
language: node_js
|
||||
sudo: false
|
||||
node_js:
|
||||
- '4'
|
||||
- '6'
|
||||
- '8'
|
||||
- '9'
|
||||
- '10'
|
17
node_modules/fast-safe-stringify/CHANGELOG.md
generated
vendored
Normal file
17
node_modules/fast-safe-stringify/CHANGELOG.md
generated
vendored
Normal file
@ -0,0 +1,17 @@
|
||||
# Changelog
|
||||
|
||||
## v.2.0.0
|
||||
|
||||
Features
|
||||
|
||||
- Added stable-stringify (see documentation)
|
||||
- Support replacer
|
||||
- Support spacer
|
||||
- toJSON support without forceDecirc property
|
||||
- Improved performance
|
||||
|
||||
Breaking changes
|
||||
|
||||
- Manipulating the input value in a `toJSON` function is not possible anymore in
|
||||
all cases (see documentation)
|
||||
- Dropped support for e.g. IE8 and Node.js < 4
|
23
node_modules/fast-safe-stringify/LICENSE
generated
vendored
Normal file
23
node_modules/fast-safe-stringify/LICENSE
generated
vendored
Normal file
@ -0,0 +1,23 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 David Mark Clements
|
||||
Copyright (c) 2017 David Mark Clements & Matteo Collina
|
||||
Copyright (c) 2018 David Mark Clements, Matteo Collina & Ruben Bridgewater
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
71
node_modules/fast-safe-stringify/benchmark.js
generated
vendored
Normal file
71
node_modules/fast-safe-stringify/benchmark.js
generated
vendored
Normal file
@ -0,0 +1,71 @@
|
||||
const Benchmark = require('benchmark')
|
||||
const suite = new Benchmark.Suite()
|
||||
const { inspect } = require('util')
|
||||
const jsonStringifySafe = require('json-stringify-safe')
|
||||
const fastSafeStringify = require('./')
|
||||
|
||||
const array = new Array(10).fill(0).map((_, i) => i)
|
||||
const obj = { foo: array }
|
||||
const circ = JSON.parse(JSON.stringify(obj))
|
||||
circ.o = { obj: circ, array }
|
||||
const deep = require('./package.json')
|
||||
deep.deep = JSON.parse(JSON.stringify(deep))
|
||||
deep.deep.deep = JSON.parse(JSON.stringify(deep))
|
||||
deep.deep.deep.deep = JSON.parse(JSON.stringify(deep))
|
||||
deep.array = array
|
||||
|
||||
const deepCirc = JSON.parse(JSON.stringify(deep))
|
||||
deepCirc.deep.deep.deep.circ = deepCirc
|
||||
deepCirc.deep.deep.circ = deepCirc
|
||||
deepCirc.deep.circ = deepCirc
|
||||
deepCirc.array = array
|
||||
|
||||
suite.add('util.inspect: simple object', function () {
|
||||
inspect(obj)
|
||||
})
|
||||
suite.add('util.inspect: circular ', function () {
|
||||
inspect(circ)
|
||||
})
|
||||
suite.add('util.inspect: deep ', function () {
|
||||
inspect(deep)
|
||||
})
|
||||
suite.add('util.inspect: deep circular', function () {
|
||||
inspect(deepCirc)
|
||||
})
|
||||
|
||||
suite.add('\njson-stringify-safe: simple object', function () {
|
||||
jsonStringifySafe(obj)
|
||||
})
|
||||
suite.add('json-stringify-safe: circular ', function () {
|
||||
jsonStringifySafe(circ)
|
||||
})
|
||||
suite.add('json-stringify-safe: deep ', function () {
|
||||
jsonStringifySafe(deep)
|
||||
})
|
||||
suite.add('json-stringify-safe: deep circular', function () {
|
||||
jsonStringifySafe(deepCirc)
|
||||
})
|
||||
|
||||
suite.add('\nfast-safe-stringify: simple object', function () {
|
||||
fastSafeStringify(obj)
|
||||
})
|
||||
suite.add('fast-safe-stringify: circular ', function () {
|
||||
fastSafeStringify(circ)
|
||||
})
|
||||
suite.add('fast-safe-stringify: deep ', function () {
|
||||
fastSafeStringify(deep)
|
||||
})
|
||||
suite.add('fast-safe-stringify: deep circular', function () {
|
||||
fastSafeStringify(deepCirc)
|
||||
})
|
||||
|
||||
// add listeners
|
||||
suite.on('cycle', function (event) {
|
||||
console.log(String(event.target))
|
||||
})
|
||||
|
||||
suite.on('complete', function () {
|
||||
console.log('\nFastest is ' + this.filter('fastest').map('name'))
|
||||
})
|
||||
|
||||
suite.run({ delay: 1, minSamples: 150 })
|
8
node_modules/fast-safe-stringify/index.d.ts
generated
vendored
Normal file
8
node_modules/fast-safe-stringify/index.d.ts
generated
vendored
Normal file
@ -0,0 +1,8 @@
|
||||
declare function stringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string;
|
||||
|
||||
declare namespace stringify {
|
||||
export function stable(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string;
|
||||
export function stableStringify(value: any, replacer?: (key: string, value: any) => any, space?: string | number): string;
|
||||
}
|
||||
|
||||
export default stringify;
|
103
node_modules/fast-safe-stringify/index.js
generated
vendored
Normal file
103
node_modules/fast-safe-stringify/index.js
generated
vendored
Normal file
@ -0,0 +1,103 @@
|
||||
module.exports = stringify
|
||||
stringify.default = stringify
|
||||
stringify.stable = deterministicStringify
|
||||
stringify.stableStringify = deterministicStringify
|
||||
|
||||
var arr = []
|
||||
|
||||
// Regular stringify
|
||||
function stringify (obj, replacer, spacer) {
|
||||
decirc(obj, '', [], undefined)
|
||||
var res = JSON.stringify(obj, replacer, spacer)
|
||||
while (arr.length !== 0) {
|
||||
var part = arr.pop()
|
||||
part[0][part[1]] = part[2]
|
||||
}
|
||||
return res
|
||||
}
|
||||
function decirc (val, k, stack, parent) {
|
||||
var i
|
||||
if (typeof val === 'object' && val !== null) {
|
||||
for (i = 0; i < stack.length; i++) {
|
||||
if (stack[i] === val) {
|
||||
parent[k] = '[Circular]'
|
||||
arr.push([parent, k, val])
|
||||
return
|
||||
}
|
||||
}
|
||||
stack.push(val)
|
||||
// Optimize for Arrays. Big arrays could kill the performance otherwise!
|
||||
if (Array.isArray(val)) {
|
||||
for (i = 0; i < val.length; i++) {
|
||||
decirc(val[i], i, stack, val)
|
||||
}
|
||||
} else {
|
||||
var keys = Object.keys(val)
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
var key = keys[i]
|
||||
decirc(val[key], key, stack, val)
|
||||
}
|
||||
}
|
||||
stack.pop()
|
||||
}
|
||||
}
|
||||
|
||||
// Stable-stringify
|
||||
function compareFunction (a, b) {
|
||||
if (a < b) {
|
||||
return -1
|
||||
}
|
||||
if (a > b) {
|
||||
return 1
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
function deterministicStringify (obj, replacer, spacer) {
|
||||
var tmp = deterministicDecirc(obj, '', [], undefined) || obj
|
||||
var res = JSON.stringify(tmp, replacer, spacer)
|
||||
while (arr.length !== 0) {
|
||||
var part = arr.pop()
|
||||
part[0][part[1]] = part[2]
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
function deterministicDecirc (val, k, stack, parent) {
|
||||
var i
|
||||
if (typeof val === 'object' && val !== null) {
|
||||
for (i = 0; i < stack.length; i++) {
|
||||
if (stack[i] === val) {
|
||||
parent[k] = '[Circular]'
|
||||
arr.push([parent, k, val])
|
||||
return
|
||||
}
|
||||
}
|
||||
if (typeof val.toJSON === 'function') {
|
||||
return
|
||||
}
|
||||
stack.push(val)
|
||||
// Optimize for Arrays. Big arrays could kill the performance otherwise!
|
||||
if (Array.isArray(val)) {
|
||||
for (i = 0; i < val.length; i++) {
|
||||
deterministicDecirc(val[i], i, stack, val)
|
||||
}
|
||||
} else {
|
||||
// Create a temporary object in the required way
|
||||
var tmp = {}
|
||||
var keys = Object.keys(val).sort(compareFunction)
|
||||
for (i = 0; i < keys.length; i++) {
|
||||
var key = keys[i]
|
||||
deterministicDecirc(val[key], key, stack, val)
|
||||
tmp[key] = val[key]
|
||||
}
|
||||
if (parent !== undefined) {
|
||||
arr.push([parent, k, val])
|
||||
parent[k] = tmp
|
||||
} else {
|
||||
return tmp
|
||||
}
|
||||
}
|
||||
stack.pop()
|
||||
}
|
||||
}
|
87
node_modules/fast-safe-stringify/package.json
generated
vendored
Normal file
87
node_modules/fast-safe-stringify/package.json
generated
vendored
Normal file
@ -0,0 +1,87 @@
|
||||
{
|
||||
"_from": "fast-safe-stringify@^2.0.4",
|
||||
"_id": "fast-safe-stringify@2.0.6",
|
||||
"_inBundle": false,
|
||||
"_integrity": "sha512-q8BZ89jjc+mz08rSxROs8VsrBBcn1SIw1kq9NjolL509tkABRk9io01RAjSaEv1Xb2uFLt8VtRiZbGp5H8iDtg==",
|
||||
"_location": "/fast-safe-stringify",
|
||||
"_phantomChildren": {},
|
||||
"_requested": {
|
||||
"type": "range",
|
||||
"registry": true,
|
||||
"raw": "fast-safe-stringify@^2.0.4",
|
||||
"name": "fast-safe-stringify",
|
||||
"escapedName": "fast-safe-stringify",
|
||||
"rawSpec": "^2.0.4",
|
||||
"saveSpec": null,
|
||||
"fetchSpec": "^2.0.4"
|
||||
},
|
||||
"_requiredBy": [
|
||||
"/logform"
|
||||
],
|
||||
"_resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.0.6.tgz",
|
||||
"_shasum": "04b26106cc56681f51a044cfc0d76cf0008ac2c2",
|
||||
"_spec": "fast-safe-stringify@^2.0.4",
|
||||
"_where": "/Users/josh.burman/Projects/braid/node_modules/logform",
|
||||
"author": {
|
||||
"name": "David Mark Clements"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/davidmarkclements/fast-safe-stringify/issues"
|
||||
},
|
||||
"bundleDependencies": false,
|
||||
"contributors": [
|
||||
{
|
||||
"name": "Ruben Bridgewater"
|
||||
},
|
||||
{
|
||||
"name": "Matteo Collina"
|
||||
},
|
||||
{
|
||||
"name": "Ben Gourley"
|
||||
},
|
||||
{
|
||||
"name": "Gabriel Lesperance"
|
||||
},
|
||||
{
|
||||
"name": "Alex Liu"
|
||||
},
|
||||
{
|
||||
"name": "Christoph Walcher"
|
||||
},
|
||||
{
|
||||
"name": "Nicholas Young"
|
||||
}
|
||||
],
|
||||
"dependencies": {},
|
||||
"deprecated": false,
|
||||
"description": "Safely and quickly serialize JavaScript objects",
|
||||
"devDependencies": {
|
||||
"benchmark": "^2.1.4",
|
||||
"clone": "^2.1.0",
|
||||
"json-stringify-safe": "^5.0.1",
|
||||
"standard": "^11.0.0",
|
||||
"tap": "^12.0.0"
|
||||
},
|
||||
"homepage": "https://github.com/davidmarkclements/fast-safe-stringify#readme",
|
||||
"keywords": [
|
||||
"stable",
|
||||
"stringify",
|
||||
"JSON",
|
||||
"JSON.stringify",
|
||||
"safe",
|
||||
"serialize"
|
||||
],
|
||||
"license": "MIT",
|
||||
"main": "index.js",
|
||||
"name": "fast-safe-stringify",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/davidmarkclements/fast-safe-stringify.git"
|
||||
},
|
||||
"scripts": {
|
||||
"benchmark": "node benchmark.js",
|
||||
"test": "standard && tap test.js test-stable.js"
|
||||
},
|
||||
"typings": "index",
|
||||
"version": "2.0.6"
|
||||
}
|
154
node_modules/fast-safe-stringify/readme.md
generated
vendored
Normal file
154
node_modules/fast-safe-stringify/readme.md
generated
vendored
Normal file
@ -0,0 +1,154 @@
|
||||
# fast-safe-stringify
|
||||
|
||||
Safe and fast serialization alternative to [JSON.stringify][].
|
||||
|
||||
Gracefully handles circular structures instead of throwing.
|
||||
|
||||
Provides a deterministic ("stable") version as well that will also gracefully
|
||||
handle circular structures. See the example below for further information.
|
||||
|
||||
## Usage
|
||||
|
||||
The same as [JSON.stringify][].
|
||||
|
||||
`stringify(value[, replacer[, space]])`
|
||||
|
||||
```js
|
||||
const safeStringify = require('fast-safe-stringify')
|
||||
const o = { a: 1 }
|
||||
o.o = o
|
||||
|
||||
console.log(safeStringify(o))
|
||||
// '{"a":1,"o":"[Circular]"}'
|
||||
console.log(JSON.stringify(o))
|
||||
// TypeError: Converting circular structure to JSON
|
||||
|
||||
function replacer(key, value) {
|
||||
console.log('Key:', JSON.stringify(key), 'Value:', JSON.stringify(value))
|
||||
// Remove the circular structure
|
||||
if (value === '[Circular]') {
|
||||
return
|
||||
}
|
||||
return value
|
||||
}
|
||||
const serialized = safeStringify(o, replacer, 2)
|
||||
// Key: "" Value: {"a":1,"o":"[Circular]"}
|
||||
// Key: "a" Value: 1
|
||||
// Key: "o" Value: "[Circular]"
|
||||
console.log(serialized)
|
||||
// {
|
||||
// "a": 1
|
||||
// }
|
||||
```
|
||||
|
||||
Using the deterministic version also works the same:
|
||||
|
||||
```js
|
||||
const safeStringify = require('fast-safe-stringify')
|
||||
const o = { b: 1, a: 0 }
|
||||
o.o = o
|
||||
|
||||
console.log(safeStringify(o))
|
||||
// '{"b":1,"a":0,"o":"[Circular]"}'
|
||||
console.log(safeStringify.stableStringify(o))
|
||||
// '{"a":0,"b":1,"o":"[Circular]"}'
|
||||
console.log(JSON.stringify(o))
|
||||
// TypeError: Converting circular structure to JSON
|
||||
```
|
||||
|
||||
A faster and side-effect free implementation is available in the
|
||||
[safe-stable-stringify][] module. However it is still considered experimental
|
||||
due to a new and more complex implementation.
|
||||
|
||||
## Differences to JSON.stringify
|
||||
|
||||
In general the behavior is identical to [JSON.stringify][]. The [`replacer`][]
|
||||
and [`space`][] options are also available.
|
||||
|
||||
A few exceptions exist to [JSON.stringify][] while using [`toJSON`][] or
|
||||
[`replacer`][]:
|
||||
|
||||
### Regular safe stringify
|
||||
|
||||
- Manipulating a circular structure of the passed in value in a `toJSON` or the
|
||||
`replacer` is not possible! It is possible for any other value and property.
|
||||
|
||||
- In case a circular structure is detected and the [`replacer`][] is used it
|
||||
will receive the string `[Circular]` as the argument instead of the circular
|
||||
object itself.
|
||||
|
||||
### Deterministic ("stable") safe stringify
|
||||
|
||||
- Manipulating the input object either in a [`toJSON`][] or the [`replacer`][]
|
||||
function will not have any effect on the output. The output entirely relies on
|
||||
the shape the input value had at the point passed to the stringify function!
|
||||
|
||||
- In case a circular structure is detected and the [`replacer`][] is used it
|
||||
will receive the string `[Circular]` as the argument instead of the circular
|
||||
object itself.
|
||||
|
||||
A side effect free variation without these limitations can be found as well
|
||||
([`safe-stable-stringify`][]). It is also faster than the current
|
||||
implementation. It is still considered experimental due to a new and more
|
||||
complex implementation.
|
||||
|
||||
## Benchmarks
|
||||
|
||||
Although not JSON, the Node.js `util.inspect` method can be used for similar
|
||||
purposes (e.g. logging) and also handles circular references.
|
||||
|
||||
Here we compare `fast-safe-stringify` with some alternatives:
|
||||
(Lenovo T450s with a i7-5600U CPU using Node.js 8.9.4)
|
||||
|
||||
```md
|
||||
fast-safe-stringify: simple object x 1,121,497 ops/sec ±0.75% (97 runs sampled)
|
||||
fast-safe-stringify: circular x 560,126 ops/sec ±0.64% (96 runs sampled)
|
||||
fast-safe-stringify: deep x 32,472 ops/sec ±0.57% (95 runs sampled)
|
||||
fast-safe-stringify: deep circular x 32,513 ops/sec ±0.80% (92 runs sampled)
|
||||
|
||||
util.inspect: simple object x 272,837 ops/sec ±1.48% (90 runs sampled)
|
||||
util.inspect: circular x 116,896 ops/sec ±1.19% (95 runs sampled)
|
||||
util.inspect: deep x 19,382 ops/sec ±0.66% (92 runs sampled)
|
||||
util.inspect: deep circular x 18,717 ops/sec ±0.63% (96 runs sampled)
|
||||
|
||||
json-stringify-safe: simple object x 233,621 ops/sec ±0.97% (94 runs sampled)
|
||||
json-stringify-safe: circular x 110,409 ops/sec ±1.85% (95 runs sampled)
|
||||
json-stringify-safe: deep x 8,705 ops/sec ±0.87% (96 runs sampled)
|
||||
json-stringify-safe: deep circular x 8,336 ops/sec ±2.20% (93 runs sampled)
|
||||
```
|
||||
|
||||
For stable stringify comparisons, see the performance benchmarks in the
|
||||
[`safe-stable-stringify`][] readme.
|
||||
|
||||
## Protip
|
||||
|
||||
Whether `fast-safe-stringify` or alternatives are used: if the use case
|
||||
consists of deeply nested objects without circular references the following
|
||||
pattern will give best results.
|
||||
Shallow or one level nested objects on the other hand will slow down with it.
|
||||
It is entirely dependant on the use case.
|
||||
|
||||
```js
|
||||
const stringify = require('fast-safe-stringify')
|
||||
|
||||
function tryJSONStringify (obj) {
|
||||
try { return JSON.stringify(obj) } catch (_) {}
|
||||
}
|
||||
|
||||
const serializedString = tryJSONStringify(deep) || stringify(deep)
|
||||
```
|
||||
|
||||
## Acknowledgements
|
||||
|
||||
Sponsored by [nearForm](http://nearform.com)
|
||||
|
||||
## License
|
||||
|
||||
MIT
|
||||
|
||||
[`replacer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The%20replacer%20parameter
|
||||
[`safe-stable-stringify`]: https://github.com/BridgeAR/safe-stable-stringify
|
||||
[`space`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#The%20space%20argument
|
||||
[`toJSON`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#toJSON()_behavior
|
||||
[benchmark]: https://github.com/epoberezkin/fast-json-stable-stringify/blob/67f688f7441010cfef91a6147280cc501701e83b/benchmark
|
||||
[JSON.stringify]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify
|
246
node_modules/fast-safe-stringify/test-stable.js
generated
vendored
Normal file
246
node_modules/fast-safe-stringify/test-stable.js
generated
vendored
Normal file
@ -0,0 +1,246 @@
|
||||
const test = require('tap').test
|
||||
const fss = require('./').stable
|
||||
const clone = require('clone')
|
||||
const s = JSON.stringify
|
||||
|
||||
test('circular reference to root', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister' }
|
||||
fixture.circle = fixture
|
||||
const expected = s(
|
||||
{ circle: '[Circular]', name: 'Tywin Lannister' }
|
||||
)
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested circular reference to root', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister' }
|
||||
fixture.id = { circle: fixture }
|
||||
const expected = s(
|
||||
{ id: { circle: '[Circular]' }, name: 'Tywin Lannister' }
|
||||
)
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('child circular reference', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister', child: { name: 'Tyrion Lannister' } }
|
||||
fixture.child.dinklage = fixture.child
|
||||
const expected = s({
|
||||
child: {
|
||||
dinklage: '[Circular]', name: 'Tyrion Lannister'
|
||||
},
|
||||
name: 'Tywin Lannister'
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested child circular reference', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister', child: { name: 'Tyrion Lannister' } }
|
||||
fixture.child.actor = { dinklage: fixture.child }
|
||||
const expected = s({
|
||||
child: {
|
||||
actor: { dinklage: '[Circular]' }, name: 'Tyrion Lannister'
|
||||
},
|
||||
name: 'Tywin Lannister'
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('circular objects in an array', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister' }
|
||||
fixture.hand = [fixture, fixture]
|
||||
const expected = s({
|
||||
hand: ['[Circular]', '[Circular]'], name: 'Tywin Lannister'
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested circular references in an array', function (assert) {
|
||||
const fixture = {
|
||||
name: 'Tywin Lannister',
|
||||
offspring: [{ name: 'Tyrion Lannister' }, { name: 'Cersei Lannister' }]
|
||||
}
|
||||
fixture.offspring[0].dinklage = fixture.offspring[0]
|
||||
fixture.offspring[1].headey = fixture.offspring[1]
|
||||
|
||||
const expected = s({
|
||||
name: 'Tywin Lannister',
|
||||
offspring: [
|
||||
{ dinklage: '[Circular]', name: 'Tyrion Lannister' },
|
||||
{ headey: '[Circular]', name: 'Cersei Lannister' }
|
||||
]
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('circular arrays', function (assert) {
|
||||
const fixture = []
|
||||
fixture.push(fixture, fixture)
|
||||
const expected = s(['[Circular]', '[Circular]'])
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested circular arrays', function (assert) {
|
||||
const fixture = []
|
||||
fixture.push(
|
||||
{ name: 'Jon Snow', bastards: fixture },
|
||||
{ name: 'Ramsay Bolton', bastards: fixture }
|
||||
)
|
||||
const expected = s([
|
||||
{ bastards: '[Circular]', name: 'Jon Snow' },
|
||||
{ bastards: '[Circular]', name: 'Ramsay Bolton' }
|
||||
])
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('repeated non-circular references in objects', function (assert) {
|
||||
const daenerys = { name: 'Daenerys Targaryen' }
|
||||
const fixture = {
|
||||
motherOfDragons: daenerys,
|
||||
queenOfMeereen: daenerys
|
||||
}
|
||||
const expected = s(fixture)
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('repeated non-circular references in arrays', function (assert) {
|
||||
const daenerys = { name: 'Daenerys Targaryen' }
|
||||
const fixture = [daenerys, daenerys]
|
||||
const expected = s(fixture)
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('double child circular reference', function (assert) {
|
||||
// create circular reference
|
||||
const child = { name: 'Tyrion Lannister' }
|
||||
child.dinklage = child
|
||||
|
||||
// include it twice in the fixture
|
||||
const fixture = { name: 'Tywin Lannister', childA: child, childB: child }
|
||||
const cloned = clone(fixture)
|
||||
const expected = s({
|
||||
childA: {
|
||||
dinklage: '[Circular]', name: 'Tyrion Lannister'
|
||||
},
|
||||
childB: {
|
||||
dinklage: '[Circular]', name: 'Tyrion Lannister'
|
||||
},
|
||||
name: 'Tywin Lannister'
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
|
||||
// check if the fixture has not been modified
|
||||
assert.deepEqual(fixture, cloned)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('child circular reference with toJSON', function (assert) {
|
||||
// Create a test object that has an overriden `toJSON` property
|
||||
TestObject.prototype.toJSON = function () { return { special: 'case' } }
|
||||
function TestObject (content) {}
|
||||
|
||||
// Creating a simple circular object structure
|
||||
const parentObject = {}
|
||||
parentObject.childObject = new TestObject()
|
||||
parentObject.childObject.parentObject = parentObject
|
||||
|
||||
// Creating a simple circular object structure
|
||||
const otherParentObject = new TestObject()
|
||||
otherParentObject.otherChildObject = {}
|
||||
otherParentObject.otherChildObject.otherParentObject = otherParentObject
|
||||
|
||||
// Making sure our original tests work
|
||||
assert.deepEqual(parentObject.childObject.parentObject, parentObject)
|
||||
assert.deepEqual(otherParentObject.otherChildObject.otherParentObject, otherParentObject)
|
||||
|
||||
// Should both be idempotent
|
||||
assert.equal(fss(parentObject), '{"childObject":{"special":"case"}}')
|
||||
assert.equal(fss(otherParentObject), '{"special":"case"}')
|
||||
|
||||
// Therefore the following assertion should be `true`
|
||||
assert.deepEqual(parentObject.childObject.parentObject, parentObject)
|
||||
assert.deepEqual(otherParentObject.otherChildObject.otherParentObject, otherParentObject)
|
||||
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('null object', function (assert) {
|
||||
const expected = s(null)
|
||||
const actual = fss(null)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('null property', function (assert) {
|
||||
const expected = s({ f: null })
|
||||
const actual = fss({ f: null })
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested child circular reference in toJSON', function (assert) {
|
||||
var circle = { some: 'data' }
|
||||
circle.circle = circle
|
||||
var a = {
|
||||
b: {
|
||||
toJSON: function () {
|
||||
a.b = 2
|
||||
return '[Redacted]'
|
||||
}
|
||||
},
|
||||
baz: {
|
||||
circle,
|
||||
toJSON: function () {
|
||||
a.baz = circle
|
||||
return '[Redacted]'
|
||||
}
|
||||
}
|
||||
}
|
||||
var o = {
|
||||
a,
|
||||
bar: a
|
||||
}
|
||||
|
||||
const expected = s({
|
||||
a: {
|
||||
b: '[Redacted]',
|
||||
baz: '[Redacted]'
|
||||
},
|
||||
bar: {
|
||||
// TODO: This is a known limitation of the current implementation.
|
||||
// The ideal result would be:
|
||||
//
|
||||
// b: 2,
|
||||
// baz: {
|
||||
// circle: '[Circular]',
|
||||
// some: 'data'
|
||||
// }
|
||||
//
|
||||
b: '[Redacted]',
|
||||
baz: '[Redacted]'
|
||||
}
|
||||
})
|
||||
const actual = fss(o)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
240
node_modules/fast-safe-stringify/test.js
generated
vendored
Normal file
240
node_modules/fast-safe-stringify/test.js
generated
vendored
Normal file
@ -0,0 +1,240 @@
|
||||
const test = require('tap').test
|
||||
const fss = require('./')
|
||||
const clone = require('clone')
|
||||
const s = JSON.stringify
|
||||
|
||||
test('circular reference to root', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister' }
|
||||
fixture.circle = fixture
|
||||
const expected = s(
|
||||
{ name: 'Tywin Lannister', circle: '[Circular]' }
|
||||
)
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested circular reference to root', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister' }
|
||||
fixture.id = { circle: fixture }
|
||||
const expected = s(
|
||||
{ name: 'Tywin Lannister', id: { circle: '[Circular]' } }
|
||||
)
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('child circular reference', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister', child: { name: 'Tyrion Lannister' } }
|
||||
fixture.child.dinklage = fixture.child
|
||||
const expected = s({
|
||||
name: 'Tywin Lannister',
|
||||
child: {
|
||||
name: 'Tyrion Lannister', dinklage: '[Circular]'
|
||||
}
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested child circular reference', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister', child: { name: 'Tyrion Lannister' } }
|
||||
fixture.child.actor = { dinklage: fixture.child }
|
||||
const expected = s({
|
||||
name: 'Tywin Lannister',
|
||||
child: {
|
||||
name: 'Tyrion Lannister', actor: { dinklage: '[Circular]' }
|
||||
}
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('circular objects in an array', function (assert) {
|
||||
const fixture = { name: 'Tywin Lannister' }
|
||||
fixture.hand = [fixture, fixture]
|
||||
const expected = s({
|
||||
name: 'Tywin Lannister', hand: ['[Circular]', '[Circular]']
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested circular references in an array', function (assert) {
|
||||
const fixture = {
|
||||
name: 'Tywin Lannister',
|
||||
offspring: [{ name: 'Tyrion Lannister' }, { name: 'Cersei Lannister' }]
|
||||
}
|
||||
fixture.offspring[0].dinklage = fixture.offspring[0]
|
||||
fixture.offspring[1].headey = fixture.offspring[1]
|
||||
|
||||
const expected = s({
|
||||
name: 'Tywin Lannister',
|
||||
offspring: [
|
||||
{ name: 'Tyrion Lannister', dinklage: '[Circular]' },
|
||||
{ name: 'Cersei Lannister', headey: '[Circular]' }
|
||||
]
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('circular arrays', function (assert) {
|
||||
const fixture = []
|
||||
fixture.push(fixture, fixture)
|
||||
const expected = s(['[Circular]', '[Circular]'])
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested circular arrays', function (assert) {
|
||||
const fixture = []
|
||||
fixture.push(
|
||||
{ name: 'Jon Snow', bastards: fixture },
|
||||
{ name: 'Ramsay Bolton', bastards: fixture }
|
||||
)
|
||||
const expected = s([
|
||||
{ name: 'Jon Snow', bastards: '[Circular]' },
|
||||
{ name: 'Ramsay Bolton', bastards: '[Circular]' }
|
||||
])
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('repeated non-circular references in objects', function (assert) {
|
||||
const daenerys = { name: 'Daenerys Targaryen' }
|
||||
const fixture = {
|
||||
motherOfDragons: daenerys,
|
||||
queenOfMeereen: daenerys
|
||||
}
|
||||
const expected = s(fixture)
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('repeated non-circular references in arrays', function (assert) {
|
||||
const daenerys = { name: 'Daenerys Targaryen' }
|
||||
const fixture = [daenerys, daenerys]
|
||||
const expected = s(fixture)
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('double child circular reference', function (assert) {
|
||||
// create circular reference
|
||||
const child = { name: 'Tyrion Lannister' }
|
||||
child.dinklage = child
|
||||
|
||||
// include it twice in the fixture
|
||||
const fixture = { name: 'Tywin Lannister', childA: child, childB: child }
|
||||
const cloned = clone(fixture)
|
||||
const expected = s({
|
||||
name: 'Tywin Lannister',
|
||||
childA: {
|
||||
name: 'Tyrion Lannister', dinklage: '[Circular]'
|
||||
},
|
||||
childB: {
|
||||
name: 'Tyrion Lannister', dinklage: '[Circular]'
|
||||
}
|
||||
})
|
||||
const actual = fss(fixture)
|
||||
assert.is(actual, expected)
|
||||
|
||||
// check if the fixture has not been modified
|
||||
assert.deepEqual(fixture, cloned)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('child circular reference with toJSON', function (assert) {
|
||||
// Create a test object that has an overriden `toJSON` property
|
||||
TestObject.prototype.toJSON = function () { return { special: 'case' } }
|
||||
function TestObject (content) {}
|
||||
|
||||
// Creating a simple circular object structure
|
||||
const parentObject = {}
|
||||
parentObject.childObject = new TestObject()
|
||||
parentObject.childObject.parentObject = parentObject
|
||||
|
||||
// Creating a simple circular object structure
|
||||
const otherParentObject = new TestObject()
|
||||
otherParentObject.otherChildObject = {}
|
||||
otherParentObject.otherChildObject.otherParentObject = otherParentObject
|
||||
|
||||
// Making sure our original tests work
|
||||
assert.deepEqual(parentObject.childObject.parentObject, parentObject)
|
||||
assert.deepEqual(otherParentObject.otherChildObject.otherParentObject, otherParentObject)
|
||||
|
||||
// Should both be idempotent
|
||||
assert.equal(fss(parentObject), '{"childObject":{"special":"case"}}')
|
||||
assert.equal(fss(otherParentObject), '{"special":"case"}')
|
||||
|
||||
// Therefore the following assertion should be `true`
|
||||
assert.deepEqual(parentObject.childObject.parentObject, parentObject)
|
||||
assert.deepEqual(otherParentObject.otherChildObject.otherParentObject, otherParentObject)
|
||||
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('null object', function (assert) {
|
||||
const expected = s(null)
|
||||
const actual = fss(null)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('null property', function (assert) {
|
||||
const expected = s({ f: null })
|
||||
const actual = fss({ f: null })
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
||||
|
||||
test('nested child circular reference in toJSON', function (assert) {
|
||||
const circle = { some: 'data' }
|
||||
circle.circle = circle
|
||||
const a = {
|
||||
b: {
|
||||
toJSON: function () {
|
||||
a.b = 2
|
||||
return '[Redacted]'
|
||||
}
|
||||
},
|
||||
baz: {
|
||||
circle,
|
||||
toJSON: function () {
|
||||
a.baz = circle
|
||||
return '[Redacted]'
|
||||
}
|
||||
}
|
||||
}
|
||||
const o = {
|
||||
a,
|
||||
bar: a
|
||||
}
|
||||
|
||||
const expected = s({
|
||||
a: {
|
||||
b: '[Redacted]',
|
||||
baz: '[Redacted]'
|
||||
},
|
||||
bar: {
|
||||
b: 2,
|
||||
baz: {
|
||||
some: 'data',
|
||||
circle: '[Circular]'
|
||||
}
|
||||
}
|
||||
})
|
||||
const actual = fss(o)
|
||||
assert.is(actual, expected)
|
||||
assert.end()
|
||||
})
|
Reference in New Issue
Block a user