9 var dit = /*<1.2compat>*/xit || /*</1.2compat>*/it; // don't run unless no compat
14 return Array.from(arguments).slice();
17 var Rules = function(){
18 return this + ' rules';
21 var Args = function(){
22 return [this].concat(Array.prototype.slice.call(arguments));
25 describe("Function Methods", function(){
29 it('should return a new function', function(){
30 var fnc = $empty.create();
31 expect($empty === fnc).toBeFalsy();
34 it('should return a new function', function(){
35 var fnc = $empty.create();
36 expect($empty === fnc).toBeFalsy();
39 it('should return a new function with specified argument', function(){
40 var fnc = fn.create({'arguments': 'rocks'});
41 expect(fnc()).toEqual(['rocks']);
44 it('should return a new function with multiple arguments', function(){
45 var fnc = fn.create({'arguments': ['MooTools', 'rocks']});
46 expect(fnc()).toEqual(['MooTools', 'rocks']);
49 it('should return a new function bound to an object', function(){
50 var fnc = Rules.create({'bind': 'MooTools'});
51 expect(fnc()).toEqual('MooTools rules');
54 it('should return a new function as an event', function(){
55 var fnc = fn.create({'arguments': [0, 1], 'event': true});
56 expect(fnc('an Event occurred')).toEqual(['an Event occurred', 0, 1]);
62 it('should return the function bound to an object', function(){
63 var fnc = Rules.bind('MooTools');
64 expect(fnc()).toEqual('MooTools rules');
67 it('should return the function bound to an object with specified argument', function(){
68 var results = Args.bind('MooTools', 'rocks')();
69 expect(results[0] + '').toEqual(new String('MooTools') + '');
70 expect(results[1]).toEqual('rocks');
73 dit('should return the function bound to an object with multiple arguments', function(){
74 var results = Args.bind('MooTools', ['rocks', 'da house'])();
75 expect(results[0] + '').toEqual(new String('MooTools') + '');
76 expect(results[1]).toEqual(['rocks', 'da house']);
80 it('should return the function bound to an object with specified argument', function(){
81 var fnc = Args.bind('MooTools', 'rocks');
82 expect(fnc()).toEqual(['MooTools', 'rocks']);
85 it('should return the function bound to an object with multiple arguments', function(){
86 var fnc = Args.bind('MooTools', ['rocks', 'da house']);
87 expect(fnc()).toEqual(['MooTools', 'rocks', 'da house']);
90 it('should return the function bound to an object and make the function an event listener', function(){
91 var fnc = Args.bindWithEvent('MooTools');
92 expect(fnc('an Event ocurred')).toEqual(['MooTools', 'an Event ocurred']);
95 it('should return the function bound to an object and make the function event listener with multiple arguments', function(){
96 var fnc = Args.bindWithEvent('MooTools', ['rocks', 'da house']);
97 expect(fnc('an Event ocurred')).toEqual(['MooTools', 'an Event ocurred', 'rocks', 'da house']);
103 it('should return a function that when called passes the specified arguments to the original function', function(){
104 var fnc = fn.pass('MooTools is beautiful and elegant');
105 expect(fnc()).toEqual(['MooTools is beautiful and elegant']);
108 it('should pass multiple arguments and bind the function to a specific object when it is called', function(){
109 var fnc = Args.pass(['rocks', 'da house'], 'MooTools');
110 expect(fnc()).toEqual(['MooTools', 'rocks', 'da house']);
115 it('should run the function', function(){
116 var result = fn.run();
117 expect(result).toEqual([]);
120 it('should run the function with multiple arguments', function(){
121 var result = fn.run(['MooTools', 'beautiful', 'elegant']);
122 expect(result).toEqual(['MooTools', 'beautiful', 'elegant']);
125 it('should run the function with multiple arguments and bind the function to an object', function(){
126 var result = Args.run(['beautiful', 'elegant'], 'MooTools');
127 expect(result).toEqual(['MooTools', 'beautiful', 'elegant']);
133 it("should extend the function's properties", function(){
134 var fnc = (function(){}).extend({a: 1, b: 'c'});
135 expect(fnc.a).toEqual(1);
136 expect(fnc.b).toEqual('c');
142 it('should call the function without raising an exception', function(){
143 var fnc = function(){
144 this_should_not_work();
149 it("should return the function's return value", function(){
150 var fnc = Function.from('hello world!');
151 expect(fnc.attempt()).toEqual('hello world!');
154 it('should return null if the function raises an exception', function(){
155 var fnc = function(){
156 this_should_not_work();
158 expect(fnc.attempt()).toBeNull();
163 it('delay should return a timer pointer', function(){
164 var timer = (function(){}).delay(10000);
165 expect(typeOf(timer) == 'number').toBeTruthy();
169 // Function.periodical
171 it('periodical should return a timer pointer', function(){
172 var timer = (function(){}).periodical(10000);
173 expect(typeOf(timer) == 'number').toBeTruthy();
174 clearInterval(timer);
179 describe('Function.attempt', function(){
181 it('should return the result of the first successful function without executing successive functions', function(){
183 var attempt = Function.attempt(function(){
185 throw new Exception();
193 expect(calls).toEqual(2);
194 expect(attempt).toEqual('success');
197 it('should return null when no function succeeded', function(){
199 var attempt = Function.attempt(function(){
201 return I_invented_this();
204 return uninstall_ie();
206 expect(calls).toEqual(2);
207 expect(attempt).toBeNull();
214 describe('Function.bind', function(){
216 it('should return the function bound to an object', function(){
217 var spy = jasmine.createSpy('Function.bind');
218 var f = spy.bind('MooTools');
219 expect(spy).not.toHaveBeenCalled();
221 expect(spy).toHaveBeenCalledWith();
223 expect(spy).toHaveBeenCalledWith('foo', 'bar');
226 it('should return the function bound to an object with specified argument', function(){
227 var binding = {some: 'binding'};
228 var spy = jasmine.createSpy('Function.bind with arg').andReturn('something');
229 var f = spy.bind(binding, 'arg');
231 expect(spy).not.toHaveBeenCalled();
232 expect(f('additional', 'arguments')).toEqual('something');
233 expect(spy.mostRecentCall.object).toEqual(binding);
236 it('should return the function bound to an object with multiple arguments', function(){
237 var binding = {some: 'binding'};
238 var spy = jasmine.createSpy('Function.bind with multiple args').andReturn('something');
239 var f = spy.bind(binding, ['foo', 'bar']);
241 expect(spy).not.toHaveBeenCalled();
242 expect(f('additional', 'arguments')).toEqual('something');
243 expect(spy.mostRecentCall.object).toEqual(binding);
246 dit('should still be possible to use it as constructor', function(){
247 function Alien(type) {
252 var Tribble = Alien.bind(thisArg, 'Polygeminus grex');
254 // `thisArg` should **not** be used for the `this` binding when called as a constructor
255 var fuzzball = new Tribble('Klingon');
256 expect(fuzzball.type).toEqual('Polygeminus grex');
259 dit('when using .call(thisArg) on a bound function, it should ignore the thisArg of .call', function(){
261 return [this.foo].concat(Array.slice(arguments));
264 expect(fn.bind({foo: 'bar'})()).toEqual(['bar']);
265 expect(fn.bind({foo: 'bar'}, 'first').call({foo: 'yeah!'}, 'yooo')).toEqual(['bar', 'first', 'yooo']);
267 var bound = fn.bind({foo: 'bar'});
268 var bound2 = fn.bind({foo: 'yep'});
269 var inst = new bound;
271 expect(bound2.call(inst, 'yoo', 'howdy')).toEqual(['yep', 'yoo', 'howdy']);
276 describe('Function.pass', function(){
278 it('should return a function that when called passes the specified arguments to the original function', function(){
279 var spy = jasmine.createSpy('Function.pass').andReturn('the result');
280 var fnc = spy.pass('an argument');
281 expect(spy).not.toHaveBeenCalled();
282 expect(fnc('additional', 'arguments')).toBe('the result');
283 expect(spy).toHaveBeenCalledWith('an argument');
284 expect(spy.callCount).toBe(1);
287 it('should pass multiple arguments and bind the function to a specific object when it is called', function(){
288 var spy = jasmine.createSpy('Function.pass with bind').andReturn('the result');
289 var binding = {some: 'binding'};
290 var fnc = spy.pass(['multiple', 'arguments'], binding);
291 expect(spy).not.toHaveBeenCalled();
292 expect(fnc('additional', 'arguments')).toBe('the result');
293 expect(spy.mostRecentCall.object).toEqual(binding);
294 expect(spy).toHaveBeenCalledWith('multiple', 'arguments');
299 describe('Function.extend', function(){
301 it("should extend the function's properties", function(){
302 var fnc = (function(){}).extend({a: 1, b: 'c'});
303 expect(fnc.a).toEqual(1);
304 expect(fnc.b).toEqual('c');
309 describe('Function.attempt', function(){
311 it('should call the function without raising an exception', function(){
312 var fnc = function(){
318 it("should return the function's return value", function(){
319 var spy = jasmine.createSpy('Function.attempt').andReturn('hello world!');
320 expect(spy.attempt()).toEqual('hello world!');
323 it('should return null if the function raises an exception', function(){
324 var fnc = function(){
327 expect(fnc.attempt()).toBeNull();
332 describe('Function.delay', function(){
334 beforeEach(function(){
335 this.clock = sinon.useFakeTimers();
338 afterEach(function(){
340 this.clock.restore();
343 it('should return a timer pointer', function(){
344 var spyA = jasmine.createSpy('Alice');
345 var spyB = jasmine.createSpy('Bob');
347 var timerA = spyA.delay(200);
348 var timerB = spyB.delay(200);
350 this.clock.tick(100);
352 expect(spyA).not.toHaveBeenCalled();
353 expect(spyB).not.toHaveBeenCalled();
354 clearTimeout(timerB);
356 this.clock.tick(250);
357 expect(spyA.callCount).toBe(1);
358 expect(spyB.callCount).toBe(0);
361 it('should pass parameter 0', function(){
362 var spy = jasmine.createSpy('Function.delay with 0');
363 spy.delay(50, null, 0);
365 this.clock.tick(100);
366 expect(spy).toHaveBeenCalledWith(0);
369 it('should not pass any argument when no arguments passed', function(){
370 var argumentCount = null;
371 var spy = function(){
372 argumentCount = arguments.length;
375 this.clock.tick(100);
376 expect(argumentCount).toEqual(0);
381 describe('Function.periodical', function(){
383 beforeEach(function(){
384 this.clock = sinon.useFakeTimers();
387 afterEach(function(){
389 this.clock.restore();
392 it('should return an interval pointer', function(){
393 var spy = jasmine.createSpy('Bond');
395 var interval = spy.periodical(10);
396 expect(spy).not.toHaveBeenCalled();
398 this.clock.tick(100);
400 expect(spy.callCount).toBeGreaterThan(2);
401 expect(spy.callCount).toBeLessThan(15);
402 clearInterval(interval);
404 expect(spy).not.toHaveBeenCalled();
406 this.clock.tick(100);
408 expect(spy).not.toHaveBeenCalled();
411 it('should pass parameter 0', function(){
412 var spy = jasmine.createSpy('Function.periodical with 0');
413 var timer = spy.periodical(10, null, 0);
415 this.clock.tick(100);
417 expect(spy).toHaveBeenCalledWith(0);
418 clearInterval(timer);
421 it('should not pass any argument when no arguments passed', function(){
422 var argumentCount = null;
423 var spy = function(){
424 argumentCount = arguments.length;
426 var timer = spy.periodical(50);
427 this.clock.tick(100);
429 expect(argumentCount).toEqual(0);
430 clearInterval(timer);