deno.land / x / mongoose@6.7.5 / test / helpers / clone.test.js
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264'use strict';
const assert = require('assert');const clone = require('../../lib/helpers/clone');const symbols = require('../../lib/helpers/symbols');const ObjectId = require('../../lib/types/objectid');const Decimal = require('../../lib/types/decimal128');
describe('clone', () => { describe('falsy', () => { it('is null when null', () => { assert.deepStrictEqual(clone(null), null); });
it('is false when false', () => { assert.deepStrictEqual(clone(false), false); });
it('is undefined when undefined', () => { assert.deepStrictEqual(clone(undefined), undefined); });
it('is 0 when 0', () => { assert.deepStrictEqual(clone(0), 0); }); });
describe('Array', () => { it('clones first level', () => { const base = [1, 2]; const cloned = clone(base); assert.deepStrictEqual(cloned, base); cloned[0] = 2; assert.deepStrictEqual(base, [1, 2]); assert.deepStrictEqual(cloned, [2, 2]); });
it('clones deeper', () => { const base = [0, [1], { 2: 2 }]; const cloned = clone(base); assert.deepStrictEqual(cloned, base); cloned[0] = 1; cloned[1][0] = 2; cloned[2][2] = 3; assert.deepStrictEqual(cloned, [1, [2], { 2: 3 }]); assert.deepStrictEqual(base, [0, [1], { 2: 2 }]); }); });
describe('mongoose object', () => { it('use toObject', () => { const base = { $__: true, myAttr: 'myAttrVal', toObject() { const obj = JSON.parse(JSON.stringify(base)); obj.toObject = base.toObject; return obj; } }; const cloned = clone(base); assert.deepStrictEqual(cloned, base); cloned.myAttr = 'otherAttrVal'; assert.equal(base.myAttr, 'myAttrVal'); assert.equal(cloned.myAttr, 'otherAttrVal'); });
it('use toJSON', () => { const base = { $__: true, myAttr: 'myAttrVal', toJSON: () => JSON.stringify({ $__: true, myAttr: 'myAttrVal' }) }; const cloned = JSON.parse(clone(base, { json: true })); assert.equal(cloned.myAttr, 'myAttrVal'); cloned.myAttr = 'otherAttrVal'; assert.equal(base.myAttr, 'myAttrVal'); assert.equal(cloned.myAttr, 'otherAttrVal'); });
it('skipSingleNestedGetters', () => { const baseOpts = { _skipSingleNestedGetters: true, $isSingleNested: true }; const base = { $__: true, myAttr: 'myAttrVal', $isSingleNested: true, toObject(cloneOpts) { assert.deepStrictEqual( Object.assign({}, baseOpts, { getters: false }), cloneOpts ); const obj = JSON.parse(JSON.stringify(base)); obj.toObject = base.toObject; return obj; } }; const cloned = clone(base, baseOpts); assert.deepStrictEqual(cloned, base); cloned.myAttr = 'otherAttrVal'; assert.equal(base.myAttr, 'myAttrVal'); assert.equal(cloned.myAttr, 'otherAttrVal'); }); });
describe('global objects', () => { describe('constructor is Object', () => { it('!minimize || isArrayChild', () => { const base = { myAttr: 'myAttrVal' }; const cloned = clone(base); assert.deepStrictEqual(cloned, base); cloned.myAttr = 'otherAttrVal'; assert.equal(base.myAttr, 'myAttrVal'); assert.equal(cloned.myAttr, 'otherAttrVal'); });
it('!constructor && !minimize || isArrayChild', () => { const base = Object.create(null); base.myAttr = 'myAttrVal'; const cloned = clone(base); assert.equal(base.myAttr, cloned.myAttr); cloned.myAttr = 'otherAttrVal'; assert.equal(base.myAttr, 'myAttrVal'); assert.equal(cloned.myAttr, 'otherAttrVal'); });
it('minimize && !isArrayChild && hasKey', () => { const base = { myAttr: 'myAttrVal', otherAttr: undefined, prototype: 'p' }; const cloned = clone(base, { minimize: true }, true); assert.equal(base.myAttr, cloned.myAttr); assert.deepStrictEqual(Object.keys(base), ['myAttr', 'otherAttr', 'prototype']); assert.deepStrictEqual(Object.keys(cloned), ['myAttr']); });
it('minimize and !isArrayChild && !hasKey', () => { const base = { otherAttr: undefined, prototype: 'p' }; const cloned = clone(base, { minimize: true }, false); assert.equal(cloned, null); }); });
describe('constructor is Data', () => { it('return new equal date ', () => { const base = new Date(); const cloned = clone(base); assert.deepStrictEqual(base, cloned); }); });
describe('constructor is RegExp', () => { it('return new equal date ', () => { const base = new RegExp(/A-Z.*/g); base.lastIndex = 2; const cloned = clone(base); assert.deepStrictEqual(base, cloned); assert.ok(base.lastIndex === cloned.lastIndex); }); }); });
describe('mongo object', () => { it('is instance of ObjectId', () => { const base = new ObjectId(); const cloned = clone(base); assert.deepStrictEqual(base, cloned); }); });
describe('schema type', () => { it('have schemaTypeSymbol property', () => { const base = { myAttr: 'myAttrVal', [symbols.schemaTypeSymbol]: 'MyType', clone() { return { myAttr: this.myAttr }; } }; const cloned = clone(base); assert.deepStrictEqual(base.myAttr, cloned.myAttr); }); });
describe('bson', () => { it('Decimal128', () => { const base = { _bsontype: 'Decimal128', toString() { return '128'; } }; base.constructor = undefined; const cloned = clone(base); const expected = Decimal.fromString(base.toString()); assert.deepStrictEqual(cloned, expected); });
it('Decimal128 (flatternDecimal)', () => { const base = { _bsontype: 'Decimal128', toJSON() { return 128; } }; base.constructor = undefined; const cloned = clone(base, { flattenDecimals: true }); assert.deepStrictEqual(cloned, base.toJSON()); });
it('does nothing', () => { class BeeSon { constructor() { this.myAttr = 'myAttrVal'; } toBSON() {} } const base = new BeeSon(); const cloned = clone(base, { bson: true }); assert.equal(base.myAttr, cloned.myAttr); cloned.myAttr = 'otherAttrVal'; assert.equal(base.myAttr, 'otherAttrVal'); assert.equal(cloned.myAttr, 'otherAttrVal'); }); });
describe('wrapper', () => {
});
describe('any else', () => { it('valueOf', () => { let called = false; class Wrapper { constructor(myAttr) { this.myAttr = myAttr; } valueOf() { called = true; return new Wrapper(this.myAttr); } } const base = new Wrapper('myAttrVal'); const cloned = clone(base); assert.ok(called); assert.deepStrictEqual(cloned, base); cloned.myAttr = 'otherAttrVal'; assert.equal(base.myAttr, 'myAttrVal'); assert.equal(cloned.myAttr, 'otherAttrVal'); });
it('cloneObject', () => { class CloneMe { constructor(myAttr) { this.myAttr = myAttr; } } const base = new CloneMe('myAttrVal'); base.valueOf = undefined; const cloned = clone(base); assert.equal(base.myAttr, cloned.myAttr); cloned.myAttr = 'otherAttrVal'; assert.equal(base.myAttr, 'myAttrVal'); assert.equal(cloned.myAttr, 'otherAttrVal'); // I can't say it's expected behavior, but is how it's behave. assert.equal(typeof cloned, 'object'); assert.equal(cloned.constructor, Object); }); });});
Version Info