-
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Bug/595 debounced project code validation is causing trouble (#608)
* The complicated async project-code validation * Revert "The complicated async project-code validation" This reverts commit 35a88fd. * Less complicated async project-code validation * track and verify value received in debounce tests * Use derived store to implement async-debouncing --------- Co-authored-by: Kevin Hahn <[email protected]>
- Loading branch information
Showing
8 changed files
with
191 additions
and
54 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
/** | ||
* @param values any number of arrays, values or undefined's | ||
* @returns a single array containing any/all the defined values from the inputs | ||
*/ | ||
export function concatAll<T>(...values: (T | T[] | undefined)[]): T[] { | ||
const mergedResult = []; | ||
for (const value of values) { | ||
if (value === undefined) continue; | ||
mergedResult.push(...(Array.isArray(value) ? value : [value])); | ||
} | ||
return mergedResult; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
import { delay, deriveAsync } from './time'; | ||
import { describe, expect, it } from 'vitest'; | ||
|
||
import { writable } from 'svelte/store'; | ||
|
||
const debounceTime = 100; | ||
const promiseTime = 50; | ||
|
||
describe('deriveAsync', () => { | ||
it('handles standard synchronous debouncing', async () => { | ||
let reachedPromise = false; | ||
let done = false; | ||
let valueReceived: number | null = null; | ||
const store = writable<number>(); | ||
const debouncedStore = deriveAsync( | ||
store, | ||
// the promise resolves immediately, so we're only testing the debounce that happens before awaiting the promise | ||
(value: number) => { | ||
reachedPromise = true; | ||
return new Promise<number>(resolve => resolve(value)); | ||
}, | ||
undefined, | ||
debounceTime); | ||
debouncedStore.subscribe((value) => { | ||
if (value !== undefined) { | ||
done = true; | ||
valueReceived = value; | ||
} | ||
}); | ||
|
||
store.set(1); | ||
expect(reachedPromise).toBe(false); | ||
expect(done).toBe(false); | ||
|
||
await delay(debounceTime * 0.75); | ||
expect(reachedPromise).toBe(false); | ||
expect(done).toBe(false); | ||
|
||
store.set(2); // restart the debounce | ||
await delay(debounceTime * 0.75); | ||
expect(reachedPromise).toBe(false); | ||
expect(done).toBe(false); | ||
|
||
store.set(3); // restart the debounce | ||
await delay(debounceTime * 0.75); | ||
expect(reachedPromise).toBe(false); | ||
expect(done).toBe(false); | ||
|
||
await delay(debounceTime * 0.25); | ||
expect(reachedPromise).toBe(true); | ||
expect(done).toBe(true); | ||
expect(valueReceived).toBe(3); | ||
}); | ||
|
||
it('handles asynchronous debouncing', async () => { | ||
let reachedPromise = false; | ||
let done = false; | ||
let valueReceived: number | null = null; | ||
const store = writable<number>(); | ||
const debouncedStore = deriveAsync( | ||
store, | ||
// the promise resolves after a delay, so it can get debounced before it hits the promise or before the promise has been resolved | ||
(value: number) => { | ||
reachedPromise = true; | ||
return new Promise<number>(resolve => { | ||
setTimeout(() => resolve(value), promiseTime); | ||
}); | ||
}, | ||
undefined, | ||
debounceTime); | ||
debouncedStore.subscribe((value) => { | ||
if (value !== undefined) { | ||
done = true; | ||
valueReceived = value; | ||
} | ||
}); | ||
|
||
store.set(1); | ||
expect(reachedPromise).toBe(false); | ||
expect(done).toBe(false); | ||
|
||
await delay(debounceTime * 0.75); | ||
expect(reachedPromise).toBe(false); | ||
expect(done).toBe(false); | ||
|
||
store.set(2); // restart the debounce | ||
await delay(debounceTime * 0.75); | ||
expect(reachedPromise).toBe(false); | ||
expect(done).toBe(false); | ||
|
||
store.set(3); // restart the debounce | ||
await delay(debounceTime * 0.75); | ||
expect(reachedPromise).toBe(false); | ||
expect(done).toBe(false); | ||
|
||
await delay(debounceTime * 0.25); | ||
expect(reachedPromise).toBe(true); // we hit the promise | ||
expect(done).toBe(false); // but it will only complete if it doesn't get debounced before the promise resolves | ||
|
||
await delay(promiseTime * 0.5); | ||
expect(done).toBe(false); | ||
|
||
store.set(4); // restart the debounce | ||
await delay(promiseTime * 0.5); | ||
expect(done).toBe(false); | ||
|
||
await delay(debounceTime + promiseTime); | ||
expect(done).toBe(true); | ||
expect(valueReceived).toBe(4); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters