merge-anything 3.0.7 → 4.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs.js DELETED
@@ -1,134 +0,0 @@
1
- 'use strict';
2
-
3
- Object.defineProperty(exports, '__esModule', { value: true });
4
-
5
- var isWhat = require('is-what');
6
-
7
- /*! *****************************************************************************
8
- Copyright (c) Microsoft Corporation. All rights reserved.
9
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
10
- this file except in compliance with the License. You may obtain a copy of the
11
- License at http://www.apache.org/licenses/LICENSE-2.0
12
-
13
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
15
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
16
- MERCHANTABLITY OR NON-INFRINGEMENT.
17
-
18
- See the Apache Version 2.0 License for specific language governing permissions
19
- and limitations under the License.
20
- ***************************************************************************** */
21
-
22
- function __spreadArrays() {
23
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
24
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
25
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
26
- r[k] = a[j];
27
- return r;
28
- }
29
-
30
- function concatArrays(originVal, newVal) {
31
- if (isWhat.isArray(originVal) && isWhat.isArray(newVal)) {
32
- // concat logic
33
- return originVal.concat(newVal);
34
- }
35
- return newVal; // always return newVal as fallback!!
36
- }
37
-
38
- function assignProp(carry, key, newVal, originalObject) {
39
- var propType = {}.propertyIsEnumerable.call(originalObject, key)
40
- ? 'enumerable'
41
- : 'nonenumerable';
42
- if (propType === 'enumerable')
43
- carry[key] = newVal;
44
- if (propType === 'nonenumerable') {
45
- Object.defineProperty(carry, key, {
46
- value: newVal,
47
- enumerable: false,
48
- writable: true,
49
- configurable: true,
50
- });
51
- }
52
- }
53
- function mergeRecursively(origin, newComer, compareFn) {
54
- // always return newComer if its not an object
55
- if (!isWhat.isPlainObject(newComer))
56
- return newComer;
57
- // define newObject to merge all values upon
58
- var newObject = {};
59
- if (isWhat.isPlainObject(origin)) {
60
- var props_1 = Object.getOwnPropertyNames(origin);
61
- var symbols_1 = Object.getOwnPropertySymbols(origin);
62
- newObject = __spreadArrays(props_1, symbols_1).reduce(function (carry, key) {
63
- var targetVal = origin[key];
64
- if ((!isWhat.isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) ||
65
- (isWhat.isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))) {
66
- assignProp(carry, key, targetVal, origin);
67
- }
68
- return carry;
69
- }, {});
70
- }
71
- // newObject has all properties that newComer hasn't
72
- var props = Object.getOwnPropertyNames(newComer);
73
- var symbols = Object.getOwnPropertySymbols(newComer);
74
- var result = __spreadArrays(props, symbols).reduce(function (carry, key) {
75
- // re-define the origin and newComer as targetVal and newVal
76
- var newVal = newComer[key];
77
- var targetVal = isWhat.isPlainObject(origin) ? origin[key] : undefined;
78
- // When newVal is an object do the merge recursively
79
- if (targetVal !== undefined && isWhat.isPlainObject(newVal)) {
80
- newVal = mergeRecursively(targetVal, newVal, compareFn);
81
- }
82
- var propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal;
83
- assignProp(carry, key, propToAssign, newComer);
84
- return carry;
85
- }, newObject);
86
- return result;
87
- }
88
- /**
89
- * Merge anything recursively.
90
- * Objects get merged, special objects (classes etc.) are re-assigned "as is".
91
- * Basic types overwrite objects or other basic types.
92
- *
93
- * @export
94
- * @template T
95
- * @template Tn
96
- * @param {T} origin
97
- * @param {...Tn} newComers
98
- * @returns {Assigned<T, Tn>}
99
- */
100
- function merge(origin) {
101
- var newComers = [];
102
- for (var _i = 1; _i < arguments.length; _i++) {
103
- newComers[_i - 1] = arguments[_i];
104
- }
105
- // @ts-ignore
106
- return newComers.reduce(function (result, newComer) {
107
- return mergeRecursively(result, newComer);
108
- }, origin);
109
- }
110
- function mergeAndCompare(compareFn, origin) {
111
- var newComers = [];
112
- for (var _i = 2; _i < arguments.length; _i++) {
113
- newComers[_i - 2] = arguments[_i];
114
- }
115
- // @ts-ignore
116
- return newComers.reduce(function (result, newComer) {
117
- return mergeRecursively(result, newComer, compareFn);
118
- }, origin);
119
- }
120
- function mergeAndConcat(origin) {
121
- var newComers = [];
122
- for (var _i = 1; _i < arguments.length; _i++) {
123
- newComers[_i - 1] = arguments[_i];
124
- }
125
- // @ts-ignore
126
- return newComers.reduce(function (result, newComer) {
127
- return mergeRecursively(result, newComer, concatArrays);
128
- }, origin);
129
- }
130
-
131
- exports.concatArrays = concatArrays;
132
- exports.merge = merge;
133
- exports.mergeAndCompare = mergeAndCompare;
134
- exports.mergeAndConcat = mergeAndConcat;
package/dist/index.esm.js DELETED
@@ -1,127 +0,0 @@
1
- import { isArray, isPlainObject, isSymbol } from 'is-what';
2
-
3
- /*! *****************************************************************************
4
- Copyright (c) Microsoft Corporation. All rights reserved.
5
- Licensed under the Apache License, Version 2.0 (the "License"); you may not use
6
- this file except in compliance with the License. You may obtain a copy of the
7
- License at http://www.apache.org/licenses/LICENSE-2.0
8
-
9
- THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
10
- KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
11
- WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
12
- MERCHANTABLITY OR NON-INFRINGEMENT.
13
-
14
- See the Apache Version 2.0 License for specific language governing permissions
15
- and limitations under the License.
16
- ***************************************************************************** */
17
-
18
- function __spreadArrays() {
19
- for (var s = 0, i = 0, il = arguments.length; i < il; i++) s += arguments[i].length;
20
- for (var r = Array(s), k = 0, i = 0; i < il; i++)
21
- for (var a = arguments[i], j = 0, jl = a.length; j < jl; j++, k++)
22
- r[k] = a[j];
23
- return r;
24
- }
25
-
26
- function concatArrays(originVal, newVal) {
27
- if (isArray(originVal) && isArray(newVal)) {
28
- // concat logic
29
- return originVal.concat(newVal);
30
- }
31
- return newVal; // always return newVal as fallback!!
32
- }
33
-
34
- function assignProp(carry, key, newVal, originalObject) {
35
- var propType = {}.propertyIsEnumerable.call(originalObject, key)
36
- ? 'enumerable'
37
- : 'nonenumerable';
38
- if (propType === 'enumerable')
39
- carry[key] = newVal;
40
- if (propType === 'nonenumerable') {
41
- Object.defineProperty(carry, key, {
42
- value: newVal,
43
- enumerable: false,
44
- writable: true,
45
- configurable: true,
46
- });
47
- }
48
- }
49
- function mergeRecursively(origin, newComer, compareFn) {
50
- // always return newComer if its not an object
51
- if (!isPlainObject(newComer))
52
- return newComer;
53
- // define newObject to merge all values upon
54
- var newObject = {};
55
- if (isPlainObject(origin)) {
56
- var props_1 = Object.getOwnPropertyNames(origin);
57
- var symbols_1 = Object.getOwnPropertySymbols(origin);
58
- newObject = __spreadArrays(props_1, symbols_1).reduce(function (carry, key) {
59
- var targetVal = origin[key];
60
- if ((!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) ||
61
- (isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))) {
62
- assignProp(carry, key, targetVal, origin);
63
- }
64
- return carry;
65
- }, {});
66
- }
67
- // newObject has all properties that newComer hasn't
68
- var props = Object.getOwnPropertyNames(newComer);
69
- var symbols = Object.getOwnPropertySymbols(newComer);
70
- var result = __spreadArrays(props, symbols).reduce(function (carry, key) {
71
- // re-define the origin and newComer as targetVal and newVal
72
- var newVal = newComer[key];
73
- var targetVal = isPlainObject(origin) ? origin[key] : undefined;
74
- // When newVal is an object do the merge recursively
75
- if (targetVal !== undefined && isPlainObject(newVal)) {
76
- newVal = mergeRecursively(targetVal, newVal, compareFn);
77
- }
78
- var propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal;
79
- assignProp(carry, key, propToAssign, newComer);
80
- return carry;
81
- }, newObject);
82
- return result;
83
- }
84
- /**
85
- * Merge anything recursively.
86
- * Objects get merged, special objects (classes etc.) are re-assigned "as is".
87
- * Basic types overwrite objects or other basic types.
88
- *
89
- * @export
90
- * @template T
91
- * @template Tn
92
- * @param {T} origin
93
- * @param {...Tn} newComers
94
- * @returns {Assigned<T, Tn>}
95
- */
96
- function merge(origin) {
97
- var newComers = [];
98
- for (var _i = 1; _i < arguments.length; _i++) {
99
- newComers[_i - 1] = arguments[_i];
100
- }
101
- // @ts-ignore
102
- return newComers.reduce(function (result, newComer) {
103
- return mergeRecursively(result, newComer);
104
- }, origin);
105
- }
106
- function mergeAndCompare(compareFn, origin) {
107
- var newComers = [];
108
- for (var _i = 2; _i < arguments.length; _i++) {
109
- newComers[_i - 2] = arguments[_i];
110
- }
111
- // @ts-ignore
112
- return newComers.reduce(function (result, newComer) {
113
- return mergeRecursively(result, newComer, compareFn);
114
- }, origin);
115
- }
116
- function mergeAndConcat(origin) {
117
- var newComers = [];
118
- for (var _i = 1; _i < arguments.length; _i++) {
119
- newComers[_i - 1] = arguments[_i];
120
- }
121
- // @ts-ignore
122
- return newComers.reduce(function (result, newComer) {
123
- return mergeRecursively(result, newComer, concatArrays);
124
- }, origin);
125
- }
126
-
127
- export { concatArrays, merge, mergeAndCompare, mergeAndConcat };
package/src/extensions.ts DELETED
@@ -1,9 +0,0 @@
1
- import { isArray } from 'is-what'
2
-
3
- export function concatArrays (originVal: any, newVal: any): any | any[] {
4
- if (isArray(originVal) && isArray(newVal)) {
5
- // concat logic
6
- return originVal.concat(newVal)
7
- }
8
- return newVal // always return newVal as fallback!!
9
- }
package/src/index.ts DELETED
@@ -1,2 +0,0 @@
1
- export { merge, mergeAndCompare, mergeAndConcat } from './merge'
2
- export { concatArrays } from './extensions'
package/src/merge.ts DELETED
@@ -1,110 +0,0 @@
1
- import { O } from 'ts-toolbelt'
2
- import { isPlainObject, isSymbol } from 'is-what'
3
- import { concatArrays } from './extensions'
4
-
5
- // @ts-ignore
6
- type PlainObject = { [key: string | symbol]: any }
7
-
8
- function assignProp (
9
- carry: PlainObject,
10
- key: string | symbol,
11
- newVal: any,
12
- originalObject: PlainObject
13
- ): void {
14
- const propType = {}.propertyIsEnumerable.call(originalObject, key)
15
- ? 'enumerable'
16
- : 'nonenumerable'
17
- if (propType === 'enumerable') carry[key] = newVal
18
- if (propType === 'nonenumerable') {
19
- Object.defineProperty(carry, key, {
20
- value: newVal,
21
- enumerable: false,
22
- writable: true,
23
- configurable: true,
24
- })
25
- }
26
- }
27
-
28
- function mergeRecursively<T1 extends PlainObject | any, T2 extends PlainObject | any> (
29
- origin: T1,
30
- newComer: T2,
31
- compareFn?: (prop1: any, prop2: any, propName: string | symbol) => any
32
- ): (T1 & T2) | T2 {
33
- // always return newComer if its not an object
34
- if (!isPlainObject(newComer)) return newComer
35
- // define newObject to merge all values upon
36
- let newObject = {} as (T1 & T2) | T2
37
- if (isPlainObject(origin)) {
38
- const props = Object.getOwnPropertyNames(origin)
39
- const symbols = Object.getOwnPropertySymbols(origin)
40
- newObject = [...props, ...symbols].reduce((carry, key) => {
41
- const targetVal = origin[key as any]
42
- if (
43
- (!isSymbol(key) && !Object.getOwnPropertyNames(newComer).includes(key)) ||
44
- (isSymbol(key) && !Object.getOwnPropertySymbols(newComer).includes(key))
45
- ) {
46
- assignProp(carry as any, key, targetVal, origin)
47
- }
48
- return carry
49
- }, {} as (T1 & T2) | T2)
50
- }
51
- // newObject has all properties that newComer hasn't
52
- const props = Object.getOwnPropertyNames(newComer)
53
- const symbols = Object.getOwnPropertySymbols(newComer)
54
- const result = [...props, ...symbols].reduce((carry, key) => {
55
- // re-define the origin and newComer as targetVal and newVal
56
- let newVal = newComer[key as any]
57
- const targetVal = isPlainObject(origin) ? origin[key as any] : undefined
58
- // When newVal is an object do the merge recursively
59
- if (targetVal !== undefined && isPlainObject(newVal)) {
60
- newVal = mergeRecursively(targetVal, newVal, compareFn)
61
- }
62
- const propToAssign = compareFn ? compareFn(targetVal, newVal, key) : newVal
63
- assignProp(carry as any, key, propToAssign, newComer)
64
- return carry
65
- }, newObject)
66
- return result
67
- }
68
-
69
- /**
70
- * Merge anything recursively.
71
- * Objects get merged, special objects (classes etc.) are re-assigned "as is".
72
- * Basic types overwrite objects or other basic types.
73
- *
74
- * @export
75
- * @template T
76
- * @template Tn
77
- * @param {T} origin
78
- * @param {...Tn} newComers
79
- * @returns {Assigned<T, Tn>}
80
- */
81
- export function merge<T extends object, Tn extends object[]> (
82
- origin: T,
83
- ...newComers: Tn
84
- ): O.Compact<T, Tn, 'deep'> {
85
- // @ts-ignore
86
- return newComers.reduce((result, newComer) => {
87
- return mergeRecursively(result, newComer)
88
- }, origin)
89
- }
90
-
91
- export function mergeAndCompare<T extends object, Tn extends object[]> (
92
- compareFn: (prop1: any, prop2: any, propName: string | symbol) => any,
93
- origin: T,
94
- ...newComers: Tn
95
- ): O.Compact<T, Tn, 'deep'> {
96
- // @ts-ignore
97
- return newComers.reduce((result, newComer) => {
98
- return mergeRecursively(result, newComer, compareFn)
99
- }, origin)
100
- }
101
-
102
- export function mergeAndConcat<T extends object, Tn extends object[]> (
103
- origin: T,
104
- ...newComers: Tn
105
- ): O.Compact<T, Tn, 'deep'> {
106
- // @ts-ignore
107
- return newComers.reduce((result, newComer) => {
108
- return mergeRecursively(result, newComer, concatArrays)
109
- }, origin)
110
- }
package/test/index.ts DELETED
@@ -1,320 +0,0 @@
1
- import test from 'ava'
2
- import { isDate } from 'is-what'
3
- import { merge } from '../src/index'
4
-
5
- function copy<T> (any: T): T {
6
- return JSON.parse(JSON.stringify(any))
7
- }
8
-
9
- test('1. origin & target stays the same | 2. works with dates', t => {
10
- const nd = new Date()
11
- const origin = { body: 'a' }
12
- const target = { dueDate: nd }
13
- const res = merge(origin, target)
14
- t.deepEqual(res, { body: 'a', dueDate: nd })
15
- t.deepEqual(origin, { body: 'a' })
16
- t.deepEqual(target, { dueDate: nd })
17
- })
18
- test('adding a prop on target1|target2|mergedObj', t => {
19
- const origin = { nested: {} }
20
- const target = { nested: {} }
21
- const res = merge(origin, target)
22
- t.deepEqual(res, { nested: {} })
23
- // @ts-ignore
24
- origin.nested.a = ''
25
- // @ts-ignore
26
- target.nested.b = ''
27
- // @ts-ignore
28
- res.nested.c = ''
29
- t.deepEqual(origin, { nested: { a: '' } })
30
- t.deepEqual(target, { nested: { b: '' } })
31
- t.deepEqual(res, { nested: { c: '' } })
32
- })
33
- test('changing a prop on target1|target2|mergedObj: failing example', t => {
34
- const origin = { nested: { a: 1 } }
35
- const target = {}
36
- const res = merge(origin, target)
37
- t.deepEqual(res, { nested: { a: 1 } })
38
- origin.nested.a = 2
39
- t.deepEqual(origin, { nested: { a: 2 } }) // linked
40
- t.deepEqual(target, {})
41
- t.deepEqual(res, { nested: { a: 2 } }) // linked
42
- // @ts-ignore
43
- target.nested = { a: 3 }
44
- t.deepEqual(origin, { nested: { a: 2 } }) // not changed
45
- t.deepEqual(target, { nested: { a: 3 } })
46
- t.deepEqual(res, { nested: { a: 2 } }) // not changed
47
- res.nested.a = 4
48
- t.deepEqual(origin, { nested: { a: 4 } }) // linked
49
- t.deepEqual(target, { nested: { a: 3 } })
50
- t.deepEqual(res, { nested: { a: 4 } }) // linked
51
- })
52
- test('changing a prop on target1|target2|mergedObj: working example', t => {
53
- const origin = { nested: { a: 1 } }
54
- const target = {}
55
- const merged = merge(origin, target)
56
- const res = copy(merged)
57
- t.deepEqual(res, { nested: { a: 1 } })
58
- origin.nested.a = 2
59
- t.deepEqual(origin, { nested: { a: 2 } }) // not linked
60
- t.deepEqual(target, {})
61
- t.deepEqual(res, { nested: { a: 1 } }) // not linked
62
- // @ts-ignore
63
- target.nested = { a: 3 }
64
- t.deepEqual(origin, { nested: { a: 2 } }) // not changed
65
- t.deepEqual(target, { nested: { a: 3 } })
66
- t.deepEqual(res, { nested: { a: 1 } }) // not changed
67
- res.nested.a = 4
68
- t.deepEqual(origin, { nested: { a: 2 } }) // not linked
69
- t.deepEqual(target, { nested: { a: 3 } })
70
- t.deepEqual(res, { nested: { a: 4 } }) // not linked
71
- })
72
- test('1. works with multiple levels | 2. overwrites entire object with null', t => {
73
- const origin = { body: '', head: null, toes: { big: true }, fingers: { '12': false } }
74
- const target = { body: {}, head: {}, toes: {}, fingers: null }
75
- const res = merge(origin, target)
76
- // @ts-ignore
77
- t.deepEqual(res, { body: {}, head: {}, toes: { big: true }, fingers: null })
78
- })
79
- test('origin and target are not modified', t => {
80
- const origin = { body: '', head: null, toes: { big: true }, fingers: { '12': false } }
81
- const target = { body: {}, head: {}, toes: {}, fingers: null }
82
- const res = merge(origin, target)
83
- // @ts-ignore
84
- t.deepEqual(res, { body: {}, head: {}, toes: { big: true }, fingers: null })
85
- t.deepEqual(origin, { body: '', head: null, toes: { big: true }, fingers: { '12': false } })
86
- t.deepEqual(target, { body: {}, head: {}, toes: {}, fingers: null })
87
- origin.body = 'a'
88
- // @ts-ignore
89
- origin.head = 'a'
90
- // @ts-ignore
91
- origin.toes.big = 'a'
92
- // @ts-ignore
93
- origin.fingers['12'] = 'a'
94
- target.body = 'b'
95
- target.head = 'b'
96
- // @ts-ignore
97
- target.toes = 'b'
98
- // @ts-ignore
99
- target.fingers = 'b'
100
- // @ts-ignore
101
- t.deepEqual(res, { body: {}, head: {}, toes: { big: true }, fingers: null })
102
- // @ts-ignore
103
- t.deepEqual(origin, { body: 'a', head: 'a', toes: { big: 'a' }, fingers: { '12': 'a' } })
104
- // @ts-ignore
105
- t.deepEqual(target, { body: 'b', head: 'b', toes: 'b', fingers: 'b' })
106
- })
107
-
108
- test('Overwrite arrays', t => {
109
- const origin = { array: ['a'] }
110
- const target = { array: ['b'] }
111
- const res = merge(origin, target)
112
- t.deepEqual(res, { array: ['b'] })
113
- })
114
- test('overwrites null with empty object', t => {
115
- const origin = { body: null }
116
- const target = { body: {} }
117
- const res = merge(origin, target)
118
- // @ts-ignore
119
- t.deepEqual(res, { body: {} })
120
- })
121
- test('overwrites null with object with props', t => {
122
- const origin = { body: null }
123
- const target = { body: { props: true } }
124
- const res = merge(origin, target)
125
- // @ts-ignore
126
- t.deepEqual(res, { body: { props: true } })
127
- })
128
- test('overwrites string values', t => {
129
- const origin = { body: 'a' }
130
- const target = { body: 'b' }
131
- const res = merge(origin, target)
132
- t.deepEqual(res, { body: 'b' })
133
- t.deepEqual(origin, { body: 'a' })
134
- t.deepEqual(target, { body: 'b' })
135
- })
136
- test('works with very deep props & dates', t => {
137
- const newDate = new Date()
138
- const origin = {
139
- info: {
140
- time: 'now',
141
- newDate,
142
- very: { deep: { prop: false } },
143
- },
144
- }
145
- const target = {
146
- info: {
147
- date: 'tomorrow',
148
- very: { deep: { prop: true } },
149
- },
150
- }
151
- const res = merge(origin, target)
152
- t.deepEqual(res, {
153
- info: {
154
- // @ts-ignore
155
- time: 'now',
156
- newDate,
157
- date: 'tomorrow',
158
- very: { deep: { prop: true } },
159
- },
160
- })
161
- t.deepEqual(origin, {
162
- info: {
163
- time: 'now',
164
- newDate,
165
- very: { deep: { prop: false } },
166
- },
167
- })
168
- t.deepEqual(target, {
169
- info: {
170
- date: 'tomorrow',
171
- very: { deep: { prop: true } },
172
- },
173
- })
174
- // @ts-ignore
175
- t.true(isDate(res.info.newDate))
176
- })
177
- test('1. does not overwrite origin prop if target prop is an empty object | 2. properly merges deep props', t => {
178
- const origin = {
179
- info: {
180
- time: { when: 'now' },
181
- very: { deep: { prop: false } },
182
- },
183
- }
184
- const target = {
185
- info: {
186
- time: {},
187
- very: { whole: 1 },
188
- },
189
- }
190
- const res = merge(origin, target)
191
- t.deepEqual(res, {
192
- info: {
193
- time: { when: 'now' },
194
- very: {
195
- // @ts-ignore
196
- deep: { prop: false },
197
- whole: 1,
198
- },
199
- },
200
- })
201
- })
202
- test('overwrites any origin prop when target prop is an object with props', t => {
203
- const origin = {
204
- body: 'a',
205
- body2: { head: false },
206
- tail: {},
207
- }
208
- const target = {
209
- body: { head: true },
210
- body2: { head: { eyes: true } },
211
- }
212
- const res = merge(origin, target)
213
- t.deepEqual(res, {
214
- // @ts-ignore
215
- body: { head: true },
216
- // @ts-ignore
217
- body2: { head: { eyes: true } },
218
- tail: {},
219
- })
220
- t.deepEqual(origin, {
221
- body: 'a',
222
- body2: { head: false },
223
- tail: {},
224
- })
225
- t.deepEqual(target, {
226
- body: { head: true },
227
- body2: { head: { eyes: true } },
228
- })
229
- })
230
-
231
- test('works with unlimited depth', t => {
232
- const date = new Date()
233
- const origin = { origin: 'a', t2: false, t3: {}, t4: 'false' }
234
- const t1 = { t1: date }
235
- const t2 = { t2: 'new' }
236
- const t3 = { t3: 'new' }
237
- const t4 = { t4: 'new', t3: {} }
238
- const res = merge(origin, t1, t2, t3, t4)
239
- // @ts-ignore
240
- t.deepEqual(res, { origin: 'a', t1: date, t2: 'new', t3: {}, t4: 'new' })
241
- t.deepEqual(origin, { origin: 'a', t2: false, t3: {}, t4: 'false' })
242
- t.deepEqual(t1, { t1: date })
243
- t.deepEqual(t2, { t2: 'new' })
244
- t.deepEqual(t3, { t3: 'new' })
245
- t.deepEqual(t4, { t4: 'new', t3: {} })
246
- })
247
-
248
- test('symbols as keys 1', t => {
249
- const mySymbol = Symbol('mySymbol')
250
- const x = { value: 42, [mySymbol]: 'hello' }
251
- const y = { other: 33 }
252
- const res = merge(x, y)
253
- t.is(res.value, 42)
254
- t.is(res.other, 33)
255
- t.is(res[mySymbol], 'hello')
256
- })
257
- test('symbols as keys 2', t => {
258
- const mySymbol = Symbol('mySymbol')
259
- const x = { value: 42 }
260
- const y = { other: 33, [mySymbol]: 'hello' }
261
- const res = merge(x, y)
262
- t.is(res.value, 42)
263
- t.is(res.other, 33)
264
- t.is(res[mySymbol], 'hello')
265
- })
266
-
267
- test('nonenumerable keys', t => {
268
- const mySymbol = Symbol('mySymbol')
269
- const x = { value: 42 }
270
- const y = { other: 33 }
271
- Object.defineProperty(x, 'xid', {
272
- value: 1,
273
- writable: true,
274
- enumerable: false,
275
- configurable: true,
276
- })
277
- Object.defineProperty(x, mySymbol, {
278
- value: 'original',
279
- writable: true,
280
- enumerable: false,
281
- configurable: true,
282
- })
283
- Object.defineProperty(y, 'yid', {
284
- value: 2,
285
- writable: true,
286
- enumerable: false,
287
- configurable: true,
288
- })
289
- Object.defineProperty(y, mySymbol, {
290
- value: 'new',
291
- writable: true,
292
- enumerable: false,
293
- configurable: true,
294
- })
295
- const res = merge(x, y)
296
- t.is(res.value, 42)
297
- t.is(res.other, 33)
298
- // @ts-ignore
299
- t.is(res.xid, 1)
300
- // @ts-ignore
301
- t.is(res.yid, 2)
302
- t.is(res[mySymbol], 'new')
303
- t.is(Object.keys(res).length, 2)
304
- t.true(Object.keys(res).includes('value'))
305
- t.true(Object.keys(res).includes('other'))
306
- })
307
-
308
- test('readme', t => {
309
- const starter = { name: 'Squirtle', types: { water: true } }
310
- const newValues = { name: 'Wartortle', types: { fighting: true }, level: 16 }
311
-
312
- const evolution = merge(starter, newValues, { is: 'cool' })
313
-
314
- t.deepEqual(evolution, {
315
- name: 'Wartortle',
316
- types: { water: true, fighting: true },
317
- level: 16,
318
- is: 'cool',
319
- })
320
- })