UNPKG

sugar

Version:

A Javascript library for working with native objects.

325 lines (248 loc) 10.1 kB
test('Function', function () { var bound,obj,result; obj = { foo: 'bar' }; bound = (function(num, bool, str, fourth, fifth) { equal(this === obj, true, 'Function#bind | Bound object is strictly equal'); equal(num, 1, 'Function#bind | first parameter'); equal(bool, true, 'Function#bind | second parameter', { mootools: undefined }); equal(str, 'wasabi', 'Function#bind | third parameter', { mootools: undefined }); equal(fourth, 'fourth', 'Function#bind | fourth parameter', { mootools: undefined }); equal(fifth, 'fifth', 'Function#bind | fifth parameter', { mootools: undefined }); return 'howdy'; }).bind(obj, 1, true, 'wasabi'); result = bound('fourth','fifth'); equal(result, 'howdy', 'Function#bind | result is correctly returned'); (function(first) { equal(Array.prototype.slice.call(arguments), [], 'Function#bind | arguments array is empty'); equal(first, undefined, 'Function#bind | first argument is undefined'); }).bind('foo')(); bound = (function(num, bool, str) {}).bind('wasabi', 'moo')(); // Prototype's delay function takes the value in seconds, so 20 makes the tests // take at least 20 seconds to finish! var delayTime = environment === 'prototype' ? 0.02 : 20; async(function(){ var fn, ref; fn = function(one, two) { equal(one, 'one', 'Function#delay | first parameter', { mootools: 'two' }); equal(two, 'two', 'Function#delay | second parameter', { mootools: undefined }); }; ref = fn.delay(delayTime, 'one', 'two'); equal(typeof ref, 'function', 'Function#delay | returns the function', { prototype: 'number', mootools: 'number' }); }); async(function(){ var fn, ref, shouldBeFalse = false; fn = function() { shouldBeFalse = true; }; fn.delay(delayTime / 4); fn.delay(delayTime / 5); fn.delay(delayTime / 6); ref = fn.cancel(); equal(typeof fn.timers, 'object', 'Function#delay | timers object should be exposed'); equal(ref, fn, 'Function#cancel | returns a reference to the function'); setTimeout(function() { equal(shouldBeFalse, false, 'Function#delay | cancel is working', { prototype: true, mootools: true }); }, 60); }); skipEnvironments(['prototype'], function() { async(function(){ var counter = 0; var fn = function(){ counter++; } fn.delay(50); fn.delay(10); setTimeout(function() { fn.cancel(); }, 30); setTimeout(function() { equal(counter, 1, 'Function#cancel | should be able to find the correct timers', { prototype: 0 }); fn.cancel(); }, 60); }); }); async(function() { var counter = 0; var expected = [['maybe','a',1],['baby','b',2],['you lazy','c',3],['biotch','d',4]]; var fn = (function(one, two) { equal([this.toString(), one, two], expected[counter], 'Function#lazy | scope and arguments are correct'); counter++; }).lazy(); fn.call('maybe', 'a', 1); fn.call('baby', 'b', 2); fn.call('you lazy', 'c', 3); equal(counter, 1, "Function#lazy | should have executed once"); setTimeout(function() { equal(counter, 3, 'Function#lazy | was executed by 10ms'); fn.call('biotch', 'd', 4); equal(counter, 4, 'Function#lazy | next execution should be immediate'); }, 100); }); async(function() { var counter = 0; var fn = (function() { counter++; }).lazy(); fn(); fn(); fn(); fn.cancel(); setTimeout(function() { equal(counter, 1, 'Function#lazy | lazy functions can also be canceled'); }, 10); }); async(function() { var counter = 0; var fn = (function() { counter++; }).lazy(0.1); for(var i = 0; i < 20; i++) { fn(); } setTimeout(function() { equal(counter, 20, 'Function#lazy | lazy (throttled) functions can have a [wait] value of < 1ms'); }, 100); }); async(function() { var counter = 0; var fn = (function() { counter++; }).lazy(0.1, 10); for(var i = 0; i < 50; i++) { fn(); } setTimeout(function() { equal(counter, 10, 'Function#lazy | lazy functions have an upper threshold'); }, 50); }); async(function() { var counter = 0; var fn = (function() { counter++; }).lazy(0.1, 1); for(var i = 0; i < 50; i++) { fn(); } setTimeout(function() { equal(counter, 1, 'Function#lazy | lazy functions with a limit of 1 WILL still execute'); }, 50); }); // Function#debounce async(function(){ var fn, ret, counter = 0, expected = [['leia', 5],['han solo', 7]]; var fn = (function(one){ equal([this.toString(), one], expected[counter], 'Function#debounce | scope and arguments are correct'); counter++; }).debounce(30); fn.call('3p0', 1); fn.call('r2d2', 2); fn.call('chewie', 3); setTimeout(function() { fn.call('leia', 5); }, 10); setTimeout(function() { fn.call('luke', 6); fn.call('han solo', 7); }, 200); ret = fn.call('vader', 4); equal(ret, undefined, 'Function#debounce | calls to a debounced function return undefined'); setTimeout(function() { equal(counter, 2, 'Function#debounce | counter is correct'); }, 500); }); async(function() { var counter = 0; var fn = (function() { counter++; }).debounce(50); fn(); fn(); fn(); fn.cancel(); equal(counter, 0, 'Function#debounce | debounced functions can also be canceled | immediate'); setTimeout(function() { equal(counter, 0, 'Function#debounce | debounced functions can also be canceled | after delay'); }, 100); }); // Function#throttle async(function(){ var fn, ret, counter = 0, expected = [['3p0', 1],['luke', 6]]; var fn = (function(one){ equal([this.toString(), one], expected[counter], 'Function#throttle | immediate execution | scope and arguments are correct'); counter++; }).throttle(50); fn.call('3p0', 1); fn.call('r2d2', 2); fn.call('chewie', 3); setTimeout(function() { fn.call('leia', 5); }, 10); setTimeout(function() { fn.call('luke', 6); fn.call('han solo', 7); }, 100); ret = fn.call('vader', 4); setTimeout(function() { equal(counter, 2, 'Function#throttle | immediate execution | counter is correct'); }, 200); }); // Function#after async(function() { var fn, ret, counter = 0, i = 1; var expectedArguments = [[[1,'bop'],[2,'bop'],[3,'bop'],[4,'bop'],[5,'bop']],[[6,'bop'],[7,'bop'],[8,'bop'],[9,'bop'],[10,'bop']]]; fn = (function(args) { equal(args, expectedArguments[counter], 'Function#after | collects arguments called'); equal(!!args[0].slice, true, 'Function#after | arguments are converted to actual arrays'); counter++; return 'hooha'; }).after(5); while(i <= 10) { ret = fn(i, 'bop'); equal(ret, (i % 5 == 0 ? 'hooha' : undefined), 'Function#after | collects return value as well'); i++; } equal(counter, 2, 'Function#after | calls a function only after a certain number of calls'); }); async(function() { var fn, counter = 0; var fn = (function(args) { counter++; }).after(0); equal(counter, 1, 'Function#after | 0 should fire the function immediately'); equal(typeof fn, 'function', 'Function#after | 0 should still return a function'); }); // Function#once async(function() { var fn, obj = { foo:'bar' }, counter = 0; fn = (function(one, two) { counter++; equal(this, obj, 'Function#once | scope is properly set'); equal(one, 'one', 'Function#once | first argument is passed'); equal(two, 'two', 'Function#once | second argument is passed'); return counter * 30; }).once(); equal(fn.call(obj, 'one', 'two'), 30, 'Function#once | first call calculates the result'); equal(fn.call(obj, 'one', 'two'), 30, 'Function#once | second call memoizes the result'); equal(fn.call(obj, 'one', 'two'), 30, 'Function#once | third call memoizes the result'); equal(fn.call(obj, 'one', 'two'), 30, 'Function#once | fourth call memoizes the result'); equal(fn.call(obj, 'one', 'two'), 30, 'Function#once | fifth call memoizes the result'); equal(counter, 1, 'Function#once | counter is only incremented once'); }); async(function() { var fn, counter = 0; fn = (function(one, two) { counter++; }).once(); fn.call(); fn.call(); fn.call(); equal(counter, 1, 'Function#once | returning undefined will not affect the number of calls'); }); // Function#fill // Now that core is being split up, Number#format may not exist, so replicating it here. var format = function(place, last){ return (last || '') + this.toFixed(place); } Number.prototype.two = format.fill(2); equal((18).two(), '18.00', 'Function#fill | two | 18'); equal((9999).two(), '9999.00', 'Function#fill | two | 9999.00'); equal((9999).two('$'), '$9999.00', 'Function#fill | two | $9999.00'); Number.prototype.euro = format.fill(undefined, '€'); equal((9999.77).euro(), '€10000', 'Function#fill | euro | no params | 9.999,77'); equal((9999.77).euro(0), '€10000', 'Function#fill | euro | 0 | 9.999'); equal((9999.77).euro(1), '€9999.8', 'Function#fill | euro | 1 | 9.999,8'); equal((9999.77).euro(2), '€9999.77', 'Function#fill | euro | 2 | 9.999,77'); equal((9999.77).euro(3), '€9999.770', 'Function#fill | euro | 3 | 9.999,777'); Number.prototype.noop = format.fill(); equal((1000).noop(3, '$'), '$1000.000', 'Function#fill | noop | noop | 1 000,000'); equal((1000).noop(4, '$'), '$1000.0000', 'Function#fill | noop | noop | 1 000,0000'); equal((1000).noop(5, '$'), '$1000.00000', 'Function#fill | noop | noop | 1 000,00000'); equal((function(first){ return first; }).fill(['a','b'])(), ['a','b'], 'Function#fill | can be passed arrays'); equal((function(){ return Array.prototype.slice.call(arguments); }).fill(0)('a'), [0, 'a'], 'Function#fill | falsy values can be passed'); });