You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

175 lines
6.7 KiB

4 years ago
'use strict'
const { test } = require('tap')
const rfdc = require('..')
const clone = rfdc()
const cloneProto = rfdc({proto: true})
const cloneCircles = rfdc({circles: true})
const cloneCirclesProto = rfdc({circles: true, proto: true})
types(clone, 'default')
types(cloneProto, 'proto option')
types(cloneCircles, 'circles option')
types(cloneCirclesProto, 'circles and proto option')
test('default does not copy proto properties', async ({is}) => {
is(clone(Object.create({a: 1})).a, undefined, 'value not copied')
})
test('proto option copies enumerable proto properties', async ({is}) => {
is(cloneProto(Object.create({a: 1})).a, 1, 'value copied')
})
test('circles option - circular object', async ({same, is, isNot}) => {
const o = {nest: {a: 1, b: 2}}
o.circular = o
same(cloneCircles(o), o, 'same values')
isNot(cloneCircles(o), o, 'different objects')
isNot(cloneCircles(o).nest, o.nest, 'different nested objects')
const c = cloneCircles(o)
is(c.circular, c, 'circular references point to copied parent')
isNot(c.circular, o, 'circular references do not point to original parent')
})
test('circles option deep circular object', async ({same, is, isNot}) => {
const o = {nest: {a: 1, b: 2}}
o.nest.circular = o
same(cloneCircles(o), o, 'same values')
isNot(cloneCircles(o), o, 'different objects')
isNot(cloneCircles(o).nest, o.nest, 'different nested objects')
const c = cloneCircles(o)
is(c.nest.circular, c, 'circular references point to copied parent')
isNot(c.nest.circular, o, 'circular references do not point to original parent')
})
test('circles option alone does not copy proto properties', async ({is}) => {
is(cloneCircles(Object.create({a: 1})).a, undefined, 'value not copied')
})
test('circles and proto option copies enumerable proto properties', async ({is}) => {
is(cloneCirclesProto(Object.create({a: 1})).a, 1, 'value copied')
})
test('circles and proto option - circular object', async ({same, is, isNot}) => {
const o = {nest: {a: 1, b: 2}}
o.circular = o
same(cloneCirclesProto(o), o, 'same values')
isNot(cloneCirclesProto(o), o, 'different objects')
isNot(cloneCirclesProto(o).nest, o.nest, 'different nested objects')
const c = cloneCirclesProto(o)
is(c.circular, c, 'circular references point to copied parent')
isNot(c.circular, o, 'circular references do not point to original parent')
})
test('circles and proto option deep circular object', async ({same, is, isNot}) => {
const o = {nest: {a: 1, b: 2}}
o.nest.circular = o
same(cloneCirclesProto(o), o, 'same values')
isNot(cloneCirclesProto(o), o, 'different objects')
isNot(cloneCirclesProto(o).nest, o.nest, 'different nested objects')
const c = cloneCirclesProto(o)
is(c.nest.circular, c, 'circular references point to copied parent')
isNot(c.nest.circular, o, 'circular references do not point to original parent')
})
test('circles and proto option deep circular array', async ({same, is, isNot}) => {
const o = { nest: [1, 2] }
o.nest.push(o)
same(cloneCirclesProto(o), o, 'same values')
isNot(cloneCirclesProto(o), o, 'different objects')
isNot(cloneCirclesProto(o).nest, o.nest, 'different nested objects')
const c = cloneCirclesProto(o)
is(c.nest[2], c, 'circular references point to copied parent')
isNot(c.nest[2], o, 'circular references do not point to original parent')
})
function types (clone, label) {
test(label + ' number', async ({is}) => {
is(clone(42), 42, 'same value')
})
test(label + ' string', async ({is}) => {
is(clone('str'), 'str', 'same value')
})
test(label + ' boolean', async ({is}) => {
is(clone(true), true, 'same value')
})
test(label + ' function', async ({is}) => {
const fn = () => {}
is(clone(fn), fn, 'same function')
})
test(label + ' async function', async ({is}) => {
const fn = async () => {}
is(clone(fn), fn, 'same function')
})
test(label + ' generator function', async ({is}) => {
const fn = function * () {}
is(clone(fn), fn, 'same function')
})
test(label + ' date', async ({is, isNot}) => {
const date = new Date()
is(+clone(date), +date, 'same value')
isNot(clone(date), date, 'different object')
})
test(label + ' null', async ({is}) => {
is(clone(null), null, 'same value')
})
test(label + ' shallow object', async ({same, isNot}) => {
const o = {a: 1, b: 2}
same(clone(o), o, 'same values')
isNot(clone(o), o, 'different object')
})
test(label + ' shallow array', async ({same, isNot}) => {
const o = [1, 2]
same(clone(o), o, 'same values')
isNot(clone(o), o, 'different arrays')
})
test(label + ' deep object', async ({same, isNot}) => {
const o = {nest: {a: 1, b: 2}}
same(clone(o), o, 'same values')
isNot(clone(o), o, 'different objects')
isNot(clone(o).nest, o.nest, 'different nested objects')
})
test(label + ' deep array', async ({same, isNot}) => {
const o = [ {a: 1, b: 2}, [3] ]
same(clone(o), o, 'same values')
isNot(clone(o), o, 'different arrays')
isNot(clone(o)[0], o[0], 'different array elements')
isNot(clone(o)[1], o[1], 'different array elements')
})
test(label + ' nested number', async ({is}) => {
is(clone({a: 1}).a, 1, 'same value')
})
test(label + ' nested string', async ({is}) => {
is(clone({s: 'str'}).s, 'str', 'same value')
})
test(label + ' nested boolean', async ({is}) => {
is(clone({b: true}).b, true, 'same value')
})
test(label + ' nested function', async ({is}) => {
const fn = () => {}
is(clone({fn}).fn, fn, 'same function')
})
test(label + ' nested async function', async ({is}) => {
const fn = async () => {}
is(clone({fn}).fn, fn, 'same function')
})
test(label + ' nested generator function', async ({is}) => {
const fn = function * () {}
is(clone({fn}).fn, fn, 'same function')
})
test(label + ' nested date', async ({is, isNot}) => {
const date = new Date()
is(+clone({d: date}).d, +date, 'same value')
isNot(clone({d: date}).d, date, 'different object')
})
test(label + ' nested date in array', async ({is, isNot}) => {
const date = new Date()
is(+clone({d: [date]}).d[0], +date, 'same value')
isNot(clone({d: [date]}).d[0], date, 'different object')
is(+cloneCircles({d: [date]}).d[0], +date, 'same value')
isNot(cloneCircles({d: [date]}).d, date, 'different object')
})
test(label + ' nested null', async ({is}) => {
is(clone({n: null}).n, null, 'same value')
})
test(label + ' arguments', async ({isNot, same}) => {
function fn (...args) {
same(clone(arguments), args, 'same values')
isNot(clone(arguments), arguments, 'different object')
}
fn(1, 2, 3)
})
}