diff options
author | Bartek IwaĆczuk <biwanczuk@gmail.com> | 2020-02-29 18:45:47 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-29 18:45:47 +0100 |
commit | f55b22e195ff0dfaf117aaef2a0fcc51fe0058c8 (patch) | |
tree | c314180b02b1ebf6b3f75ccbb4decade3b4fb511 /cli/js/test_util.ts | |
parent | 199fb195f334b582e4ee3fccaa9a33aa2a06ca48 (diff) |
add assertResources sanitizer to cli/js/ unit tests (#4161)
Diffstat (limited to 'cli/js/test_util.ts')
-rw-r--r-- | cli/js/test_util.ts | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/cli/js/test_util.ts b/cli/js/test_util.ts index b8ae3ca93..6f52c01df 100644 --- a/cli/js/test_util.ts +++ b/cli/js/test_util.ts @@ -106,6 +106,22 @@ function normalizeTestPermissions(perms: TestPermissions): Permissions { }; } +// Wrap `TestFunction` in additional assertion that makes sure +// the test case does not "leak" resources - ie. resource table after +// the test has exactly the same contents as before the test. +function assertResources(fn: Deno.TestFunction): Deno.TestFunction { + return async function(): Promise<void> { + const preResources = Deno.resources(); + await fn(); + const postResources = Deno.resources(); + const msg = `Test case is leaking resources. +Before: ${JSON.stringify(preResources, null, 2)} +After: ${JSON.stringify(postResources, null, 2)}`; + + assertEquals(preResources, postResources, msg); + }; +} + export function testPerm(perms: TestPermissions, fn: Deno.TestFunction): void { const normalizedPerms = normalizeTestPermissions(perms); @@ -115,7 +131,7 @@ export function testPerm(perms: TestPermissions, fn: Deno.TestFunction): void { return; } - Deno.test(fn); + Deno.test(fn.name, assertResources(fn)); } export function test(fn: Deno.TestFunction): void { @@ -171,6 +187,24 @@ export async function parseUnitTestOutput( return { actual, expected, resultOutput: result }; } +export interface ResolvableMethods<T> { + resolve: (value?: T | PromiseLike<T>) => void; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + reject: (reason?: any) => void; +} + +export type Resolvable<T> = Promise<T> & ResolvableMethods<T>; + +export function createResolvable<T>(): Resolvable<T> { + let methods: ResolvableMethods<T>; + const promise = new Promise<T>((resolve, reject): void => { + methods = { resolve, reject }; + }); + // TypeScript doesn't know that the Promise callback occurs synchronously + // therefore use of not null assertion (`!`) + return Object.assign(promise, methods!) as Resolvable<T>; +} + test(function permissionsMatches(): void { assert( permissionsMatch( @@ -265,28 +299,25 @@ testPerm({ read: true }, async function parsingUnitTestOutput(): Promise<void> { let result; // This is an example of a successful unit test output. - result = await parseUnitTestOutput( - await Deno.open(`${testDataPath}/unit_test_output1.txt`), - false - ); + const f1 = await Deno.open(`${testDataPath}/unit_test_output1.txt`); + result = await parseUnitTestOutput(f1, false); assertEquals(result.actual, 96); assertEquals(result.expected, 96); + f1.close(); // This is an example of a silently dying unit test. - result = await parseUnitTestOutput( - await Deno.open(`${testDataPath}/unit_test_output2.txt`), - false - ); + const f2 = await Deno.open(`${testDataPath}/unit_test_output2.txt`); + result = await parseUnitTestOutput(f2, false); assertEquals(result.actual, undefined); assertEquals(result.expected, 96); + f2.close(); // This is an example of compiling before successful unit tests. - result = await parseUnitTestOutput( - await Deno.open(`${testDataPath}/unit_test_output3.txt`), - false - ); + const f3 = await Deno.open(`${testDataPath}/unit_test_output3.txt`); + result = await parseUnitTestOutput(f3, false); assertEquals(result.actual, 96); assertEquals(result.expected, 96); + f3.close(); // Check what happens on empty output. const f = new Deno.Buffer(new TextEncoder().encode("\n\n\n")); |