From 87ed79ce8ae9573be5064142db6c570f647c80ce Mon Sep 17 00:00:00 2001 From: Wojciech Maj Date: Thu, 19 Nov 2020 10:40:17 +0100 Subject: [PATCH] Add unit tests ensuring utils take exactly the time necessary to execute --- src/every.spec.js | 17 +++++++++++++++++ src/every_strict.spec.js | 17 +++++++++++++++++ src/filter.spec.js | 17 +++++++++++++++++ src/filter_strict.spec.js | 17 +++++++++++++++++ src/forEach.spec.js | 17 +++++++++++++++++ src/forEach_strict.spec.js | 17 +++++++++++++++++ src/map.spec.js | 17 +++++++++++++++++ src/map_strict.spec.js | 17 +++++++++++++++++ src/reduce.spec.js | 20 ++++++++++++++++++++ src/some.spec.js | 17 +++++++++++++++++ src/some_strict.spec.js | 17 +++++++++++++++++ test-utils.js | 20 ++++++++++++++++++-- 12 files changed, 208 insertions(+), 2 deletions(-) diff --git a/src/every.spec.js b/src/every.spec.js index 3907b37..77b7eec 100644 --- a/src/every.spec.js +++ b/src/every.spec.js @@ -1,9 +1,11 @@ import asyncEvery from './every'; import { + getTimer, inputArr, largerThanOneHundred, largerThanOneHundredInRandomTime, + makeDelayed, } from '../test-utils'; function largerOrEqualThanZero(x) { @@ -25,6 +27,21 @@ describe('asyncEvery()', () => { expect(largerThanZero).toBe(true); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncEvery([1, 2, 3], makeDelayed((el) => el > 0, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThanOrEqual(delay); + expect(timeElapsed).toBeLessThan(delay + 10); + }); + it.skip('assertions below are valid for synchronous .every()', () => { const mapper = jest.fn().mockImplementation(largerOrEqualThanZero); diff --git a/src/every_strict.spec.js b/src/every_strict.spec.js index d02d3e1..b3a9bb4 100644 --- a/src/every_strict.spec.js +++ b/src/every_strict.spec.js @@ -2,9 +2,11 @@ import asyncEveryStrict from './every_strict'; import { doubleInputArr, + getTimer, inputArr, largerThanOneHundred, largerThanOneHundredInRandomTime, + makeDelayed, makePushDuplicate, makePushDuplicateInRandomTime, } from '../test-utils'; @@ -37,6 +39,21 @@ describe('asyncEvery()', () => { expect(indexes).toEqual([0, 1, 2]); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncEveryStrict([1, 2, 3], makeDelayed((el) => el > 0, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThan(delay * 3); + expect(timeElapsed).toBeLessThan((delay + 10) * 3); + }); + it.skip('assertions below are valid for synchronous .every()', () => { const mapper = jest.fn().mockImplementation(largerOrEqualThanZero); diff --git a/src/filter.spec.js b/src/filter.spec.js index 0938c8b..e477293 100644 --- a/src/filter.spec.js +++ b/src/filter.spec.js @@ -1,9 +1,11 @@ import asyncFilter from './filter'; import { + getTimer, inputArr, largerThanTwo, largerThanTwoInRandomTime, + makeDelayed, } from '../test-utils'; describe('asyncFilter()', () => { @@ -13,6 +15,21 @@ describe('asyncFilter()', () => { expect(asyncFilteredArr).toEqual([2, 3]); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncFilter([1, 2, 3], makeDelayed((el) => el > 1, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThanOrEqual(delay); + expect(timeElapsed).toBeLessThan(delay + 10); + }); + it.skip('assertions below are valid for synchronous .filter()', () => { const filter = jest.fn().mockImplementation(largerThanTwo); diff --git a/src/filter_strict.spec.js b/src/filter_strict.spec.js index fcab6c6..5d69ca1 100644 --- a/src/filter_strict.spec.js +++ b/src/filter_strict.spec.js @@ -2,9 +2,11 @@ import asyncFilterStrict from './filter_strict'; import { doubleInputArr, + getTimer, inputArr, largerThanTwo, largerThanTwoInRandomTime, + makeDelayed, makePushDuplicate, makePushDuplicateInRandomTime, } from '../test-utils'; @@ -25,6 +27,21 @@ describe('asyncFilterStrict()', () => { expect(indexes).toEqual([0, 1, 2]); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncFilterStrict([1, 2, 3], makeDelayed((el) => el > 1, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThan(delay * 3); + expect(timeElapsed).toBeLessThan((delay + 10) * 3); + }); + it.skip('assertions below are valid for synchronous .filter()', () => { const filter = jest.fn().mockImplementation(largerThanTwo); diff --git a/src/forEach.spec.js b/src/forEach.spec.js index 131153c..797625e 100644 --- a/src/forEach.spec.js +++ b/src/forEach.spec.js @@ -1,7 +1,9 @@ import asyncForEach from './forEach'; import { + getTimer, inputArr, + makeDelayed, makePushDuplicate, makePushDuplicateInRandomTime, } from '../test-utils'; @@ -21,6 +23,21 @@ describe('asyncForEach()', () => { expect(consoleLog).toHaveBeenCalledWith(6); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncForEach([1, 2, 3], makeDelayed((el) => el * 2, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThanOrEqual(delay); + expect(timeElapsed).toBeLessThan(delay + 10); + }); + it.skip('assertions below are valid for synchronous .forEach()', () => { const [arr, pushDuplicate] = makePushDuplicate(); const mapper = jest.fn().mockImplementation(pushDuplicate); diff --git a/src/forEach_strict.spec.js b/src/forEach_strict.spec.js index 493e247..98bfebf 100644 --- a/src/forEach_strict.spec.js +++ b/src/forEach_strict.spec.js @@ -1,7 +1,9 @@ import asyncForEachStrict from './forEach_strict'; import { doubleInputArr, + getTimer, inputArr, + makeDelayed, makePushDuplicate, makePushDuplicateInRandomTime, } from '../test-utils'; @@ -27,6 +29,21 @@ describe('asyncForEachStrict()', () => { expect(indexes).toEqual([0, 1, 2]); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncForEachStrict([1, 2, 3], makeDelayed((el) => el * 2, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThan(delay * 3); + expect(timeElapsed).toBeLessThan((delay + 10) * 3); + }); + it.skip('assertions below are valid for synchronous .forEach()', () => { const [arr, pushDuplicate] = makePushDuplicate(); const mapper = jest.fn().mockImplementation(pushDuplicate); diff --git a/src/map.spec.js b/src/map.spec.js index 8d23caa..ddea85b 100644 --- a/src/map.spec.js +++ b/src/map.spec.js @@ -4,7 +4,9 @@ import { doubleInputArr, duplicate, duplicateInRandomTime, + getTimer, inputArr, + makeDelayed, } from '../test-utils'; describe('asyncMap()', () => { @@ -14,6 +16,21 @@ describe('asyncMap()', () => { expect(asyncMappedArr).toEqual([2, 4, 6]); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncMap([1, 2, 3], makeDelayed((el) => el * 2, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThanOrEqual(delay); + expect(timeElapsed).toBeLessThan(delay + 10); + }); + it.skip('assertions below are valid for synchronous .map()', () => { const mapper = jest.fn().mockImplementation(duplicate); diff --git a/src/map_strict.spec.js b/src/map_strict.spec.js index 7167e4e..9d69e6b 100644 --- a/src/map_strict.spec.js +++ b/src/map_strict.spec.js @@ -4,7 +4,9 @@ import { doubleInputArr, duplicate, duplicateInRandomTime, + getTimer, inputArr, + makeDelayed, makePushDuplicate, makePushDuplicateInRandomTime, } from '../test-utils'; @@ -25,6 +27,21 @@ describe('asyncMapStrict()', () => { expect(indexes).toEqual([0, 1, 2]); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncMapStrict([1, 2, 3], makeDelayed((el) => el * 2, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThan(delay * 3); + expect(timeElapsed).toBeLessThan((delay + 10) * 3); + }); + it.skip('assertions below are valid for synchronous .map()', () => { const mapper = jest.fn().mockImplementation(duplicate); diff --git a/src/reduce.spec.js b/src/reduce.spec.js index 13f5ac0..f671d47 100644 --- a/src/reduce.spec.js +++ b/src/reduce.spec.js @@ -1,3 +1,4 @@ +import { getTimer, makeDelayed } from '../test-utils'; import asyncReduce from './reduce'; describe('asyncReduce()', () => { @@ -11,6 +12,25 @@ describe('asyncReduce()', () => { expect(result).toBe(6); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncReduce( + [1, 2, 3], + makeDelayed((tmp, cur) => tmp + cur, delay), + 0, + ); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThan(delay * 3); + expect(timeElapsed).toBeLessThan((delay + 10) * 3); + }); + it.skip('assertions below are valid for synchronous .reduce()', () => { const mapper = jest.fn().mockImplementation((temp, cur, idx) => [...temp, `${idx}:${cur}`]); diff --git a/src/some.spec.js b/src/some.spec.js index b7d0a42..e726f36 100644 --- a/src/some.spec.js +++ b/src/some.spec.js @@ -6,6 +6,8 @@ import { largerThanTwoInRandomTime, largerThanOneHundred, largerThanOneHundredInRandomTime, + getTimer, + makeDelayed, } from '../test-utils'; const firstElementLargerThanTwo = inputArr.findIndex(largerThanTwo); @@ -17,6 +19,21 @@ describe('asyncSome()', () => { expect(largerThanZero).toBe(true); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncSome([1, 2, 3], makeDelayed((el) => el < 0, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThanOrEqual(delay); + expect(timeElapsed).toBeLessThan(delay + 10); + }); + it.skip('assertions below are valid for synchronous .some()', () => { const mapper = jest.fn().mockImplementation(largerThanTwo); diff --git a/src/some_strict.spec.js b/src/some_strict.spec.js index 82fb347..b11c35c 100644 --- a/src/some_strict.spec.js +++ b/src/some_strict.spec.js @@ -9,6 +9,8 @@ import { largerThanOneHundredInRandomTime, makePushDuplicate, makePushDuplicateInRandomTime, + makeDelayed, + getTimer, } from '../test-utils'; const firstElementLargerThanTwo = inputArr.findIndex(largerThanTwo); @@ -29,6 +31,21 @@ describe('asyncSomeStrict()', () => { expect(indexes).toEqual([0]); }); + it('takes exactly the time necessary to execute', async () => { + const delay = 100; + + const timer = getTimer(); + + timer.start(); + + await asyncSomeStrict([1, 2, 3], makeDelayed((el) => el < 0, delay)); + + const timeElapsed = timer.stop(); + + expect(timeElapsed).toBeGreaterThanOrEqual(delay); + expect(timeElapsed).toBeLessThan((delay + 10) * 3); + }); + it.skip('assertions below are valid for synchronous .some()', () => { const mapper = jest.fn().mockImplementation(largerThanTwo); diff --git a/test-utils.js b/test-utils.js index e46cab3..972c8dc 100644 --- a/test-utils.js +++ b/test-utils.js @@ -2,12 +2,28 @@ export function getRandomTime() { return Math.random() * 100; } -export function makeDelayed(fn) { +export function getTimer() { + let startTime; + + function start() { + startTime = new Date(); + } + + function stop() { + const endTime = new Date(); + + return endTime - startTime; + } + + return { start, stop }; +} + +export function makeDelayed(fn, delay = getRandomTime()) { return function delayedFunction(x) { return new Promise( (resolve) => setTimeout(() => { resolve(fn(x)); - }, getRandomTime()), + }, delay), ); }; } -- 2.51.2