1 | import test from 'ava'
|
---|
2 | import { copy } from '../src/index'
|
---|
3 |
|
---|
4 | test('copy - change original', t => {
|
---|
5 | const original = { a: 0, b: 0, c: { d: 0 } }
|
---|
6 | const copied = copy(original)
|
---|
7 | t.deepEqual(copied, original)
|
---|
8 | // change original
|
---|
9 | original.a = 1
|
---|
10 | t.is(original.a, 1)
|
---|
11 | t.is(copied.a, 0)
|
---|
12 | original.c.d = 1
|
---|
13 | t.is(original.c.d, 1)
|
---|
14 | t.is(copied.c.d, 0)
|
---|
15 | // @ts-ignore
|
---|
16 | original.c.e = 'new'
|
---|
17 | // @ts-ignore
|
---|
18 | t.is(original.c.e, 'new')
|
---|
19 | // @ts-ignore
|
---|
20 | t.is(copied.c.e, undefined)
|
---|
21 | })
|
---|
22 | test('copy - change copied', t => {
|
---|
23 | const original = { a: false, b: '', c: { d: false } }
|
---|
24 | const copied = copy(original)
|
---|
25 | // change copied
|
---|
26 | copied.a = true
|
---|
27 | t.is(copied.a, true)
|
---|
28 | t.is(original.a, false)
|
---|
29 | copied.c.d = true
|
---|
30 | t.is(copied.c.d, true)
|
---|
31 | t.is(original.c.d, false)
|
---|
32 | // @ts-ignore
|
---|
33 | copied.c.e = 'new'
|
---|
34 | // @ts-ignore
|
---|
35 | t.is(copied.c.e, 'new')
|
---|
36 | // @ts-ignore
|
---|
37 | t.is(original.c.e, undefined)
|
---|
38 | })
|
---|
39 |
|
---|
40 | test('Arrays in objects - change original', t => {
|
---|
41 | const original = { a: [1, 2], c: { d: ['a'] } }
|
---|
42 | const copied = copy(original)
|
---|
43 | t.deepEqual(copied, original)
|
---|
44 | // change original
|
---|
45 | original.a.push(3)
|
---|
46 | t.deepEqual(original.a, [1, 2, 3])
|
---|
47 | t.deepEqual(copied.a, [1, 2])
|
---|
48 | original.c.d.splice(0, 0, 'z')
|
---|
49 | t.deepEqual(original.c.d, ['z', 'a'])
|
---|
50 | t.deepEqual(copied.c.d, ['a'])
|
---|
51 | })
|
---|
52 | test('Arrays in objects - change copied', t => {
|
---|
53 | const original = { a: [1, 2], c: { d: ['a'] } }
|
---|
54 | const copied = copy(original)
|
---|
55 | t.deepEqual(copied, original)
|
---|
56 | // change copied
|
---|
57 | copied.a.push(3)
|
---|
58 | t.deepEqual(copied.a, [1, 2, 3])
|
---|
59 | t.deepEqual(original.a, [1, 2])
|
---|
60 | copied.c.d.splice(0, 0, 'z')
|
---|
61 | t.deepEqual(copied.c.d, ['z', 'a'])
|
---|
62 | t.deepEqual(original.c.d, ['a'])
|
---|
63 | })
|
---|
64 |
|
---|
65 | test('Arrays with objects in objects - change original', t => {
|
---|
66 | const original = { a: [{ a: 1 }], c: { d: [{ b: 1 }] } }
|
---|
67 | const copied = copy(original)
|
---|
68 | t.deepEqual(copied, original)
|
---|
69 | // change original
|
---|
70 | original.a[0].a = 2
|
---|
71 | t.deepEqual(original.a, [{ a: 2 }])
|
---|
72 | t.deepEqual(copied.a, [{ a: 1 }])
|
---|
73 | original.c.d[0].b = 2
|
---|
74 | t.deepEqual(original.c.d, [{ b: 2 }])
|
---|
75 | t.deepEqual(copied.c.d, [{ b: 1 }])
|
---|
76 | })
|
---|
77 | test('Arrays with objects in objects - change copied', t => {
|
---|
78 | const original = { a: [{ a: 1 }], c: { d: [{ b: 1 }] } }
|
---|
79 | const copied = copy(original)
|
---|
80 | t.deepEqual(copied, original)
|
---|
81 | // change copied
|
---|
82 | copied.a[0].a = 2
|
---|
83 | t.deepEqual(copied.a, [{ a: 2 }])
|
---|
84 | t.deepEqual(original.a, [{ a: 1 }])
|
---|
85 | copied.c.d[0].b = 2
|
---|
86 | t.deepEqual(copied.c.d, [{ b: 2 }])
|
---|
87 | t.deepEqual(original.c.d, [{ b: 1 }])
|
---|
88 | })
|
---|
89 |
|
---|
90 | test('Arrays', t => {
|
---|
91 | const original = [1, 2, 3, 4]
|
---|
92 | const copied = copy(original)
|
---|
93 | t.deepEqual(copied, original)
|
---|
94 | copied.splice(0, 0, 0)
|
---|
95 | t.deepEqual(original, [1, 2, 3, 4])
|
---|
96 | t.deepEqual(copied, [0, 1, 2, 3, 4])
|
---|
97 | })
|
---|
98 |
|
---|
99 | test('non objects 1', t => {
|
---|
100 | const original = 'ha'
|
---|
101 | const copied = copy(original)
|
---|
102 | t.is(copied, original)
|
---|
103 | })
|
---|
104 | test('non objects 2', t => {
|
---|
105 | const original = 1
|
---|
106 | const copied = copy(original)
|
---|
107 | t.is(copied, original)
|
---|
108 | })
|
---|
109 | test('non objects 3', t => {
|
---|
110 | const original = undefined
|
---|
111 | const copied = copy(original)
|
---|
112 | t.is(copied, original)
|
---|
113 | })
|
---|
114 |
|
---|
115 | test('special objects 1', t => {
|
---|
116 | const original = new Date()
|
---|
117 | const copied = copy(original)
|
---|
118 | t.deepEqual(copied, original)
|
---|
119 | })
|
---|
120 | test('special objects 2', t => {
|
---|
121 | const original = {}
|
---|
122 | const copied = copy(original)
|
---|
123 | t.deepEqual(copied, original)
|
---|
124 | })
|
---|
125 |
|
---|
126 | test('symbols as keys', t => {
|
---|
127 | const mySymbol = Symbol('mySymbol')
|
---|
128 | const original = { value: 42, [mySymbol]: 'hello' }
|
---|
129 | const copied = copy(original)
|
---|
130 | // change original
|
---|
131 | original.value = 1
|
---|
132 | // @ts-ignore
|
---|
133 | original[mySymbol] = 2
|
---|
134 | t.is(copied.value, 42)
|
---|
135 | t.is(copied[mySymbol], 'hello')
|
---|
136 | t.is(original.value, 1)
|
---|
137 | // @ts-ignore
|
---|
138 | t.is(original[mySymbol], 2)
|
---|
139 | })
|
---|
140 |
|
---|
141 | test('nonenumerable keys - turned on', t => {
|
---|
142 | const mySymbol = Symbol('mySymbol')
|
---|
143 | const original = { value: 42 }
|
---|
144 | Object.defineProperty(original, 'id', {
|
---|
145 | value: 1,
|
---|
146 | writable: true,
|
---|
147 | enumerable: false,
|
---|
148 | configurable: true,
|
---|
149 | })
|
---|
150 | Object.defineProperty(original, mySymbol, {
|
---|
151 | value: 'original',
|
---|
152 | writable: true,
|
---|
153 | enumerable: false,
|
---|
154 | configurable: true,
|
---|
155 | })
|
---|
156 | const copied = copy(original, { nonenumerable: true })
|
---|
157 | // change original
|
---|
158 | // @ts-ignore
|
---|
159 | original.id = 100
|
---|
160 | original[mySymbol] = 'new'
|
---|
161 | original.value = 300
|
---|
162 | t.is(copied.value, 42)
|
---|
163 | // @ts-ignore
|
---|
164 | t.is(copied.id, 1)
|
---|
165 | t.is(copied[mySymbol], 'original')
|
---|
166 | t.is(Object.keys(copied).length, 1)
|
---|
167 | t.true(Object.keys(copied).includes('value'))
|
---|
168 | // @ts-ignore
|
---|
169 | t.is(original.id, 100)
|
---|
170 | t.is(original[mySymbol], 'new')
|
---|
171 | t.is(original.value, 300)
|
---|
172 | t.is(Object.keys(original).length, 1)
|
---|
173 | })
|
---|
174 |
|
---|
175 | test('nonenumerable keys - turned off', t => {
|
---|
176 | const mySymbol = Symbol('mySymbol')
|
---|
177 | const original = { value: 42 }
|
---|
178 | Object.defineProperty(original, 'id', {
|
---|
179 | value: 1,
|
---|
180 | writable: true,
|
---|
181 | enumerable: false,
|
---|
182 | configurable: true,
|
---|
183 | })
|
---|
184 | Object.defineProperty(original, mySymbol, {
|
---|
185 | value: 'original',
|
---|
186 | writable: true,
|
---|
187 | enumerable: false,
|
---|
188 | configurable: true,
|
---|
189 | })
|
---|
190 | const copied = copy(original)
|
---|
191 | // change original
|
---|
192 | t.is(copied.value, 42)
|
---|
193 | // @ts-ignore
|
---|
194 | t.is(copied.id, undefined)
|
---|
195 | t.is(copied[mySymbol], undefined)
|
---|
196 | })
|
---|
197 |
|
---|
198 | test('specific props', t => {
|
---|
199 | const mySymbol = Symbol('mySymbol')
|
---|
200 | const mySymbol2 = Symbol('mySymbol')
|
---|
201 | const original = { value: 42, value2: 24 }
|
---|
202 | Object.defineProperty(original, 'id', {
|
---|
203 | value: 1,
|
---|
204 | writable: true,
|
---|
205 | enumerable: false,
|
---|
206 | configurable: true,
|
---|
207 | })
|
---|
208 | Object.defineProperty(original, mySymbol, {
|
---|
209 | value: 'original',
|
---|
210 | writable: true,
|
---|
211 | enumerable: false,
|
---|
212 | configurable: true,
|
---|
213 | })
|
---|
214 | Object.defineProperty(original, 'id2', {
|
---|
215 | value: 2,
|
---|
216 | writable: true,
|
---|
217 | enumerable: false,
|
---|
218 | configurable: true,
|
---|
219 | })
|
---|
220 | Object.defineProperty(original, mySymbol2, {
|
---|
221 | value: 'original2',
|
---|
222 | writable: true,
|
---|
223 | enumerable: false,
|
---|
224 | configurable: true,
|
---|
225 | })
|
---|
226 | // only enumerable
|
---|
227 | const copied = copy(original, { props: [mySymbol, 'value', 'id'] })
|
---|
228 | t.is(copied.value, 42)
|
---|
229 | // @ts-ignore
|
---|
230 | t.is(copied.id, undefined)
|
---|
231 | t.is(copied[mySymbol], undefined)
|
---|
232 | t.is(copied.value2, undefined)
|
---|
233 | // @ts-ignore
|
---|
234 | t.is(copied.id2, undefined)
|
---|
235 | t.is(copied[mySymbol2], undefined)
|
---|
236 | t.is(Object.keys(copied).length, 1)
|
---|
237 | t.true(Object.keys(copied).includes('value'))
|
---|
238 | t.is(Object.keys(original).length, 2)
|
---|
239 |
|
---|
240 | // non-enumerable included
|
---|
241 | const copied2 = copy(original, { props: [mySymbol, 'value', 'id'], nonenumerable: true })
|
---|
242 | t.is(copied2.value, 42)
|
---|
243 | // @ts-ignore
|
---|
244 | t.is(copied2.id, 1)
|
---|
245 | t.is(copied2[mySymbol], 'original')
|
---|
246 | t.is(copied2.value2, undefined)
|
---|
247 | // @ts-ignore
|
---|
248 | t.is(copied2.id2, undefined)
|
---|
249 | t.is(copied2[mySymbol2], undefined)
|
---|
250 | t.is(Object.keys(copied2).length, 1)
|
---|
251 | t.true(Object.keys(copied2).includes('value'))
|
---|
252 | t.is(Object.keys(original).length, 2)
|
---|
253 | })
|
---|