mirror of
https://github.com/denoland/deno.git
synced 2025-03-04 01:44:26 -05:00
add assertResources sanitizer to cli/js/ unit tests (#4161)
This commit is contained in:
parent
199fb195f3
commit
f55b22e195
11 changed files with 95 additions and 36 deletions
|
@ -19,9 +19,11 @@ if (Deno.build.os !== "win") {
|
||||||
const uid = parseInt(
|
const uid = parseInt(
|
||||||
new TextDecoder("utf-8").decode(await uidProc.output())
|
new TextDecoder("utf-8").decode(await uidProc.output())
|
||||||
);
|
);
|
||||||
|
uidProc.close();
|
||||||
const gid = parseInt(
|
const gid = parseInt(
|
||||||
new TextDecoder("utf-8").decode(await gidProc.output())
|
new TextDecoder("utf-8").decode(await gidProc.output())
|
||||||
);
|
);
|
||||||
|
gidProc.close();
|
||||||
|
|
||||||
return { uid, gid };
|
return { uid, gid };
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,8 @@ import {
|
||||||
assert,
|
assert,
|
||||||
assertEquals,
|
assertEquals,
|
||||||
assertStrContains,
|
assertStrContains,
|
||||||
assertThrows,
|
assertThrows
|
||||||
fail
|
// fail
|
||||||
} from "./test_util.ts";
|
} from "./test_util.ts";
|
||||||
|
|
||||||
testPerm({ net: true }, async function fetchProtocolError(): Promise<void> {
|
testPerm({ net: true }, async function fetchProtocolError(): Promise<void> {
|
||||||
|
@ -51,6 +51,7 @@ test(async function fetchPerm(): Promise<void> {
|
||||||
testPerm({ net: true }, async function fetchUrl(): Promise<void> {
|
testPerm({ net: true }, async function fetchUrl(): Promise<void> {
|
||||||
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
|
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
|
||||||
assertEquals(response.url, "http://localhost:4545/cli/tests/fixture.json");
|
assertEquals(response.url, "http://localhost:4545/cli/tests/fixture.json");
|
||||||
|
response.body.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ net: true }, async function fetchURL(): Promise<void> {
|
testPerm({ net: true }, async function fetchURL(): Promise<void> {
|
||||||
|
@ -58,6 +59,7 @@ testPerm({ net: true }, async function fetchURL(): Promise<void> {
|
||||||
new URL("http://localhost:4545/cli/tests/fixture.json")
|
new URL("http://localhost:4545/cli/tests/fixture.json")
|
||||||
);
|
);
|
||||||
assertEquals(response.url, "http://localhost:4545/cli/tests/fixture.json");
|
assertEquals(response.url, "http://localhost:4545/cli/tests/fixture.json");
|
||||||
|
response.body.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ net: true }, async function fetchHeaders(): Promise<void> {
|
testPerm({ net: true }, async function fetchHeaders(): Promise<void> {
|
||||||
|
@ -65,6 +67,7 @@ testPerm({ net: true }, async function fetchHeaders(): Promise<void> {
|
||||||
const headers = response.headers;
|
const headers = response.headers;
|
||||||
assertEquals(headers.get("Content-Type"), "application/json");
|
assertEquals(headers.get("Content-Type"), "application/json");
|
||||||
assert(headers.get("Server")!.startsWith("SimpleHTTP"));
|
assert(headers.get("Server")!.startsWith("SimpleHTTP"));
|
||||||
|
response.body.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ net: true }, async function fetchBlob(): Promise<void> {
|
testPerm({ net: true }, async function fetchBlob(): Promise<void> {
|
||||||
|
@ -95,6 +98,7 @@ testPerm({ net: true }, async function fetchAsyncIterator(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(total, Number(headers.get("Content-Length")));
|
assertEquals(total, Number(headers.get("Content-Length")));
|
||||||
|
response.body.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ net: true }, async function responseClone(): Promise<void> {
|
testPerm({ net: true }, async function responseClone(): Promise<void> {
|
||||||
|
@ -151,6 +155,8 @@ testPerm(
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO: leaking resources
|
||||||
testPerm({ net: true }, async function fetchWithRedirection(): Promise<void> {
|
testPerm({ net: true }, async function fetchWithRedirection(): Promise<void> {
|
||||||
const response = await fetch("http://localhost:4546/"); // will redirect to http://localhost:4545/
|
const response = await fetch("http://localhost:4546/"); // will redirect to http://localhost:4545/
|
||||||
assertEquals(response.status, 200);
|
assertEquals(response.status, 200);
|
||||||
|
@ -160,6 +166,7 @@ testPerm({ net: true }, async function fetchWithRedirection(): Promise<void> {
|
||||||
assert(body.includes("<title>Directory listing for /</title>"));
|
assert(body.includes("<title>Directory listing for /</title>"));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: leaking resources
|
||||||
testPerm({ net: true }, async function fetchWithRelativeRedirection(): Promise<
|
testPerm({ net: true }, async function fetchWithRelativeRedirection(): Promise<
|
||||||
void
|
void
|
||||||
> {
|
> {
|
||||||
|
@ -169,6 +176,7 @@ testPerm({ net: true }, async function fetchWithRelativeRedirection(): Promise<
|
||||||
const body = await response.text();
|
const body = await response.text();
|
||||||
assert(body.includes("<title>Directory listing for /cli/tests/</title>"));
|
assert(body.includes("<title>Directory listing for /cli/tests/</title>"));
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
// The feature below is not implemented, but the test should work after implementation
|
// The feature below is not implemented, but the test should work after implementation
|
||||||
/*
|
/*
|
||||||
|
@ -371,6 +379,8 @@ testPerm({ net: true }, async function fetchPostBodyTypedArray():Promise<void> {
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
// TODO: leaking resources
|
||||||
testPerm({ net: true }, async function fetchWithManualRedirection(): Promise<
|
testPerm({ net: true }, async function fetchWithManualRedirection(): Promise<
|
||||||
void
|
void
|
||||||
> {
|
> {
|
||||||
|
@ -391,6 +401,7 @@ testPerm({ net: true }, async function fetchWithManualRedirection(): Promise<
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// TODO: leaking resources
|
||||||
testPerm({ net: true }, async function fetchWithErrorRedirection(): Promise<
|
testPerm({ net: true }, async function fetchWithErrorRedirection(): Promise<
|
||||||
void
|
void
|
||||||
> {
|
> {
|
||||||
|
@ -410,6 +421,7 @@ testPerm({ net: true }, async function fetchWithErrorRedirection(): Promise<
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
test(function responseRedirect(): void {
|
test(function responseRedirect(): void {
|
||||||
const response = new Response(
|
const response = new Response(
|
||||||
|
|
|
@ -21,6 +21,7 @@ testPerm({ read: true }, async function filesCopyToStdout(): Promise<void> {
|
||||||
const fileSize = Deno.statSync(filename).len;
|
const fileSize = Deno.statSync(filename).len;
|
||||||
assertEquals(bytesWritten, fileSize);
|
assertEquals(bytesWritten, fileSize);
|
||||||
console.log("bytes written", bytesWritten);
|
console.log("bytes written", bytesWritten);
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ read: true }, async function filesToAsyncIterator(): Promise<void> {
|
testPerm({ read: true }, async function filesToAsyncIterator(): Promise<void> {
|
||||||
|
@ -33,6 +34,7 @@ testPerm({ read: true }, async function filesToAsyncIterator(): Promise<void> {
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(totalSize, 12);
|
assertEquals(totalSize, 12);
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
test(async function readerToAsyncIterator(): Promise<void> {
|
test(async function readerToAsyncIterator(): Promise<void> {
|
||||||
|
@ -308,6 +310,7 @@ testPerm({ read: true }, async function seekStart(): Promise<void> {
|
||||||
await file.read(buf);
|
await file.read(buf);
|
||||||
const decoded = new TextDecoder().decode(buf);
|
const decoded = new TextDecoder().decode(buf);
|
||||||
assertEquals(decoded, "world!");
|
assertEquals(decoded, "world!");
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ read: true }, function seekSyncStart(): void {
|
testPerm({ read: true }, function seekSyncStart(): void {
|
||||||
|
@ -321,6 +324,7 @@ testPerm({ read: true }, function seekSyncStart(): void {
|
||||||
file.readSync(buf);
|
file.readSync(buf);
|
||||||
const decoded = new TextDecoder().decode(buf);
|
const decoded = new TextDecoder().decode(buf);
|
||||||
assertEquals(decoded, "world!");
|
assertEquals(decoded, "world!");
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ read: true }, async function seekCurrent(): Promise<void> {
|
testPerm({ read: true }, async function seekCurrent(): Promise<void> {
|
||||||
|
@ -334,6 +338,7 @@ testPerm({ read: true }, async function seekCurrent(): Promise<void> {
|
||||||
await file.read(buf);
|
await file.read(buf);
|
||||||
const decoded = new TextDecoder().decode(buf);
|
const decoded = new TextDecoder().decode(buf);
|
||||||
assertEquals(decoded, "world!");
|
assertEquals(decoded, "world!");
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ read: true }, function seekSyncCurrent(): void {
|
testPerm({ read: true }, function seekSyncCurrent(): void {
|
||||||
|
@ -347,6 +352,7 @@ testPerm({ read: true }, function seekSyncCurrent(): void {
|
||||||
file.readSync(buf);
|
file.readSync(buf);
|
||||||
const decoded = new TextDecoder().decode(buf);
|
const decoded = new TextDecoder().decode(buf);
|
||||||
assertEquals(decoded, "world!");
|
assertEquals(decoded, "world!");
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ read: true }, async function seekEnd(): Promise<void> {
|
testPerm({ read: true }, async function seekEnd(): Promise<void> {
|
||||||
|
@ -357,6 +363,7 @@ testPerm({ read: true }, async function seekEnd(): Promise<void> {
|
||||||
await file.read(buf);
|
await file.read(buf);
|
||||||
const decoded = new TextDecoder().decode(buf);
|
const decoded = new TextDecoder().decode(buf);
|
||||||
assertEquals(decoded, "world!");
|
assertEquals(decoded, "world!");
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ read: true }, function seekSyncEnd(): void {
|
testPerm({ read: true }, function seekSyncEnd(): void {
|
||||||
|
@ -367,6 +374,7 @@ testPerm({ read: true }, function seekSyncEnd(): void {
|
||||||
file.readSync(buf);
|
file.readSync(buf);
|
||||||
const decoded = new TextDecoder().decode(buf);
|
const decoded = new TextDecoder().decode(buf);
|
||||||
assertEquals(decoded, "world!");
|
assertEquals(decoded, "world!");
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ read: true }, async function seekMode(): Promise<void> {
|
testPerm({ read: true }, async function seekMode(): Promise<void> {
|
||||||
|
@ -387,4 +395,5 @@ testPerm({ read: true }, async function seekMode(): Promise<void> {
|
||||||
const buf = new Uint8Array(1);
|
const buf = new Uint8Array(1);
|
||||||
await file.read(buf); // "H"
|
await file.read(buf); // "H"
|
||||||
assertEquals(new TextDecoder().decode(buf), "H");
|
assertEquals(new TextDecoder().decode(buf), "H");
|
||||||
|
file.close();
|
||||||
});
|
});
|
||||||
|
|
|
@ -112,6 +112,8 @@ testPerm({ net: true }, async function netUdpSendReceive(): Promise<void> {
|
||||||
assertEquals(1, recvd[0]);
|
assertEquals(1, recvd[0]);
|
||||||
assertEquals(2, recvd[1]);
|
assertEquals(2, recvd[1]);
|
||||||
assertEquals(3, recvd[2]);
|
assertEquals(3, recvd[2]);
|
||||||
|
alice.close();
|
||||||
|
bob.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm(
|
testPerm(
|
||||||
|
|
|
@ -76,6 +76,7 @@ if (Deno.build.os === "win") {
|
||||||
new TextDecoder().decode(await proc.output())
|
new TextDecoder().decode(await proc.output())
|
||||||
);
|
);
|
||||||
assertEquals(actualValues, expectedValues);
|
assertEquals(actualValues, expectedValues);
|
||||||
|
proc.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
assertEquals(Deno.env("path"), Deno.env("PATH"));
|
assertEquals(Deno.env("path"), Deno.env("PATH"));
|
||||||
|
|
|
@ -299,6 +299,7 @@ testPerm({ run: true }, async function runClose(): Promise<void> {
|
||||||
const data = new Uint8Array(10);
|
const data = new Uint8Array(10);
|
||||||
const r = await p.stderr!.read(data);
|
const r = await p.stderr!.read(data);
|
||||||
assertEquals(r, Deno.EOF);
|
assertEquals(r, Deno.EOF);
|
||||||
|
p.stderr!.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
test(function signalNumbers(): void {
|
test(function signalNumbers(): void {
|
||||||
|
@ -341,6 +342,7 @@ if (Deno.build.os !== "win") {
|
||||||
// re-enable when it can be made deterministic.
|
// re-enable when it can be made deterministic.
|
||||||
// assertEquals(status.code, 1);
|
// assertEquals(status.code, 1);
|
||||||
// assertEquals(status.signal, Deno.Signal.SIGINT);
|
// assertEquals(status.signal, Deno.Signal.SIGINT);
|
||||||
|
p.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
testPerm({ run: true }, async function killFailed(): Promise<void> {
|
testPerm({ run: true }, async function killFailed(): Promise<void> {
|
||||||
|
|
|
@ -31,8 +31,9 @@ testPerm({ net: true }, async function resourcesNet(): Promise<void> {
|
||||||
|
|
||||||
testPerm({ read: true }, async function resourcesFile(): Promise<void> {
|
testPerm({ read: true }, async function resourcesFile(): Promise<void> {
|
||||||
const resourcesBefore = Deno.resources();
|
const resourcesBefore = Deno.resources();
|
||||||
await Deno.open("cli/tests/hello.txt");
|
const f = await Deno.open("cli/tests/hello.txt");
|
||||||
const resourcesAfter = Deno.resources();
|
const resourcesAfter = Deno.resources();
|
||||||
|
f.close();
|
||||||
|
|
||||||
// check that exactly one new resource (file) was added
|
// check that exactly one new resource (file) was added
|
||||||
assertEquals(
|
assertEquals(
|
||||||
|
|
|
@ -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 {
|
export function testPerm(perms: TestPermissions, fn: Deno.TestFunction): void {
|
||||||
const normalizedPerms = normalizeTestPermissions(perms);
|
const normalizedPerms = normalizeTestPermissions(perms);
|
||||||
|
|
||||||
|
@ -115,7 +131,7 @@ export function testPerm(perms: TestPermissions, fn: Deno.TestFunction): void {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Deno.test(fn);
|
Deno.test(fn.name, assertResources(fn));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function test(fn: Deno.TestFunction): void {
|
export function test(fn: Deno.TestFunction): void {
|
||||||
|
@ -171,6 +187,24 @@ export async function parseUnitTestOutput(
|
||||||
return { actual, expected, resultOutput: result };
|
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 {
|
test(function permissionsMatches(): void {
|
||||||
assert(
|
assert(
|
||||||
permissionsMatch(
|
permissionsMatch(
|
||||||
|
@ -265,28 +299,25 @@ testPerm({ read: true }, async function parsingUnitTestOutput(): Promise<void> {
|
||||||
let result;
|
let result;
|
||||||
|
|
||||||
// This is an example of a successful unit test output.
|
// This is an example of a successful unit test output.
|
||||||
result = await parseUnitTestOutput(
|
const f1 = await Deno.open(`${testDataPath}/unit_test_output1.txt`);
|
||||||
await Deno.open(`${testDataPath}/unit_test_output1.txt`),
|
result = await parseUnitTestOutput(f1, false);
|
||||||
false
|
|
||||||
);
|
|
||||||
assertEquals(result.actual, 96);
|
assertEquals(result.actual, 96);
|
||||||
assertEquals(result.expected, 96);
|
assertEquals(result.expected, 96);
|
||||||
|
f1.close();
|
||||||
|
|
||||||
// This is an example of a silently dying unit test.
|
// This is an example of a silently dying unit test.
|
||||||
result = await parseUnitTestOutput(
|
const f2 = await Deno.open(`${testDataPath}/unit_test_output2.txt`);
|
||||||
await Deno.open(`${testDataPath}/unit_test_output2.txt`),
|
result = await parseUnitTestOutput(f2, false);
|
||||||
false
|
|
||||||
);
|
|
||||||
assertEquals(result.actual, undefined);
|
assertEquals(result.actual, undefined);
|
||||||
assertEquals(result.expected, 96);
|
assertEquals(result.expected, 96);
|
||||||
|
f2.close();
|
||||||
|
|
||||||
// This is an example of compiling before successful unit tests.
|
// This is an example of compiling before successful unit tests.
|
||||||
result = await parseUnitTestOutput(
|
const f3 = await Deno.open(`${testDataPath}/unit_test_output3.txt`);
|
||||||
await Deno.open(`${testDataPath}/unit_test_output3.txt`),
|
result = await parseUnitTestOutput(f3, false);
|
||||||
false
|
|
||||||
);
|
|
||||||
assertEquals(result.actual, 96);
|
assertEquals(result.actual, 96);
|
||||||
assertEquals(result.expected, 96);
|
assertEquals(result.expected, 96);
|
||||||
|
f3.close();
|
||||||
|
|
||||||
// Check what happens on empty output.
|
// Check what happens on empty output.
|
||||||
const f = new Deno.Buffer(new TextEncoder().encode("\n\n\n"));
|
const f = new Deno.Buffer(new TextEncoder().encode("\n\n\n"));
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
import { test, testPerm, assert, assertEquals } from "./test_util.ts";
|
import {
|
||||||
|
test,
|
||||||
|
testPerm,
|
||||||
|
assert,
|
||||||
|
assertEquals,
|
||||||
|
createResolvable
|
||||||
|
} from "./test_util.ts";
|
||||||
import { BufWriter, BufReader } from "../../std/io/bufio.ts";
|
import { BufWriter, BufReader } from "../../std/io/bufio.ts";
|
||||||
import { TextProtoReader } from "../../std/textproto/mod.ts";
|
import { TextProtoReader } from "../../std/textproto/mod.ts";
|
||||||
|
|
||||||
|
@ -142,6 +148,7 @@ testPerm(
|
||||||
testPerm({ read: true, net: true }, async function dialAndListenTLS(): Promise<
|
testPerm({ read: true, net: true }, async function dialAndListenTLS(): Promise<
|
||||||
void
|
void
|
||||||
> {
|
> {
|
||||||
|
const resolvable = createResolvable();
|
||||||
const hostname = "localhost";
|
const hostname = "localhost";
|
||||||
const port = 4500;
|
const port = 4500;
|
||||||
|
|
||||||
|
@ -164,6 +171,7 @@ testPerm({ read: true, net: true }, async function dialAndListenTLS(): Promise<
|
||||||
// TODO(bartlomieju): this might be a bug
|
// TODO(bartlomieju): this might be a bug
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
conn.close();
|
conn.close();
|
||||||
|
resolvable.resolve();
|
||||||
}, 0);
|
}, 0);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -196,4 +204,6 @@ testPerm({ read: true, net: true }, async function dialAndListenTLS(): Promise<
|
||||||
await r.readFull(bodyBuf);
|
await r.readFull(bodyBuf);
|
||||||
assertEquals(decoder.decode(bodyBuf), "Hello World\n");
|
assertEquals(decoder.decode(bodyBuf), "Hello World\n");
|
||||||
conn.close();
|
conn.close();
|
||||||
|
listener.close();
|
||||||
|
await resolvable;
|
||||||
});
|
});
|
||||||
|
|
|
@ -7,6 +7,7 @@ testPerm({ read: true }, function isatty(): void {
|
||||||
// CI not under TTY, so cannot test stdin/stdout/stderr.
|
// CI not under TTY, so cannot test stdin/stdout/stderr.
|
||||||
const f = Deno.openSync("cli/tests/hello.txt");
|
const f = Deno.openSync("cli/tests/hello.txt");
|
||||||
assert(!Deno.isatty(f.rid));
|
assert(!Deno.isatty(f.rid));
|
||||||
|
f.close();
|
||||||
});
|
});
|
||||||
|
|
||||||
test(function isattyError(): void {
|
test(function isattyError(): void {
|
||||||
|
|
|
@ -1,23 +1,11 @@
|
||||||
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
|
||||||
import { test, testPerm, assert, assertEquals } from "./test_util.ts";
|
import {
|
||||||
|
test,
|
||||||
export interface ResolvableMethods<T> {
|
testPerm,
|
||||||
resolve: (value?: T | PromiseLike<T>) => void;
|
assert,
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
assertEquals,
|
||||||
reject: (reason?: any) => void;
|
createResolvable
|
||||||
}
|
} from "./test_util.ts";
|
||||||
|
|
||||||
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(async function workersBasic(): Promise<void> {
|
test(async function workersBasic(): Promise<void> {
|
||||||
const promise = createResolvable();
|
const promise = createResolvable();
|
||||||
|
|
Loading…
Add table
Reference in a new issue