UNPKG

decircularize

Version:
294 lines (287 loc) 8.57 kB
const decircularize = require('../index') describe('decircularize.js', () => { var testData beforeEach(() => { testData = {} }) describe('An object with only strings', () => { beforeEach(() => { testData.input = { prop: 'some string', otherProp: 'some other string', } testData.result = decircularize(testData.input) }) it('should return a copy', () => { expect(testData.result).to.not.equal(testData.input) }) it('should not change any of the values', () => { expect(testData.result).to.deep.equal(testData.input) }) }) describe('An object with nested objects', () => { beforeEach(() => { testData.input = { prop: 'some string', otherProp: 'some other string', object: { key: 1, }, } testData.result = decircularize(testData.input) }) it('should return a deep copy', () => { expect(testData.result).to.not.equal(testData.input) expect(testData.result.object).to.not.equal(testData.input.object) }) it('should not change any of the values', () => { expect(testData.result).to.deep.equal(testData.input) }) }) describe('An array of simple types', () => { beforeEach(() => { testData.input = ['1', 2] testData.result = decircularize(testData.input) }) it('should return a deep copy', () => { expect(testData.result).to.not.equal(testData.input) }) it('should not change any of the values', () => { expect(testData.result).to.deep.equal(testData.input) }) }) describe('An array of nested objects and arrays', () => { beforeEach(() => { testData.input = [ '1', 2, { object: { a: 1 } }, [ 1, { number: 123, object2: { b: 2 }, array: [ 1, 2 ] } ], ] testData.result = decircularize(testData.input) }) it('should return a deep copy', () => { expect(testData.result).to.not.equal(testData.input) expect(testData.result[2]).to.not.equal(testData.input[2], 'first object') expect(testData.result[2].object).to.not.equal(testData.input[2].object, 'nested object of first object') expect(testData.result[3]).to.not.equal(testData.input[3], 'first array') expect(testData.result[3][1]).to.not.equal(testData.input[3][1], 'second object') expect(testData.result[3][1].object2).to.not.equal(testData.input[3][1].object2, 'nested object of second object') expect(testData.result[3][1].array).to.not.equal(testData.input[3][1].array, 'nested array of second object') }) it('should not change any of the values', () => { expect(testData.result).to.deep.equal(testData.input) }) }) describe('Object with circular ref to itself', () => { beforeEach(() => { testData.input = {} testData.input.circular = testData.input testData.result = decircularize(testData.input) }) it('should return a deep copy', () => { expect(testData.result).to.not.equal(testData.input) }) it('should replace the circular ref with a string explaining the issue', () => { expect(testData.result).to.deep.equal({ circular: '[Circular to: <root>]' }) }) }) describe('Object with nested circular ref', () => { beforeEach(() => { testData.input = { a: { b: {} } } testData.input.a.b.circular = testData.input.a testData.result = decircularize(testData.input) }) it('should return a deep copy', () => { expect(testData.result).to.not.equal(testData.input) expect(testData.result.a).to.not.equal(testData.input.a) expect(testData.result.a.b).to.not.equal(testData.input.a.b) }) it('should replace the circular ref with a string explaining the issue', () => { expect(testData.result).to.deep.equal({ a: { b: { circular: '[Circular to: <root>.a]' } } }) }) }) describe('Array with circular ref', () => { beforeEach(() => { testData.input = [] testData.input.push(testData.input) testData.result = decircularize(testData.input) }) it('should return a deep copy', () => { expect(testData.result).to.not.equal(testData.input) }) it('should replace the circular ref with a string explaining the issue', () => { expect(testData.result).to.deep.equal([ '[Circular to: <root>]' ]) }) }) describe('Object with nested array with circular ref', () => { beforeEach(() => { testData.input = [ { a: 1 } ] testData.input[0].circular = testData.input[0] testData.result = decircularize(testData.input) }) it('should return a deep copy', () => { expect(testData.result).to.not.equal(testData.input) expect(testData.result[0]).to.not.equal(testData.input[0]) }) it('should replace the circular ref with a string explaining the issue', () => { expect(testData.result).to.deep.equal([ { a: 1, circular: '[Circular to: <root>.0]', } ]) }) }) describe('Object with both arrays and objects with circular refs', () => { beforeEach(() => { testData.input = { array: [ [ {}, ], { abc: [ 1, 2, ] } ], object: { first: [ {}, ], second: { abc: [ 1, 2, ] }, } } testData.input.array[0][0].circular = testData.input.array[0] testData.input.array[0].push(testData.input.array[0]) testData.input.array[1].abc.push(testData.input.array[1].abc) testData.input.array[1].abc.push({ circular: testData.input.array[1].abc }) testData.input.object.first[0].circular = testData.input.object.first testData.input.object.first.push(testData.input.object.first) testData.input.object.second.abc.push(testData.input.object.second.abc) testData.input.object.second.abc.push({ circular: testData.input.object.second.abc }) testData.result = decircularize(testData.input) }) it('should replace the circular ref with a string explaining the issue', () => { expect(testData.result).to.deep.equal({ array: [ [ { circular: '[Circular to: <root>.array.0]' }, '[Circular to: <root>.array.0]' ], { abc: [ 1, 2, '[Circular to: <root>.array.1.abc]', { circular: '[Circular to: <root>.array.1.abc]' }, ], }, ], object: { first: [ { circular: '[Circular to: <root>.object.first]' }, '[Circular to: <root>.object.first]', ], second: { abc: [ 1, 2, '[Circular to: <root>.object.second.abc]', { circular: '[Circular to: <root>.object.second.abc]' }, ] } }, }) }) }) describe('Object where an item is referenced as siblings', () => { beforeEach(() => { const common = { a: 1 } testData.input = { first: common, second: common, } testData.result = decircularize(testData.input) }) it('should copy everything', () => { expect(testData.result).to.not.equal(testData.input) expect(testData.result.first).to.not.equal(testData.input.first) expect(testData.result.second).to.not.equal(testData.input.second) expect(testData.result.first).to.not.equal(testData.input.second) }) it('should not change any of them', () => { expect(testData.result).to.deep.equal({ first: { a: 1 }, second: { a: 1 }, }) }) }) describe('Array where an item is referenced as siblings', () => { beforeEach(() => { const common = { a: 1 } testData.input = [ common, common, ] testData.result = decircularize(testData.input) }) it('should copy everything', () => { expect(testData.result).to.not.equal(testData.input) expect(testData.result[0]).to.not.equal(testData.input[0]) expect(testData.result[1]).to.not.equal(testData.input[1]) expect(testData.result[0]).to.not.equal(testData.input[1]) }) it('should not change any of them', () => { expect(testData.result).to.deep.equal([ { a: 1 }, { a: 1 }, ]) }) }) describe('Passing types other than object and array', () => { const types = [ null, undefined, true, false, 1, 'a', function() {}, () => {} ] types.forEach(type => { describe(`: \`${null}\``, () => { describe('directly into the exported function', () => { it('should return the input', () => { expect(decircularize(type)).to.equal(type) }) }) describe('contained in an array', () => { it('should return a copy with the type', () => { expect(decircularize([type])).to.deep.equal([type]) }) }) describe('contained in an object', () => { it('should return a copy with the type', () => { expect(decircularize({ value: type })).to.deep.equal({ value: type }) }) }) }) }) }) })