mirror of
https://github.com/whoisclebs/lodash.git
synced 2026-01-29 06:27:49 +00:00
* test: fix throttle.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix pickBy.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix isBuffer.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: partially fix attempt.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: partially fix dropRightWhile.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix defer.spec.js and rest.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix invoke.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix isArray.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: partially fix iteration-methods.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix xor-methods.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix property.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix ary.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix omit-methods.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix debounce-and-throttle.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix unzip-and-zip.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix toPairs-methods.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix exit-early.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: temporarily comment out takeWhile and dropWhile tests Signed-off-by: tison <wander4096@gmail.com> * test: partially fix union*.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix startsWith-and-endsWith.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix isNil.spec.js Signed-off-by: tison <wander4096@gmail.com> * test: fix some of syntax errors Signed-off-by: tison <wander4096@gmail.com> --------- Signed-off-by: tison <wander4096@gmail.com>
256 lines
8.2 KiB
JavaScript
256 lines
8.2 KiB
JavaScript
import lodashStable from 'lodash';
|
|
import { push, falsey, stubTrue } from './utils';
|
|
import bind from '../src/bind';
|
|
import placeholder from '../src/placeholder';
|
|
|
|
describe('bind', () => {
|
|
function fn() {
|
|
const result = [this];
|
|
push.apply(result, arguments);
|
|
return result;
|
|
}
|
|
|
|
it('should bind a function to an object', () => {
|
|
const object = {},
|
|
bound = bind(fn, object);
|
|
|
|
expect(bound('a')).toEqual([object, 'a']);
|
|
});
|
|
|
|
it('should accept a falsey `thisArg`', () => {
|
|
const values = lodashStable.reject(falsey.slice(1), (value) => value == null),
|
|
expected = lodashStable.map(values, (value) => [value]);
|
|
|
|
const actual = lodashStable.map(values, (value) => {
|
|
try {
|
|
const bound = bind(fn, value);
|
|
return bound();
|
|
} catch (e) {}
|
|
});
|
|
|
|
assert.ok(
|
|
lodashStable.every(actual, (value, index) =>
|
|
lodashStable.isEqual(value, expected[index]),
|
|
),
|
|
);
|
|
});
|
|
|
|
it('should bind a function to nullish values', () => {
|
|
let bound = bind(fn, null),
|
|
actual = bound('a');
|
|
|
|
expect(actual[0] === null || (actual[0] && actual[0].Array))
|
|
expect(actual[1]).toBe('a');
|
|
|
|
lodashStable.times(2, (index) => {
|
|
bound = index ? bind(fn, undefined) : bind(fn);
|
|
actual = bound('b');
|
|
|
|
expect(actual[0] === undefined || (actual[0] && actual[0].Array))
|
|
expect(actual[1]).toBe('b');
|
|
});
|
|
});
|
|
|
|
it('should partially apply arguments ', () => {
|
|
let object = {},
|
|
bound = bind(fn, object, 'a');
|
|
|
|
expect(bound()).toEqual([object, 'a']);
|
|
|
|
bound = bind(fn, object, 'a');
|
|
expect(bound('b')).toEqual([object, 'a', 'b']);
|
|
|
|
bound = bind(fn, object, 'a', 'b');
|
|
expect(bound()).toEqual([object, 'a', 'b']);
|
|
expect(bound('c', 'd')).toEqual([object, 'a', 'b', 'c', 'd']);
|
|
});
|
|
|
|
it('should support placeholders', () => {
|
|
const object = {},
|
|
ph = bind.placeholder,
|
|
bound = bind(fn, object, ph, 'b', ph);
|
|
|
|
expect(bound('a', 'c')).toEqual([object, 'a', 'b', 'c']);
|
|
expect(bound('a')).toEqual([object, 'a', 'b', undefined]);
|
|
expect(bound('a', 'c', 'd')).toEqual([object, 'a', 'b', 'c', 'd']);
|
|
expect(bound()).toEqual([object, undefined, 'b', undefined]);
|
|
});
|
|
|
|
it('should use `_.placeholder` when set', () => {
|
|
const _ph = (placeholder = {}),
|
|
ph = bind.placeholder,
|
|
object = {},
|
|
bound = bind(fn, object, _ph, 'b', ph);
|
|
|
|
expect(bound('a', 'c')).toEqual([object, 'a', 'b', ph, 'c']);
|
|
delete placeholder;
|
|
});
|
|
|
|
it('should create a function with a `length` of `0`', () => {
|
|
let fn = function (a, b, c) {},
|
|
bound = bind(fn, {});
|
|
|
|
expect(bound.length).toBe(0);
|
|
|
|
bound = bind(fn, {}, 1);
|
|
expect(bound.length).toBe(0);
|
|
});
|
|
|
|
it('should ignore binding when called with the `new` operator', () => {
|
|
function Foo() {
|
|
return this;
|
|
}
|
|
|
|
const bound = bind(Foo, { a: 1 }),
|
|
newBound = new bound();
|
|
|
|
expect(bound().a).toBe(1);
|
|
expect(newBound.a).toBe(undefined);
|
|
expect(newBound instanceof Foo)
|
|
});
|
|
|
|
it('should handle a number of arguments when called with the `new` operator', () => {
|
|
function Foo() {
|
|
return this;
|
|
}
|
|
|
|
function Bar() {}
|
|
|
|
const thisArg = { a: 1 },
|
|
boundFoo = bind(Foo, thisArg),
|
|
boundBar = bind(Bar, thisArg),
|
|
count = 9,
|
|
expected = lodashStable.times(count, lodashStable.constant([undefined, undefined]));
|
|
|
|
const actual = lodashStable.times(count, (index) => {
|
|
try {
|
|
switch (index) {
|
|
case 0:
|
|
return [new boundFoo().a, new boundBar().a];
|
|
case 1:
|
|
return [new boundFoo(1).a, new boundBar(1).a];
|
|
case 2:
|
|
return [new boundFoo(1, 2).a, new boundBar(1, 2).a];
|
|
case 3:
|
|
return [new boundFoo(1, 2, 3).a, new boundBar(1, 2, 3).a];
|
|
case 4:
|
|
return [new boundFoo(1, 2, 3, 4).a, new boundBar(1, 2, 3, 4).a];
|
|
case 5:
|
|
return [new boundFoo(1, 2, 3, 4, 5).a, new boundBar(1, 2, 3, 4, 5).a];
|
|
case 6:
|
|
return [new boundFoo(1, 2, 3, 4, 5, 6).a, new boundBar(1, 2, 3, 4, 5, 6).a];
|
|
case 7:
|
|
return [
|
|
new boundFoo(1, 2, 3, 4, 5, 6, 7).a,
|
|
new boundBar(1, 2, 3, 4, 5, 6, 7).a,
|
|
];
|
|
case 8:
|
|
return [
|
|
new boundFoo(1, 2, 3, 4, 5, 6, 7, 8).a,
|
|
new boundBar(1, 2, 3, 4, 5, 6, 7, 8).a,
|
|
];
|
|
}
|
|
} catch (e) {}
|
|
});
|
|
|
|
expect(actual).toEqual(expected);
|
|
});
|
|
|
|
it('should ensure `new bound` is an instance of `func`', () => {
|
|
function Foo(value) {
|
|
return value && object;
|
|
}
|
|
|
|
var bound = bind(Foo),
|
|
object = {};
|
|
|
|
expect(new bound() instanceof Foo)
|
|
expect(new bound(true)).toBe(object);
|
|
});
|
|
|
|
it('should append array arguments to partially applied arguments', () => {
|
|
const object = {},
|
|
bound = bind(fn, object, 'a');
|
|
|
|
expect(bound(['b'], 'c')).toEqual([object, 'a', ['b'], 'c']);
|
|
});
|
|
|
|
it('should not rebind functions', () => {
|
|
const object1 = {},
|
|
object2 = {},
|
|
object3 = {};
|
|
|
|
const bound1 = bind(fn, object1),
|
|
bound2 = bind(bound1, object2, 'a'),
|
|
bound3 = bind(bound1, object3, 'b');
|
|
|
|
expect(bound1()).toEqual([object1]);
|
|
expect(bound2()).toEqual([object1, 'a']);
|
|
expect(bound3()).toEqual([object1, 'b']);
|
|
});
|
|
|
|
it('should not error when instantiating bound built-ins', () => {
|
|
let Ctor = bind(Date, null),
|
|
expected = new Date(2012, 4, 23, 0, 0, 0, 0);
|
|
|
|
try {
|
|
var actual = new Ctor(2012, 4, 23, 0, 0, 0, 0);
|
|
} catch (e) {}
|
|
|
|
expect(actual).toEqual(expected);
|
|
|
|
Ctor = bind(Date, null, 2012, 4, 23);
|
|
|
|
try {
|
|
actual = new Ctor(0, 0, 0, 0);
|
|
} catch (e) {}
|
|
|
|
expect(actual).toEqual(expected);
|
|
});
|
|
|
|
it('should not error when calling bound class constructors with the `new` operator', () => {
|
|
const createCtor = lodashStable.attempt(Function, '"use strict";return class A{}');
|
|
|
|
if (typeof createCtor === 'function') {
|
|
const bound = bind(createCtor()),
|
|
count = 8,
|
|
expected = lodashStable.times(count, stubTrue);
|
|
|
|
const actual = lodashStable.times(count, (index) => {
|
|
try {
|
|
switch (index) {
|
|
case 0:
|
|
return !!new bound();
|
|
case 1:
|
|
return !!new bound(1);
|
|
case 2:
|
|
return !!new bound(1, 2);
|
|
case 3:
|
|
return !!new bound(1, 2, 3);
|
|
case 4:
|
|
return !!new bound(1, 2, 3, 4);
|
|
case 5:
|
|
return !!new bound(1, 2, 3, 4, 5);
|
|
case 6:
|
|
return !!new bound(1, 2, 3, 4, 5, 6);
|
|
case 7:
|
|
return !!new bound(1, 2, 3, 4, 5, 6, 7);
|
|
}
|
|
} catch (e) {}
|
|
});
|
|
|
|
expect(actual).toEqual(expected);
|
|
}
|
|
});
|
|
|
|
it('should return a wrapped value when chaining', () => {
|
|
const object = {},
|
|
bound = _(fn).bind({}, 'a', 'b');
|
|
|
|
expect(bound instanceof _).toBeTruthy()
|
|
|
|
const actual = bound.value()('c');
|
|
expect(actual).toEqual([object, 'a', 'b', 'c']);
|
|
});
|
|
});
|