|
4 | 4 | */ |
5 | 5 |
|
6 | 6 | import assert from 'assert' |
7 | | -import { once, onceChanged, debounce } from '../../../shared/utilities/functionUtils' |
| 7 | +import { once, onceChanged, debounce, throttle } from '../../../shared/utilities/functionUtils' |
8 | 8 | import { installFakeClock } from '../../testUtil' |
9 | 9 |
|
10 | 10 | describe('functionUtils', function () { |
@@ -107,3 +107,53 @@ describe('debounce', function () { |
107 | 107 | }) |
108 | 108 | }) |
109 | 109 | }) |
| 110 | + |
| 111 | +describe('throttle', function () { |
| 112 | + let counter: number |
| 113 | + let fn: () => Promise<number> |
| 114 | + let clock: ReturnType<typeof installFakeClock> |
| 115 | + |
| 116 | + const callAndSleep = async (delayInMs: number) => { |
| 117 | + const r = await fn() |
| 118 | + await clock.tickAsync(delayInMs) |
| 119 | + return r |
| 120 | + } |
| 121 | + |
| 122 | + const callAndSleepN = async (delayInMs: number, n: number) => { |
| 123 | + const results = [] |
| 124 | + for (const _ of Array.from({ length: n })) { |
| 125 | + results.push(await callAndSleep(delayInMs)) |
| 126 | + } |
| 127 | + return results |
| 128 | + } |
| 129 | + |
| 130 | + beforeEach(function () { |
| 131 | + clock = installFakeClock() |
| 132 | + counter = 0 |
| 133 | + fn = throttle(() => ++counter, 10) |
| 134 | + }) |
| 135 | + |
| 136 | + afterEach(function () { |
| 137 | + clock.uninstall() |
| 138 | + }) |
| 139 | + |
| 140 | + it('prevents a function from executing more than once in the `delay` window', async function () { |
| 141 | + await callAndSleepN(3, 3) |
| 142 | + assert.strictEqual(counter, 1, 'total calls should be 1') |
| 143 | + }) |
| 144 | + |
| 145 | + it('returns cached value on subsequent calls within window', async function () { |
| 146 | + const result = await callAndSleepN(3, 3) |
| 147 | + assert.deepStrictEqual(result, [1, 1, 1], 'all calls in window should return cached value') |
| 148 | + }) |
| 149 | + |
| 150 | + it('updates cache for next window', async function () { |
| 151 | + const result = await callAndSleepN(10, 3) |
| 152 | + assert.deepStrictEqual(result, [1, 2, 3], 'each call should return a new value') |
| 153 | + }) |
| 154 | + |
| 155 | + it('properly manages rolling cache window', async function () { |
| 156 | + const result = await callAndSleepN(5, 10) |
| 157 | + assert.deepStrictEqual(result, [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]) |
| 158 | + }) |
| 159 | +}) |
0 commit comments