/* eslint-env qunit */ import sinon from 'sinon'; import * as Fn from '../../../src/js/utils/fn'; QUnit.module('utils/fn', { beforeEach() { this.clock = sinon.useFakeTimers(); }, afterEach() { this.clock.restore(); } }); QUnit.test('should add context to a function', function(assert) { assert.expect(1); const newContext = { test: 'obj'}; const asdf = function() { assert.ok(this === newContext); }; const fdsa = Fn.bind_(newContext, asdf); fdsa(); }); QUnit.test('should throttle functions properly', function(assert) { assert.expect(3); const tester = sinon.spy(); const throttled = Fn.throttle(tester, 100); // We must wait a full wait period before the function can be called. this.clock.tick(100); throttled(); throttled(); this.clock.tick(50); throttled(); assert.strictEqual(tester.callCount, 1, 'the throttled function has been called the correct number of times'); this.clock.tick(50); throttled(); assert.strictEqual(tester.callCount, 2, 'the throttled function has been called the correct number of times'); throttled(); this.clock.tick(100); throttled(); assert.strictEqual(tester.callCount, 3, 'the throttled function has been called the correct number of times'); }); QUnit.test('should debounce functions properly', function(assert) { assert.expect(6); const tester = sinon.spy(); const debounced = Fn.debounce(tester, 100); // Called twice on each assertion to ensure that multiple calls only result // in a call to the inner function. debounced(); debounced(); assert.strictEqual(tester.callCount, 0, 'the debounced function was NOT called because no time has elapsed'); this.clock.tick(100); assert.strictEqual(tester.callCount, 1, 'the debounced function was called because enough time elapsed'); this.clock.tick(100); assert.strictEqual(tester.callCount, 1, 'the debounced function was NOT called again even though time elapsed'); debounced(); debounced(); assert.strictEqual(tester.callCount, 1, 'the debounced function was NOT called because no time has elapsed since invocation'); this.clock.tick(50); assert.strictEqual(tester.callCount, 1, 'the debounced function was NOT called because the clock has NOT ticket forward enough'); this.clock.tick(50); assert.strictEqual(tester.callCount, 2, 'the debounced function was called because the clock ticked forward enough'); }); QUnit.test('may immediately invoke debounced functions', function(assert) { assert.expect(2); const tester = sinon.spy(); const debounced = Fn.debounce(tester, 100, true); // Called twice on each assertion to ensure that multiple calls only result // in a call to the inner function. debounced(); debounced(); assert.strictEqual(tester.callCount, 1, 'the debounced function was called because true was passed'); this.clock.tick(100); assert.strictEqual(tester.callCount, 1, 'the debounced function was NOT called because it has only been invoked once'); }); QUnit.test('may cancel debounced functions', function(assert) { assert.expect(2); const tester = sinon.spy(); const debounced = Fn.debounce(tester, 100); debounced(); this.clock.tick(50); debounced.cancel(); this.clock.tick(50); assert.strictEqual(tester.callCount, 0, 'the debounced function was NOT called because it was cancelled'); debounced(); this.clock.tick(100); assert.strictEqual(tester.callCount, 1, 'the debounced function was called because it was NOT cancelled'); });