懒羊羊
2023-08-30 1ac2bc1590406d9babec036e154d8d08f34a6aa1
提交 | 用户 | 时间
1ac2bc 1
2 describe('Function', function() {
3     "use strict";
4     describe('bind', function() {
5         var actual, expected,
6             testSubject;
7         
8         testSubject = {
9             push: function(o) {
10                 this.a.push(o);
11             }
12         };
13         
14         function func() {
15             Array.prototype.forEach.call(arguments, function(a) {
16                 this.push(a);
17             }, this);
18             return this;
19         };
20         
21         beforeEach(function() {
22             actual = [];
23             testSubject.a = [];
24         });
25         
26         it('binds properly without a context', function() {
27             var context;
28             testSubject.func = function() {
29                 context = this;
30             }.bind();
31             testSubject.func();
32             expect(context).toBe(function() {return this}.call());
33         });
34         it('binds properly without a context, and still supplies bound arguments', function() {
35             var a, context;
36             testSubject.func = function() {
37                 a = Array.prototype.slice.call(arguments);
38                 context = this;
39             }.bind(undefined, 1,2,3);
40             testSubject.func(1,2,3);
41             expect(a).toEqual([1,2,3,1,2,3]);
42             expect(context).toBe(function() {return this}.call());
43         });
44         it('binds a context properly', function() {
45             testSubject.func = func.bind(actual);
46             testSubject.func(1,2,3);
47             expect(actual).toEqual([1,2,3]);
48             expect(testSubject.a).toEqual([]);
49         });
50         it('binds a context and supplies bound arguments', function() {
51             testSubject.func = func.bind(actual, 1,2,3);
52             testSubject.func(4,5,6);
53             expect(actual).toEqual([1,2,3,4,5,6]);
54             expect(testSubject.a).toEqual([]);
55         });
56         
57         it('returns properly without binding a context', function() {
58             testSubject.func = function() {
59                 return this;
60             }.bind();
61             var context = testSubject.func();
62             expect(context).toBe(function() {return this}.call());
63         });
64         it('returns properly without binding a context, and still supplies bound arguments', function() {
65             var context;
66             testSubject.func = function() {
67                 context = this;
68                 return Array.prototype.slice.call(arguments);
69             }.bind(undefined, 1,2,3);
70             actual = testSubject.func(1,2,3);
71             expect(context).toBe(function() {return this}.call());
72             expect(actual).toEqual([1,2,3,1,2,3]);
73         });
74         it('returns properly while binding a context properly', function() {
75             var ret;
76             testSubject.func = func.bind(actual);
77             ret = testSubject.func(1,2,3);
78             expect(ret).toBe(actual);
79             expect(ret).not.toBe(testSubject);
80         });
81         it('returns properly while binding a context and supplies bound arguments', function() {
82             var ret;
83             testSubject.func = func.bind(actual, 1,2,3);
84             ret = testSubject.func(4,5,6);
85             expect(ret).toBe(actual);
86             expect(ret).not.toBe(testSubject);
87         });
88         it('passes the correct arguments as a constructor', function() {
89             var ret, expected = { name: "Correct" };
90             testSubject.func = function(arg) {
91                 return arg;
92             }.bind({ name: "Incorrect" });
93             ret = new testSubject.func(expected);
94             expect(ret).toBe(expected);
95         });
96         it('returns the return value of the bound function when called as a constructor', function () {
97             var oracle = [1, 2, 3];
98             var subject = function () {
99                 return oracle;
100             }.bind(null);
101             var result = new subject;
102             expect(result).toBe(oracle);
103         });
104         it('returns the correct value if constructor returns primitive', function() {
105             var oracle = [1, 2, 3];
106             var subject = function () {
107                 return oracle;
108             }.bind(null);
109             var result = new subject;
110             expect(result).toBe(oracle);
111
112             oracle = {};
113             result = new subject;
114             expect(result).toBe(oracle);
115
116             oracle = function(){};
117             result = new subject;
118             expect(result).toBe(oracle);
119
120             oracle = "asdf";
121             result = new subject;
122             expect(result).not.toBe(oracle);
123
124             oracle = null;
125             result = new subject;
126             expect(result).not.toBe(oracle);
127
128             oracle = true;
129             result = new subject;
130             expect(result).not.toBe(oracle);
131
132             oracle = 1;
133             result = new subject;
134             expect(result).not.toBe(oracle);
135         });
136         it('returns the value that instance of original "class" when called as a constructor', function() {
137             var classA = function(x) {
138                 this.name = x || "A";
139             }
140             var classB = classA.bind(null, "B");
141             
142             var result = new classB;
143             expect(result instanceof classA).toBe(true);
144             expect(result instanceof classB).toBe(true);
145         });
146     });
147 });