forked from jestjs/jest
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathdeep_cyclic_copy.test.js
More file actions
115 lines (91 loc) · 3.14 KB
/
deep_cyclic_copy.test.js
File metadata and controls
115 lines (91 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
/**
* Copyright (c) 2017-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
*/
import deepCyclicCopy from '../deep_cyclic_copy';
it('returns the same value for primitive or function values', () => {
const fn = () => {};
expect(deepCyclicCopy(undefined)).toBe(undefined);
expect(deepCyclicCopy(null)).toBe(null);
expect(deepCyclicCopy(true)).toBe(true);
expect(deepCyclicCopy(42)).toBe(42);
expect(Number.isNaN(deepCyclicCopy(NaN))).toBe(true);
expect(deepCyclicCopy('foo')).toBe('foo');
expect(deepCyclicCopy(fn)).toBe(fn);
});
it('does not execute getters/setters, but copies them', () => {
const fn = jest.fn();
const obj = {
get foo() {
fn();
},
};
const copy = deepCyclicCopy(obj);
expect(Object.getOwnPropertyDescriptor(copy, 'foo')).toBeDefined();
expect(fn).not.toBeCalled();
});
it('copies symbols', () => {
const symbol = Symbol('foo');
const obj = {[symbol]: 42};
expect(deepCyclicCopy(obj)[symbol]).toBe(42);
});
it('copies arrays as array objects', () => {
const array = [null, 42, 'foo', 'bar', [], {}];
expect(deepCyclicCopy(array)).toEqual(array);
expect(Array.isArray(deepCyclicCopy(array))).toBe(true);
});
it('handles cyclic dependencies', () => {
const cyclic = {a: 42, subcycle: {}};
cyclic.subcycle.baz = cyclic;
cyclic.bar = cyclic;
expect(() => deepCyclicCopy(cyclic)).not.toThrow();
const copy = deepCyclicCopy(cyclic);
expect(copy.a).toBe(42);
expect(copy.bar).toEqual(copy);
expect(copy.subcycle.baz).toEqual(copy);
});
it('uses the blacklist to avoid copying properties on the first level', () => {
const obj = {
blacklisted: 41,
subObj: {
blacklisted: 42,
},
};
expect(deepCyclicCopy(obj, {blacklist: new Set(['blacklisted'])})).toEqual({
subObj: {
blacklisted: 42,
},
});
});
it('does not keep the prototype by default', () => {
const obj = new function() {}();
obj.nestedObj = new function() {}();
const copy = deepCyclicCopy(obj);
expect(Object.getPrototypeOf(copy)).not.toBe(Object.getPrototypeOf(obj));
expect(Object.getPrototypeOf(copy.nestedObj)).not.toBe(
Object.getPrototypeOf(obj.nestedObj),
);
expect(Object.getPrototypeOf(copy)).toBe(Object.getPrototypeOf({}));
});
it('does not keep the prototype for keepPrototype = false', () => {
const obj = new function() {}();
obj.nestedObj = new function() {}();
const copy = deepCyclicCopy(obj, {keepPrototype: false});
expect(Object.getPrototypeOf(copy)).not.toBe(Object.getPrototypeOf(obj));
expect(Object.getPrototypeOf(copy.nestedObj)).not.toBe(
Object.getPrototypeOf(obj.nestedObj),
);
expect(Object.getPrototypeOf(copy)).toBe(Object.getPrototypeOf({}));
});
it('keeps the prototype for keepPrototype = true', () => {
const obj = new function() {}();
obj.nestedObj = new function() {}();
const copy = deepCyclicCopy(obj, {keepPrototype: true});
expect(Object.getPrototypeOf(copy)).toBe(Object.getPrototypeOf(obj));
expect(Object.getPrototypeOf(copy.nestedObj)).toBe(
Object.getPrototypeOf(obj.nestedObj),
);
});