| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 | const test = require('tap').testconst fss = require('./')const clone = require('clone')const s = JSON.stringifyconst 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()})
 |