Skip to content

Instantly share code, notes, and snippets.

@ivikash
Last active March 19, 2018 21:35
Show Gist options
  • Save ivikash/c69eddf82df786ccc24c0fe227a8f11c to your computer and use it in GitHub Desktop.
Save ivikash/c69eddf82df786ccc24c0fe227a8f11c to your computer and use it in GitHub Desktop.
/**
* Debounce is a technique of grouping multiple calls into single call
*
* @param {Function} fn function to be debounce
* @param {Number} delay time is seconds for which fn should be debounce
*/
function debounce(fn, delay = 100) {
let timeout;
return function later(...args) {
const context = this;
clearTimeout(timeout);
return setTimeout(() => fn.apply(context, args), delay);
};
}
export { debounce };
import { debounce } from '../src/debounce';
jest.useFakeTimers();
describe('Debounce', () => {
it('should not execute immediately', () => {
let isExecuted = false;
const fn = debounce(() => {
isExecuted = true;
}, 0);
expect(isExecuted).toBe(false);
fn();
expect(isExecuted).toBe(false);
});
it('should execute after a delay', () => {
const callback = jest.fn();
const f = debounce(callback, 1000);
f();
jest.advanceTimersByTime(1000);
expect(callback).toBeCalled();
expect(callback).toHaveBeenCalledTimes(1);
});
it('should happen only once', () => {
const callback = jest.fn();
const f = debounce(callback, 1000);
f();
f();
f();
f();
expect(callback).not.toBeCalled();
jest.advanceTimersByTime(1000);
f();
f();
f();
f();
f();
expect(callback).toBeCalled();
expect(callback).toHaveBeenCalledTimes(4);
jest.advanceTimersByTime(1000);
expect(callback).toHaveBeenCalledTimes(9);
});
it('should merge arguments', () => {
const arr = [];
const callback = jest.fn((x) => {
arr.push(x);
});
const f = debounce(callback, 1000);
f(1);
f(2);
expect(arr).toEqual([]);
expect(callback).not.toBeCalled();
jest.advanceTimersByTime(1000);
expect(arr).toEqual([1, 2]);
f(3);
jest.advanceTimersByTime(1000);
f(4);
jest.advanceTimersByTime(1000);
expect(arr).toEqual([1, 2, 3, 4]);
});
it('should debounce independent functions', () => {
let hasAHappened = false;
let hasBHappened = false;
const a = debounce(() => {
hasAHappened = true;
}, 100);
const b = debounce(() => {
hasBHappened = true;
}, 2000);
a();
jest.advanceTimersByTime(100);
expect(hasAHappened).toBe(true);
expect(hasBHappened).toBe(false);
b();
jest.runAllTimers();
expect(hasAHappened).toBe(true);
expect(hasBHappened).toBe(true);
});
it('should maintain context', () => {
let context;
const barFoo = jest.fn(function f() {
context = this.foo;
});
const mockObj = {
foo: 'Hello',
bar: debounce(barFoo),
};
mockObj.bar();
jest.runAllTimers();
expect(context).toBe(mockObj.foo);
});
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment