mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 06:27:49 +00:00
210 lines
7.1 KiB
TypeScript
210 lines
7.1 KiB
TypeScript
import assert from 'node:assert';
|
|
import lodashStable from 'lodash';
|
|
import { _, primitives, stubTrue, defineProperty, slice } from './utils';
|
|
import has from '../src/has';
|
|
|
|
describe('object assignments', () => {
|
|
lodashStable.each(['assign', 'assignIn', 'defaults', 'defaultsDeep', 'merge'], (methodName) => {
|
|
const func = _[methodName],
|
|
isAssign = methodName === 'assign',
|
|
isDefaults = /^defaults/.test(methodName);
|
|
|
|
it(`\`_.${methodName}\` should coerce primitives to objects`, () => {
|
|
const expected = lodashStable.map(primitives, (value) => {
|
|
const object = Object(value);
|
|
object.a = 1;
|
|
return object;
|
|
});
|
|
|
|
const actual = lodashStable.map(primitives, (value) => func(value, { a: 1 }));
|
|
|
|
assert.deepStrictEqual(actual, expected);
|
|
});
|
|
|
|
it(`\`_.${methodName}\` should assign own ${
|
|
isAssign ? '' : 'and inherited '
|
|
}string keyed source properties`, () => {
|
|
function Foo() {
|
|
this.a = 1;
|
|
}
|
|
Foo.prototype.b = 2;
|
|
|
|
const expected = isAssign ? { a: 1 } : { a: 1, b: 2 };
|
|
assert.deepStrictEqual(func({}, new Foo()), expected);
|
|
});
|
|
|
|
it(`\`_.${methodName}\` should not skip a trailing function source`, () => {
|
|
function fn() {}
|
|
fn.b = 2;
|
|
|
|
assert.deepStrictEqual(func({}, { a: 1 }, fn), { a: 1, b: 2 });
|
|
});
|
|
|
|
it(`\`_.${methodName}\` should not error on nullish sources`, () => {
|
|
try {
|
|
assert.deepStrictEqual(func({ a: 1 }, undefined, { b: 2 }, null), { a: 1, b: 2 });
|
|
} catch (e) {
|
|
assert.ok(false, e.message);
|
|
}
|
|
});
|
|
|
|
it(`\`_.${methodName}\` should create an object when \`object\` is nullish`, () => {
|
|
const source = { a: 1 },
|
|
values = [null, undefined],
|
|
expected = lodashStable.map(values, stubTrue);
|
|
|
|
let actual = lodashStable.map(values, (value) => {
|
|
const object = func(value, source);
|
|
return object !== source && lodashStable.isEqual(object, source);
|
|
});
|
|
|
|
assert.deepStrictEqual(actual, expected);
|
|
|
|
actual = lodashStable.map(values, (value) => lodashStable.isEqual(func(value), {}));
|
|
|
|
assert.deepStrictEqual(actual, expected);
|
|
});
|
|
|
|
it(`\`_.${methodName}\` should work as an iteratee for methods like \`_.reduce\``, () => {
|
|
const array = [{ a: 1 }, { b: 2 }, { c: 3 }],
|
|
expected = { a: isDefaults ? 0 : 1, b: 2, c: 3 };
|
|
|
|
function fn() {}
|
|
fn.a = array[0];
|
|
fn.b = array[1];
|
|
fn.c = array[2];
|
|
|
|
assert.deepStrictEqual(lodashStable.reduce(array, func, { a: 0 }), expected);
|
|
assert.deepStrictEqual(lodashStable.reduce(fn, func, { a: 0 }), expected);
|
|
});
|
|
|
|
it(`\`_.${methodName}\` should not return the existing wrapped value when chaining`, () => {
|
|
const wrapped = _({ a: 1 }),
|
|
actual = wrapped[methodName]({ b: 2 });
|
|
|
|
assert.notStrictEqual(actual, wrapped);
|
|
});
|
|
});
|
|
|
|
lodashStable.each(['assign', 'assignIn', 'merge'], (methodName) => {
|
|
const func = _[methodName];
|
|
|
|
it(`\`_.${methodName}\` should not treat \`object\` as \`source\``, () => {
|
|
function Foo() {}
|
|
Foo.prototype.a = 1;
|
|
|
|
const actual = func(new Foo(), { b: 2 });
|
|
assert.ok(!has(actual, 'a'));
|
|
});
|
|
});
|
|
|
|
lodashStable.each(
|
|
[
|
|
'assign',
|
|
'assignIn',
|
|
'assignInWith',
|
|
'assignWith',
|
|
'defaults',
|
|
'defaultsDeep',
|
|
'merge',
|
|
'mergeWith',
|
|
],
|
|
(methodName) => {
|
|
const func = _[methodName];
|
|
|
|
it(`\`_.${methodName}\` should not assign values that are the same as their destinations`, () => {
|
|
lodashStable.each(['a', ['a'], { a: 1 }, NaN], (value) => {
|
|
let object = {},
|
|
pass = true;
|
|
|
|
defineProperty(object, 'a', {
|
|
configurable: true,
|
|
enumerable: true,
|
|
get: lodashStable.constant(value),
|
|
set: function () {
|
|
pass = false;
|
|
},
|
|
});
|
|
|
|
func(object, { a: value });
|
|
assert.ok(pass);
|
|
});
|
|
});
|
|
},
|
|
);
|
|
|
|
lodashStable.each(['assignWith', 'assignInWith', 'mergeWith'], (methodName) => {
|
|
const func = _[methodName],
|
|
isMergeWith = methodName === 'mergeWith';
|
|
|
|
it(`\`_.${methodName}\` should provide correct \`customizer\` arguments`, () => {
|
|
let args,
|
|
object = { a: 1 },
|
|
source = { a: 2 },
|
|
expected = lodashStable.map([1, 2, 'a', object, source], lodashStable.cloneDeep);
|
|
|
|
func(object, source, function () {
|
|
args ||
|
|
(args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
|
|
});
|
|
|
|
assert.deepStrictEqual(args, expected, 'primitive values');
|
|
|
|
const argsList = [],
|
|
objectValue = [1, 2],
|
|
sourceValue = { b: 2 };
|
|
|
|
object = { a: objectValue };
|
|
source = { a: sourceValue };
|
|
expected = [
|
|
lodashStable.map(
|
|
[objectValue, sourceValue, 'a', object, source],
|
|
lodashStable.cloneDeep,
|
|
),
|
|
];
|
|
|
|
if (isMergeWith) {
|
|
expected.push(
|
|
lodashStable.map(
|
|
[undefined, 2, 'b', objectValue, sourceValue],
|
|
lodashStable.cloneDeep,
|
|
),
|
|
);
|
|
}
|
|
func(object, source, function () {
|
|
argsList.push(
|
|
lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep),
|
|
);
|
|
});
|
|
|
|
assert.deepStrictEqual(argsList, expected, 'object values');
|
|
|
|
args = undefined;
|
|
object = { a: 1 };
|
|
source = { b: 2 };
|
|
expected = lodashStable.map(
|
|
[undefined, 2, 'b', object, source],
|
|
lodashStable.cloneDeep,
|
|
);
|
|
|
|
func(object, source, function () {
|
|
args ||
|
|
(args = lodashStable.map(slice.call(arguments, 0, 5), lodashStable.cloneDeep));
|
|
});
|
|
|
|
assert.deepStrictEqual(args, expected, 'undefined properties');
|
|
});
|
|
|
|
it(`\`_.${methodName}\` should not treat the second argument as a \`customizer\` callback`, () => {
|
|
function callback() {}
|
|
callback.b = 2;
|
|
|
|
let actual = func({ a: 1 }, callback);
|
|
assert.deepStrictEqual(actual, { a: 1, b: 2 });
|
|
|
|
actual = func({ a: 1 }, callback, { c: 3 });
|
|
assert.deepStrictEqual(actual, { a: 1, b: 2, c: 3 });
|
|
});
|
|
});
|
|
});
|