1 /* global describe, it, expect, beforeEach */
3 describe('Function', function () {
6 describe('#apply()', function () {
7 it('works with arraylike objects', function () {
8 var arrayLike = { length: 4, 0: 1, 2: 4, 3: true };
9 var expectedArray = [1, undefined, 4, true];
10 var actualArray = (function () {
11 return Array.prototype.slice.apply(arguments);
12 }.apply(null, arrayLike));
13 expect(actualArray).toEqual(expectedArray);
17 describe('#bind()', function () {
26 var func = function func() {
27 Array.prototype.forEach.call(arguments, function (a) {
33 beforeEach(function () {
38 it('binds properly without a context', function () {
40 testSubject.func = function () {
44 expect(context).toBe(function () { return this; }.call());
46 it('binds properly without a context, and still supplies bound arguments', function () {
48 testSubject.func = function () {
49 a = Array.prototype.slice.call(arguments);
51 }.bind(undefined, 1, 2, 3);
52 testSubject.func(1, 2, 3);
53 expect(a).toEqual([1, 2, 3, 1, 2, 3]);
54 expect(context).toBe(function () { return this; }.call());
56 it('binds a context properly', function () {
57 testSubject.func = func.bind(actual);
58 testSubject.func(1, 2, 3);
59 expect(actual).toEqual([1, 2, 3]);
60 expect(testSubject.a).toEqual([]);
62 it('binds a context and supplies bound arguments', function () {
63 testSubject.func = func.bind(actual, 1, 2, 3);
64 testSubject.func(4, 5, 6);
65 expect(actual).toEqual([1, 2, 3, 4, 5, 6]);
66 expect(testSubject.a).toEqual([]);
69 it('returns properly without binding a context', function () {
70 testSubject.func = function () {
73 var context = testSubject.func();
74 expect(context).toBe(function () { return this; }.call());
76 it('returns properly without binding a context, and still supplies bound arguments', function () {
78 testSubject.func = function () {
80 return Array.prototype.slice.call(arguments);
81 }.bind(undefined, 1, 2, 3);
82 actual = testSubject.func(1, 2, 3);
83 expect(context).toBe(function () { return this; }.call());
84 expect(actual).toEqual([1, 2, 3, 1, 2, 3]);
86 it('returns properly while binding a context properly', function () {
88 testSubject.func = func.bind(actual);
89 ret = testSubject.func(1, 2, 3);
90 expect(ret).toBe(actual);
91 expect(ret).not.toBe(testSubject);
93 it('returns properly while binding a context and supplies bound arguments', function () {
95 testSubject.func = func.bind(actual, 1, 2, 3);
96 ret = testSubject.func(4, 5, 6);
97 expect(ret).toBe(actual);
98 expect(ret).not.toBe(testSubject);
100 it('has the new instance\'s context as a constructor', function () {
102 var expectedContext = { foo: 'bar' };
103 testSubject.Func = function () {
104 actualContext = this;
105 }.bind(expectedContext);
106 var result = new testSubject.Func();
107 expect(result).toBeTruthy();
108 expect(actualContext).not.toBe(expectedContext);
110 it('passes the correct arguments as a constructor', function () {
111 var expected = { name: 'Correct' };
112 testSubject.Func = function (arg) {
113 expect(Object.prototype.hasOwnProperty.call(this, 'name')).toBe(false);
115 }.bind({ name: 'Incorrect' });
116 var ret = new testSubject.Func(expected);
117 expect(ret).toBe(expected);
119 it('returns the return value of the bound function when called as a constructor', function () {
120 var oracle = [1, 2, 3];
121 var Subject = function () {
122 expect(this).not.toBe(oracle);
125 var result = new Subject();
126 expect(result).toBe(oracle);
129 it('returns the correct value if constructor returns primitive', function () {
130 var Subject = function (oracle) {
131 expect(this).not.toBe(oracle);
135 var primitives = ['asdf', null, true, 1];
136 for (var i = 0; i < primitives.length; ++i) {
137 expect(new Subject(primitives[i])).not.toBe(primitives[i]);
140 var objects = [[1, 2, 3], {}, function () {}];
141 for (var j = 0; j < objects.length; ++j) {
142 expect(new Subject(objects[j])).toBe(objects[j]);
145 it('returns the value that instance of original "class" when called as a constructor', function () {
146 var ClassA = function (x) {
147 this.name = x || 'A';
149 var ClassB = ClassA.bind(null, 'B');
151 var result = new ClassB();
152 expect(result instanceof ClassA).toBe(true);
153 expect(result instanceof ClassB).toBe(true);
155 it('sets a correct length without thisArg', function () {
156 var Subject = function (a, b, c) { return a + b + c; }.bind();
157 expect(Subject.length).toBe(3);
159 it('sets a correct length with thisArg', function () {
160 var Subject = function (a, b, c) { return a + b + c + this.d; }.bind({ d: 1 });
161 expect(Subject.length).toBe(3);
163 it('sets a correct length with thisArg and first argument', function () {
164 var Subject = function (a, b, c) { return a + b + c + this.d; }.bind({ d: 1 }, 1);
165 expect(Subject.length).toBe(2);
167 it('sets a correct length without thisArg and first argument', function () {
168 var Subject = function (a, b, c) { return a + b + c; }.bind(undefined, 1);
169 expect(Subject.length).toBe(2);
171 it('sets a correct length without thisArg and too many argument', function () {
172 var Subject = function (a, b, c) { return a + b + c; }.bind(undefined, 1, 2, 3, 4);
173 expect(Subject.length).toBe(0);