9 var dit = /*<1.2compat>*/xit || /*</1.2compat>*/it; // Don't run unless no compat.
13 var MooTools = new String('MooTools');
16 return Array.convert(arguments).slice();
19 var Rules = function(){
20 return this + ' rules';
23 var Args = function(){
24 return [this].concat(Array.prototype.slice.call(arguments));
27 describe('Function Method', function(){
30 describe('Function.create', function(){
32 it('should return a new function', function(){
33 var fnc = $empty.create();
34 expect($empty).to.not.equal(fnc);
37 it('should return a new function with specified argument', function(){
38 var fnc = fn.create({'arguments': 'rocks'});
39 expect(fnc()).to.eql(['rocks']);
42 it('should return a new function with multiple arguments', function(){
43 var fnc = fn.create({'arguments': ['MooTools', 'rocks']});
44 expect(fnc()).to.eql(['MooTools', 'rocks']);
47 it('should return a new function bound to an object', function(){
48 var fnc = Rules.create({'bind': 'MooTools'});
49 expect(fnc()).to.equal('MooTools rules');
52 it('should return a new function as an event', function(){
53 var fnc = fn.create({'arguments': [0, 1], 'event': true});
54 expect(fnc('an Event occurred')).to.eql(['an Event occurred', 0, 1]);
59 describe('Function.bind', function(){
61 it('should return the function bound to an object', function(){
62 var fnc = Rules.bind('MooTools');
63 expect(fnc()).to.equal('MooTools rules');
66 it('should return the function bound to an object with specified argument', function(){
67 var results = Args.bind(MooTools, 'rocks')();
68 expect(results[0]).to.equal(MooTools);
69 expect(results[1]).to.equal('rocks');
72 dit('should return the function bound to an object with multiple arguments', function(){
73 var results = Args.bind(MooTools, ['rocks', 'da house'])();
74 expect(results[0]).to.equal(MooTools);
75 expect(results[1]).to.eql(['rocks', 'da house']);
79 it('should return the function bound to an object with specified argument', function(){
80 var fnc = Args.bind(MooTools, 'rocks');
82 expect(result[0]).to.equal(MooTools);
83 expect(result).to.eql([MooTools, 'rocks']);
86 it('should return the function bound to an object with multiple arguments', function(){
87 var fnc = Args.bind(MooTools, ['rocks', 'da house']);
89 expect(result[0]).to.equal(MooTools);
90 expect(result).to.eql([MooTools, 'rocks', 'da house']);
93 it('should return the function bound to an object and make the function an event listener', function(){
94 var fnc = Args.bindWithEvent(MooTools);
95 var result = fnc('an Event occurred');
96 expect(result[0]).to.equal(MooTools);
97 expect(result).to.eql([MooTools, 'an Event occurred']);
100 it('should return the function bound to an object and make the function event listener with multiple arguments', function(){
101 var fnc = Args.bindWithEvent(MooTools, ['rocks', 'da house']);
102 var result = fnc('an Event occurred');
103 expect(result[0]).to.equal(MooTools);
104 expect(result).to.eql([MooTools, 'an Event occurred', 'rocks', 'da house']);
110 describe('Function.pass', function(){
112 it('should return a function that when called passes the specified arguments to the original function', function(){
113 var fnc = fn.pass('MooTools is beautiful and elegant');
114 expect(fnc()).to.eql(['MooTools is beautiful and elegant']);
117 it('should pass multiple arguments and bind the function to a specific object when it is called', function(){
118 var fnc = Args.pass(['rocks', 'da house'], MooTools);
120 expect(result[0]).to.equal(MooTools);
121 expect(result).to.eql([MooTools, 'rocks', 'da house']);
127 describe('Function.run', function(){
129 it('should run the function', function(){
130 var result = fn.run();
131 expect(result).to.eql([]);
134 it('should run the function with multiple arguments', function(){
135 var result = fn.run(['MooTools', 'beautiful', 'elegant']);
136 expect(result).to.eql(['MooTools', 'beautiful', 'elegant']);
139 it('should run the function with multiple arguments and bind the function to an object', function(){
140 var result = Args.run(['beautiful', 'elegant'], MooTools);
141 expect(result[0]).to.equal(MooTools);
142 expect(result).to.eql([MooTools, 'beautiful', 'elegant']);
148 describe('Function.extend', function(){
150 it('should extend the properties of a function', function(){
151 var fnc = (function(){}).extend({a: 1, b: 'c'});
152 expect(fnc.a).to.equal(1);
153 expect(fnc.b).to.equal('c');
158 describe('Function.attempt', function(){
160 it('should call the function without raising an exception', function(){
161 var fnc = function(){
162 this_should_not_work();
167 it('should return the return value of a function', function(){
168 var fnc = Function.convert('hello world!');
169 expect(fnc.attempt()).to.equal('hello world!');
172 it('should return null if the function raises an exception', function(){
173 var fnc = function(){
174 this_should_not_work();
176 expect(fnc.attempt()).to.equal(null);
181 describe('Function.delay', function(){
183 it('delay should return a timer pointer', function(){
184 var referenceTimer = setTimeout(function(){}, 10000);
185 var timer = (function(){}).delay(10000);
186 expect(typeOf(timer)).to.equal(typeOf(referenceTimer));
188 clearTimeout(referenceTimer);
193 describe('Function.periodical', function(){
195 it('periodical should return a timer pointer', function(){
196 var referenceTimer = setInterval(function(){}, 10000);
197 var timer = (function(){}).periodical(10000);
198 expect(typeOf(timer)).to.equal(typeOf(referenceTimer));
199 clearInterval(timer);
200 clearInterval(referenceTimer);
207 describe('Function.attempt', function(){
209 it('should return the result of the first successful function without executing successive functions', function(){
211 var attempt = Function.attempt(function(){
213 throw new Exception();
221 expect(calls).to.equal(2);
222 expect(attempt).to.equal('success');
225 it('should return null when no function succeeded', function(){
227 var attempt = Function.attempt(function(){
229 return I_invented_this();
232 return uninstall_ie();
234 expect(calls).to.equal(2);
235 expect(attempt).to.equal(null);
242 describe('Function.bind', function(){
244 it('should return the function bound to an object', function(){
245 var spy = sinon.spy();
246 var f = spy.bind('MooTools');
247 expect(spy.called).to.equal(false);
249 expect(spy.calledWith()).to.equal(true);
251 expect(spy.calledWith('foo', 'bar')).to.equal(true);
254 it('should return the function bound to an object with specified argument', function(){
255 var binding = {some: 'binding'};
256 var spy = sinon.stub().returns('something');
257 var f = spy.bind(binding, 'arg');
259 expect(spy.called).to.equal(false);
260 expect(f('additional', 'arguments')).to.equal('something');
261 expect(spy.lastCall.thisValue).to.equal(binding);
264 it('should return the function bound to an object with multiple arguments', function(){
265 var binding = {some: 'binding'};
266 var spy = sinon.stub().returns('something');
267 var f = spy.bind(binding, ['foo', 'bar']);
269 expect(spy.called).to.equal(false);
270 expect(f('additional', 'arguments')).to.equal('something');
271 expect(spy.lastCall.thisValue).to.equal(binding);
274 dit('should still be possible to use it as constructor', function(){
275 function Alien(type){
280 var Tribble = Alien.bind(thisArg, 'Polygeminus grex');
282 // `thisArg` should **not** be used for the `this` binding when called as a constructor.
283 var fuzzball = new Tribble('Klingon');
284 expect(fuzzball.type).to.equal('Polygeminus grex');
287 dit('when using .call(thisArg) on a bound function, it should ignore the thisArg of .call', function(){
289 return [this.foo].concat(Array.slice(arguments));
292 expect(fn.bind({foo: 'bar'})()).to.eql(['bar']);
293 expect(fn.bind({foo: 'bar'}, 'first').call({foo: 'yeah!'}, 'yooo')).to.eql(['bar', 'first', 'yooo']);
295 var bound = fn.bind({foo: 'bar'});
296 var bound2 = fn.bind({foo: 'yep'});
297 var inst = new bound;
299 expect(bound2.call(inst, 'yoo', 'howdy')).to.eql(['yep', 'yoo', 'howdy']);
304 describe('Function.pass', function(){
306 it('should return a function that when called passes the specified arguments to the original function', function(){
307 var spy = sinon.stub().returns('the result');
308 var fnc = spy.pass('an argument');
309 expect(spy.called).to.equal(false);
310 expect(fnc('additional', 'arguments')).to.equal('the result');
311 expect(spy.calledWith('an argument')).to.equal(true);
312 expect(spy.callCount).to.equal(1);
315 it('should pass multiple arguments and bind the function to a specific object when it is called', function(){
316 var spy = sinon.stub().returns('the result');
317 var binding = {some: 'binding'};
318 var fnc = spy.pass(['multiple', 'arguments'], binding);
319 expect(spy.called).to.equal(false);
320 expect(fnc('additional', 'arguments')).to.equal('the result');
321 expect(spy.lastCall.thisValue).to.equal(binding);
322 expect(spy.calledWith('multiple', 'arguments')).to.equal(true);
327 describe('Function.extend', function(){
329 it('should extend the properties of a function', function(){
330 var fnc = (function(){}).extend({a: 1, b: 'c'});
331 expect(fnc.a).to.equal(1);
332 expect(fnc.b).to.equal('c');
337 describe('Function.attempt', function(){
339 it('should call the function without raising an exception', function(){
340 var fnc = function(){
346 it('should return the return value of a function', function(){
347 var spy = sinon.stub().returns('hello world!');
348 expect(spy.attempt()).to.equal('hello world!');
351 it('should return null if the function raises an exception', function(){
352 var fnc = function(){
355 expect(fnc.attempt()).to.equal(null);
360 describe('Function.delay', function(){
362 beforeEach(function(){
363 this.clock = sinon.useFakeTimers();
366 afterEach(function(){
368 this.clock.restore();
371 it('should return a timer pointer', function(){
372 var spyA = sinon.spy();
373 var spyB = sinon.spy();
375 var timerA = spyA.delay(200);
376 var timerB = spyB.delay(200);
378 this.clock.tick(100);
380 expect(spyA.called).to.equal(false);
381 expect(spyB.called).to.equal(false);
382 clearTimeout(timerB);
384 this.clock.tick(250);
385 expect(spyA.callCount).to.equal(1);
386 expect(spyB.callCount).to.equal(0);
387 clearTimeout(timerA);
390 it('should pass parameter 0', function(){
391 var spy = sinon.spy();
392 spy.delay(50, null, 0);
394 this.clock.tick(100);
395 expect(spy.calledWith(0)).to.equal(true);
398 it('should not pass any argument when no arguments passed', function(){
399 var argumentCount = null;
400 var spy = function(){
401 argumentCount = arguments.length;
404 this.clock.tick(100);
405 expect(argumentCount).to.equal(0);
410 describe('Function.periodical', function(){
412 beforeEach(function(){
413 this.clock = sinon.useFakeTimers();
416 afterEach(function(){
418 this.clock.restore();
421 it('should return an interval pointer', function(){
422 var spy = sinon.spy();
424 var interval = spy.periodical(10);
425 expect(spy.called).to.equal(false);
427 this.clock.tick(100);
429 expect(spy.callCount).to.be.greaterThan(2);
430 expect(spy.callCount).to.be.lessThan(15);
431 clearInterval(interval);
433 expect(spy.called).to.equal(false);
435 this.clock.tick(100);
437 expect(spy.called).to.equal(false);
440 it('should pass parameter 0', function(){
441 var spy = sinon.spy();
442 var timer = spy.periodical(10, null, 0);
444 this.clock.tick(100);
446 expect(spy.calledWith(0)).to.equal(true);
447 clearInterval(timer);
450 it('should not pass any argument when no arguments passed', function(){
451 var argumentCount = null;
452 var spy = function(){
453 argumentCount = arguments.length;
455 var timer = spy.periodical(50);
456 this.clock.tick(100);
458 expect(argumentCount).to.equal(0);
459 clearInterval(timer);