core-functions
Advanced tools
Comparing version 2.0.10 to 2.0.11
@@ -64,2 +64,7 @@ "use strict"; | ||
Object.defineProperty(this, 'causeStatus', {value: causeStatus, enumerable: true}); | ||
// Use the given error's stack instead of this object's own stack | ||
if (cause instanceof Error) { | ||
this.stack = cause.stack; | ||
} | ||
} | ||
@@ -66,0 +71,0 @@ } |
'use strict'; | ||
const Numbers = require('./numbers'); | ||
/** | ||
@@ -37,2 +35,5 @@ * Module containing utilities for working with objects. | ||
function merge(from, to, replace, deep) { | ||
if (!from || typeof from !== 'object') throw new TypeError(`from must be a non-null object`); | ||
if (!to || typeof to !== 'object') throw new TypeError(`to must be a non-null object`); | ||
const history = new WeakMap(); | ||
@@ -47,9 +48,39 @@ | ||
const srcNames = Object.getOwnPropertyNames(src); | ||
// If both src and dest are arrays then special case for arrays | ||
const srcIsArray = Array.isArray(src); | ||
const destIsArray = Array.isArray(dest); | ||
if (srcIsArray && destIsArray) { | ||
// First merge all corresponding elements of src into dest | ||
const n = Math.min(src.length, dest.length); | ||
for (let i = 0; i < n; ++i) { | ||
const srcElement = src[i]; | ||
const srcElementIsObject = srcElement && typeof srcElement === 'object'; | ||
const destElement = dest[i]; | ||
if (deep && srcElementIsObject && destElement && typeof destElement === 'object') { | ||
mergeWithHistory(srcElement, destElement, replace, deep); | ||
} else if (replace) { | ||
dest[i] = srcElementIsObject ? copy(srcElement, true) : srcElement; | ||
} | ||
} | ||
// If src was longer than dest, then append copies of any remaining elements of src (if any) to the end of dest | ||
for (let j = n; j < src.length; ++j) { | ||
const srcElement = src[j]; | ||
const srcElementIsObject = srcElement && typeof srcElement === 'object'; | ||
dest.push(srcElementIsObject ? copy(srcElement, true) : srcElement); | ||
} | ||
} | ||
// Arrays can also be given other properties, so special case when both arrays, skip src length and numeric property names | ||
const allSrcNames = Object.getOwnPropertyNames(src); | ||
const srcNames = srcIsArray && destIsArray ? | ||
allSrcNames.filter(n => n !== 'length' && Number.isNaN(Number.parseInt(n))) : allSrcNames; | ||
const destNames = Object.getOwnPropertyNames(dest); | ||
for (let i = 0; i < srcNames.length; ++i) { | ||
const name = srcNames[i]; | ||
const srcPropertyValue = src[name]; | ||
const srcPropertyIsObject = srcPropertyValue && typeof srcPropertyValue === 'object'; | ||
const srcProperty = src[name]; | ||
const srcPropertyIsObject = srcProperty && typeof srcProperty === 'object'; | ||
@@ -59,10 +90,10 @@ const existsOnDest = destNames.indexOf(name) !== -1; | ||
if (existsOnDest) { | ||
const destPropertyValue = dest[name]; | ||
if (deep && srcPropertyIsObject && destPropertyValue && typeof destPropertyValue === 'object') { | ||
mergeWithHistory(srcPropertyValue, destPropertyValue, replace, deep); | ||
const destProperty = dest[name]; | ||
if (deep && srcPropertyIsObject && destProperty && typeof destProperty === 'object') { | ||
mergeWithHistory(srcProperty, destProperty, replace, deep); | ||
} else if (replace) { | ||
dest[name] = srcPropertyIsObject ? copy(srcPropertyValue, true) : srcPropertyValue; | ||
dest[name] = srcPropertyIsObject ? copy(srcProperty, true) : srcProperty; | ||
} | ||
} else { | ||
dest[name] = srcPropertyIsObject ? copy(srcPropertyValue, true) : srcPropertyValue; | ||
dest[name] = srcPropertyIsObject ? copy(srcProperty, true) : srcProperty; | ||
} | ||
@@ -78,3 +109,4 @@ } | ||
* Copies the enumerable properties of the given object into a new object. Executes a deep copy if the given deep flag | ||
* is true, otherwise only does a shallow copy. Returns the new copy of the original object. | ||
* is true, otherwise only does a shallow copy. Returns the new copy of the original object or the original object if it | ||
* was NOT a non-null instance of Object. | ||
* @param {Object} object - the object from which to copy enumerable properties into a new object | ||
@@ -84,4 +116,11 @@ * @param {boolean|undefined} [deep] - Executes a deep copy if the given deep flag is true, otherwise only does a shallow copy | ||
function copy(object, deep) { | ||
if (!object || typeof object !== 'object') { | ||
return object; | ||
} | ||
const history = new WeakMap(); | ||
function newDest(object) { | ||
return Array.isArray(object) ? new Array(object.length) : Object.create(object.__proto__); | ||
} | ||
function copyWithHistory(src, dest) { | ||
@@ -94,3 +133,15 @@ if (history.has(src)) { | ||
const names = Object.getOwnPropertyNames(src); | ||
const srcIsArray = Array.isArray(src); | ||
if (srcIsArray) { | ||
for (let i = 0; i < src.length; ++i) { | ||
const element = src[i]; | ||
const elementIsObject = element && typeof element === 'object'; | ||
dest[i] = deep && elementIsObject ? | ||
copyWithHistory(element, newDest(element)) : element; | ||
} | ||
} | ||
// Arrays can also be given other properties, so special case for arrays, skip length and numeric property names | ||
const allNames = Object.getOwnPropertyNames(src); | ||
const names = srcIsArray ? allNames.filter(n => n !== 'length' && Number.isNaN(Number.parseInt(n))) : allNames; | ||
for (let i = 0; i < names.length; ++i) { | ||
@@ -100,3 +151,4 @@ const name = names[i]; | ||
const propertyIsObject = property && typeof property === 'object'; | ||
dest[name] = deep && propertyIsObject ? copyWithHistory(property, {}) : property; | ||
dest[name] = deep && propertyIsObject ? | ||
copyWithHistory(property, newDest(property)) : property; | ||
} | ||
@@ -106,3 +158,3 @@ return dest; | ||
return copyWithHistory(object, {}); | ||
return copyWithHistory(object, newDest(object)); | ||
} |
{ | ||
"name": "core-functions", | ||
"version": "2.0.10", | ||
"version": "2.0.11", | ||
"description": "Core functions, utilities and classes for working with Node/JavaScript primitives and built-in objects, including strings, booleans, Promises, base 64, Arrays, Objects, standard AppErrors, etc.", | ||
@@ -5,0 +5,0 @@ "author": "Byron du Preez", |
@@ -1,2 +0,2 @@ | ||
# core-functions v2.0.10 | ||
# core-functions v2.0.11 | ||
@@ -107,2 +107,8 @@ Core functions, utilities and classes for working with Node/JavaScript primitives and built-in objects, including | ||
### 2.0.11 | ||
- Changed `app-errors.js` module's `AppError` constructor: | ||
- To preserve and use the more useful stack of its cause (if cause is an Error) instead of its own stack | ||
- Changed `objects.js` module's `copy` and `merge` functions: | ||
- To support copying and merging of Arrays as well | ||
### 2.0.10 | ||
@@ -109,0 +115,0 @@ - Changed `strings.js` module's `stringify` function: |
@@ -170,2 +170,6 @@ 'use strict'; | ||
if (error instanceof Error) { | ||
t.equal(appError.stack, error.stack, 'toAppError stack of appError must be stack of original error'); | ||
} | ||
// AppErrors must pass through as is unless their message and/or code don't match specified ones | ||
@@ -172,0 +176,0 @@ const originalAppError = error instanceof AppError && (!message || error.message === message) && (!code || error.code === code); |
@@ -13,2 +13,5 @@ 'use strict'; | ||
const strings = require('../strings'); | ||
const stringify = strings.stringify; | ||
const testing = require('./testing'); | ||
@@ -90,7 +93,17 @@ // const okNotOk = testing.okNotOk; | ||
t.notDeepEqual(merge2, from, 'shallow merge with replace must not be from'); | ||
t.deepEqual(merge2, {a: 1, b: '2', c: {d: 3, e: '4'}, z: 'ZZZ'}, 'shallow merge with replace must have all of from + only top-level extra original to2 properties'); | ||
t.deepEqual(merge2, { | ||
a: 1, | ||
b: '2', | ||
c: {d: 3, e: '4'}, | ||
z: 'ZZZ' | ||
}, 'shallow merge with replace must have all of from + only top-level extra original to2 properties'); | ||
// deep must preserve inner extras | ||
const to3 = {a: 2, b: '3', c: {d: 4, e: '5', f: 6}, z: 'ZZZ'}; | ||
t.deepEqual(Objects.merge(from, to3, true, true), {a: 1, b: '2', c: {d: 3, e: '4', f: 6}, z: 'ZZZ'}, 'deep merge with replace must have all of from + all extra original to2 properties'); | ||
t.deepEqual(Objects.merge(from, to3, true, true), { | ||
a: 1, | ||
b: '2', | ||
c: {d: 3, e: '4', f: 6}, | ||
z: 'ZZZ' | ||
}, 'deep merge with replace must have all of from + all extra original to2 properties'); | ||
@@ -103,6 +116,14 @@ // deep without replace must NOT replace any matching properties | ||
// check that functions get merged in too | ||
function a1() {} | ||
function a2() {} | ||
function b() {} | ||
function c() {} | ||
function a1() { | ||
} | ||
function a2() { | ||
} | ||
function b() { | ||
} | ||
function c() { | ||
} | ||
const from5 = {a: a2, b: b, c: c, z: 'Z2'}; | ||
@@ -117,3 +138,5 @@ const to5 = {a: a1, z: 'Z1'}; | ||
function x() {} | ||
function x() { | ||
} | ||
const to6 = {a: a1, x: x, y: 'y1', z: 'Z1'}; | ||
@@ -131,3 +154,5 @@ const expected6 = {a: a2, b: b, c: c, x: x, y: 'y1', z: 'Z2'}; | ||
function d() {} | ||
function d() { | ||
} | ||
const from8 = {o: {a: a2, b: b}, c: c, z: 'Z2'}; | ||
@@ -178,5 +203,11 @@ const to8 = {o: {a: a1, x: x, y: 'y1'}, d: d, z: 'Z1'}; | ||
test('copy', t => { | ||
function a() {} | ||
function b() {} | ||
function c() {} | ||
function a() { | ||
} | ||
function b() { | ||
} | ||
function c() { | ||
} | ||
//function d() {} | ||
@@ -216,1 +247,486 @@ | ||
}); | ||
// ===================================================================================================================== | ||
// copy arrays | ||
// ===================================================================================================================== | ||
test('copy arrays', t => { | ||
// Shallow copy of empty array | ||
const a0 = []; | ||
const c0 = Objects.copy(a0, false); | ||
t.ok(Array.isArray(c0), `shallow copy ${stringify(c0)} must be an array`); | ||
t.notEqual(c0, a0, `shallow copy ${stringify(c0)} must not be same instance`); | ||
t.deepEqual(c0, a0, `shallow copy ${stringify(c0)} must be deep equal`); | ||
// Deep copy of empty array | ||
const a1 = []; | ||
const c1 = Objects.copy(a1, true); | ||
t.ok(Array.isArray(c1), `deep copy ${stringify(c1)} must be an array`); | ||
t.notEqual(c1, a1, `deep copy ${stringify(c1)} must NOT be same instance`); | ||
t.deepEqual(c1, a1, `deep copy ${stringify(c1)} must be deep equal`); | ||
// Shallow copy of complex array | ||
const a2 = [1, 2, "3", undefined, null, {a: 1}, [4, 5, "6", null, undefined, {b: 2, c: [7]}]]; | ||
const c2 = Objects.copy(a2, false); | ||
t.ok(Array.isArray(c2), `shallow copy ${stringify(c2)} must be an array`); | ||
t.equal(c2.length, a2.length, `shallow copy ${stringify(c2)} lengths must be same`); | ||
t.notEqual(c2, a2, `shallow copy ${stringify(c2)} must NOT be same instance`); | ||
t.deepEqual(c2, a2, `shallow copy ${stringify(c2)} must be deep equal`); | ||
for (let i = 0; i < a2.length; ++i) { | ||
t.equal(c2[i], a2[i], `shallow copy [${i}] ${stringify(c2[i])} must be equal`); | ||
t.deepEqual(c2[i], a2[i], `shallow copy [${i}] ${stringify(c2[i])} must be deep equal`); | ||
} | ||
// Deep copy of complex array | ||
const a3 = [1, 2, "3", undefined, null, {a: 1}, [4, 5, "6", null, undefined, {b: 2, c: [7]}]]; | ||
const c3 = Objects.copy(a3, true); | ||
t.ok(Array.isArray(c3), `deep copy ${stringify(c3)} must be an array`); | ||
t.equal(c3.length, a3.length, `deep copy ${stringify(c3)} lengths must be same`); | ||
t.notEqual(c3, a3, `deep copy ${stringify(c3)} must NOT be same instance`); | ||
t.deepEqual(c3, a3, `deep copy ${stringify(c3)} must be deep equal`); | ||
for (let i = 0; i < a3.length; ++i) { | ||
if (a3[i] && typeof a3[i] === 'object') | ||
t.notEqual(c3[i], a3[i], `deep copy [${i}] ${stringify(c3[i])} must NOT be same instance`); | ||
else | ||
t.equal(c3[i], a3[i], `deep copy [${i}] ${stringify(c3[i])} must be equal`); | ||
t.deepEqual(c3[i], a3[i], `deep copy [${i}] ${stringify(c3[i])} must be deep equal`); | ||
} | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// copy objects with arrays | ||
// ===================================================================================================================== | ||
test('copy objects with arrays', t => { | ||
// Shallow copy of object with empty array | ||
const a0 = {a: []}; | ||
const c0 = Objects.copy(a0, false); | ||
t.ok(!Array.isArray(c0), `shallow copy ${stringify(c0)} must NOT be an array`); | ||
t.notEqual(c0, a0, `shallow copy ${stringify(c0)} must not be same instance`); | ||
t.deepEqual(c0, a0, `shallow copy ${stringify(c0)} must be deep equal`); | ||
// Deep copy of empty array | ||
const a1 = {a: []}; | ||
const c1 = Objects.copy(a1, true); | ||
t.ok(!Array.isArray(c1), `deep copy ${stringify(c1)} must NOT be an array`); | ||
t.notEqual(c1, a1, `deep copy ${stringify(c1)} must NOT be same instance`); | ||
t.deepEqual(c1, a1, `deep copy ${stringify(c1)} must be deep equal`); | ||
// Shallow copy of complex array | ||
const a2 = {a: [1, 2, "3", undefined, null, {a: 1}, [4, 5, "6", null, undefined, {b: 2, c: [7]}]]}; | ||
const c2 = Objects.copy(a2, false); | ||
t.ok(!Array.isArray(c2), `shallow copy ${stringify(c2)} must NOT be an array`); | ||
t.notEqual(c2, a2, `shallow copy ${stringify(c2)} must NOT be same instance`); | ||
t.deepEqual(c2, a2, `shallow copy ${stringify(c2)} must be deep equal`); | ||
for (let i = 0; i < a2.length; ++i) { | ||
t.equal(c2[i], a2[i], `shallow copy [${i}] ${stringify(c2[i])} must be equal`); | ||
t.deepEqual(c2[i], a2[i], `shallow copy [${i}] ${stringify(c2[i])} must be deep equal`); | ||
} | ||
// Deep copy of complex array | ||
const a3 = {a: [1, 2, "3", undefined, null, {a: 1}, [4, 5, "6", null, undefined, {b: 2, c: [7]}]]}; | ||
const c3 = Objects.copy(a3, true); | ||
t.ok(!Array.isArray(c3), `deep copy ${stringify(c3)} must NOT be an array`); | ||
t.notEqual(c3, a3, `deep copy ${stringify(c3)} must NOT be same instance`); | ||
t.deepEqual(c3, a3, `deep copy ${stringify(c3)} must be deep equal`); | ||
for (let n of Object.getOwnPropertyNames(a3)) { | ||
if (a3[n] && typeof a3[n] === 'object') | ||
t.notEqual(c3[n], a3[n], `deep copy [${n}] ${stringify(c3[n])} must NOT be same instance`); | ||
else | ||
t.equal(c3[n], a3[n], `deep copy [${n}] ${stringify(c3[n])} must be equal`); | ||
t.deepEqual(c3[n], a3[n], `deep copy [${n}] ${stringify(c3[n])} must be deep equal`); | ||
} | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// merge arrays | ||
// ===================================================================================================================== | ||
test('merge empty arrays', t => { | ||
// Shallow merge of empty array | ||
const a0 = []; | ||
const b0 = []; | ||
const c0 = Objects.merge(a0, b0, false, false); | ||
t.ok(Array.isArray(c0), `shallow merge ${stringify(c0)} must be an array`); | ||
t.notEqual(c0, a0, `shallow merge ${stringify(c0)} must not be same instance`); | ||
t.deepEqual(c0, a0, `shallow merge ${stringify(c0)} must be deep equal`); | ||
// Deep merge of empty array | ||
const a1 = []; | ||
const b1 = []; | ||
const c1 = Objects.merge(a1, b1, false, true); | ||
t.ok(Array.isArray(c1), `deep merge ${stringify(c1)} must be an array`); | ||
t.notEqual(c1, a1, `deep merge ${stringify(c1)} must NOT be same instance`); | ||
t.deepEqual(c1, a1, `deep merge ${stringify(c1)} must be deep equal`); | ||
t.end(); | ||
}); | ||
test('merge simple arrays to empty arrays', t => { | ||
// Shallow merge of simple array to empty | ||
const a0 = [1, 2, 3]; | ||
const b0 = []; | ||
const c0 = Objects.merge(a0, b0, false, false); | ||
t.ok(Array.isArray(c0), `shallow merge ${stringify(c0)} must be an array`); | ||
t.notEqual(c0, a0, `shallow merge ${stringify(c0)} must not be same instance`); | ||
t.deepEqual(c0, a0, `shallow merge ${stringify(c0)} must be deep equal`); | ||
// Deep merge of empty array | ||
const a1 = [1, 2, 3]; | ||
const b1 = []; | ||
const c1 = Objects.merge(a1, b1, false, true); | ||
t.ok(Array.isArray(c1), `deep merge ${stringify(c1)} must be an array`); | ||
t.notEqual(c1, a1, `deep merge ${stringify(c1)} must NOT be same instance`); | ||
t.deepEqual(c1, a1, `deep merge ${stringify(c1)} must be deep equal`); | ||
t.end(); | ||
}); | ||
test('merge empty arrays to simple arrays', t => { | ||
// Shallow merge of simple array to empty | ||
const a0 = []; | ||
const b0 = [1, 2, 3]; | ||
const x0 = [1, 2, 3]; | ||
Objects.merge(a0, b0, false, false); | ||
t.ok(Array.isArray(b0), `shallow merge ${stringify(b0)} must be an array`); | ||
t.notEqual(b0, a0, `shallow merge ${stringify(b0)} must not be same instance`); | ||
t.deepEqual(b0, x0, `shallow merge ${stringify(b0)} must be deep equal`); | ||
// Deep merge of empty array | ||
const a1 = []; | ||
const b1 = ["1", 2, "3"]; | ||
const x1 = ["1", 2, "3"]; | ||
const c1 = Objects.merge(a1, b1, false, true); | ||
t.ok(Array.isArray(c1), `deep merge ${stringify(c1)} must be an array`); | ||
t.notEqual(c1, a1, `deep merge ${stringify(c1)} must NOT be same instance`); | ||
t.deepEqual(c1, x1, `deep merge ${stringify(c1)} must be deep equal`); | ||
t.end(); | ||
}); | ||
test('merge simple arrays to shorter arrays', t => { | ||
// Shallow merge without replace | ||
const a0 = ["1", 2, "3", 4.0]; | ||
const b0 = [9, "8"]; | ||
const x0 = [9, "8", "3", 4.0]; | ||
Objects.merge(a0, b0, false, false); | ||
t.ok(Array.isArray(b0), `shallow merge ${stringify(b0)} must be an array`); | ||
t.notEqual(b0, a0, `shallow merge ${stringify(b0)} must not be same instance`); | ||
t.deepEqual(b0, x0, `shallow merge ${stringify(b0)} must be deep equal`); | ||
// Shallow merge with replace | ||
const a1 = ["1", 2, "3", 4.0]; | ||
const b1 = [9, "8"]; | ||
const x1 = ["1", 2, "3", 4.0]; | ||
Objects.merge(a1, b1, true, false); | ||
t.ok(Array.isArray(b1), `deep merge ${stringify(b1)} must be an array`); | ||
t.notEqual(b1, a1, `deep merge ${stringify(b1)} must NOT be same instance`); | ||
t.deepEqual(b1, x1, `deep merge ${stringify(b1)} must be deep equal`); | ||
// Deep merge without replace | ||
const a2 = [1, 2, 3, 4.0]; | ||
const b2 = ["9", 8]; | ||
const x2 = ["9", 8, 3, 4.0]; | ||
Objects.merge(a2, b2, false, true); | ||
t.ok(Array.isArray(b2), `deep merge ${stringify(b2)} must be an array`); | ||
t.notEqual(b2, a2, `deep merge ${stringify(b2)} must not be same instance`); | ||
t.deepEqual(b2, x2, `deep merge ${stringify(b2)} must be deep equal`); | ||
// Deep merge with replace | ||
const a4 = ["1", 2, "3", 4.0]; | ||
const b4 = [9, 8]; | ||
const x4 = ["1", 2, "3", 4.0]; | ||
Objects.merge(a4, b4, true, true); | ||
t.ok(Array.isArray(b4), `deep merge ${stringify(b4)} must be an array`); | ||
t.notEqual(b4, a4, `deep merge ${stringify(b4)} must NOT be same instance`); | ||
t.deepEqual(b4, x4, `deep merge ${stringify(b4)} must be deep equal`); | ||
t.end(); | ||
}); | ||
test('merge simple arrays to longer arrays', t => { | ||
// Shallow merge without replace | ||
const a0 = [9, "8"]; | ||
const b0 = ["1", 2, "3", 4.0, [5]]; | ||
const x0 = ["1", 2, "3", 4.0, [5]]; | ||
Objects.merge(a0, b0, false, false); | ||
t.ok(Array.isArray(b0), `shallow merge ${stringify(b0)} must be an array`); | ||
t.notEqual(b0, a0, `shallow merge ${stringify(b0)} must not be same instance`); | ||
t.deepEqual(b0, x0, `shallow merge ${stringify(b0)} must be deep equal`); | ||
// Shallow merge with replace | ||
const a1 = [9, "8"]; | ||
const b1 = ["1", 2, "3", 4.0, [5]]; | ||
const x1 = [9, "8", "3", 4.0, [5]]; | ||
Objects.merge(a1, b1, true, false); | ||
t.ok(Array.isArray(b1), `deep merge ${stringify(b1)} must be an array`); | ||
t.notEqual(b1, a1, `deep merge ${stringify(b1)} must NOT be same instance`); | ||
t.deepEqual(b1, x1, `deep merge ${stringify(b1)} must be deep equal`); | ||
// Deep merge without replace | ||
const a2 = ["9", 8]; | ||
const b2 = [1, 2, 3, 4.0, [5]]; | ||
const x2 = [1, 2, 3, 4.0, [5]]; | ||
Objects.merge(a2, b2, false, true); | ||
t.ok(Array.isArray(b2), `deep merge ${stringify(b2)} must be an array`); | ||
t.notEqual(b2, a2, `deep merge ${stringify(b2)} must not be same instance`); | ||
t.deepEqual(b2, x2, `deep merge ${stringify(b2)} must be deep equal`); | ||
// Deep merge with replace | ||
const a4 = [9, 8]; | ||
const b4 = ["1", 2, "3", 4.0, [5]]; | ||
const x4 = [9, 8, "3", 4.0, [5]]; | ||
Objects.merge(a4, b4, true, true); | ||
t.ok(Array.isArray(b4), `deep merge ${stringify(b4)} must be an array`); | ||
t.notEqual(b4, a4, `deep merge ${stringify(b4)} must NOT be same instance`); | ||
t.deepEqual(b4, x4, `deep merge ${stringify(b4)} must be deep equal`); | ||
t.end(); | ||
}); | ||
test('merge complex arrays', t => { | ||
// Shallow merge without replace | ||
const a1 = [1, 2, "3", undefined, null, {a: 1}, [4, 5, "6", null, undefined, {b: 2, c: [7]}]]; | ||
const b1 = [2, 3, "4", null, undefined, {b: 2}, [9, 8, "7", undefined, null, {d: 3, e: [8, 9.0]}]]; | ||
const x1 = [2, 3, "4", null, undefined, b1[5], b1[6]]; | ||
Objects.merge(a1, b1, false, false); | ||
t.ok(Array.isArray(b1), `shallow merge ${stringify(b1)} must be an array`); | ||
t.equal(b1.length, a1.length, `shallow merge ${stringify(b1)} lengths must be same`); | ||
t.notEqual(b1, a1, `shallow merge ${stringify(b1)} must NOT be same instance`); | ||
t.deepEqual(b1, x1, `shallow merge ${stringify(b1)} must be deep equal`); | ||
t.equal(b1[5], x1[5], `shallow merge ${stringify(b1[5])} must be same instance`); | ||
t.deepEqual(b1[5], x1[5], `shallow merge ${stringify(b1[5])} must be deep equal`); | ||
// Shallow merge with replace | ||
const a2 = [1, 2, "3", undefined, null, {a: 1}, [4, 5, "6", null, undefined, {b: 2, c: [7]}]]; | ||
const b2 = [2, 3, "4", null, undefined, {b: 2}, [9, 8, "7", undefined, null, {d: 3, e: [8, 9.0]}]]; | ||
const x2 = [1, 2, "3", undefined, null, a2[5], a2[6]]; | ||
Objects.merge(a2, b2, true, false); | ||
t.ok(Array.isArray(b2), `shallow merge ${stringify(b2)} must be an array`); | ||
t.equal(b2.length, a2.length, `shallow merge ${stringify(b2)} lengths must be same`); | ||
t.notEqual(b2, a2, `shallow merge ${stringify(b2)} must NOT be same instance`); | ||
t.deepEqual(b2, a2, `shallow merge ${stringify(b2)} must be deep equal a2`); | ||
t.deepEqual(b2, x2, `shallow merge ${stringify(b2)} must be deep equal`); | ||
t.notEqual(b2[5], a2[5], `shallow merge ${stringify(b2[5])} must NOT be same instance`); | ||
t.deepEqual(b2[5], a2[5], `shallow merge ${stringify(b2[5])} must be deep equal`); | ||
t.notEqual(b2[6], a2[6], `shallow merge ${stringify(b2[6])} must NOT be same instance`); | ||
t.deepEqual(b2[6], a2[6], `shallow merge ${stringify(b2[6])} must be deep equal`); | ||
t.notEqual(b2[6][5], a2[6][5], `shallow merge ${stringify(b2[6][5])} must NOT be same instance`); | ||
t.deepEqual(b2[6][5], a2[6][5], `shallow merge ${stringify(b2[6][5])} must be deep equal`); | ||
// Deep merge without replace | ||
const a3 = [1, 2, "3", undefined, null, {a: 1}, [4, 5, "6", null, undefined, {b: 2, c: [7], e: [8, 9]}]]; | ||
const b3 = [9, 8, "7", null, undefined, {b: 2}, [1, 2, "3", undefined, null, {d: 3, c: [6, 5], e: [4]}]]; | ||
const x3 = [9, 8, "7", null, undefined, {b: 2, a: 1}, [1, 2, "3", undefined, null, { | ||
d: 3, | ||
c: [6, 5], | ||
b: 2, | ||
e: [4, 9] | ||
}]]; | ||
Objects.merge(a3, b3, false, true); | ||
t.ok(Array.isArray(b3), `deep merge ${stringify(b3)} must be an array`); | ||
t.equal(b3.length, a3.length, `deep merge ${stringify(b3)} lengths must be same`); | ||
t.notEqual(b3, a3, `deep merge ${stringify(b3)} must NOT be same instance`); | ||
t.deepEqual(b3, x3, `deep merge ${stringify(b3)} must be deep equal`); | ||
// Deep merge with replace | ||
const a4 = [1, 2, "3", undefined, null, {a: 1}, [4, 5, "6", null, undefined, {b: 2, c: [7], e: [8, 9]}]]; | ||
const b4 = [9, 8, "7", null, undefined, {b: 2}, [1, 2, "3", undefined, null, {d: 3, c: [6, 5], e: [4]}]]; | ||
const x4 = [1, 2, "3", undefined, null, {b: 2, a: 1}, [4, 5, "6", null, undefined, { | ||
d: 3, | ||
c: [7, 5], | ||
e: [8, 9], | ||
b: 2 | ||
}]]; | ||
Objects.merge(a4, b4, true, true); | ||
t.ok(Array.isArray(b4), `deep merge ${stringify(b4)} must be an array`); | ||
t.equal(b4.length, a4.length, `deep merge ${stringify(b4)} lengths must be same`); | ||
t.notEqual(b4, a4, `deep merge ${stringify(b4)} must NOT be same instance`); | ||
t.deepEqual(b4, x4, `deep merge ${stringify(b4)} must be deep equal`); | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// merge objects with arrays | ||
// ===================================================================================================================== | ||
test('merge objects with arrays', t => { | ||
// Shallow merge without replace | ||
const a0 = {a: [3], b: {c: [4, 5]}}; | ||
const b0 = {a: [1, 2], b: {c: [6]}}; | ||
const x0 = {a: [1, 2], b: {c: [6]}}; | ||
Objects.merge(a0, b0, false, false); | ||
t.ok(!Array.isArray(b0), `shallow merge ${stringify(b0)} must NOT be an array`); | ||
t.ok(Array.isArray(b0.a), `shallow merge ${stringify(b0.a)} must be an array`); | ||
t.notEqual(b0, a0, `shallow merge ${stringify(b0)} must not be same instance`); | ||
t.deepEqual(b0, x0, `shallow merge ${stringify(b0)} must be deep equal`); | ||
// Shallow merge with replace | ||
const a1 = {a: [3], b: {c: [4, 5]}}; | ||
const b1 = {a: [1, 2], b: {c: [6]}}; | ||
const x1 = {a: [3], b: {c: [4, 5]}}; | ||
Objects.merge(a1, b1, true, false); | ||
t.ok(!Array.isArray(b1), `shallow merge ${stringify(b1)} must NOT be an array`); | ||
t.ok(Array.isArray(b1.a), `shallow merge ${stringify(b1.a)} must be an array`); | ||
t.notEqual(b1, a1, `shallow merge ${stringify(b1)} must NOT be same instance`); | ||
t.deepEqual(b1, x1, `shallow merge ${stringify(b1)} must be deep equal`); | ||
// Deep merge without replace | ||
const a2 = {a: [3], b: {c: [4, 5]}}; | ||
const b2 = {a: [1, 2], b: {c: [6]}}; | ||
const x2 = {a: [1, 2], b: {c: [6, 5]}}; | ||
Objects.merge(a2, b2, false, true); | ||
t.ok(!Array.isArray(b2), `deep merge ${stringify(b2)} must NOT be an array`); | ||
t.ok(Array.isArray(b2.a), `deep merge ${stringify(b2.a)} must be an array`); | ||
t.notEqual(b2, a2, `deep merge ${stringify(b2)} must NOT be same instance`); | ||
t.deepEqual(b2, x2, `deep merge ${stringify(b2)} must be deep equal`); | ||
// Deep merge with replace | ||
const a3 = {a: [3], b: {c: [4, 5]}}; | ||
const b3 = {a: [1, 2], b: {c: [6]}}; | ||
const x3 = {a: [3, 2], b: {c: [4, 5]}}; | ||
Objects.merge(a3, b3, true, true); | ||
t.ok(!Array.isArray(b3), `deep merge ${stringify(b3)} must NOT be an array`); | ||
t.ok(Array.isArray(b3.a), `deep merge ${stringify(b3.a)} must be an array`); | ||
t.notEqual(b3, a3, `deep merge ${stringify(b3)} must NOT be same instance`); | ||
t.deepEqual(b3, x3, `deep merge ${stringify(b3)} must be deep equal`); | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// merge object with array | ||
// ===================================================================================================================== | ||
test('merge objects with arrays', t => { | ||
// Shallow merge without replace | ||
const a0 = {a: [3], b: {c: [4, 5]}}; | ||
const b0 = ["9", "8"]; b0.a = [1, 2]; b0.b = {c: [6]}; | ||
const x0 = ["9", "8"]; x0.a = [1, 2]; x0.b = {c: [6]}; | ||
Objects.merge(a0, b0, false, false); | ||
t.ok(Array.isArray(b0), `shallow merge ${stringify(b0)} must be an array`); | ||
t.deepEqual(b0, x0, `shallow merge ${stringify(b0)} must be deep equal`); | ||
t.deepEqual(b0.a, x0.a, `shallow merge a ${stringify(b0.a)} must be deep equal`); | ||
t.deepEqual(b0.b, x0.b, `shallow merge b ${stringify(b0.b)} must be deep equal`); | ||
// Shallow merge with replace | ||
const a1 = {a: [3], b: {c: [4, 5]}}; | ||
const b1 = ["9", "8"]; b1.a = [1, 2]; b1.b = {c: [6]}; | ||
const x1 = ["9", "8"]; x1.a = [3]; x1.b = {c: [4, 5]}; | ||
Objects.merge(a1, b1, true, false); | ||
t.ok(Array.isArray(b1), `shallow merge ${stringify(b1)} must be an array`); | ||
t.deepEqual(b1, x1, `shallow merge ${stringify(b1)} must be deep equal`); | ||
t.deepEqual(b1.a, x1.a, `shallow merge a ${stringify(b1.a)} must be deep equal`); | ||
t.deepEqual(b1.b, x1.b, `shallow merge b ${stringify(b1.b)} must be deep equal`); | ||
// Deep merge without replace | ||
const a2 = {a: [3], b: {c: [4,5]}}; | ||
const b2 = [9,7]; b2.a = [1,2]; b2.b = {c: [6]}; | ||
const x2 = [9,7]; x2.a = [1,2]; x2.b = {c: [6,5]}; | ||
Objects.merge(a2, b2, false, true); | ||
t.ok(Array.isArray(b2), `deep merge ${stringify(b2)} must be an array`); | ||
t.deepEqual(b2, x2, `deep merge ${stringify(b2)} must be deep equal`); | ||
t.deepEqual(b2.a, x2.a, `deep merge a ${stringify(b2.a)} must be deep equal`); | ||
t.deepEqual(b2.b, x2.b, `deep merge b ${stringify(b2.b)} must be deep equal`); | ||
// Deep merge with replace | ||
const a3 = {a: [3], b: {c: [4,5]}}; | ||
const b3 = [9,7]; b3.a = [1,2]; b3.b = {c: [6]}; | ||
const x3 = [9,7]; x3.a = [3,2]; x3.b = {c: [4,5]}; | ||
Objects.merge(a3, b3, true, true); | ||
t.ok(Array.isArray(b3), `deep merge ${stringify(b3)} must be an array`); | ||
t.deepEqual(b3, x3, `deep merge ${stringify(b3)} must be deep equal`); | ||
t.deepEqual(b3.a, x3.a, `deep merge a ${stringify(b3.a)} must be deep equal`); | ||
t.deepEqual(b3.b, x3.b, `deep merge b ${stringify(b3.b)} must be deep equal`); | ||
t.end(); | ||
}); | ||
// ===================================================================================================================== | ||
// merge array with object | ||
// ===================================================================================================================== | ||
test('merge array with object', t => { | ||
// Shallow merge without replace | ||
const a0 = ["9", "8"]; a0.a = [3]; a0.b = {c: [4, 5]}; | ||
const b0 = {a: [1, 2], b: {c: [6]}}; | ||
const x0 = {"0": "9", "1": "8", "length": 2, a: [1, 2], b: {c: [6]}}; | ||
Objects.merge(a0, b0, false, false); | ||
t.ok(!Array.isArray(b0), `shallow merge ${stringify(b0)} must not be an array`); | ||
t.deepEqual(b0, x0, `shallow merge ${stringify(b0)} must be deep equal`); | ||
t.deepEqual(b0.a, x0.a, `shallow merge a ${stringify(b0.a)} must be deep equal`); | ||
t.deepEqual(b0.b, x0.b, `shallow merge b ${stringify(b0.b)} must be deep equal`); | ||
// Shallow merge with replace | ||
const a1 = ["9", "8"]; a1.a = [3]; a1.b = {c: [4, 5]}; | ||
const b1 = {a: [1, 2], b: {c: [6]}}; | ||
const x1 = {"0": "9", "1": "8", "length": 2, a: [3], b: {c: [4,5]}}; | ||
Objects.merge(a1, b1, true, false); | ||
t.ok(!Array.isArray(b1), `shallow merge ${stringify(b1)} must not be an array`); | ||
t.deepEqual(b1, x1, `shallow merge ${stringify(b1)} must be deep equal`); | ||
t.deepEqual(b1.a, x1.a, `shallow merge a ${stringify(b1.a)} must be deep equal`); | ||
t.deepEqual(b1.b, x1.b, `shallow merge b ${stringify(b1.b)} must be deep equal`); | ||
// Deep merge without replace | ||
const a2 = ["9", "8"]; a2.a = [3]; a2.b = {c: [4, 5]}; | ||
const b2 = {a: [1, 2], b: {c: [6]}}; | ||
const x2 = {"0": "9", "1": "8", "length": 2, a: [1,2], b: {c: [6,5]}}; | ||
Objects.merge(a2, b2, false, true); | ||
t.ok(!Array.isArray(b2), `deep merge ${stringify(b2)} must not be an array`); | ||
t.deepEqual(b2, x2, `deep merge ${stringify(b2)} must be deep equal`); | ||
t.deepEqual(b2.a, x2.a, `deep merge a ${stringify(b2.a)} must be deep equal`); | ||
t.deepEqual(b2.b, x2.b, `deep merge b ${stringify(b2.b)} must be deep equal`); | ||
// Deep merge with replace | ||
const a3 = ["9", "8"]; a3.a = [3]; a3.b = {c: [4, 5]}; | ||
const b3 = {a: [1, 2], b: {c: [6]}}; | ||
const x3 = {"0": "9", "1": "8", "length": 2, a: [3,2], b: {c: [4,5]}}; | ||
Objects.merge(a3, b3, true, true); | ||
t.ok(!Array.isArray(b3), `deep merge ${stringify(b3)} must not be an array`); | ||
t.deepEqual(b3, x3, `deep merge ${stringify(b3)} must be deep equal`); | ||
t.deepEqual(b3.a, x3.a, `deep merge a ${stringify(b3.a)} must be deep equal`); | ||
t.deepEqual(b3.b, x3.b, `deep merge b ${stringify(b3.b)} must be deep equal`); | ||
t.end(); | ||
}); |
{ | ||
"name": "core-functions-tests", | ||
"version": "2.0.10", | ||
"version": "2.0.11", | ||
"author": "Byron du Preez", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
220454
4234
195