123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- const test = require('tap').test
- const fss = require('./')
- const clone = require('clone')
- const s = JSON.stringify
- const stream = require('stream')
- 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.equal(actual, expected)
- assert.end()
- })
- test('circular getter reference to root', function (assert) {
- const fixture = {
- name: 'Tywin Lannister',
- get circle () {
- return fixture
- }
- }
- const expected = s({ name: 'Tywin Lannister', circle: '[Circular]' })
- const actual = fss(fixture)
- assert.equal(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.equal(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.equal(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.equal(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.equal(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.equal(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.equal(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.equal(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.equal(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.equal(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.equal(actual, expected)
- // check if the fixture has not been modified
- assert.same(fixture, cloned)
- assert.end()
- })
- test('child circular reference with toJSON', function (assert) {
- // Create a test object that has an overridden `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.same(parentObject.childObject.parentObject, parentObject)
- assert.same(
- 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.same(parentObject.childObject.parentObject, parentObject)
- assert.same(
- otherParentObject.otherChildObject.otherParentObject,
- otherParentObject
- )
- assert.end()
- })
- test('null object', function (assert) {
- const expected = s(null)
- const actual = fss(null)
- assert.equal(actual, expected)
- assert.end()
- })
- test('null property', function (assert) {
- const expected = s({ f: null })
- const actual = fss({ f: null })
- assert.equal(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.equal(actual, expected)
- assert.end()
- })
- test('circular getters are restored when stringified', function (assert) {
- const fixture = {
- name: 'Tywin Lannister',
- get circle () {
- return fixture
- }
- }
- fss(fixture)
- assert.equal(fixture.circle, fixture)
- assert.end()
- })
- test('non-configurable circular getters use a replacer instead of markers', function (assert) {
- const fixture = { name: 'Tywin Lannister' }
- Object.defineProperty(fixture, 'circle', {
- configurable: false,
- get: function () {
- return fixture
- },
- enumerable: true
- })
- fss(fixture)
- assert.equal(fixture.circle, fixture)
- assert.end()
- })
- test('getter child circular reference are replaced instead of marked', function (assert) {
- const fixture = {
- name: 'Tywin Lannister',
- child: {
- name: 'Tyrion Lannister',
- get dinklage () {
- return fixture.child
- }
- },
- get self () {
- return fixture
- }
- }
- const expected = s({
- name: 'Tywin Lannister',
- child: {
- name: 'Tyrion Lannister',
- dinklage: '[Circular]'
- },
- self: '[Circular]'
- })
- const actual = fss(fixture)
- assert.equal(actual, expected)
- assert.end()
- })
- test('Proxy throwing', function (assert) {
- assert.plan(1)
- const s = new stream.PassThrough()
- s.resume()
- s.write('', () => {
- assert.end()
- })
- const actual = fss({ s, p: new Proxy({}, { get () { throw new Error('kaboom') } }) })
- assert.equal(actual, '"[unable to serialize, circular reference is too complex to analyze]"')
- })
- test('depthLimit option - will replace deep objects', function (assert) {
- const fixture = {
- name: 'Tywin Lannister',
- child: {
- name: 'Tyrion Lannister'
- },
- get self () {
- return fixture
- }
- }
- const expected = s({
- name: 'Tywin Lannister',
- child: '[...]',
- self: '[Circular]'
- })
- const actual = fss(fixture, undefined, undefined, {
- depthLimit: 1,
- edgesLimit: 1
- })
- assert.equal(actual, expected)
- assert.end()
- })
- test('edgesLimit option - will replace deep objects', function (assert) {
- const fixture = {
- object: {
- 1: { test: 'test' },
- 2: { test: 'test' },
- 3: { test: 'test' },
- 4: { test: 'test' }
- },
- array: [
- { test: 'test' },
- { test: 'test' },
- { test: 'test' },
- { test: 'test' }
- ],
- get self () {
- return fixture
- }
- }
- const expected = s({
- object: {
- 1: { test: 'test' },
- 2: { test: 'test' },
- 3: { test: 'test' },
- 4: '[...]'
- },
- array: [{ test: 'test' }, { test: 'test' }, { test: 'test' }, '[...]'],
- self: '[Circular]'
- })
- const actual = fss(fixture, undefined, undefined, {
- depthLimit: 3,
- edgesLimit: 3
- })
- assert.equal(actual, expected)
- assert.end()
- })
|