You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
175 lines
7.0 KiB
175 lines
7.0 KiB
4 years ago
|
describe('Function', function () {
|
||
|
'use strict';
|
||
|
|
||
|
describe('#apply()', function () {
|
||
|
it('works with arraylike objects', function () {
|
||
|
var arrayLike = { length: 4, 0: 1, 2: 4, 3: true };
|
||
|
var expectedArray = [1, undefined, 4, true];
|
||
|
var actualArray = (function () {
|
||
|
return Array.prototype.slice.apply(arguments);
|
||
|
}.apply(null, arrayLike));
|
||
|
expect(actualArray).toEqual(expectedArray);
|
||
|
});
|
||
|
});
|
||
|
|
||
|
describe('#bind()', function () {
|
||
|
var actual;
|
||
|
|
||
|
var testSubject = {
|
||
|
push: function (o) {
|
||
|
this.a.push(o);
|
||
|
}
|
||
|
};
|
||
|
|
||
|
var func = function func() {
|
||
|
Array.prototype.forEach.call(arguments, function (a) {
|
||
|
this.push(a);
|
||
|
}, this);
|
||
|
return this;
|
||
|
};
|
||
|
|
||
|
beforeEach(function () {
|
||
|
actual = [];
|
||
|
testSubject.a = [];
|
||
|
});
|
||
|
|
||
|
it('binds properly without a context', function () {
|
||
|
var context;
|
||
|
testSubject.func = function () {
|
||
|
context = this;
|
||
|
}.bind();
|
||
|
testSubject.func();
|
||
|
expect(context).toBe(function () { return this; }.call());
|
||
|
});
|
||
|
it('binds properly without a context, and still supplies bound arguments', function () {
|
||
|
var a, context;
|
||
|
testSubject.func = function () {
|
||
|
a = Array.prototype.slice.call(arguments);
|
||
|
context = this;
|
||
|
}.bind(undefined, 1, 2, 3);
|
||
|
testSubject.func(1, 2, 3);
|
||
|
expect(a).toEqual([1, 2, 3, 1, 2, 3]);
|
||
|
expect(context).toBe(function () { return this; }.call());
|
||
|
});
|
||
|
it('binds a context properly', function () {
|
||
|
testSubject.func = func.bind(actual);
|
||
|
testSubject.func(1, 2, 3);
|
||
|
expect(actual).toEqual([1, 2, 3]);
|
||
|
expect(testSubject.a).toEqual([]);
|
||
|
});
|
||
|
it('binds a context and supplies bound arguments', function () {
|
||
|
testSubject.func = func.bind(actual, 1, 2, 3);
|
||
|
testSubject.func(4, 5, 6);
|
||
|
expect(actual).toEqual([1, 2, 3, 4, 5, 6]);
|
||
|
expect(testSubject.a).toEqual([]);
|
||
|
});
|
||
|
|
||
|
it('returns properly without binding a context', function () {
|
||
|
testSubject.func = function () {
|
||
|
return this;
|
||
|
}.bind();
|
||
|
var context = testSubject.func();
|
||
|
expect(context).toBe(function () { return this; }.call());
|
||
|
});
|
||
|
it('returns properly without binding a context, and still supplies bound arguments', function () {
|
||
|
var context;
|
||
|
testSubject.func = function () {
|
||
|
context = this;
|
||
|
return Array.prototype.slice.call(arguments);
|
||
|
}.bind(undefined, 1, 2, 3);
|
||
|
actual = testSubject.func(1, 2, 3);
|
||
|
expect(context).toBe(function () { return this; }.call());
|
||
|
expect(actual).toEqual([1, 2, 3, 1, 2, 3]);
|
||
|
});
|
||
|
it('returns properly while binding a context properly', function () {
|
||
|
var ret;
|
||
|
testSubject.func = func.bind(actual);
|
||
|
ret = testSubject.func(1, 2, 3);
|
||
|
expect(ret).toBe(actual);
|
||
|
expect(ret).not.toBe(testSubject);
|
||
|
});
|
||
|
it('returns properly while binding a context and supplies bound arguments', function () {
|
||
|
var ret;
|
||
|
testSubject.func = func.bind(actual, 1, 2, 3);
|
||
|
ret = testSubject.func(4, 5, 6);
|
||
|
expect(ret).toBe(actual);
|
||
|
expect(ret).not.toBe(testSubject);
|
||
|
});
|
||
|
it('has the new instance\'s context as a constructor', function () {
|
||
|
var actualContext;
|
||
|
var expectedContext = { foo: 'bar' };
|
||
|
testSubject.Func = function () {
|
||
|
actualContext = this;
|
||
|
}.bind(expectedContext);
|
||
|
var result = new testSubject.Func();
|
||
|
expect(result).toBeTruthy();
|
||
|
expect(actualContext).not.toBe(expectedContext);
|
||
|
});
|
||
|
it('passes the correct arguments as a constructor', function () {
|
||
|
var expected = { name: 'Correct' };
|
||
|
testSubject.Func = function (arg) {
|
||
|
expect(Object.prototype.hasOwnProperty.call(this, 'name')).toBe(false);
|
||
|
return arg;
|
||
|
}.bind({ name: 'Incorrect' });
|
||
|
var ret = new testSubject.Func(expected);
|
||
|
expect(ret).toBe(expected);
|
||
|
});
|
||
|
it('returns the return value of the bound function when called as a constructor', function () {
|
||
|
var oracle = [1, 2, 3];
|
||
|
var Subject = function () {
|
||
|
expect(this).not.toBe(oracle);
|
||
|
return oracle;
|
||
|
}.bind(null);
|
||
|
var result = new Subject();
|
||
|
expect(result).toBe(oracle);
|
||
|
});
|
||
|
|
||
|
it('returns the correct value if constructor returns primitive', function () {
|
||
|
var Subject = function (oracle) {
|
||
|
expect(this).not.toBe(oracle);
|
||
|
return oracle;
|
||
|
}.bind(null);
|
||
|
|
||
|
var primitives = ['asdf', null, true, 1];
|
||
|
for (var i = 0; i < primitives.length; ++i) {
|
||
|
expect(new Subject(primitives[i])).not.toBe(primitives[i]);
|
||
|
}
|
||
|
|
||
|
var objects = [[1, 2, 3], {}, function () {}];
|
||
|
for (var j = 0; j < objects.length; ++j) {
|
||
|
expect(new Subject(objects[j])).toBe(objects[j]);
|
||
|
}
|
||
|
});
|
||
|
it('returns the value that instance of original "class" when called as a constructor', function () {
|
||
|
var ClassA = function (x) {
|
||
|
this.name = x || 'A';
|
||
|
};
|
||
|
var ClassB = ClassA.bind(null, 'B');
|
||
|
|
||
|
var result = new ClassB();
|
||
|
expect(result instanceof ClassA).toBe(true);
|
||
|
expect(result instanceof ClassB).toBe(true);
|
||
|
});
|
||
|
it('sets a correct length without thisArg', function () {
|
||
|
var Subject = function (a, b, c) { return a + b + c; }.bind();
|
||
|
expect(Subject.length).toBe(3);
|
||
|
});
|
||
|
it('sets a correct length with thisArg', function () {
|
||
|
var Subject = function (a, b, c) { return a + b + c + this.d; }.bind({ d: 1 });
|
||
|
expect(Subject.length).toBe(3);
|
||
|
});
|
||
|
it('sets a correct length with thisArg and first argument', function () {
|
||
|
var Subject = function (a, b, c) { return a + b + c + this.d; }.bind({ d: 1 }, 1);
|
||
|
expect(Subject.length).toBe(2);
|
||
|
});
|
||
|
it('sets a correct length without thisArg and first argument', function () {
|
||
|
var Subject = function (a, b, c) { return a + b + c; }.bind(undefined, 1);
|
||
|
expect(Subject.length).toBe(2);
|
||
|
});
|
||
|
it('sets a correct length without thisArg and too many argument', function () {
|
||
|
var Subject = function (a, b, c) { return a + b + c; }.bind(undefined, 1, 2, 3, 4);
|
||
|
expect(Subject.length).toBe(0);
|
||
|
});
|
||
|
});
|
||
|
});
|