123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- 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);
- });
- });
- });
|