Version 1
[yaffs-website] / node_modules / es5-shim / tests / spec / s-function.js
1 /* global describe, it, expect, beforeEach */
2
3 describe('Function', function () {
4     'use strict';
5
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);
14         });
15     });
16
17     describe('#bind()', function () {
18         var actual;
19
20         var testSubject = {
21             push: function (o) {
22                 this.a.push(o);
23             }
24         };
25
26         var func = function func() {
27             Array.prototype.forEach.call(arguments, function (a) {
28                 this.push(a);
29             }, this);
30             return this;
31         };
32
33         beforeEach(function () {
34             actual = [];
35             testSubject.a = [];
36         });
37
38         it('binds properly without a context', function () {
39             var context;
40             testSubject.func = function () {
41                 context = this;
42             }.bind();
43             testSubject.func();
44             expect(context).toBe(function () { return this; }.call());
45         });
46         it('binds properly without a context, and still supplies bound arguments', function () {
47             var a, context;
48             testSubject.func = function () {
49                 a = Array.prototype.slice.call(arguments);
50                 context = this;
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());
55         });
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([]);
61         });
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([]);
67         });
68
69         it('returns properly without binding a context', function () {
70             testSubject.func = function () {
71                 return this;
72             }.bind();
73             var context = testSubject.func();
74             expect(context).toBe(function () { return this; }.call());
75         });
76         it('returns properly without binding a context, and still supplies bound arguments', function () {
77             var context;
78             testSubject.func = function () {
79                 context = this;
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]);
85         });
86         it('returns properly while binding a context properly', function () {
87             var ret;
88             testSubject.func = func.bind(actual);
89             ret = testSubject.func(1, 2, 3);
90             expect(ret).toBe(actual);
91             expect(ret).not.toBe(testSubject);
92         });
93         it('returns properly while binding a context and supplies bound arguments', function () {
94             var ret;
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);
99         });
100         it('has the new instance\'s context as a constructor', function () {
101             var actualContext;
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);
109         });
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);
114                 return arg;
115             }.bind({ name: 'Incorrect' });
116             var ret = new testSubject.Func(expected);
117             expect(ret).toBe(expected);
118         });
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);
123                 return oracle;
124             }.bind(null);
125             var result = new Subject();
126             expect(result).toBe(oracle);
127         });
128
129         it('returns the correct value if constructor returns primitive', function () {
130             var Subject = function (oracle) {
131                 expect(this).not.toBe(oracle);
132                 return oracle;
133             }.bind(null);
134
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]);
138             }
139
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]);
143             }
144         });
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';
148             };
149             var ClassB = ClassA.bind(null, 'B');
150
151             var result = new ClassB();
152             expect(result instanceof ClassA).toBe(true);
153             expect(result instanceof ClassB).toBe(true);
154         });
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);
158         });
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);
162         });
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);
166         });
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);
170         });
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);
174         });
175     });
176 });