move js unit tests to cli/tests (#5678)

This commit is contained in:
Ryan Dahl 2020-05-20 17:52:51 -04:00 committed by GitHub
parent 49dda23f6b
commit 30702e2678
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
71 changed files with 14 additions and 14 deletions

View file

@ -1,80 +0,0 @@
# Deno runtime tests
Files in this directory are unit tests for Deno runtime.
They are run under compiled Deno binary as opposed to files in `cli/js/` which
are bundled and snapshotted using `deno_typescript` crate.
Testing Deno runtime code requires checking API under different runtime
permissions (ie. running with different `--allow-*` flags). To accomplish this
all tests exercised are created using `unitTest()` function.
```
import { unitTest } from "./test_util.ts";
unitTest(function simpleTestFn(): void {
// test code here
});
unitTest({
ignore: Deno.build.os === "windows",
perms: { read: true, write: true },
},
function complexTestFn(): void {
// test code here
}
);
```
`unitTest` is is a wrapper function that enhances `Deno.test()` API in several
ways:
- ability to conditionally skip tests using `UnitTestOptions.skip`
- ability to register required set of permissions for given test case using
`UnitTestOptions.perms`
- sanitization of resources - ensuring that tests close all opened resources
preventing interference between tests
- sanitization of async ops - ensuring that tests don't leak async ops by
ensuring that all started async ops are done before test finishes
## Running tests
`unit_test_runner.ts` is the main script used to run unit tests.
Runner discovers required permissions combinations by loading
`cli/js/tests/unit_tests.ts` and going through all registered instances of
`unitTest`.
There are three ways to run `unit_test_runner.ts`:
```
# Run all tests. Spawns worker processes for each discovered permission
# combination:
target/debug/deno run -A cli/js/tests/unit_test_runner.ts --master
# By default all output of worker processes is discarded; for debug purposes
# the --verbose flag preserves output from the worker
target/debug/deno run -A cli/js/tests/unit_test_runner.ts --master --verbose
# Run subset of tests that don't require any permissions
target/debug/deno run --unstable cli/js/tests/unit_test_runner.ts
# Run subset tests that require "net" and "read" permissions
target/debug/deno run --unstable --allow-net --allow-read cli/js/tests/unit_test_runner.ts
# "worker" mode communicates with parent using TCP socket on provided address;
# after initial setup drops permissions to specified set. It shouldn't be used
# directly, only be "master" process.
target/debug/deno run -A cli/js/tests/unit_test_runner.ts --worker --addr=127.0.0.1:4500 --perms=net,write,run
# Run specific tests
target/debug/deno run --unstable --allow-net cli/js/tests/unit_test_runner.ts -- netTcpListenClose
RUST_BACKTRACE=1 cargo run -- run --unstable --allow-read --allow-write cli/js/tests/unit_test_runner.ts -- netUnixDialListen
```
### Http server
`tools/http_server.py` is required to run when one's running unit tests. During
CI it's spawned automatically, but if you want to run tests manually make sure
that server is spawned otherwise there'll be cascade of test failures.

View file

@ -1,56 +0,0 @@
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(function basicAbortController() {
const controller = new AbortController();
assert(controller);
const { signal } = controller;
assert(signal);
assertEquals(signal.aborted, false);
controller.abort();
assertEquals(signal.aborted, true);
});
unitTest(function signalCallsOnabort() {
const controller = new AbortController();
const { signal } = controller;
let called = false;
signal.onabort = (evt): void => {
assert(evt);
assertEquals(evt.type, "abort");
called = true;
};
controller.abort();
assert(called);
});
unitTest(function signalEventListener() {
const controller = new AbortController();
const { signal } = controller;
let called = false;
signal.addEventListener("abort", function (ev) {
assert(this === signal);
assertEquals(ev.type, "abort");
called = true;
});
controller.abort();
assert(called);
});
unitTest(function onlyAbortsOnce() {
const controller = new AbortController();
const { signal } = controller;
let called = 0;
signal.addEventListener("abort", () => called++);
signal.onabort = (): void => {
called++;
};
controller.abort();
assertEquals(called, 2);
controller.abort();
assertEquals(called, 2);
});
unitTest(function controllerHasProperToString() {
const actual = Object.prototype.toString.call(new AbortController());
assertEquals(actual, "[object AbortController]");
});

View file

@ -1,92 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
import { concat } from "../../../std/bytes/mod.ts";
import { decode } from "../../../std/encoding/utf8.ts";
unitTest(function blobString(): void {
const b1 = new Blob(["Hello World"]);
const str = "Test";
const b2 = new Blob([b1, str]);
assertEquals(b2.size, b1.size + str.length);
});
unitTest(function blobBuffer(): void {
const buffer = new ArrayBuffer(12);
const u8 = new Uint8Array(buffer);
const f1 = new Float32Array(buffer);
const b1 = new Blob([buffer, u8]);
assertEquals(b1.size, 2 * u8.length);
const b2 = new Blob([b1, f1]);
assertEquals(b2.size, 3 * u8.length);
});
unitTest(function blobSlice(): void {
const blob = new Blob(["Deno", "Foo"]);
const b1 = blob.slice(0, 3, "Text/HTML");
assert(b1 instanceof Blob);
assertEquals(b1.size, 3);
assertEquals(b1.type, "text/html");
const b2 = blob.slice(-1, 3);
assertEquals(b2.size, 0);
const b3 = blob.slice(100, 3);
assertEquals(b3.size, 0);
const b4 = blob.slice(0, 10);
assertEquals(b4.size, blob.size);
});
unitTest(function blobInvalidType(): void {
const blob = new Blob(["foo"], {
type: "\u0521",
});
assertEquals(blob.type, "");
});
unitTest(function blobShouldNotThrowError(): void {
let hasThrown = false;
try {
const options1: object = {
ending: "utf8",
hasOwnProperty: "hasOwnProperty",
};
const options2: object = Object.create(null);
new Blob(["Hello World"], options1);
new Blob(["Hello World"], options2);
} catch {
hasThrown = true;
}
assertEquals(hasThrown, false);
});
unitTest(function nativeEndLine(): void {
const options: object = {
ending: "native",
};
const blob = new Blob(["Hello\nWorld"], options);
assertEquals(blob.size, Deno.build.os === "windows" ? 12 : 11);
});
unitTest(async function blobText(): Promise<void> {
const blob = new Blob(["Hello World"]);
assertEquals(await blob.text(), "Hello World");
});
unitTest(async function blobStream(): Promise<void> {
const blob = new Blob(["Hello World"]);
const stream = blob.stream();
assert(stream instanceof ReadableStream);
const reader = stream.getReader();
let bytes = new Uint8Array();
const read = async (): Promise<void> => {
const { done, value } = await reader.read();
if (!done && value) {
bytes = concat(bytes, value);
return read();
}
};
await read();
assertEquals(decode(bytes), "Hello World");
});

View file

@ -1,74 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals, assert } from "./test_util.ts";
// just a hack to get a body object
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function buildBody(body: any): Body {
const stub = new Request("", {
body: body,
});
return stub as Body;
}
const intArrays = [
Int8Array,
Int16Array,
Int32Array,
Uint8Array,
Uint16Array,
Uint32Array,
Uint8ClampedArray,
Float32Array,
Float64Array,
];
unitTest(async function arrayBufferFromByteArrays(): Promise<void> {
const buffer = new TextEncoder().encode("ahoyhoy8").buffer;
for (const type of intArrays) {
const body = buildBody(new type(buffer));
const text = new TextDecoder("utf-8").decode(await body.arrayBuffer());
assertEquals(text, "ahoyhoy8");
}
});
//FormData
unitTest(
{ perms: { net: true } },
async function bodyMultipartFormData(): Promise<void> {
const response = await fetch(
"http://localhost:4545/cli/tests/subdir/multipart_form_data.txt"
);
const text = await response.text();
const body = buildBody(text);
// @ts-ignore
body.contentType = "multipart/form-data;boundary=boundary";
const formData = await body.formData();
assert(formData.has("field_1"));
assertEquals(formData.get("field_1")!.toString(), "value_1 \r\n");
assert(formData.has("field_2"));
}
);
unitTest(
{ perms: { net: true } },
async function bodyURLEncodedFormData(): Promise<void> {
const response = await fetch(
"http://localhost:4545/cli/tests/subdir/form_urlencoded.txt"
);
const text = await response.text();
const body = buildBody(text);
// @ts-ignore
body.contentType = "application/x-www-form-urlencoded";
const formData = await body.formData();
assert(formData.has("field_1"));
assertEquals(formData.get("field_1")!.toString(), "Hi");
assert(formData.has("field_2"));
assertEquals(formData.get("field_2")!.toString(), "<Deno>");
}
);

View file

@ -1,294 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// This code has been ported almost directly from Go's src/bytes/buffer_test.go
// Copyright 2009 The Go Authors. All rights reserved. BSD license.
// https://github.com/golang/go/blob/master/LICENSE
import {
assertEquals,
assert,
assertStrContains,
unitTest,
} from "./test_util.ts";
const { Buffer, readAll, readAllSync, writeAll, writeAllSync } = Deno;
type Buffer = Deno.Buffer;
// N controls how many iterations of certain checks are performed.
const N = 100;
let testBytes: Uint8Array | null;
let testString: string | null;
function init(): void {
if (testBytes == null) {
testBytes = new Uint8Array(N);
for (let i = 0; i < N; i++) {
testBytes[i] = "a".charCodeAt(0) + (i % 26);
}
const decoder = new TextDecoder();
testString = decoder.decode(testBytes);
}
}
function check(buf: Deno.Buffer, s: string): void {
const bytes = buf.bytes();
assertEquals(buf.length, bytes.byteLength);
const decoder = new TextDecoder();
const bytesStr = decoder.decode(bytes);
assertEquals(bytesStr, s);
assertEquals(buf.length, s.length);
}
// Fill buf through n writes of byte slice fub.
// The initial contents of buf corresponds to the string s;
// the result is the final contents of buf returned as a string.
async function fillBytes(
buf: Buffer,
s: string,
n: number,
fub: Uint8Array
): Promise<string> {
check(buf, s);
for (; n > 0; n--) {
const m = await buf.write(fub);
assertEquals(m, fub.byteLength);
const decoder = new TextDecoder();
s += decoder.decode(fub);
check(buf, s);
}
return s;
}
// Empty buf through repeated reads into fub.
// The initial contents of buf corresponds to the string s.
async function empty(buf: Buffer, s: string, fub: Uint8Array): Promise<void> {
check(buf, s);
while (true) {
const r = await buf.read(fub);
if (r === null) {
break;
}
s = s.slice(r);
check(buf, s);
}
check(buf, "");
}
function repeat(c: string, bytes: number): Uint8Array {
assertEquals(c.length, 1);
const ui8 = new Uint8Array(bytes);
ui8.fill(c.charCodeAt(0));
return ui8;
}
unitTest(function bufferNewBuffer(): void {
init();
assert(testBytes);
assert(testString);
const buf = new Buffer(testBytes.buffer as ArrayBuffer);
check(buf, testString);
});
unitTest(async function bufferBasicOperations(): Promise<void> {
init();
assert(testBytes);
assert(testString);
const buf = new Buffer();
for (let i = 0; i < 5; i++) {
check(buf, "");
buf.reset();
check(buf, "");
buf.truncate(0);
check(buf, "");
let n = await buf.write(testBytes.subarray(0, 1));
assertEquals(n, 1);
check(buf, "a");
n = await buf.write(testBytes.subarray(1, 2));
assertEquals(n, 1);
check(buf, "ab");
n = await buf.write(testBytes.subarray(2, 26));
assertEquals(n, 24);
check(buf, testString.slice(0, 26));
buf.truncate(26);
check(buf, testString.slice(0, 26));
buf.truncate(20);
check(buf, testString.slice(0, 20));
await empty(buf, testString.slice(0, 20), new Uint8Array(5));
await empty(buf, "", new Uint8Array(100));
// TODO buf.writeByte()
// TODO buf.readByte()
}
});
unitTest(async function bufferReadEmptyAtEOF(): Promise<void> {
// check that EOF of 'buf' is not reached (even though it's empty) if
// results are written to buffer that has 0 length (ie. it can't store any data)
const buf = new Buffer();
const zeroLengthTmp = new Uint8Array(0);
const result = await buf.read(zeroLengthTmp);
assertEquals(result, 0);
});
unitTest(async function bufferLargeByteWrites(): Promise<void> {
init();
const buf = new Buffer();
const limit = 9;
for (let i = 3; i < limit; i += 3) {
const s = await fillBytes(buf, "", 5, testBytes!);
await empty(buf, s, new Uint8Array(Math.floor(testString!.length / i)));
}
check(buf, "");
});
unitTest(async function bufferTooLargeByteWrites(): Promise<void> {
init();
const tmp = new Uint8Array(72);
const growLen = Number.MAX_VALUE;
const xBytes = repeat("x", 0);
const buf = new Buffer(xBytes.buffer as ArrayBuffer);
await buf.read(tmp);
let err;
try {
buf.grow(growLen);
} catch (e) {
err = e;
}
assert(err instanceof Error);
assertStrContains(err.message, "grown beyond the maximum size");
});
unitTest(async function bufferLargeByteReads(): Promise<void> {
init();
assert(testBytes);
assert(testString);
const buf = new Buffer();
for (let i = 3; i < 30; i += 3) {
const n = Math.floor(testBytes.byteLength / i);
const s = await fillBytes(buf, "", 5, testBytes.subarray(0, n));
await empty(buf, s, new Uint8Array(testString.length));
}
check(buf, "");
});
unitTest(function bufferCapWithPreallocatedSlice(): void {
const buf = new Buffer(new ArrayBuffer(10));
assertEquals(buf.capacity, 10);
});
unitTest(async function bufferReadFrom(): Promise<void> {
init();
assert(testBytes);
assert(testString);
const buf = new Buffer();
for (let i = 3; i < 30; i += 3) {
const s = await fillBytes(
buf,
"",
5,
testBytes.subarray(0, Math.floor(testBytes.byteLength / i))
);
const b = new Buffer();
await b.readFrom(buf);
const fub = new Uint8Array(testString.length);
await empty(b, s, fub);
}
});
unitTest(async function bufferReadFromSync(): Promise<void> {
init();
assert(testBytes);
assert(testString);
const buf = new Buffer();
for (let i = 3; i < 30; i += 3) {
const s = await fillBytes(
buf,
"",
5,
testBytes.subarray(0, Math.floor(testBytes.byteLength / i))
);
const b = new Buffer();
b.readFromSync(buf);
const fub = new Uint8Array(testString.length);
await empty(b, s, fub);
}
});
unitTest(async function bufferTestGrow(): Promise<void> {
const tmp = new Uint8Array(72);
for (const startLen of [0, 100, 1000, 10000, 100000]) {
const xBytes = repeat("x", startLen);
for (const growLen of [0, 100, 1000, 10000, 100000]) {
const buf = new Buffer(xBytes.buffer as ArrayBuffer);
// If we read, this affects buf.off, which is good to test.
const nread = (await buf.read(tmp)) ?? 0;
buf.grow(growLen);
const yBytes = repeat("y", growLen);
await buf.write(yBytes);
// Check that buffer has correct data.
assertEquals(
buf.bytes().subarray(0, startLen - nread),
xBytes.subarray(nread)
);
assertEquals(
buf.bytes().subarray(startLen - nread, startLen - nread + growLen),
yBytes
);
}
}
});
unitTest(async function testReadAll(): Promise<void> {
init();
assert(testBytes);
const reader = new Buffer(testBytes.buffer as ArrayBuffer);
const actualBytes = await readAll(reader);
assertEquals(testBytes.byteLength, actualBytes.byteLength);
for (let i = 0; i < testBytes.length; ++i) {
assertEquals(testBytes[i], actualBytes[i]);
}
});
unitTest(function testReadAllSync(): void {
init();
assert(testBytes);
const reader = new Buffer(testBytes.buffer as ArrayBuffer);
const actualBytes = readAllSync(reader);
assertEquals(testBytes.byteLength, actualBytes.byteLength);
for (let i = 0; i < testBytes.length; ++i) {
assertEquals(testBytes[i], actualBytes[i]);
}
});
unitTest(async function testWriteAll(): Promise<void> {
init();
assert(testBytes);
const writer = new Buffer();
await writeAll(writer, testBytes);
const actualBytes = writer.bytes();
assertEquals(testBytes.byteLength, actualBytes.byteLength);
for (let i = 0; i < testBytes.length; ++i) {
assertEquals(testBytes[i], actualBytes[i]);
}
});
unitTest(function testWriteAllSync(): void {
init();
assert(testBytes);
const writer = new Buffer();
writeAllSync(writer, testBytes);
const actualBytes = writer.bytes();
assertEquals(testBytes.byteLength, actualBytes.byteLength);
for (let i = 0; i < testBytes.length; ++i) {
assertEquals(testBytes[i], actualBytes[i]);
}
});

View file

@ -1,10 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
unitTest(function buildInfo(): void {
// Deno.build is injected by rollup at compile time. Here
// we check it has been properly transformed.
const { arch, os } = Deno.build;
assert(arch.length > 0);
assert(os === "darwin" || os === "windows" || os === "linux");
});

View file

@ -1,149 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
function chmodSyncSuccess(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const tempDir = Deno.makeTempDirSync();
const filename = tempDir + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
Deno.chmodSync(filename, 0o777);
const fileInfo = Deno.statSync(filename);
assert(fileInfo.mode);
assertEquals(fileInfo.mode & 0o777, 0o777);
}
);
// Check symlink when not on windows
unitTest(
{
ignore: Deno.build.os === "windows",
perms: { read: true, write: true },
},
function chmodSyncSymlinkSuccess(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const tempDir = Deno.makeTempDirSync();
const filename = tempDir + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const symlinkName = tempDir + "/test_symlink.txt";
Deno.symlinkSync(filename, symlinkName);
let symlinkInfo = Deno.lstatSync(symlinkName);
assert(symlinkInfo.mode);
const symlinkMode = symlinkInfo.mode & 0o777; // platform dependent
Deno.chmodSync(symlinkName, 0o777);
// Change actual file mode, not symlink
const fileInfo = Deno.statSync(filename);
assert(fileInfo.mode);
assertEquals(fileInfo.mode & 0o777, 0o777);
symlinkInfo = Deno.lstatSync(symlinkName);
assert(symlinkInfo.mode);
assertEquals(symlinkInfo.mode & 0o777, symlinkMode);
}
);
unitTest({ perms: { write: true } }, function chmodSyncFailure(): void {
let err;
try {
const filename = "/badfile.txt";
Deno.chmodSync(filename, 0o777);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
});
unitTest({ perms: { write: false } }, function chmodSyncPerm(): void {
let err;
try {
Deno.chmodSync("/somefile.txt", 0o777);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
async function chmodSuccess(): Promise<void> {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const tempDir = Deno.makeTempDirSync();
const filename = tempDir + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
await Deno.chmod(filename, 0o777);
const fileInfo = Deno.statSync(filename);
assert(fileInfo.mode);
assertEquals(fileInfo.mode & 0o777, 0o777);
}
);
// Check symlink when not on windows
unitTest(
{
ignore: Deno.build.os === "windows",
perms: { read: true, write: true },
},
async function chmodSymlinkSuccess(): Promise<void> {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const tempDir = Deno.makeTempDirSync();
const filename = tempDir + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const symlinkName = tempDir + "/test_symlink.txt";
Deno.symlinkSync(filename, symlinkName);
let symlinkInfo = Deno.lstatSync(symlinkName);
assert(symlinkInfo.mode);
const symlinkMode = symlinkInfo.mode & 0o777; // platform dependent
await Deno.chmod(symlinkName, 0o777);
// Just change actual file mode, not symlink
const fileInfo = Deno.statSync(filename);
assert(fileInfo.mode);
assertEquals(fileInfo.mode & 0o777, 0o777);
symlinkInfo = Deno.lstatSync(symlinkName);
assert(symlinkInfo.mode);
assertEquals(symlinkInfo.mode & 0o777, symlinkMode);
}
);
unitTest({ perms: { write: true } }, async function chmodFailure(): Promise<
void
> {
let err;
try {
const filename = "/badfile.txt";
await Deno.chmod(filename, 0o777);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
});
unitTest({ perms: { write: false } }, async function chmodPerm(): Promise<
void
> {
let err;
try {
await Deno.chmod("/somefile.txt", 0o777);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});

View file

@ -1,147 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals, assert } from "./test_util.ts";
// chown on Windows is noop for now, so ignore its testing on Windows
if (Deno.build.os !== "windows") {
async function getUidAndGid(): Promise<{ uid: number; gid: number }> {
// get the user ID and group ID of the current process
const uidProc = Deno.run({
stdout: "piped",
cmd: ["python", "-c", "import os; print(os.getuid())"],
});
const gidProc = Deno.run({
stdout: "piped",
cmd: ["python", "-c", "import os; print(os.getgid())"],
});
assertEquals((await uidProc.status()).code, 0);
assertEquals((await gidProc.status()).code, 0);
const uid = parseInt(
new TextDecoder("utf-8").decode(await uidProc.output())
);
uidProc.close();
const gid = parseInt(
new TextDecoder("utf-8").decode(await gidProc.output())
);
gidProc.close();
return { uid, gid };
}
unitTest(async function chownNoWritePermission(): Promise<void> {
const filePath = "chown_test_file.txt";
try {
await Deno.chown(filePath, 1000, 1000);
} catch (e) {
assert(e instanceof Deno.errors.PermissionDenied);
}
});
unitTest(
{ perms: { run: true, write: true } },
async function chownSyncFileNotExist(): Promise<void> {
const { uid, gid } = await getUidAndGid();
const filePath = Deno.makeTempDirSync() + "/chown_test_file.txt";
try {
Deno.chownSync(filePath, uid, gid);
} catch (e) {
assert(e instanceof Deno.errors.NotFound);
}
}
);
unitTest(
{ perms: { run: true, write: true } },
async function chownFileNotExist(): Promise<void> {
const { uid, gid } = await getUidAndGid();
const filePath = (await Deno.makeTempDir()) + "/chown_test_file.txt";
try {
await Deno.chown(filePath, uid, gid);
} catch (e) {
assert(e instanceof Deno.errors.NotFound);
}
}
);
unitTest(
{ perms: { write: true } },
function chownSyncPermissionDenied(): void {
const enc = new TextEncoder();
const dirPath = Deno.makeTempDirSync();
const filePath = dirPath + "/chown_test_file.txt";
const fileData = enc.encode("Hello");
Deno.writeFileSync(filePath, fileData);
try {
// try changing the file's owner to root
Deno.chownSync(filePath, 0, 0);
} catch (e) {
assert(e instanceof Deno.errors.PermissionDenied);
}
Deno.removeSync(dirPath, { recursive: true });
}
);
unitTest(
{ perms: { write: true } },
async function chownPermissionDenied(): Promise<void> {
const enc = new TextEncoder();
const dirPath = await Deno.makeTempDir();
const filePath = dirPath + "/chown_test_file.txt";
const fileData = enc.encode("Hello");
await Deno.writeFile(filePath, fileData);
try {
// try changing the file's owner to root
await Deno.chown(filePath, 0, 0);
} catch (e) {
assert(e instanceof Deno.errors.PermissionDenied);
}
await Deno.remove(dirPath, { recursive: true });
}
);
unitTest(
{ perms: { run: true, write: true } },
async function chownSyncSucceed(): Promise<void> {
// TODO: when a file's owner is actually being changed,
// chown only succeeds if run under priviledged user (root)
// The test script has no such privilege, so need to find a better way to test this case
const { uid, gid } = await getUidAndGid();
const enc = new TextEncoder();
const dirPath = Deno.makeTempDirSync();
const filePath = dirPath + "/chown_test_file.txt";
const fileData = enc.encode("Hello");
Deno.writeFileSync(filePath, fileData);
// the test script creates this file with the same uid and gid,
// here chown is a noop so it succeeds under non-priviledged user
Deno.chownSync(filePath, uid, gid);
Deno.removeSync(dirPath, { recursive: true });
}
);
unitTest(
{ perms: { run: true, write: true } },
async function chownSucceed(): Promise<void> {
// TODO: same as chownSyncSucceed
const { uid, gid } = await getUidAndGid();
const enc = new TextEncoder();
const dirPath = await Deno.makeTempDir();
const filePath = dirPath + "/chown_test_file.txt";
const fileData = enc.encode("Hello");
await Deno.writeFile(filePath, fileData);
// the test script creates this file with the same uid and gid,
// here chown is a noop so it succeeds under non-priviledged user
await Deno.chown(filePath, uid, gid);
Deno.removeSync(dirPath, { recursive: true });
}
);
}

File diff suppressed because it is too large Load diff

View file

@ -1,176 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
function readFileString(filename: string): string {
const dataRead = Deno.readFileSync(filename);
const dec = new TextDecoder("utf-8");
return dec.decode(dataRead);
}
function writeFileString(filename: string, s: string): void {
const enc = new TextEncoder();
const data = enc.encode(s);
Deno.writeFileSync(filename, data, { mode: 0o666 });
}
function assertSameContent(filename1: string, filename2: string): void {
const data1 = Deno.readFileSync(filename1);
const data2 = Deno.readFileSync(filename2);
assertEquals(data1, data2);
}
unitTest(
{ perms: { read: true, write: true } },
function copyFileSyncSuccess(): void {
const tempDir = Deno.makeTempDirSync();
const fromFilename = tempDir + "/from.txt";
const toFilename = tempDir + "/to.txt";
writeFileString(fromFilename, "Hello world!");
Deno.copyFileSync(fromFilename, toFilename);
// No change to original file
assertEquals(readFileString(fromFilename), "Hello world!");
// Original == Dest
assertSameContent(fromFilename, toFilename);
}
);
unitTest(
{ perms: { write: true, read: true } },
function copyFileSyncFailure(): void {
const tempDir = Deno.makeTempDirSync();
const fromFilename = tempDir + "/from.txt";
const toFilename = tempDir + "/to.txt";
// We skip initial writing here, from.txt does not exist
let err;
try {
Deno.copyFileSync(fromFilename, toFilename);
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: false } },
function copyFileSyncPerm1(): void {
let caughtError = false;
try {
Deno.copyFileSync("/from.txt", "/to.txt");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
}
);
unitTest(
{ perms: { write: false, read: true } },
function copyFileSyncPerm2(): void {
let caughtError = false;
try {
Deno.copyFileSync("/from.txt", "/to.txt");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
}
);
unitTest(
{ perms: { read: true, write: true } },
function copyFileSyncOverwrite(): void {
const tempDir = Deno.makeTempDirSync();
const fromFilename = tempDir + "/from.txt";
const toFilename = tempDir + "/to.txt";
writeFileString(fromFilename, "Hello world!");
// Make Dest exist and have different content
writeFileString(toFilename, "Goodbye!");
Deno.copyFileSync(fromFilename, toFilename);
// No change to original file
assertEquals(readFileString(fromFilename), "Hello world!");
// Original == Dest
assertSameContent(fromFilename, toFilename);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function copyFileSuccess(): Promise<void> {
const tempDir = Deno.makeTempDirSync();
const fromFilename = tempDir + "/from.txt";
const toFilename = tempDir + "/to.txt";
writeFileString(fromFilename, "Hello world!");
await Deno.copyFile(fromFilename, toFilename);
// No change to original file
assertEquals(readFileString(fromFilename), "Hello world!");
// Original == Dest
assertSameContent(fromFilename, toFilename);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function copyFileFailure(): Promise<void> {
const tempDir = Deno.makeTempDirSync();
const fromFilename = tempDir + "/from.txt";
const toFilename = tempDir + "/to.txt";
// We skip initial writing here, from.txt does not exist
let err;
try {
await Deno.copyFile(fromFilename, toFilename);
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function copyFileOverwrite(): Promise<void> {
const tempDir = Deno.makeTempDirSync();
const fromFilename = tempDir + "/from.txt";
const toFilename = tempDir + "/to.txt";
writeFileString(fromFilename, "Hello world!");
// Make Dest exist and have different content
writeFileString(toFilename, "Goodbye!");
await Deno.copyFile(fromFilename, toFilename);
// No change to original file
assertEquals(readFileString(fromFilename), "Hello world!");
// Original == Dest
assertSameContent(fromFilename, toFilename);
}
);
unitTest(
{ perms: { read: false, write: true } },
async function copyFilePerm1(): Promise<void> {
let caughtError = false;
try {
await Deno.copyFile("/from.txt", "/to.txt");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
}
);
unitTest(
{ perms: { read: true, write: false } },
async function copyFilePerm2(): Promise<void> {
let caughtError = false;
try {
await Deno.copyFile("/from.txt", "/to.txt");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
}
);

View file

@ -1,27 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals } from "./test_util.ts";
unitTest(function customEventInitializedWithDetail(): void {
const type = "touchstart";
const detail = { message: "hello" };
const customEventInit = {
bubbles: true,
cancelable: true,
detail,
} as CustomEventInit;
const event = new CustomEvent(type, customEventInit);
assertEquals(event.bubbles, true);
assertEquals(event.cancelable, true);
assertEquals(event.currentTarget, null);
assertEquals(event.detail, detail);
assertEquals(event.isTrusted, false);
assertEquals(event.target, null);
assertEquals(event.type, type);
});
unitTest(function toStringShouldBeWebCompatibility(): void {
const type = "touchstart";
const event = new CustomEvent(type, {});
assertEquals(event.toString(), "[object CustomEvent]");
});

View file

@ -1,60 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest({ perms: { read: true } }, function dirCwdNotNull(): void {
assert(Deno.cwd() != null);
});
unitTest(
{ perms: { read: true, write: true } },
function dirCwdChdirSuccess(): void {
const initialdir = Deno.cwd();
const path = Deno.makeTempDirSync();
Deno.chdir(path);
const current = Deno.cwd();
if (Deno.build.os === "darwin") {
assertEquals(current, "/private" + path);
} else {
assertEquals(current, path);
}
Deno.chdir(initialdir);
}
);
unitTest({ perms: { read: true, write: true } }, function dirCwdError(): void {
// excluding windows since it throws resource busy, while removeSync
if (["linux", "darwin"].includes(Deno.build.os)) {
const initialdir = Deno.cwd();
const path = Deno.makeTempDirSync();
Deno.chdir(path);
Deno.removeSync(path);
try {
Deno.cwd();
throw Error("current directory removed, should throw error");
} catch (err) {
if (err instanceof Deno.errors.NotFound) {
assert(err.name === "NotFound");
} else {
throw Error("raised different exception");
}
}
Deno.chdir(initialdir);
}
});
unitTest(
{ perms: { read: true, write: true } },
function dirChdirError(): void {
const path = Deno.makeTempDirSync() + "test";
try {
Deno.chdir(path);
throw Error("directory not available, should throw error");
} catch (err) {
if (err instanceof Deno.errors.NotFound) {
assert(err.name === "NotFound");
} else {
throw Error("raised different exception");
}
}
}
);

View file

@ -1,32 +0,0 @@
import { assert, unitTest, assertMatch, unreachable } from "./test_util.ts";
const openErrorStackPattern = new RegExp(
`^.*
at unwrapResponse \\(.*dispatch_json\\.ts:.*\\)
at Object.sendAsync \\(.*dispatch_json\\.ts:.*\\)
at async Object\\.open \\(.*files\\.ts:.*\\).*$`,
"ms"
);
unitTest(
{ perms: { read: true } },
async function sendAsyncStackTrace(): Promise<void> {
await Deno.open("nonexistent.txt")
.then(unreachable)
.catch((error): void => {
assertMatch(error.stack, openErrorStackPattern);
});
}
);
unitTest(function malformedJsonControlBuffer(): void {
// @ts-ignore
const opId = Deno.core.ops()["op_open"];
// @ts-ignore
const res = Deno.core.send(opId, new Uint8Array([1, 2, 3, 4, 5]));
const resText = new TextDecoder().decode(res);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const resJson = JSON.parse(resText) as any;
assert(!resJson.ok);
assert(resJson.err);
});

View file

@ -1,43 +0,0 @@
import {
assert,
assertEquals,
assertMatch,
unitTest,
unreachable,
} from "./test_util.ts";
const readErrorStackPattern = new RegExp(
`^.*
at unwrapResponse \\(.*dispatch_minimal\\.ts:.*\\)
at Object.sendAsyncMinimal \\(.*dispatch_minimal\\.ts:.*\\)
at async Object\\.read \\(.*io\\.ts:.*\\).*$`,
"ms"
);
unitTest(async function sendAsyncStackTrace(): Promise<void> {
const buf = new Uint8Array(10);
const rid = 10;
try {
await Deno.read(rid, buf);
unreachable();
} catch (error) {
assertMatch(error.stack, readErrorStackPattern);
}
});
unitTest(function malformedMinimalControlBuffer(): void {
// @ts-ignore
const readOpId = Deno.core.ops()["op_read"];
// @ts-ignore
const res = Deno.core.send(readOpId, new Uint8Array([1, 2, 3, 4, 5]));
const header = res.slice(0, 12);
const buf32 = new Int32Array(
header.buffer,
header.byteOffset,
header.byteLength / 4
);
const arg = buf32[1];
const message = new TextDecoder().decode(res.slice(12)).trim();
assert(arg < 0);
assertEquals(message, "Unparsable control buffer");
});

View file

@ -1,9 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals, assert } from "./test_util.ts";
unitTest(function testDomError() {
const de = new DOMException("foo", "bar");
assert(de);
assertEquals(de.message, "foo");
assertEquals(de.name, "bar");
});

View file

@ -1,87 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
function setup() {
const dataSymbol = Symbol("data symbol");
class Base {
[dataSymbol] = new Map<string, number>();
constructor(
data: Array<[string, number]> | IterableIterator<[string, number]>
) {
for (const [key, value] of data) {
this[dataSymbol].set(key, value);
}
}
}
return {
Base,
// This is using an internal API we don't want published as types, so having
// to cast to any to "trick" TypeScript
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol
DomIterable: Deno[Deno.internal].DomIterableMixin(Base, dataSymbol),
};
}
unitTest(function testDomIterable(): void {
const { DomIterable, Base } = setup();
const fixture: Array<[string, number]> = [
["foo", 1],
["bar", 2],
];
const domIterable = new DomIterable(fixture);
assertEquals(Array.from(domIterable.entries()), fixture);
assertEquals(Array.from(domIterable.values()), [1, 2]);
assertEquals(Array.from(domIterable.keys()), ["foo", "bar"]);
let result: Array<[string, number]> = [];
for (const [key, value] of domIterable) {
assert(key != null);
assert(value != null);
result.push([key, value]);
}
assertEquals(fixture, result);
result = [];
const scope = {};
function callback(
this: typeof scope,
value: number,
key: string,
parent: typeof domIterable
): void {
assertEquals(parent, domIterable);
assert(key != null);
assert(value != null);
assert(this === scope);
result.push([key, value]);
}
domIterable.forEach(callback, scope);
assertEquals(fixture, result);
assertEquals(DomIterable.name, Base.name);
});
unitTest(function testDomIterableScope(): void {
const { DomIterable } = setup();
const domIterable = new DomIterable([["foo", 1]]);
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function checkScope(thisArg: any, expected: any): void {
function callback(this: typeof thisArg): void {
assertEquals(this, expected);
}
domIterable.forEach(callback, thisArg);
}
checkScope(0, Object(0));
checkScope("", Object(""));
checkScope(null, window);
checkScope(undefined, window);
});

View file

@ -1,108 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol
const { setPrepareStackTrace } = Deno[Deno.internal];
interface CallSite {
getThis(): unknown;
getTypeName(): string | null;
getFunction(): Function | null;
getFunctionName(): string | null;
getMethodName(): string | null;
getFileName(): string | null;
getLineNumber(): number | null;
getColumnNumber(): number | null;
getEvalOrigin(): string | null;
isToplevel(): boolean | null;
isEval(): boolean;
isNative(): boolean;
isConstructor(): boolean;
isAsync(): boolean;
isPromiseAll(): boolean;
getPromiseIndex(): number | null;
}
function getMockCallSite(
fileName: string,
lineNumber: number | null,
columnNumber: number | null
): CallSite {
return {
getThis(): unknown {
return undefined;
},
getTypeName(): string {
return "";
},
getFunction(): Function {
return (): void => {};
},
getFunctionName(): string {
return "";
},
getMethodName(): string {
return "";
},
getFileName(): string {
return fileName;
},
getLineNumber(): number | null {
return lineNumber;
},
getColumnNumber(): number | null {
return columnNumber;
},
getEvalOrigin(): null {
return null;
},
isToplevel(): false {
return false;
},
isEval(): false {
return false;
},
isNative(): false {
return false;
},
isConstructor(): false {
return false;
},
isAsync(): false {
return false;
},
isPromiseAll(): false {
return false;
},
getPromiseIndex(): null {
return null;
},
};
}
unitTest(function prepareStackTrace(): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const MockError = {} as any;
setPrepareStackTrace(MockError);
assert(typeof MockError.prepareStackTrace === "function");
const prepareStackTrace: (
error: Error,
structuredStackTrace: CallSite[]
) => string = MockError.prepareStackTrace;
const result = prepareStackTrace(new Error("foo"), [
getMockCallSite("CLI_SNAPSHOT.js", 23, 0),
]);
assert(result.startsWith("Error: foo\n"));
assert(result.includes(".ts:"), "should remap to something in 'js/'");
});
unitTest(function applySourceMap(): void {
const result = Deno.applySourceMap({
fileName: "CLI_SNAPSHOT.js",
lineNumber: 23,
columnNumber: 0,
});
assert(result.fileName.endsWith(".ts"));
assert(result.lineNumber != null);
assert(result.columnNumber != null);
});

View file

@ -1,231 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals } from "./test_util.ts";
unitTest(function addEventListenerTest(): void {
const document = new EventTarget();
// @ts-ignore tests ignoring the type system for resilience
assertEquals(document.addEventListener("x", null, false), undefined);
// @ts-ignore
assertEquals(document.addEventListener("x", null, true), undefined);
// @ts-ignore
assertEquals(document.addEventListener("x", null), undefined);
});
unitTest(function constructedEventTargetCanBeUsedAsExpected(): void {
const target = new EventTarget();
const event = new Event("foo", { bubbles: true, cancelable: false });
let callCount = 0;
const listener = (e: Event): void => {
assertEquals(e, event);
++callCount;
};
target.addEventListener("foo", listener);
target.dispatchEvent(event);
assertEquals(callCount, 1);
target.dispatchEvent(event);
assertEquals(callCount, 2);
target.removeEventListener("foo", listener);
target.dispatchEvent(event);
assertEquals(callCount, 2);
});
unitTest(function anEventTargetCanBeSubclassed(): void {
class NicerEventTarget extends EventTarget {
on(
type: string,
callback: ((e: Event) => void) | null,
options?: AddEventListenerOptions
): void {
this.addEventListener(type, callback, options);
}
off(
type: string,
callback: ((e: Event) => void) | null,
options?: EventListenerOptions
): void {
this.removeEventListener(type, callback, options);
}
}
const target = new NicerEventTarget();
new Event("foo", { bubbles: true, cancelable: false });
let callCount = 0;
const listener = (): void => {
++callCount;
};
target.on("foo", listener);
assertEquals(callCount, 0);
target.off("foo", listener);
assertEquals(callCount, 0);
});
unitTest(function removingNullEventListenerShouldSucceed(): void {
const document = new EventTarget();
// @ts-ignore
assertEquals(document.removeEventListener("x", null, false), undefined);
// @ts-ignore
assertEquals(document.removeEventListener("x", null, true), undefined);
// @ts-ignore
assertEquals(document.removeEventListener("x", null), undefined);
});
unitTest(function constructedEventTargetUseObjectPrototype(): void {
const target = new EventTarget();
const event = new Event("toString", { bubbles: true, cancelable: false });
let callCount = 0;
const listener = (e: Event): void => {
assertEquals(e, event);
++callCount;
};
target.addEventListener("toString", listener);
target.dispatchEvent(event);
assertEquals(callCount, 1);
target.dispatchEvent(event);
assertEquals(callCount, 2);
target.removeEventListener("toString", listener);
target.dispatchEvent(event);
assertEquals(callCount, 2);
});
unitTest(function toStringShouldBeWebCompatible(): void {
const target = new EventTarget();
assertEquals(target.toString(), "[object EventTarget]");
});
unitTest(function dispatchEventShouldNotThrowError(): void {
let hasThrown = false;
try {
const target = new EventTarget();
const event = new Event("hasOwnProperty", {
bubbles: true,
cancelable: false,
});
const listener = (): void => {};
target.addEventListener("hasOwnProperty", listener);
target.dispatchEvent(event);
} catch {
hasThrown = true;
}
assertEquals(hasThrown, false);
});
unitTest(function eventTargetThisShouldDefaultToWindow(): void {
const {
addEventListener,
dispatchEvent,
removeEventListener,
} = EventTarget.prototype;
let n = 1;
const event = new Event("hello");
const listener = (): void => {
n = 2;
};
addEventListener("hello", listener);
window.dispatchEvent(event);
assertEquals(n, 2);
n = 1;
removeEventListener("hello", listener);
window.dispatchEvent(event);
assertEquals(n, 1);
window.addEventListener("hello", listener);
dispatchEvent(event);
assertEquals(n, 2);
n = 1;
window.removeEventListener("hello", listener);
dispatchEvent(event);
assertEquals(n, 1);
});
unitTest(function eventTargetShouldAcceptEventListenerObject(): void {
const target = new EventTarget();
const event = new Event("foo", { bubbles: true, cancelable: false });
let callCount = 0;
const listener = {
handleEvent(e: Event): void {
assertEquals(e, event);
++callCount;
},
};
target.addEventListener("foo", listener);
target.dispatchEvent(event);
assertEquals(callCount, 1);
target.dispatchEvent(event);
assertEquals(callCount, 2);
target.removeEventListener("foo", listener);
target.dispatchEvent(event);
assertEquals(callCount, 2);
});
unitTest(function eventTargetShouldAcceptAsyncFunction(): void {
const target = new EventTarget();
const event = new Event("foo", { bubbles: true, cancelable: false });
let callCount = 0;
const listener = (e: Event): void => {
assertEquals(e, event);
++callCount;
};
target.addEventListener("foo", listener);
target.dispatchEvent(event);
assertEquals(callCount, 1);
target.dispatchEvent(event);
assertEquals(callCount, 2);
target.removeEventListener("foo", listener);
target.dispatchEvent(event);
assertEquals(callCount, 2);
});
unitTest(
function eventTargetShouldAcceptAsyncFunctionForEventListenerObject(): void {
const target = new EventTarget();
const event = new Event("foo", { bubbles: true, cancelable: false });
let callCount = 0;
const listener = {
handleEvent(e: Event): void {
assertEquals(e, event);
++callCount;
},
};
target.addEventListener("foo", listener);
target.dispatchEvent(event);
assertEquals(callCount, 1);
target.dispatchEvent(event);
assertEquals(callCount, 2);
target.removeEventListener("foo", listener);
target.dispatchEvent(event);
assertEquals(callCount, 2);
}
);

View file

@ -1,94 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals, assert } from "./test_util.ts";
unitTest(function eventInitializedWithType(): void {
const type = "click";
const event = new Event(type);
assertEquals(event.isTrusted, false);
assertEquals(event.target, null);
assertEquals(event.currentTarget, null);
assertEquals(event.type, "click");
assertEquals(event.bubbles, false);
assertEquals(event.cancelable, false);
});
unitTest(function eventInitializedWithTypeAndDict(): void {
const init = "submit";
const eventInit = { bubbles: true, cancelable: true } as EventInit;
const event = new Event(init, eventInit);
assertEquals(event.isTrusted, false);
assertEquals(event.target, null);
assertEquals(event.currentTarget, null);
assertEquals(event.type, "submit");
assertEquals(event.bubbles, true);
assertEquals(event.cancelable, true);
});
unitTest(function eventComposedPathSuccess(): void {
const type = "click";
const event = new Event(type);
const composedPath = event.composedPath();
assertEquals(composedPath, []);
});
unitTest(function eventStopPropagationSuccess(): void {
const type = "click";
const event = new Event(type);
assertEquals(event.cancelBubble, false);
event.stopPropagation();
assertEquals(event.cancelBubble, true);
});
unitTest(function eventStopImmediatePropagationSuccess(): void {
const type = "click";
const event = new Event(type);
assertEquals(event.cancelBubble, false);
event.stopImmediatePropagation();
assertEquals(event.cancelBubble, true);
});
unitTest(function eventPreventDefaultSuccess(): void {
const type = "click";
const event = new Event(type);
assertEquals(event.defaultPrevented, false);
event.preventDefault();
assertEquals(event.defaultPrevented, false);
const eventInit = { bubbles: true, cancelable: true } as EventInit;
const cancelableEvent = new Event(type, eventInit);
assertEquals(cancelableEvent.defaultPrevented, false);
cancelableEvent.preventDefault();
assertEquals(cancelableEvent.defaultPrevented, true);
});
unitTest(function eventInitializedWithNonStringType(): void {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const type: any = undefined;
const event = new Event(type);
assertEquals(event.isTrusted, false);
assertEquals(event.target, null);
assertEquals(event.currentTarget, null);
assertEquals(event.type, "undefined");
assertEquals(event.bubbles, false);
assertEquals(event.cancelable, false);
});
// ref https://github.com/web-platform-tests/wpt/blob/master/dom/events/Event-isTrusted.any.js
unitTest(function eventIsTrusted(): void {
const desc1 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
assert(desc1);
assertEquals(typeof desc1.get, "function");
const desc2 = Object.getOwnPropertyDescriptor(new Event("x"), "isTrusted");
assert(desc2);
assertEquals(typeof desc2!.get, "function");
assertEquals(desc1!.get, desc2!.get);
});

View file

@ -1,534 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
unitTest,
assert,
assertEquals,
assertStrContains,
assertThrows,
fail,
} from "./test_util.ts";
unitTest({ perms: { net: true } }, async function fetchProtocolError(): Promise<
void
> {
let err;
try {
await fetch("file:///");
} catch (err_) {
err = err_;
}
assert(err instanceof TypeError);
assertStrContains(err.message, "not supported");
});
unitTest(
{ perms: { net: true } },
async function fetchConnectionError(): Promise<void> {
let err;
try {
await fetch("http://localhost:4000");
} catch (err_) {
err = err_;
}
assert(err instanceof Deno.errors.Http);
assertStrContains(err.message, "error trying to connect");
}
);
unitTest({ perms: { net: true } }, async function fetchJsonSuccess(): Promise<
void
> {
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
const json = await response.json();
assertEquals(json.name, "deno");
});
unitTest(async function fetchPerm(): Promise<void> {
let err;
try {
await fetch("http://localhost:4545/cli/tests/fixture.json");
} catch (err_) {
err = err_;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest({ perms: { net: true } }, async function fetchUrl(): Promise<void> {
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
assertEquals(response.url, "http://localhost:4545/cli/tests/fixture.json");
const _json = await response.json();
});
unitTest({ perms: { net: true } }, async function fetchURL(): Promise<void> {
const response = await fetch(
new URL("http://localhost:4545/cli/tests/fixture.json")
);
assertEquals(response.url, "http://localhost:4545/cli/tests/fixture.json");
const _json = await response.json();
});
unitTest({ perms: { net: true } }, async function fetchHeaders(): Promise<
void
> {
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
const headers = response.headers;
assertEquals(headers.get("Content-Type"), "application/json");
assert(headers.get("Server")!.startsWith("SimpleHTTP"));
const _json = await response.json();
});
unitTest({ perms: { net: true } }, async function fetchBlob(): Promise<void> {
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
const headers = response.headers;
const blob = await response.blob();
assertEquals(blob.type, headers.get("Content-Type"));
assertEquals(blob.size, Number(headers.get("Content-Length")));
});
unitTest({ perms: { net: true } }, async function fetchBodyUsed(): Promise<
void
> {
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
assertEquals(response.bodyUsed, false);
assertThrows((): void => {
// Assigning to read-only property throws in the strict mode.
// @ts-ignore
response.bodyUsed = true;
});
await response.blob();
assertEquals(response.bodyUsed, true);
});
// TODO(ry) response.body shouldn't be iterable. Instead we should use
// response.body.getReader().
/*
unitTest({ perms: { net: true } }, async function fetchAsyncIterator(): Promise<
void
> {
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
const headers = response.headers;
let total = 0;
for await (const chunk of response.body) {
total += chunk.length;
}
assertEquals(total, Number(headers.get("Content-Length")));
const _json = await response.json();
});
*/
unitTest({ perms: { net: true } }, async function responseClone(): Promise<
void
> {
const response = await fetch("http://localhost:4545/cli/tests/fixture.json");
const response1 = response.clone();
assert(response !== response1);
assertEquals(response.status, response1.status);
assertEquals(response.statusText, response1.statusText);
const u8a = new Uint8Array(await response.arrayBuffer());
const u8a1 = new Uint8Array(await response1.arrayBuffer());
for (let i = 0; i < u8a.byteLength; i++) {
assertEquals(u8a[i], u8a1[i]);
}
});
unitTest({ perms: { net: true } }, async function fetchEmptyInvalid(): Promise<
void
> {
let err;
try {
await fetch("");
} catch (err_) {
err = err_;
}
assert(err instanceof URIError);
});
unitTest(
{ perms: { net: true } },
async function fetchMultipartFormDataSuccess(): Promise<void> {
const response = await fetch(
"http://localhost:4545/cli/tests/subdir/multipart_form_data.txt"
);
const formData = await response.formData();
assert(formData.has("field_1"));
assertEquals(formData.get("field_1")!.toString(), "value_1 \r\n");
assert(formData.has("field_2"));
/* TODO(ry) Re-enable this test once we bring back the global File type.
const file = formData.get("field_2") as File;
assertEquals(file.name, "file.js");
*/
// Currently we cannot read from file...
}
);
unitTest(
{ perms: { net: true } },
async function fetchURLEncodedFormDataSuccess(): Promise<void> {
const response = await fetch(
"http://localhost:4545/cli/tests/subdir/form_urlencoded.txt"
);
const formData = await response.formData();
assert(formData.has("field_1"));
assertEquals(formData.get("field_1")!.toString(), "Hi");
assert(formData.has("field_2"));
assertEquals(formData.get("field_2")!.toString(), "<Deno>");
}
);
unitTest(
{
perms: { net: true },
},
async function fetchWithRedirection(): Promise<void> {
const response = await fetch("http://localhost:4546/"); // will redirect to http://localhost:4545/
assertEquals(response.status, 200);
assertEquals(response.statusText, "OK");
assertEquals(response.url, "http://localhost:4545/");
const body = await response.text();
assert(body.includes("<title>Directory listing for /</title>"));
}
);
unitTest(
{
perms: { net: true },
},
async function fetchWithRelativeRedirection(): Promise<void> {
const response = await fetch("http://localhost:4545/cli/tests"); // will redirect to /cli/tests/
assertEquals(response.status, 200);
assertEquals(response.statusText, "OK");
const body = await response.text();
assert(body.includes("<title>Directory listing for /cli/tests/</title>"));
}
);
unitTest(
{
// FIXME(bartlomieju):
// The feature below is not implemented, but the test should work after implementation
ignore: true,
perms: { net: true },
},
async function fetchWithInfRedirection(): Promise<void> {
const response = await fetch("http://localhost:4549/cli/tests"); // will redirect to the same place
assertEquals(response.status, 0); // network error
}
);
unitTest(
{ perms: { net: true } },
async function fetchInitStringBody(): Promise<void> {
const data = "Hello World";
const response = await fetch("http://localhost:4545/echo_server", {
method: "POST",
body: data,
});
const text = await response.text();
assertEquals(text, data);
assert(response.headers.get("content-type")!.startsWith("text/plain"));
}
);
unitTest(
{ perms: { net: true } },
async function fetchRequestInitStringBody(): Promise<void> {
const data = "Hello World";
const req = new Request("http://localhost:4545/echo_server", {
method: "POST",
body: data,
});
const response = await fetch(req);
const text = await response.text();
assertEquals(text, data);
}
);
unitTest(
{ perms: { net: true } },
async function fetchInitTypedArrayBody(): Promise<void> {
const data = "Hello World";
const response = await fetch("http://localhost:4545/echo_server", {
method: "POST",
body: new TextEncoder().encode(data),
});
const text = await response.text();
assertEquals(text, data);
}
);
unitTest(
{ perms: { net: true } },
async function fetchInitURLSearchParamsBody(): Promise<void> {
const data = "param1=value1&param2=value2";
const params = new URLSearchParams(data);
const response = await fetch("http://localhost:4545/echo_server", {
method: "POST",
body: params,
});
const text = await response.text();
assertEquals(text, data);
assert(
response.headers
.get("content-type")!
.startsWith("application/x-www-form-urlencoded")
);
}
);
unitTest({ perms: { net: true } }, async function fetchInitBlobBody(): Promise<
void
> {
const data = "const a = 1";
const blob = new Blob([data], {
type: "text/javascript",
});
const response = await fetch("http://localhost:4545/echo_server", {
method: "POST",
body: blob,
});
const text = await response.text();
assertEquals(text, data);
assert(response.headers.get("content-type")!.startsWith("text/javascript"));
});
unitTest(
{ perms: { net: true } },
async function fetchInitFormDataBody(): Promise<void> {
const form = new FormData();
form.append("field", "value");
const response = await fetch("http://localhost:4545/echo_server", {
method: "POST",
body: form,
});
const resultForm = await response.formData();
assertEquals(form.get("field"), resultForm.get("field"));
}
);
unitTest({ perms: { net: true } }, async function fetchUserAgent(): Promise<
void
> {
const data = "Hello World";
const response = await fetch("http://localhost:4545/echo_server", {
method: "POST",
body: new TextEncoder().encode(data),
});
assertEquals(response.headers.get("user-agent"), `Deno/${Deno.version.deno}`);
await response.text();
});
// TODO(ry) The following tests work but are flaky. There's a race condition
// somewhere. Here is what one of these flaky failures looks like:
//
// unitTest fetchPostBodyString_permW0N1E0R0
// assertEquals failed. actual = expected = POST /blah HTTP/1.1
// hello: World
// foo: Bar
// host: 127.0.0.1:4502
// content-length: 11
// hello world
// Error: actual: expected: POST /blah HTTP/1.1
// hello: World
// foo: Bar
// host: 127.0.0.1:4502
// content-length: 11
// hello world
// at Object.assertEquals (file:///C:/deno/js/testing/util.ts:29:11)
// at fetchPostBodyString (file
function bufferServer(addr: string): Deno.Buffer {
const [hostname, port] = addr.split(":");
const listener = Deno.listen({
hostname,
port: Number(port),
}) as Deno.Listener;
const buf = new Deno.Buffer();
listener.accept().then(async (conn: Deno.Conn) => {
const p1 = buf.readFrom(conn);
const p2 = conn.write(
new TextEncoder().encode(
"HTTP/1.0 404 Not Found\r\nContent-Length: 2\r\n\r\nNF"
)
);
// Wait for both an EOF on the read side of the socket and for the write to
// complete before closing it. Due to keep-alive, the EOF won't be sent
// until the Connection close (HTTP/1.0) response, so readFrom() can't
// proceed write. Conversely, if readFrom() is async, waiting for the
// write() to complete is not a guarantee that we've read the incoming
// request.
await Promise.all([p1, p2]);
conn.close();
listener.close();
});
return buf;
}
unitTest(
{
// FIXME(bartlomieju)
ignore: true,
perms: { net: true },
},
async function fetchRequest(): Promise<void> {
const addr = "127.0.0.1:4501";
const buf = bufferServer(addr);
const response = await fetch(`http://${addr}/blah`, {
method: "POST",
headers: [
["Hello", "World"],
["Foo", "Bar"],
],
});
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
const actual = new TextDecoder().decode(buf.bytes());
const expected = [
"POST /blah HTTP/1.1\r\n",
"hello: World\r\n",
"foo: Bar\r\n",
`host: ${addr}\r\n\r\n`,
].join("");
assertEquals(actual, expected);
}
);
unitTest(
{
// FIXME(bartlomieju)
ignore: true,
perms: { net: true },
},
async function fetchPostBodyString(): Promise<void> {
const addr = "127.0.0.1:4502";
const buf = bufferServer(addr);
const body = "hello world";
const response = await fetch(`http://${addr}/blah`, {
method: "POST",
headers: [
["Hello", "World"],
["Foo", "Bar"],
],
body,
});
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
const actual = new TextDecoder().decode(buf.bytes());
const expected = [
"POST /blah HTTP/1.1\r\n",
"hello: World\r\n",
"foo: Bar\r\n",
`host: ${addr}\r\n`,
`content-length: ${body.length}\r\n\r\n`,
body,
].join("");
assertEquals(actual, expected);
}
);
unitTest(
{
// FIXME(bartlomieju)
ignore: true,
perms: { net: true },
},
async function fetchPostBodyTypedArray(): Promise<void> {
const addr = "127.0.0.1:4503";
const buf = bufferServer(addr);
const bodyStr = "hello world";
const body = new TextEncoder().encode(bodyStr);
const response = await fetch(`http://${addr}/blah`, {
method: "POST",
headers: [
["Hello", "World"],
["Foo", "Bar"],
],
body,
});
assertEquals(response.status, 404);
assertEquals(response.headers.get("Content-Length"), "2");
const actual = new TextDecoder().decode(buf.bytes());
const expected = [
"POST /blah HTTP/1.1\r\n",
"hello: World\r\n",
"foo: Bar\r\n",
`host: ${addr}\r\n`,
`content-length: ${body.byteLength}\r\n\r\n`,
bodyStr,
].join("");
assertEquals(actual, expected);
}
);
unitTest(
{
perms: { net: true },
},
async function fetchWithManualRedirection(): Promise<void> {
const response = await fetch("http://localhost:4546/", {
redirect: "manual",
}); // will redirect to http://localhost:4545/
assertEquals(response.status, 0);
assertEquals(response.statusText, "");
assertEquals(response.url, "");
assertEquals(response.type, "opaqueredirect");
try {
await response.text();
fail(
"Reponse.text() didn't throw on a filtered response without a body (type opaqueredirect)"
);
} catch (e) {
return;
}
}
);
unitTest(
{
perms: { net: true },
},
async function fetchWithErrorRedirection(): Promise<void> {
const response = await fetch("http://localhost:4546/", {
redirect: "error",
}); // will redirect to http://localhost:4545/
assertEquals(response.status, 0);
assertEquals(response.statusText, "");
assertEquals(response.url, "");
assertEquals(response.type, "error");
try {
await response.text();
fail(
"Reponse.text() didn't throw on a filtered response without a body (type error)"
);
} catch (e) {
return;
}
}
);
unitTest(function responseRedirect(): void {
const redir = Response.redirect("example.com/newLocation", 301);
assertEquals(redir.status, 301);
assertEquals(redir.statusText, "");
assertEquals(redir.url, "");
assertEquals(redir.headers.get("Location"), "example.com/newLocation");
assertEquals(redir.type, "default");
});
unitTest(function responseConstructionHeaderRemoval(): void {
const res = new Response(
"example.com",
200,
"OK",
[["Set-Cookie", "mysessionid"]],
-1,
false,
"basic",
null
);
assert(res.headers.get("Set-Cookie") != "mysessionid");
});

View file

@ -1,105 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function testFirstArgument(arg1: any[], expectedSize: number): void {
const file = new File(arg1, "name");
assert(file instanceof File);
assertEquals(file.name, "name");
assertEquals(file.size, expectedSize);
assertEquals(file.type, "");
}
unitTest(function fileEmptyFileBits(): void {
testFirstArgument([], 0);
});
unitTest(function fileStringFileBits(): void {
testFirstArgument(["bits"], 4);
});
unitTest(function fileUnicodeStringFileBits(): void {
testFirstArgument(["𝓽𝓮𝔁𝓽"], 16);
});
unitTest(function fileStringObjectFileBits(): void {
testFirstArgument([new String("string object")], 13);
});
unitTest(function fileEmptyBlobFileBits(): void {
testFirstArgument([new Blob()], 0);
});
unitTest(function fileBlobFileBits(): void {
testFirstArgument([new Blob(["bits"])], 4);
});
unitTest(function fileEmptyFileFileBits(): void {
testFirstArgument([new File([], "world.txt")], 0);
});
unitTest(function fileFileFileBits(): void {
testFirstArgument([new File(["bits"], "world.txt")], 4);
});
unitTest(function fileArrayBufferFileBits(): void {
testFirstArgument([new ArrayBuffer(8)], 8);
});
unitTest(function fileTypedArrayFileBits(): void {
testFirstArgument([new Uint8Array([0x50, 0x41, 0x53, 0x53])], 4);
});
unitTest(function fileVariousFileBits(): void {
testFirstArgument(
[
"bits",
new Blob(["bits"]),
new Blob(),
new Uint8Array([0x50, 0x41]),
new Uint16Array([0x5353]),
new Uint32Array([0x53534150]),
],
16
);
});
unitTest(function fileNumberInFileBits(): void {
testFirstArgument([12], 2);
});
unitTest(function fileArrayInFileBits(): void {
testFirstArgument([[1, 2, 3]], 5);
});
unitTest(function fileObjectInFileBits(): void {
// "[object Object]"
testFirstArgument([{}], 15);
});
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function testSecondArgument(arg2: any, expectedFileName: string): void {
const file = new File(["bits"], arg2);
assert(file instanceof File);
assertEquals(file.name, expectedFileName);
}
unitTest(function fileUsingFileName(): void {
testSecondArgument("dummy", "dummy");
});
unitTest(function fileUsingSpecialCharacterInFileName(): void {
testSecondArgument("dummy/foo", "dummy:foo");
});
unitTest(function fileUsingNullFileName(): void {
testSecondArgument(null, "null");
});
unitTest(function fileUsingNumberFileName(): void {
testSecondArgument(1, "1");
});
unitTest(function fileUsingEmptyStringFileName(): void {
testSecondArgument("", "");
});

View file

@ -1,571 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
unitTest,
assert,
assertEquals,
assertStrContains,
} from "./test_util.ts";
unitTest(function filesStdioFileDescriptors(): void {
assertEquals(Deno.stdin.rid, 0);
assertEquals(Deno.stdout.rid, 1);
assertEquals(Deno.stderr.rid, 2);
});
unitTest({ perms: { read: true } }, async function filesCopyToStdout(): Promise<
void
> {
const filename = "cli/tests/fixture.json";
const file = await Deno.open(filename);
assert(file.rid > 2);
const bytesWritten = await Deno.copy(file, Deno.stdout);
const fileSize = Deno.statSync(filename).size;
assertEquals(bytesWritten, fileSize);
console.log("bytes written", bytesWritten);
file.close();
});
unitTest({ perms: { read: true } }, async function filesIter(): Promise<void> {
const filename = "cli/tests/hello.txt";
const file = await Deno.open(filename);
let totalSize = 0;
for await (const buf of Deno.iter(file)) {
totalSize += buf.byteLength;
}
assertEquals(totalSize, 12);
file.close();
});
unitTest(
{ perms: { read: true } },
async function filesIterCustomBufSize(): Promise<void> {
const filename = "cli/tests/hello.txt";
const file = await Deno.open(filename);
let totalSize = 0;
let iterations = 0;
for await (const buf of Deno.iter(file, { bufSize: 6 })) {
totalSize += buf.byteLength;
iterations += 1;
}
assertEquals(totalSize, 12);
assertEquals(iterations, 2);
file.close();
}
);
unitTest({ perms: { read: true } }, function filesIterSync(): void {
const filename = "cli/tests/hello.txt";
const file = Deno.openSync(filename);
let totalSize = 0;
for (const buf of Deno.iterSync(file)) {
totalSize += buf.byteLength;
}
assertEquals(totalSize, 12);
file.close();
});
unitTest(
{ perms: { read: true } },
function filesIterSyncCustomBufSize(): void {
const filename = "cli/tests/hello.txt";
const file = Deno.openSync(filename);
let totalSize = 0;
let iterations = 0;
for (const buf of Deno.iterSync(file, { bufSize: 6 })) {
totalSize += buf.byteLength;
iterations += 1;
}
assertEquals(totalSize, 12);
assertEquals(iterations, 2);
file.close();
}
);
unitTest(async function readerIter(): Promise<void> {
// ref: https://github.com/denoland/deno/issues/2330
const encoder = new TextEncoder();
class TestReader implements Deno.Reader {
#offset = 0;
#buf: Uint8Array;
constructor(s: string) {
this.#buf = new Uint8Array(encoder.encode(s));
}
read(p: Uint8Array): Promise<number | null> {
const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset);
p.set(this.#buf.slice(this.#offset, this.#offset + n));
this.#offset += n;
if (n === 0) {
return Promise.resolve(null);
}
return Promise.resolve(n);
}
}
const reader = new TestReader("hello world!");
let totalSize = 0;
for await (const buf of Deno.iter(reader)) {
totalSize += buf.byteLength;
}
assertEquals(totalSize, 12);
});
unitTest(async function readerIterSync(): Promise<void> {
// ref: https://github.com/denoland/deno/issues/2330
const encoder = new TextEncoder();
class TestReader implements Deno.ReaderSync {
#offset = 0;
#buf: Uint8Array;
constructor(s: string) {
this.#buf = new Uint8Array(encoder.encode(s));
}
readSync(p: Uint8Array): number | null {
const n = Math.min(p.byteLength, this.#buf.byteLength - this.#offset);
p.set(this.#buf.slice(this.#offset, this.#offset + n));
this.#offset += n;
if (n === 0) {
return null;
}
return n;
}
}
const reader = new TestReader("hello world!");
let totalSize = 0;
for await (const buf of Deno.iterSync(reader)) {
totalSize += buf.byteLength;
}
assertEquals(totalSize, 12);
});
unitTest(
{
perms: { read: true, write: true },
},
function openSyncMode(): void {
const path = Deno.makeTempDirSync() + "/test_openSync.txt";
const file = Deno.openSync(path, {
write: true,
createNew: true,
mode: 0o626,
});
file.close();
const pathInfo = Deno.statSync(path);
if (Deno.build.os !== "windows") {
assertEquals(pathInfo.mode! & 0o777, 0o626 & ~Deno.umask());
}
}
);
unitTest(
{
perms: { read: true, write: true },
},
async function openMode(): Promise<void> {
const path = (await Deno.makeTempDir()) + "/test_open.txt";
const file = await Deno.open(path, {
write: true,
createNew: true,
mode: 0o626,
});
file.close();
const pathInfo = Deno.statSync(path);
if (Deno.build.os !== "windows") {
assertEquals(pathInfo.mode! & 0o777, 0o626 & ~Deno.umask());
}
}
);
unitTest(
{ perms: { write: false } },
async function writePermFailure(): Promise<void> {
const filename = "tests/hello.txt";
const openOptions: Deno.OpenOptions[] = [{ write: true }, { append: true }];
for (const options of openOptions) {
let err;
try {
await Deno.open(filename, options);
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
}
);
unitTest(async function openOptions(): Promise<void> {
const filename = "cli/tests/fixture.json";
let err;
try {
await Deno.open(filename, { write: false });
} catch (e) {
err = e;
}
assert(!!err);
assertStrContains(
err.message,
"OpenOptions requires at least one option to be true"
);
try {
await Deno.open(filename, { truncate: true, write: false });
} catch (e) {
err = e;
}
assert(!!err);
assertStrContains(err.message, "'truncate' option requires 'write' option");
try {
await Deno.open(filename, { create: true, write: false });
} catch (e) {
err = e;
}
assert(!!err);
assertStrContains(
err.message,
"'create' or 'createNew' options require 'write' or 'append' option"
);
try {
await Deno.open(filename, { createNew: true, append: false });
} catch (e) {
err = e;
}
assert(!!err);
assertStrContains(
err.message,
"'create' or 'createNew' options require 'write' or 'append' option"
);
});
unitTest({ perms: { read: false } }, async function readPermFailure(): Promise<
void
> {
let caughtError = false;
try {
await Deno.open("package.json", { read: true });
await Deno.open("cli/tests/fixture.json", { read: true });
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest(
{ perms: { write: true } },
async function writeNullBufferFailure(): Promise<void> {
const tempDir = Deno.makeTempDirSync();
const filename = tempDir + "hello.txt";
const w = {
write: true,
truncate: true,
create: true,
};
const file = await Deno.open(filename, w);
// writing null should throw an error
let err;
try {
// @ts-ignore
await file.write(null);
} catch (e) {
err = e;
}
// TODO: Check error kind when dispatch_minimal pipes errors properly
assert(!!err);
file.close();
await Deno.remove(tempDir, { recursive: true });
}
);
unitTest(
{ perms: { write: true, read: true } },
async function readNullBufferFailure(): Promise<void> {
const tempDir = Deno.makeTempDirSync();
const filename = tempDir + "hello.txt";
const file = await Deno.open(filename, {
read: true,
write: true,
truncate: true,
create: true,
});
// reading into an empty buffer should return 0 immediately
const bytesRead = await file.read(new Uint8Array(0));
assert(bytesRead === 0);
// reading file into null buffer should throw an error
let err;
try {
// @ts-ignore
await file.read(null);
} catch (e) {
err = e;
}
// TODO: Check error kind when dispatch_minimal pipes errors properly
assert(!!err);
file.close();
await Deno.remove(tempDir, { recursive: true });
}
);
unitTest(
{ perms: { write: false, read: false } },
async function readWritePermFailure(): Promise<void> {
const filename = "tests/hello.txt";
let err;
try {
await Deno.open(filename, { read: true });
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
);
unitTest(
{ perms: { read: true, write: true } },
async function createFile(): Promise<void> {
const tempDir = await Deno.makeTempDir();
const filename = tempDir + "/test.txt";
const f = await Deno.create(filename);
let fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile);
assert(fileInfo.size === 0);
const enc = new TextEncoder();
const data = enc.encode("Hello");
await f.write(data);
fileInfo = Deno.statSync(filename);
assert(fileInfo.size === 5);
f.close();
// TODO: test different modes
await Deno.remove(tempDir, { recursive: true });
}
);
unitTest(
{ perms: { read: true, write: true } },
async function openModeWrite(): Promise<void> {
const tempDir = Deno.makeTempDirSync();
const encoder = new TextEncoder();
const filename = tempDir + "hello.txt";
const data = encoder.encode("Hello world!\n");
let file = await Deno.open(filename, {
create: true,
write: true,
truncate: true,
});
// assert file was created
let fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile);
assertEquals(fileInfo.size, 0);
// write some data
await file.write(data);
fileInfo = Deno.statSync(filename);
assertEquals(fileInfo.size, 13);
// assert we can't read from file
let thrown = false;
try {
const buf = new Uint8Array(20);
await file.read(buf);
} catch (e) {
thrown = true;
} finally {
assert(thrown, "'w' mode shouldn't allow to read file");
}
file.close();
// assert that existing file is truncated on open
file = await Deno.open(filename, {
write: true,
truncate: true,
});
file.close();
const fileSize = Deno.statSync(filename).size;
assertEquals(fileSize, 0);
await Deno.remove(tempDir, { recursive: true });
}
);
unitTest(
{ perms: { read: true, write: true } },
async function openModeWriteRead(): Promise<void> {
const tempDir = Deno.makeTempDirSync();
const encoder = new TextEncoder();
const filename = tempDir + "hello.txt";
const data = encoder.encode("Hello world!\n");
const file = await Deno.open(filename, {
write: true,
truncate: true,
create: true,
read: true,
});
const seekPosition = 0;
// assert file was created
let fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile);
assertEquals(fileInfo.size, 0);
// write some data
await file.write(data);
fileInfo = Deno.statSync(filename);
assertEquals(fileInfo.size, 13);
const buf = new Uint8Array(20);
// seeking from beginning of a file
const cursorPosition = await file.seek(seekPosition, Deno.SeekMode.Start);
assertEquals(seekPosition, cursorPosition);
const result = await file.read(buf);
assertEquals(result, 13);
file.close();
await Deno.remove(tempDir, { recursive: true });
}
);
unitTest({ perms: { read: true } }, async function seekStart(): Promise<void> {
const filename = "cli/tests/hello.txt";
const file = await Deno.open(filename);
const seekPosition = 6;
// Deliberately move 1 step forward
await file.read(new Uint8Array(1)); // "H"
// Skipping "Hello "
// seeking from beginning of a file plus seekPosition
const cursorPosition = await file.seek(seekPosition, Deno.SeekMode.Start);
assertEquals(seekPosition, cursorPosition);
const buf = new Uint8Array(6);
await file.read(buf);
const decoded = new TextDecoder().decode(buf);
assertEquals(decoded, "world!");
file.close();
});
unitTest({ perms: { read: true } }, function seekSyncStart(): void {
const filename = "cli/tests/hello.txt";
const file = Deno.openSync(filename);
const seekPosition = 6;
// Deliberately move 1 step forward
file.readSync(new Uint8Array(1)); // "H"
// Skipping "Hello "
// seeking from beginning of a file plus seekPosition
const cursorPosition = file.seekSync(seekPosition, Deno.SeekMode.Start);
assertEquals(seekPosition, cursorPosition);
const buf = new Uint8Array(6);
file.readSync(buf);
const decoded = new TextDecoder().decode(buf);
assertEquals(decoded, "world!");
file.close();
});
unitTest({ perms: { read: true } }, async function seekCurrent(): Promise<
void
> {
const filename = "cli/tests/hello.txt";
const file = await Deno.open(filename);
// Deliberately move 1 step forward
await file.read(new Uint8Array(1)); // "H"
// Skipping "ello "
const seekPosition = 5;
// seekPosition is relative to current cursor position after read
const cursorPosition = await file.seek(seekPosition, Deno.SeekMode.Current);
assertEquals(seekPosition + 1, cursorPosition);
const buf = new Uint8Array(6);
await file.read(buf);
const decoded = new TextDecoder().decode(buf);
assertEquals(decoded, "world!");
file.close();
});
unitTest({ perms: { read: true } }, function seekSyncCurrent(): void {
const filename = "cli/tests/hello.txt";
const file = Deno.openSync(filename);
// Deliberately move 1 step forward
file.readSync(new Uint8Array(1)); // "H"
// Skipping "ello "
const seekPosition = 5;
// seekPosition is relative to current cursor position after read
const cursorPosition = file.seekSync(seekPosition, Deno.SeekMode.Current);
assertEquals(seekPosition + 1, cursorPosition);
const buf = new Uint8Array(6);
file.readSync(buf);
const decoded = new TextDecoder().decode(buf);
assertEquals(decoded, "world!");
file.close();
});
unitTest({ perms: { read: true } }, async function seekEnd(): Promise<void> {
const filename = "cli/tests/hello.txt";
const file = await Deno.open(filename);
const seekPosition = -6;
// seek from end of file that has 12 chars, 12 - 6 = 6
const cursorPosition = await file.seek(seekPosition, Deno.SeekMode.End);
assertEquals(6, cursorPosition);
const buf = new Uint8Array(6);
await file.read(buf);
const decoded = new TextDecoder().decode(buf);
assertEquals(decoded, "world!");
file.close();
});
unitTest({ perms: { read: true } }, function seekSyncEnd(): void {
const filename = "cli/tests/hello.txt";
const file = Deno.openSync(filename);
const seekPosition = -6;
// seek from end of file that has 12 chars, 12 - 6 = 6
const cursorPosition = file.seekSync(seekPosition, Deno.SeekMode.End);
assertEquals(6, cursorPosition);
const buf = new Uint8Array(6);
file.readSync(buf);
const decoded = new TextDecoder().decode(buf);
assertEquals(decoded, "world!");
file.close();
});
unitTest({ perms: { read: true } }, async function seekMode(): Promise<void> {
const filename = "cli/tests/hello.txt";
const file = await Deno.open(filename);
let err;
try {
await file.seek(1, -1);
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof TypeError);
assertStrContains(err.message, "Invalid seek mode");
// We should still be able to read the file
// since it is still open.
const buf = new Uint8Array(1);
await file.read(buf); // "H"
assertEquals(new TextDecoder().decode(buf), "H");
file.close();
});

View file

@ -1,203 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
unitTest,
assert,
assertEquals,
assertStrContains,
} from "./test_util.ts";
unitTest({ ignore: true }, function formDataHasCorrectNameProp(): void {
assertEquals(FormData.name, "FormData");
});
unitTest(function formDataParamsAppendSuccess(): void {
const formData = new FormData();
formData.append("a", "true");
assertEquals(formData.get("a"), "true");
});
unitTest(function formDataParamsDeleteSuccess(): void {
const formData = new FormData();
formData.append("a", "true");
formData.append("b", "false");
assertEquals(formData.get("b"), "false");
formData.delete("b");
assertEquals(formData.get("a"), "true");
assertEquals(formData.get("b"), null);
});
unitTest(function formDataParamsGetAllSuccess(): void {
const formData = new FormData();
formData.append("a", "true");
formData.append("b", "false");
formData.append("a", "null");
assertEquals(formData.getAll("a"), ["true", "null"]);
assertEquals(formData.getAll("b"), ["false"]);
assertEquals(formData.getAll("c"), []);
});
unitTest(function formDataParamsGetSuccess(): void {
const formData = new FormData();
formData.append("a", "true");
formData.append("b", "false");
formData.append("a", "null");
// @ts-ignore
formData.append("d", undefined);
// @ts-ignore
formData.append("e", null);
assertEquals(formData.get("a"), "true");
assertEquals(formData.get("b"), "false");
assertEquals(formData.get("c"), null);
assertEquals(formData.get("d"), "undefined");
assertEquals(formData.get("e"), "null");
});
unitTest(function formDataParamsHasSuccess(): void {
const formData = new FormData();
formData.append("a", "true");
formData.append("b", "false");
assert(formData.has("a"));
assert(formData.has("b"));
assert(!formData.has("c"));
});
unitTest(function formDataParamsSetSuccess(): void {
const formData = new FormData();
formData.append("a", "true");
formData.append("b", "false");
formData.append("a", "null");
assertEquals(formData.getAll("a"), ["true", "null"]);
assertEquals(formData.getAll("b"), ["false"]);
formData.set("a", "false");
assertEquals(formData.getAll("a"), ["false"]);
// @ts-ignore
formData.set("d", undefined);
assertEquals(formData.get("d"), "undefined");
// @ts-ignore
formData.set("e", null);
assertEquals(formData.get("e"), "null");
});
unitTest(function fromDataUseDomFile(): void {
const formData = new FormData();
const file = new File(["foo"], "bar", {
type: "text/plain",
});
formData.append("file", file);
assertEquals(formData.get("file"), file);
});
unitTest(function formDataSetEmptyBlobSuccess(): void {
const formData = new FormData();
formData.set("a", new Blob([]), "blank.txt");
formData.get("a");
/* TODO Fix this test.
assert(file instanceof File);
if (typeof file !== "string") {
assertEquals(file.name, "blank.txt");
}
*/
});
unitTest(function formDataParamsForEachSuccess(): void {
const init = [
["a", "54"],
["b", "true"],
];
const formData = new FormData();
for (const [name, value] of init) {
formData.append(name, value);
}
let callNum = 0;
formData.forEach((value, key, parent): void => {
assertEquals(formData, parent);
assertEquals(value, init[callNum][1]);
assertEquals(key, init[callNum][0]);
callNum++;
});
assertEquals(callNum, init.length);
});
unitTest(function formDataParamsArgumentsCheck(): void {
const methodRequireOneParam = [
"delete",
"getAll",
"get",
"has",
"forEach",
] as const;
const methodRequireTwoParams = ["append", "set"] as const;
methodRequireOneParam.forEach((method): void => {
const formData = new FormData();
let hasThrown = 0;
let errMsg = "";
try {
// @ts-ignore
formData[method]();
hasThrown = 1;
} catch (err) {
errMsg = err.message;
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
assertStrContains(
errMsg,
`${method} requires at least 1 argument, but only 0 present`
);
});
methodRequireTwoParams.forEach((method: string): void => {
const formData = new FormData();
let hasThrown = 0;
let errMsg = "";
try {
// @ts-ignore
formData[method]();
hasThrown = 1;
} catch (err) {
errMsg = err.message;
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
assertStrContains(
errMsg,
`${method} requires at least 2 arguments, but only 0 present`
);
hasThrown = 0;
errMsg = "";
try {
// @ts-ignore
formData[method]("foo");
hasThrown = 1;
} catch (err) {
errMsg = err.message;
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
assertStrContains(
errMsg,
`${method} requires at least 2 arguments, but only 1 present`
);
});
});
unitTest(function toStringShouldBeWebCompatibility(): void {
const formData = new FormData();
assertEquals(formData.toString(), "[object FormData]");
});

View file

@ -1,33 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { assert, unitTest } from "./test_util.ts";
unitTest(function formatDiagnosticBasic() {
const fixture: Deno.DiagnosticItem[] = [
{
message: "Example error",
category: Deno.DiagnosticCategory.Error,
sourceLine: "abcdefghijklmnopqrstuv",
lineNumber: 1000,
scriptResourceName: "foo.ts",
startColumn: 1,
endColumn: 2,
code: 4000,
},
];
const out = Deno.formatDiagnostics(fixture);
assert(out.includes("Example error"));
assert(out.includes("foo.ts"));
});
unitTest(function formatDiagnosticError() {
let thrown = false;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const bad = ([{ hello: 123 }] as any) as Deno.DiagnosticItem[];
try {
Deno.formatDiagnostics(bad);
} catch (e) {
assert(e instanceof Deno.errors.InvalidData);
thrown = true;
}
assert(thrown);
});

View file

@ -1,71 +0,0 @@
// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
// TODO(ry) Add more tests to specify format.
unitTest({ perms: { read: false } }, function watchFsPermissions() {
let thrown = false;
try {
Deno.watchFs(".");
} catch (err) {
assert(err instanceof Deno.errors.PermissionDenied);
thrown = true;
}
assert(thrown);
});
unitTest({ perms: { read: true } }, function watchFsInvalidPath() {
let thrown = false;
try {
Deno.watchFs("non-existant.file");
} catch (err) {
console.error(err);
if (Deno.build.os === "windows") {
assert(
err.message.includes(
"Input watch path is neither a file nor a directory"
)
);
} else {
assert(err instanceof Deno.errors.NotFound);
}
thrown = true;
}
assert(thrown);
});
async function getTwoEvents(
iter: AsyncIterableIterator<Deno.FsEvent>
): Promise<Deno.FsEvent[]> {
const events = [];
for await (const event of iter) {
events.push(event);
if (events.length > 2) break;
}
return events;
}
unitTest(
{ perms: { read: true, write: true } },
async function watchFsBasic(): Promise<void> {
const testDir = await Deno.makeTempDir();
const iter = Deno.watchFs(testDir);
// Asynchornously capture two fs events.
const eventsPromise = getTwoEvents(iter);
// Make some random file system activity.
const file1 = testDir + "/file1.txt";
const file2 = testDir + "/file2.txt";
Deno.writeFileSync(file1, new Uint8Array([0, 1, 2]));
Deno.writeFileSync(file2, new Uint8Array([0, 1, 2]));
// We should have gotten two fs events.
const events = await eventsPromise;
assert(events.length >= 2);
assert(events[0].kind == "create");
assert(events[0].paths[0].includes(testDir));
assert(events[1].kind == "create" || events[1].kind == "modify");
assert(events[1].paths[0].includes(testDir));
}
);

View file

@ -1,51 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertNotEquals, assertStrictEq } from "./test_util.ts";
unitTest(function getRandomValuesInt8Array(): void {
const arr = new Int8Array(32);
crypto.getRandomValues(arr);
assertNotEquals(arr, new Int8Array(32));
});
unitTest(function getRandomValuesUint8Array(): void {
const arr = new Uint8Array(32);
crypto.getRandomValues(arr);
assertNotEquals(arr, new Uint8Array(32));
});
unitTest(function getRandomValuesUint8ClampedArray(): void {
const arr = new Uint8ClampedArray(32);
crypto.getRandomValues(arr);
assertNotEquals(arr, new Uint8ClampedArray(32));
});
unitTest(function getRandomValuesInt16Array(): void {
const arr = new Int16Array(4);
crypto.getRandomValues(arr);
assertNotEquals(arr, new Int16Array(4));
});
unitTest(function getRandomValuesUint16Array(): void {
const arr = new Uint16Array(4);
crypto.getRandomValues(arr);
assertNotEquals(arr, new Uint16Array(4));
});
unitTest(function getRandomValuesInt32Array(): void {
const arr = new Int32Array(8);
crypto.getRandomValues(arr);
assertNotEquals(arr, new Int32Array(8));
});
unitTest(function getRandomValuesUint32Array(): void {
const arr = new Uint32Array(8);
crypto.getRandomValues(arr);
assertNotEquals(arr, new Uint32Array(8));
});
unitTest(function getRandomValuesReturnValue(): void {
const arr = new Uint32Array(8);
const rtn = crypto.getRandomValues(arr);
assertNotEquals(arr, new Uint32Array(8));
assertStrictEq(rtn, arr);
});

View file

@ -1,112 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
unitTest(function globalThisExists(): void {
assert(globalThis != null);
});
unitTest(function windowExists(): void {
assert(window != null);
});
unitTest(function selfExists(): void {
assert(self != null);
});
unitTest(function windowWindowExists(): void {
assert(window.window === window);
});
unitTest(function windowSelfExists(): void {
assert(window.self === window);
});
unitTest(function globalThisEqualsWindow(): void {
assert(globalThis === window);
});
unitTest(function globalThisEqualsSelf(): void {
assert(globalThis === self);
});
unitTest(function DenoNamespaceExists(): void {
assert(Deno != null);
});
unitTest(function DenoNamespaceEqualsWindowDeno(): void {
assert(Deno === window.Deno);
});
unitTest(function DenoNamespaceIsFrozen(): void {
assert(Object.isFrozen(Deno));
});
unitTest(function webAssemblyExists(): void {
assert(typeof WebAssembly.compile === "function");
});
unitTest(function DenoNamespaceImmutable(): void {
const denoCopy = window.Deno;
try {
// @ts-ignore
Deno = 1;
} catch {}
assert(denoCopy === Deno);
try {
// @ts-ignore
window.Deno = 1;
} catch {}
assert(denoCopy === Deno);
try {
delete window.Deno;
} catch {}
assert(denoCopy === Deno);
const { readFile } = Deno;
try {
// @ts-ignore
Deno.readFile = 1;
} catch {}
assert(readFile === Deno.readFile);
try {
delete window.Deno.readFile;
} catch {}
assert(readFile === Deno.readFile);
// @ts-ignore
const { print } = Deno.core;
try {
// @ts-ignore
Deno.core.print = 1;
} catch {}
// @ts-ignore
assert(print === Deno.core.print);
try {
// @ts-ignore
delete Deno.core.print;
} catch {}
// @ts-ignore
assert(print === Deno.core.print);
});
unitTest(async function windowQueueMicrotask(): Promise<void> {
let resolve1: () => void | undefined;
let resolve2: () => void | undefined;
let microtaskDone = false;
const p1 = new Promise((res): void => {
resolve1 = (): void => {
microtaskDone = true;
res();
};
});
const p2 = new Promise((res): void => {
resolve2 = (): void => {
assert(microtaskDone);
res();
};
});
window.queueMicrotask(resolve1!);
setTimeout(resolve2!, 0);
await p1;
await p2;
});

View file

@ -1,420 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
unitTest,
assert,
assertEquals,
assertStrContains,
} from "./test_util.ts";
const {
stringifyArgs,
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol
} = Deno[Deno.internal];
// Logic heavily copied from web-platform-tests, make
// sure pass mostly header basic test
// ref: https://github.com/web-platform-tests/wpt/blob/7c50c216081d6ea3c9afe553ee7b64534020a1b2/fetch/api/headers/headers-basic.html
unitTest(function newHeaderTest(): void {
new Headers();
new Headers(undefined);
new Headers({});
try {
// @ts-ignore
new Headers(null);
} catch (e) {
assertEquals(
e.message,
"Failed to construct 'Headers'; The provided value was not valid"
);
}
});
const headerDict: Record<string, string> = {
name1: "value1",
name2: "value2",
name3: "value3",
// @ts-ignore
name4: undefined,
"Content-Type": "value4",
};
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const headerSeq: any[] = [];
for (const name in headerDict) {
headerSeq.push([name, headerDict[name]]);
}
unitTest(function newHeaderWithSequence(): void {
const headers = new Headers(headerSeq);
for (const name in headerDict) {
assertEquals(headers.get(name), String(headerDict[name]));
}
assertEquals(headers.get("length"), null);
});
unitTest(function newHeaderWithRecord(): void {
const headers = new Headers(headerDict);
for (const name in headerDict) {
assertEquals(headers.get(name), String(headerDict[name]));
}
});
unitTest(function newHeaderWithHeadersInstance(): void {
const headers = new Headers(headerDict);
const headers2 = new Headers(headers);
for (const name in headerDict) {
assertEquals(headers2.get(name), String(headerDict[name]));
}
});
unitTest(function headerAppendSuccess(): void {
const headers = new Headers();
for (const name in headerDict) {
headers.append(name, headerDict[name]);
assertEquals(headers.get(name), String(headerDict[name]));
}
});
unitTest(function headerSetSuccess(): void {
const headers = new Headers();
for (const name in headerDict) {
headers.set(name, headerDict[name]);
assertEquals(headers.get(name), String(headerDict[name]));
}
});
unitTest(function headerHasSuccess(): void {
const headers = new Headers(headerDict);
for (const name in headerDict) {
assert(headers.has(name), "headers has name " + name);
assert(
!headers.has("nameNotInHeaders"),
"headers do not have header: nameNotInHeaders"
);
}
});
unitTest(function headerDeleteSuccess(): void {
const headers = new Headers(headerDict);
for (const name in headerDict) {
assert(headers.has(name), "headers have a header: " + name);
headers.delete(name);
assert(!headers.has(name), "headers do not have anymore a header: " + name);
}
});
unitTest(function headerGetSuccess(): void {
const headers = new Headers(headerDict);
for (const name in headerDict) {
assertEquals(headers.get(name), String(headerDict[name]));
assertEquals(headers.get("nameNotInHeaders"), null);
}
});
unitTest(function headerEntriesSuccess(): void {
const headers = new Headers(headerDict);
const iterators = headers.entries();
for (const it of iterators) {
const key = it[0];
const value = it[1];
assert(headers.has(key));
assertEquals(value, headers.get(key));
}
});
unitTest(function headerKeysSuccess(): void {
const headers = new Headers(headerDict);
const iterators = headers.keys();
for (const it of iterators) {
assert(headers.has(it));
}
});
unitTest(function headerValuesSuccess(): void {
const headers = new Headers(headerDict);
const iterators = headers.values();
const entries = headers.entries();
const values = [];
for (const pair of entries) {
values.push(pair[1]);
}
for (const it of iterators) {
assert(values.includes(it));
}
});
const headerEntriesDict: Record<string, string> = {
name1: "value1",
Name2: "value2",
name: "value3",
"content-Type": "value4",
"Content-Typ": "value5",
"Content-Types": "value6",
};
unitTest(function headerForEachSuccess(): void {
const headers = new Headers(headerEntriesDict);
const keys = Object.keys(headerEntriesDict);
keys.forEach((key): void => {
const value = headerEntriesDict[key];
const newkey = key.toLowerCase();
headerEntriesDict[newkey] = value;
});
let callNum = 0;
headers.forEach((value, key, container): void => {
assertEquals(headers, container);
assertEquals(value, headerEntriesDict[key]);
callNum++;
});
assertEquals(callNum, keys.length);
});
unitTest(function headerSymbolIteratorSuccess(): void {
assert(Symbol.iterator in Headers.prototype);
const headers = new Headers(headerEntriesDict);
for (const header of headers) {
const key = header[0];
const value = header[1];
assert(headers.has(key));
assertEquals(value, headers.get(key));
}
});
unitTest(function headerTypesAvailable(): void {
function newHeaders(): Headers {
return new Headers();
}
const headers = newHeaders();
assert(headers instanceof Headers);
});
// Modified from https://github.com/bitinn/node-fetch/blob/7d3293200a91ad52b5ca7962f9d6fd1c04983edb/test/test.js#L2001-L2014
// Copyright (c) 2016 David Frank. MIT License.
unitTest(function headerIllegalReject(): void {
let errorCount = 0;
try {
new Headers({ "He y": "ok" });
} catch (e) {
errorCount++;
}
try {
new Headers({ "Hé-y": "ok" });
} catch (e) {
errorCount++;
}
try {
new Headers({ "He-y": "ăk" });
} catch (e) {
errorCount++;
}
const headers = new Headers();
try {
headers.append("Hé-y", "ok");
} catch (e) {
errorCount++;
}
try {
headers.delete("Hé-y");
} catch (e) {
errorCount++;
}
try {
headers.get("Hé-y");
} catch (e) {
errorCount++;
}
try {
headers.has("Hé-y");
} catch (e) {
errorCount++;
}
try {
headers.set("Hé-y", "ok");
} catch (e) {
errorCount++;
}
try {
headers.set("", "ok");
} catch (e) {
errorCount++;
}
assertEquals(errorCount, 9);
// 'o k' is valid value but invalid name
new Headers({ "He-y": "o k" });
});
// If pair does not contain exactly two items,then throw a TypeError.
unitTest(function headerParamsShouldThrowTypeError(): void {
let hasThrown = 0;
try {
new Headers(([["1"]] as unknown) as Array<[string, string]>);
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
});
unitTest(function headerParamsArgumentsCheck(): void {
const methodRequireOneParam = ["delete", "get", "has", "forEach"];
const methodRequireTwoParams = ["append", "set"];
methodRequireOneParam.forEach((method): void => {
const headers = new Headers();
let hasThrown = 0;
let errMsg = "";
try {
// @ts-ignore
headers[method]();
hasThrown = 1;
} catch (err) {
errMsg = err.message;
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
assertStrContains(
errMsg,
`${method} requires at least 1 argument, but only 0 present`
);
});
methodRequireTwoParams.forEach((method): void => {
const headers = new Headers();
let hasThrown = 0;
let errMsg = "";
try {
// @ts-ignore
headers[method]();
hasThrown = 1;
} catch (err) {
errMsg = err.message;
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
assertStrContains(
errMsg,
`${method} requires at least 2 arguments, but only 0 present`
);
hasThrown = 0;
errMsg = "";
try {
// @ts-ignore
headers[method]("foo");
hasThrown = 1;
} catch (err) {
errMsg = err.message;
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
assertStrContains(
errMsg,
`${method} requires at least 2 arguments, but only 1 present`
);
});
});
unitTest(function headersInitMultiple(): void {
const headers = new Headers([
["Set-Cookie", "foo=bar"],
["Set-Cookie", "bar=baz"],
["X-Deno", "foo"],
["X-Deno", "bar"],
]);
const actual = [...headers];
assertEquals(actual, [
["set-cookie", "foo=bar"],
["set-cookie", "bar=baz"],
["x-deno", "foo, bar"],
]);
});
unitTest(function headersAppendMultiple(): void {
const headers = new Headers([
["Set-Cookie", "foo=bar"],
["X-Deno", "foo"],
]);
headers.append("set-Cookie", "bar=baz");
headers.append("x-Deno", "bar");
const actual = [...headers];
assertEquals(actual, [
["set-cookie", "foo=bar"],
["x-deno", "foo, bar"],
["set-cookie", "bar=baz"],
]);
});
unitTest(function headersAppendDuplicateSetCookieKey(): void {
const headers = new Headers([["Set-Cookie", "foo=bar"]]);
headers.append("set-Cookie", "foo=baz");
headers.append("Set-cookie", "baz=bar");
const actual = [...headers];
assertEquals(actual, [
["set-cookie", "foo=baz"],
["set-cookie", "baz=bar"],
]);
});
unitTest(function headersSetDuplicateCookieKey(): void {
const headers = new Headers([["Set-Cookie", "foo=bar"]]);
headers.set("set-Cookie", "foo=baz");
headers.set("set-cookie", "bar=qat");
const actual = [...headers];
assertEquals(actual, [
["set-cookie", "foo=baz"],
["set-cookie", "bar=qat"],
]);
});
unitTest(function headersGetSetCookie(): void {
const headers = new Headers([
["Set-Cookie", "foo=bar"],
["set-Cookie", "bar=qat"],
]);
assertEquals(headers.get("SET-COOKIE"), "foo=bar, bar=qat");
});
unitTest(function toStringShouldBeWebCompatibility(): void {
const headers = new Headers();
assertEquals(headers.toString(), "[object Headers]");
});
function stringify(...args: unknown[]): string {
return stringifyArgs(args).replace(/\n$/, "");
}
unitTest(function customInspectReturnsCorrectHeadersFormat(): void {
const blankHeaders = new Headers();
assertEquals(stringify(blankHeaders), "Headers {}");
const singleHeader = new Headers([["Content-Type", "application/json"]]);
assertEquals(
stringify(singleHeader),
"Headers { content-type: application/json }"
);
const multiParamHeader = new Headers([
["Content-Type", "application/json"],
["Content-Length", "1337"],
]);
assertEquals(
stringify(multiParamHeader),
"Headers { content-type: application/json, content-length: 1337 }"
);
});

View file

@ -1,10 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
unitTest(function internalsExists(): void {
const {
stringifyArgs,
// @ts-ignore TypeScript (as of 3.7) does not support indexing namespaces by symbol
} = Deno[Deno.internal];
assert(!!stringifyArgs);
});

View file

@ -1,73 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals } from "./test_util.ts";
const DEFAULT_BUF_SIZE = 32 * 1024;
type Spy = { calls: number };
function repeat(c: string, bytes: number): Uint8Array {
assertEquals(c.length, 1);
const ui8 = new Uint8Array(bytes);
ui8.fill(c.charCodeAt(0));
return ui8;
}
function spyRead(obj: Deno.Buffer): Spy {
const spy: Spy = {
calls: 0,
};
const orig = obj.read.bind(obj);
obj.read = (p: Uint8Array): Promise<number | null> => {
spy.calls++;
return orig(p);
};
return spy;
}
unitTest(async function copyWithDefaultBufferSize() {
const xBytes = repeat("b", DEFAULT_BUF_SIZE);
const reader = new Deno.Buffer(xBytes.buffer as ArrayBuffer);
const write = new Deno.Buffer();
const readSpy = spyRead(reader);
const n = await Deno.copy(reader, write);
assertEquals(n, xBytes.length);
assertEquals(write.length, xBytes.length);
assertEquals(readSpy.calls, 2); // read with DEFAULT_BUF_SIZE bytes + read with 0 bytes
});
unitTest(async function copyWithCustomBufferSize() {
const bufSize = 1024;
const xBytes = repeat("b", DEFAULT_BUF_SIZE);
const reader = new Deno.Buffer(xBytes.buffer as ArrayBuffer);
const write = new Deno.Buffer();
const readSpy = spyRead(reader);
const n = await Deno.copy(reader, write, { bufSize });
assertEquals(n, xBytes.length);
assertEquals(write.length, xBytes.length);
assertEquals(readSpy.calls, DEFAULT_BUF_SIZE / bufSize + 1);
});
unitTest({ perms: { write: true } }, async function copyBufferToFile() {
const filePath = "test-file.txt";
// bigger than max File possible buffer 16kb
const bufSize = 32 * 1024;
const xBytes = repeat("b", bufSize);
const reader = new Deno.Buffer(xBytes.buffer as ArrayBuffer);
const write = await Deno.open(filePath, { write: true, create: true });
const n = await Deno.copy(reader, write, { bufSize });
assertEquals(n, xBytes.length);
write.close();
await Deno.remove(filePath);
});

View file

@ -1,147 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(
{ perms: { read: true, write: true } },
function linkSyncSuccess(): void {
const testDir = Deno.makeTempDirSync();
const oldData = "Hardlink";
const oldName = testDir + "/oldname";
const newName = testDir + "/newname";
Deno.writeFileSync(oldName, new TextEncoder().encode(oldData));
// Create the hard link.
Deno.linkSync(oldName, newName);
// We should expect reading the same content.
const newData = new TextDecoder().decode(Deno.readFileSync(newName));
assertEquals(oldData, newData);
// Writing to newname also affects oldname.
const newData2 = "Modified";
Deno.writeFileSync(newName, new TextEncoder().encode(newData2));
assertEquals(
newData2,
new TextDecoder().decode(Deno.readFileSync(oldName))
);
// Writing to oldname also affects newname.
const newData3 = "ModifiedAgain";
Deno.writeFileSync(oldName, new TextEncoder().encode(newData3));
assertEquals(
newData3,
new TextDecoder().decode(Deno.readFileSync(newName))
);
// Remove oldname. File still accessible through newname.
Deno.removeSync(oldName);
const newNameStat = Deno.statSync(newName);
assert(newNameStat.isFile);
assert(!newNameStat.isSymlink); // Not a symlink.
assertEquals(
newData3,
new TextDecoder().decode(Deno.readFileSync(newName))
);
}
);
unitTest(
{ perms: { read: true, write: true } },
function linkSyncExists(): void {
const testDir = Deno.makeTempDirSync();
const oldName = testDir + "/oldname";
const newName = testDir + "/newname";
Deno.writeFileSync(oldName, new TextEncoder().encode("oldName"));
// newname is already created.
Deno.writeFileSync(newName, new TextEncoder().encode("newName"));
let err;
try {
Deno.linkSync(oldName, newName);
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Deno.errors.AlreadyExists);
}
);
unitTest(
{ perms: { read: true, write: true } },
function linkSyncNotFound(): void {
const testDir = Deno.makeTempDirSync();
const oldName = testDir + "/oldname";
const newName = testDir + "/newname";
let err;
try {
Deno.linkSync(oldName, newName);
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { read: false, write: true } },
function linkSyncReadPerm(): void {
let err;
try {
Deno.linkSync("oldbaddir", "newbaddir");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
);
unitTest(
{ perms: { read: true, write: false } },
function linkSyncWritePerm(): void {
let err;
try {
Deno.linkSync("oldbaddir", "newbaddir");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
);
unitTest(
{ perms: { read: true, write: true } },
async function linkSuccess(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const oldData = "Hardlink";
const oldName = testDir + "/oldname";
const newName = testDir + "/newname";
Deno.writeFileSync(oldName, new TextEncoder().encode(oldData));
// Create the hard link.
await Deno.link(oldName, newName);
// We should expect reading the same content.
const newData = new TextDecoder().decode(Deno.readFileSync(newName));
assertEquals(oldData, newData);
// Writing to newname also affects oldname.
const newData2 = "Modified";
Deno.writeFileSync(newName, new TextEncoder().encode(newData2));
assertEquals(
newData2,
new TextDecoder().decode(Deno.readFileSync(oldName))
);
// Writing to oldname also affects newname.
const newData3 = "ModifiedAgain";
Deno.writeFileSync(oldName, new TextEncoder().encode(newData3));
assertEquals(
newData3,
new TextDecoder().decode(Deno.readFileSync(newName))
);
// Remove oldname. File still accessible through newname.
Deno.removeSync(oldName);
const newNameStat = Deno.statSync(newName);
assert(newNameStat.isFile);
assert(!newNameStat.isSymlink); // Not a symlink.
assertEquals(
newData3,
new TextDecoder().decode(Deno.readFileSync(newName))
);
}
);

View file

@ -1,178 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest({ perms: { write: true } }, function makeTempDirSyncSuccess(): void {
const dir1 = Deno.makeTempDirSync({ prefix: "hello", suffix: "world" });
const dir2 = Deno.makeTempDirSync({ prefix: "hello", suffix: "world" });
// Check that both dirs are different.
assert(dir1 !== dir2);
for (const dir of [dir1, dir2]) {
// Check that the prefix and suffix are applied.
const lastPart = dir.replace(/^.*[\\\/]/, "");
assert(lastPart.startsWith("hello"));
assert(lastPart.endsWith("world"));
}
// Check that the `dir` option works.
const dir3 = Deno.makeTempDirSync({ dir: dir1 });
assert(dir3.startsWith(dir1));
assert(/^[\\\/]/.test(dir3.slice(dir1.length)));
// Check that creating a temp dir inside a nonexisting directory fails.
let err;
try {
Deno.makeTempDirSync({ dir: "/baddir" });
} catch (err_) {
err = err_;
}
assert(err instanceof Deno.errors.NotFound);
});
unitTest(
{ perms: { read: true, write: true } },
function makeTempDirSyncMode(): void {
const path = Deno.makeTempDirSync();
const pathInfo = Deno.statSync(path);
if (Deno.build.os !== "windows") {
assertEquals(pathInfo.mode! & 0o777, 0o700 & ~Deno.umask());
}
}
);
unitTest(function makeTempDirSyncPerm(): void {
// makeTempDirSync should require write permissions (for now).
let err;
try {
Deno.makeTempDirSync({ dir: "/baddir" });
} catch (err_) {
err = err_;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{ perms: { write: true } },
async function makeTempDirSuccess(): Promise<void> {
const dir1 = await Deno.makeTempDir({ prefix: "hello", suffix: "world" });
const dir2 = await Deno.makeTempDir({ prefix: "hello", suffix: "world" });
// Check that both dirs are different.
assert(dir1 !== dir2);
for (const dir of [dir1, dir2]) {
// Check that the prefix and suffix are applied.
const lastPart = dir.replace(/^.*[\\\/]/, "");
assert(lastPart.startsWith("hello"));
assert(lastPart.endsWith("world"));
}
// Check that the `dir` option works.
const dir3 = await Deno.makeTempDir({ dir: dir1 });
assert(dir3.startsWith(dir1));
assert(/^[\\\/]/.test(dir3.slice(dir1.length)));
// Check that creating a temp dir inside a nonexisting directory fails.
let err;
try {
await Deno.makeTempDir({ dir: "/baddir" });
} catch (err_) {
err = err_;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function makeTempDirMode(): Promise<void> {
const path = await Deno.makeTempDir();
const pathInfo = Deno.statSync(path);
if (Deno.build.os !== "windows") {
assertEquals(pathInfo.mode! & 0o777, 0o700 & ~Deno.umask());
}
}
);
unitTest({ perms: { write: true } }, function makeTempFileSyncSuccess(): void {
const file1 = Deno.makeTempFileSync({ prefix: "hello", suffix: "world" });
const file2 = Deno.makeTempFileSync({ prefix: "hello", suffix: "world" });
// Check that both dirs are different.
assert(file1 !== file2);
for (const dir of [file1, file2]) {
// Check that the prefix and suffix are applied.
const lastPart = dir.replace(/^.*[\\\/]/, "");
assert(lastPart.startsWith("hello"));
assert(lastPart.endsWith("world"));
}
// Check that the `dir` option works.
const dir = Deno.makeTempDirSync({ prefix: "tempdir" });
const file3 = Deno.makeTempFileSync({ dir });
assert(file3.startsWith(dir));
assert(/^[\\\/]/.test(file3.slice(dir.length)));
// Check that creating a temp file inside a nonexisting directory fails.
let err;
try {
Deno.makeTempFileSync({ dir: "/baddir" });
} catch (err_) {
err = err_;
}
assert(err instanceof Deno.errors.NotFound);
});
unitTest(
{ perms: { read: true, write: true } },
function makeTempFileSyncMode(): void {
const path = Deno.makeTempFileSync();
const pathInfo = Deno.statSync(path);
if (Deno.build.os !== "windows") {
assertEquals(pathInfo.mode! & 0o777, 0o600 & ~Deno.umask());
}
}
);
unitTest(function makeTempFileSyncPerm(): void {
// makeTempFileSync should require write permissions (for now).
let err;
try {
Deno.makeTempFileSync({ dir: "/baddir" });
} catch (err_) {
err = err_;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{ perms: { write: true } },
async function makeTempFileSuccess(): Promise<void> {
const file1 = await Deno.makeTempFile({ prefix: "hello", suffix: "world" });
const file2 = await Deno.makeTempFile({ prefix: "hello", suffix: "world" });
// Check that both dirs are different.
assert(file1 !== file2);
for (const dir of [file1, file2]) {
// Check that the prefix and suffix are applied.
const lastPart = dir.replace(/^.*[\\\/]/, "");
assert(lastPart.startsWith("hello"));
assert(lastPart.endsWith("world"));
}
// Check that the `dir` option works.
const dir = Deno.makeTempDirSync({ prefix: "tempdir" });
const file3 = await Deno.makeTempFile({ dir });
assert(file3.startsWith(dir));
assert(/^[\\\/]/.test(file3.slice(dir.length)));
// Check that creating a temp file inside a nonexisting directory fails.
let err;
try {
await Deno.makeTempFile({ dir: "/baddir" });
} catch (err_) {
err = err_;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function makeTempFileMode(): Promise<void> {
const path = await Deno.makeTempFile();
const pathInfo = Deno.statSync(path);
if (Deno.build.os !== "windows") {
assertEquals(pathInfo.mode! & 0o777, 0o600 & ~Deno.umask());
}
}
);

View file

@ -1,58 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
unitTest(async function metrics(): Promise<void> {
const m1 = Deno.metrics();
assert(m1.opsDispatched > 0);
assert(m1.opsDispatchedSync > 0);
assert(m1.opsCompleted > 0);
assert(m1.opsCompletedSync > 0);
assert(m1.bytesSentControl > 0);
assert(m1.bytesSentData >= 0);
assert(m1.bytesReceived > 0);
// Write to stdout to ensure a "data" message gets sent instead of just
// control messages.
const dataMsg = new Uint8Array([13, 13, 13]); // "\r\r\r",
await Deno.stdout.write(dataMsg);
const m2 = Deno.metrics();
assert(m2.opsDispatched > m1.opsDispatched);
assert(m2.opsDispatchedSync > m1.opsDispatchedSync);
assert(m2.opsDispatchedAsync > m1.opsDispatchedAsync);
assert(m2.opsCompleted > m1.opsCompleted);
assert(m2.opsCompletedSync > m1.opsCompletedSync);
assert(m2.opsCompletedAsync > m1.opsCompletedAsync);
assert(m2.bytesSentControl > m1.bytesSentControl);
assert(m2.bytesSentData >= m1.bytesSentData + dataMsg.byteLength);
assert(m2.bytesReceived > m1.bytesReceived);
});
unitTest(
{ perms: { write: true } },
function metricsUpdatedIfNoResponseSync(): void {
const filename = Deno.makeTempDirSync() + "/test.txt";
const data = new Uint8Array([41, 42, 43]);
Deno.writeFileSync(filename, data, { mode: 0o666 });
const metrics = Deno.metrics();
assert(metrics.opsDispatched === metrics.opsCompleted);
assert(metrics.opsDispatchedSync === metrics.opsCompletedSync);
}
);
unitTest(
{ perms: { write: true } },
async function metricsUpdatedIfNoResponseAsync(): Promise<void> {
const filename = Deno.makeTempDirSync() + "/test.txt";
const data = new Uint8Array([41, 42, 43]);
await Deno.writeFile(filename, data, { mode: 0o666 });
const metrics = Deno.metrics();
assert(metrics.opsDispatched === metrics.opsCompleted);
assert(metrics.opsDispatchedSync === metrics.opsCompletedSync);
assert(metrics.opsDispatchedAsync === metrics.opsCompletedAsync);
}
);

View file

@ -1,206 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals, assertThrows } from "./test_util.ts";
function assertDirectory(path: string, mode?: number): void {
const info = Deno.lstatSync(path);
assert(info.isDirectory);
if (Deno.build.os !== "windows" && mode !== undefined) {
assertEquals(info.mode! & 0o777, mode & ~Deno.umask());
}
}
unitTest(
{ perms: { read: true, write: true } },
function mkdirSyncSuccess(): void {
const path = Deno.makeTempDirSync() + "/dir";
Deno.mkdirSync(path);
assertDirectory(path);
}
);
unitTest(
{ perms: { read: true, write: true } },
function mkdirSyncMode(): void {
const path = Deno.makeTempDirSync() + "/dir";
Deno.mkdirSync(path, { mode: 0o737 });
assertDirectory(path, 0o737);
}
);
unitTest({ perms: { write: false } }, function mkdirSyncPerm(): void {
let err;
try {
Deno.mkdirSync("/baddir");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{ perms: { read: true, write: true } },
async function mkdirSuccess(): Promise<void> {
const path = Deno.makeTempDirSync() + "/dir";
await Deno.mkdir(path);
assertDirectory(path);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function mkdirMode(): Promise<void> {
const path = Deno.makeTempDirSync() + "/dir";
await Deno.mkdir(path, { mode: 0o737 });
assertDirectory(path, 0o737);
}
);
unitTest({ perms: { write: true } }, function mkdirErrSyncIfExists(): void {
let err;
try {
Deno.mkdirSync(".");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.AlreadyExists);
});
unitTest({ perms: { write: true } }, async function mkdirErrIfExists(): Promise<
void
> {
let err;
try {
await Deno.mkdir(".");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.AlreadyExists);
});
unitTest(
{ perms: { read: true, write: true } },
function mkdirSyncRecursive(): void {
const path = Deno.makeTempDirSync() + "/nested/directory";
Deno.mkdirSync(path, { recursive: true });
assertDirectory(path);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function mkdirRecursive(): Promise<void> {
const path = Deno.makeTempDirSync() + "/nested/directory";
await Deno.mkdir(path, { recursive: true });
assertDirectory(path);
}
);
unitTest(
{ perms: { read: true, write: true } },
function mkdirSyncRecursiveMode(): void {
const nested = Deno.makeTempDirSync() + "/nested";
const path = nested + "/dir";
Deno.mkdirSync(path, { mode: 0o737, recursive: true });
assertDirectory(path, 0o737);
assertDirectory(nested, 0o737);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function mkdirRecursiveMode(): Promise<void> {
const nested = Deno.makeTempDirSync() + "/nested";
const path = nested + "/dir";
await Deno.mkdir(path, { mode: 0o737, recursive: true });
assertDirectory(path, 0o737);
assertDirectory(nested, 0o737);
}
);
unitTest(
{ perms: { read: true, write: true } },
function mkdirSyncRecursiveIfExists(): void {
const path = Deno.makeTempDirSync() + "/dir";
Deno.mkdirSync(path, { mode: 0o737 });
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(path, { recursive: true, mode: 0o731 });
assertDirectory(path, 0o737);
if (Deno.build.os !== "windows") {
const pathLink = path + "Link";
Deno.symlinkSync(path, pathLink);
Deno.mkdirSync(pathLink, { recursive: true });
Deno.mkdirSync(pathLink, { recursive: true, mode: 0o731 });
assertDirectory(path, 0o737);
}
}
);
unitTest(
{ perms: { read: true, write: true } },
async function mkdirRecursiveIfExists(): Promise<void> {
const path = Deno.makeTempDirSync() + "/dir";
await Deno.mkdir(path, { mode: 0o737 });
await Deno.mkdir(path, { recursive: true });
await Deno.mkdir(path, { recursive: true, mode: 0o731 });
assertDirectory(path, 0o737);
if (Deno.build.os !== "windows") {
const pathLink = path + "Link";
Deno.symlinkSync(path, pathLink);
await Deno.mkdir(pathLink, { recursive: true });
await Deno.mkdir(pathLink, { recursive: true, mode: 0o731 });
assertDirectory(path, 0o737);
}
}
);
unitTest(
{ perms: { read: true, write: true } },
function mkdirSyncErrors(): void {
const testDir = Deno.makeTempDirSync();
const emptydir = testDir + "/empty";
const fulldir = testDir + "/dir";
const file = fulldir + "/file";
Deno.mkdirSync(emptydir);
Deno.mkdirSync(fulldir);
Deno.createSync(file).close();
assertThrows((): void => {
Deno.mkdirSync(emptydir, { recursive: false });
}, Deno.errors.AlreadyExists);
assertThrows((): void => {
Deno.mkdirSync(fulldir, { recursive: false });
}, Deno.errors.AlreadyExists);
assertThrows((): void => {
Deno.mkdirSync(file, { recursive: false });
}, Deno.errors.AlreadyExists);
assertThrows((): void => {
Deno.mkdirSync(file, { recursive: true });
}, Deno.errors.AlreadyExists);
if (Deno.build.os !== "windows") {
const fileLink = testDir + "/fileLink";
const dirLink = testDir + "/dirLink";
const danglingLink = testDir + "/danglingLink";
Deno.symlinkSync(file, fileLink);
Deno.symlinkSync(emptydir, dirLink);
Deno.symlinkSync(testDir + "/nonexistent", danglingLink);
assertThrows((): void => {
Deno.mkdirSync(dirLink, { recursive: false });
}, Deno.errors.AlreadyExists);
assertThrows((): void => {
Deno.mkdirSync(fileLink, { recursive: false });
}, Deno.errors.AlreadyExists);
assertThrows((): void => {
Deno.mkdirSync(fileLink, { recursive: true });
}, Deno.errors.AlreadyExists);
assertThrows((): void => {
Deno.mkdirSync(danglingLink, { recursive: false });
}, Deno.errors.AlreadyExists);
assertThrows((): void => {
Deno.mkdirSync(danglingLink, { recursive: true });
}, Deno.errors.AlreadyExists);
}
}
);

View file

@ -1,527 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
unitTest,
assert,
assertEquals,
createResolvable,
} from "./test_util.ts";
unitTest({ perms: { net: true } }, function netTcpListenClose(): void {
const listener = Deno.listen({ hostname: "127.0.0.1", port: 3500 });
assert(listener.addr.transport === "tcp");
assertEquals(listener.addr.hostname, "127.0.0.1");
assertEquals(listener.addr.port, 3500);
listener.close();
});
unitTest(
{
perms: { net: true },
// TODO:
ignore: Deno.build.os === "windows",
},
function netUdpListenClose(): void {
const socket = Deno.listenDatagram({
hostname: "127.0.0.1",
port: 3500,
transport: "udp",
});
assert(socket.addr.transport === "udp");
assertEquals(socket.addr.hostname, "127.0.0.1");
assertEquals(socket.addr.port, 3500);
socket.close();
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
function netUnixListenClose(): void {
const filePath = Deno.makeTempFileSync();
const socket = Deno.listen({
path: filePath,
transport: "unix",
});
assert(socket.addr.transport === "unix");
assertEquals(socket.addr.path, filePath);
socket.close();
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
function netUnixPacketListenClose(): void {
const filePath = Deno.makeTempFileSync();
const socket = Deno.listenDatagram({
path: filePath,
transport: "unixpacket",
});
assert(socket.addr.transport === "unixpacket");
assertEquals(socket.addr.path, filePath);
socket.close();
}
);
unitTest(
{
perms: { net: true },
},
async function netTcpCloseWhileAccept(): Promise<void> {
const listener = Deno.listen({ port: 4501 });
const p = listener.accept();
listener.close();
let err;
try {
await p;
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Error);
assertEquals(err.message, "Listener has been closed");
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
async function netUnixCloseWhileAccept(): Promise<void> {
const filePath = await Deno.makeTempFile();
const listener = Deno.listen({
path: filePath,
transport: "unix",
});
const p = listener.accept();
listener.close();
let err;
try {
await p;
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Error);
assertEquals(err.message, "Listener has been closed");
}
);
unitTest(
{ perms: { net: true } },
async function netTcpConcurrentAccept(): Promise<void> {
const listener = Deno.listen({ port: 4502 });
let acceptErrCount = 0;
const checkErr = (e: Error): void => {
if (e.message === "Listener has been closed") {
assertEquals(acceptErrCount, 1);
} else if (e.message === "Another accept task is ongoing") {
acceptErrCount++;
} else {
throw new Error("Unexpected error message");
}
};
const p = listener.accept().catch(checkErr);
const p1 = listener.accept().catch(checkErr);
await Promise.race([p, p1]);
listener.close();
await Promise.all([p, p1]);
assertEquals(acceptErrCount, 1);
}
);
// TODO(jsouto): Enable when tokio updates mio to v0.7!
unitTest(
{ ignore: true, perms: { read: true, write: true } },
async function netUnixConcurrentAccept(): Promise<void> {
const filePath = await Deno.makeTempFile();
const listener = Deno.listen({ transport: "unix", path: filePath });
let acceptErrCount = 0;
const checkErr = (e: Error): void => {
if (e.message === "Listener has been closed") {
assertEquals(acceptErrCount, 1);
} else if (e.message === "Another accept task is ongoing") {
acceptErrCount++;
} else {
throw new Error("Unexpected error message");
}
};
const p = listener.accept().catch(checkErr);
const p1 = listener.accept().catch(checkErr);
await Promise.race([p, p1]);
listener.close();
await [p, p1];
assertEquals(acceptErrCount, 1);
}
);
unitTest({ perms: { net: true } }, async function netTcpDialListen(): Promise<
void
> {
const listener = Deno.listen({ port: 3500 });
listener.accept().then(
async (conn): Promise<void> => {
assert(conn.remoteAddr != null);
assert(conn.localAddr.transport === "tcp");
assertEquals(conn.localAddr.hostname, "127.0.0.1");
assertEquals(conn.localAddr.port, 3500);
await conn.write(new Uint8Array([1, 2, 3]));
conn.close();
}
);
const conn = await Deno.connect({ hostname: "127.0.0.1", port: 3500 });
assert(conn.remoteAddr.transport === "tcp");
assertEquals(conn.remoteAddr.hostname, "127.0.0.1");
assertEquals(conn.remoteAddr.port, 3500);
assert(conn.localAddr != null);
const buf = new Uint8Array(1024);
const readResult = await conn.read(buf);
assertEquals(3, readResult);
assertEquals(1, buf[0]);
assertEquals(2, buf[1]);
assertEquals(3, buf[2]);
assert(conn.rid > 0);
assert(readResult !== null);
const readResult2 = await conn.read(buf);
assertEquals(readResult2, null);
listener.close();
conn.close();
});
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
async function netUnixDialListen(): Promise<void> {
const filePath = await Deno.makeTempFile();
const listener = Deno.listen({ path: filePath, transport: "unix" });
listener.accept().then(
async (conn): Promise<void> => {
assert(conn.remoteAddr != null);
assert(conn.localAddr.transport === "unix");
assertEquals(conn.localAddr.path, filePath);
await conn.write(new Uint8Array([1, 2, 3]));
conn.close();
}
);
const conn = await Deno.connect({ path: filePath, transport: "unix" });
assert(conn.remoteAddr.transport === "unix");
assertEquals(conn.remoteAddr.path, filePath);
assert(conn.remoteAddr != null);
const buf = new Uint8Array(1024);
const readResult = await conn.read(buf);
assertEquals(3, readResult);
assertEquals(1, buf[0]);
assertEquals(2, buf[1]);
assertEquals(3, buf[2]);
assert(conn.rid > 0);
assert(readResult !== null);
const readResult2 = await conn.read(buf);
assertEquals(readResult2, null);
listener.close();
conn.close();
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { net: true } },
async function netUdpSendReceive(): Promise<void> {
const alice = Deno.listenDatagram({ port: 3500, transport: "udp" });
assert(alice.addr.transport === "udp");
assertEquals(alice.addr.port, 3500);
assertEquals(alice.addr.hostname, "127.0.0.1");
const bob = Deno.listenDatagram({ port: 4501, transport: "udp" });
assert(bob.addr.transport === "udp");
assertEquals(bob.addr.port, 4501);
assertEquals(bob.addr.hostname, "127.0.0.1");
const sent = new Uint8Array([1, 2, 3]);
await alice.send(sent, bob.addr);
const [recvd, remote] = await bob.receive();
assert(remote.transport === "udp");
assertEquals(remote.port, 3500);
assertEquals(recvd.length, 3);
assertEquals(1, recvd[0]);
assertEquals(2, recvd[1]);
assertEquals(3, recvd[2]);
alice.close();
bob.close();
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
async function netUnixPacketSendReceive(): Promise<void> {
const filePath = await Deno.makeTempFile();
const alice = Deno.listenDatagram({
path: filePath,
transport: "unixpacket",
});
assert(alice.addr.transport === "unixpacket");
assertEquals(alice.addr.path, filePath);
const bob = Deno.listenDatagram({
path: filePath,
transport: "unixpacket",
});
assert(bob.addr.transport === "unixpacket");
assertEquals(bob.addr.path, filePath);
const sent = new Uint8Array([1, 2, 3]);
await alice.send(sent, bob.addr);
const [recvd, remote] = await bob.receive();
assert(remote.transport === "unixpacket");
assertEquals(remote.path, filePath);
assertEquals(recvd.length, 3);
assertEquals(1, recvd[0]);
assertEquals(2, recvd[1]);
assertEquals(3, recvd[2]);
alice.close();
bob.close();
}
);
unitTest(
{ perms: { net: true } },
async function netTcpListenIteratorBreakClosesResource(): Promise<void> {
const promise = createResolvable();
async function iterate(listener: Deno.Listener): Promise<void> {
let i = 0;
for await (const conn of listener) {
conn.close();
i++;
if (i > 1) {
break;
}
}
promise.resolve();
}
const addr = { hostname: "127.0.0.1", port: 8888 };
const listener = Deno.listen(addr);
iterate(listener);
await new Promise((resolve: () => void, _) => {
setTimeout(resolve, 100);
});
const conn1 = await Deno.connect(addr);
conn1.close();
const conn2 = await Deno.connect(addr);
conn2.close();
await promise;
}
);
unitTest(
{ perms: { net: true } },
async function netTcpListenCloseWhileIterating(): Promise<void> {
const listener = Deno.listen({ port: 8000 });
const nextWhileClosing = listener[Symbol.asyncIterator]().next();
listener.close();
assertEquals(await nextWhileClosing, { value: undefined, done: true });
const nextAfterClosing = listener[Symbol.asyncIterator]().next();
assertEquals(await nextAfterClosing, { value: undefined, done: true });
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { net: true } },
async function netUdpListenCloseWhileIterating(): Promise<void> {
const socket = Deno.listenDatagram({ port: 8000, transport: "udp" });
const nextWhileClosing = socket[Symbol.asyncIterator]().next();
socket.close();
assertEquals(await nextWhileClosing, { value: undefined, done: true });
const nextAfterClosing = socket[Symbol.asyncIterator]().next();
assertEquals(await nextAfterClosing, { value: undefined, done: true });
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
async function netUnixListenCloseWhileIterating(): Promise<void> {
const filePath = Deno.makeTempFileSync();
const socket = Deno.listen({ path: filePath, transport: "unix" });
const nextWhileClosing = socket[Symbol.asyncIterator]().next();
socket.close();
assertEquals(await nextWhileClosing, { value: undefined, done: true });
const nextAfterClosing = socket[Symbol.asyncIterator]().next();
assertEquals(await nextAfterClosing, { value: undefined, done: true });
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
async function netUnixPacketListenCloseWhileIterating(): Promise<void> {
const filePath = Deno.makeTempFileSync();
const socket = Deno.listenDatagram({
path: filePath,
transport: "unixpacket",
});
const nextWhileClosing = socket[Symbol.asyncIterator]().next();
socket.close();
assertEquals(await nextWhileClosing, { value: undefined, done: true });
const nextAfterClosing = socket[Symbol.asyncIterator]().next();
assertEquals(await nextAfterClosing, { value: undefined, done: true });
}
);
unitTest(
{
// FIXME(bartlomieju)
ignore: true,
perms: { net: true },
},
async function netListenAsyncIterator(): Promise<void> {
const addr = { hostname: "127.0.0.1", port: 3500 };
const listener = Deno.listen(addr);
const runAsyncIterator = async (): Promise<void> => {
for await (const conn of listener) {
await conn.write(new Uint8Array([1, 2, 3]));
conn.close();
}
};
runAsyncIterator();
const conn = await Deno.connect(addr);
const buf = new Uint8Array(1024);
const readResult = await conn.read(buf);
assertEquals(3, readResult);
assertEquals(1, buf[0]);
assertEquals(2, buf[1]);
assertEquals(3, buf[2]);
assert(conn.rid > 0);
assert(readResult !== null);
const readResult2 = await conn.read(buf);
assertEquals(readResult2, null);
listener.close();
conn.close();
}
);
unitTest(
{
// FIXME(bartlomieju)
ignore: true,
perms: { net: true },
},
async function netCloseWriteSuccess() {
const addr = { hostname: "127.0.0.1", port: 3500 };
const listener = Deno.listen(addr);
const closeDeferred = createResolvable();
listener.accept().then(async (conn) => {
await conn.write(new Uint8Array([1, 2, 3]));
await closeDeferred;
conn.close();
});
const conn = await Deno.connect(addr);
conn.closeWrite(); // closing write
const buf = new Uint8Array(1024);
// Check read not impacted
const readResult = await conn.read(buf);
assertEquals(3, readResult);
assertEquals(1, buf[0]);
assertEquals(2, buf[1]);
assertEquals(3, buf[2]);
// Check write should be closed
let err;
try {
await conn.write(new Uint8Array([1, 2, 3]));
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Deno.errors.BrokenPipe);
closeDeferred.resolve();
listener.close();
conn.close();
}
);
unitTest(
{
// FIXME(bartlomieju)
ignore: true,
perms: { net: true },
},
async function netDoubleCloseWrite() {
const addr = { hostname: "127.0.0.1", port: 3500 };
const listener = Deno.listen(addr);
const closeDeferred = createResolvable();
listener.accept().then(async (conn) => {
await closeDeferred;
conn.close();
});
const conn = await Deno.connect(addr);
conn.closeWrite(); // closing write
let err;
try {
// Duplicated close should throw error
conn.closeWrite();
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof Deno.errors.NotConnected);
closeDeferred.resolve();
listener.close();
conn.close();
}
);
unitTest(
{
perms: { net: true },
},
async function netHangsOnClose() {
let acceptedConn: Deno.Conn;
const resolvable = createResolvable();
async function iteratorReq(listener: Deno.Listener): Promise<void> {
const p = new Uint8Array(10);
const conn = await listener.accept();
acceptedConn = conn;
try {
while (true) {
const nread = await conn.read(p);
if (nread === null) {
break;
}
await conn.write(new Uint8Array([1, 2, 3]));
}
} catch (err) {
assert(!!err);
assert(err instanceof Deno.errors.BadResource);
}
resolvable.resolve();
}
const addr = { hostname: "127.0.0.1", port: 3500 };
const listener = Deno.listen(addr);
iteratorReq(listener);
const conn = await Deno.connect(addr);
await conn.write(new Uint8Array([1, 2, 3, 4]));
const buf = new Uint8Array(10);
await conn.read(buf);
conn!.close();
acceptedConn!.close();
listener.close();
await resolvable;
}
);

View file

@ -1,338 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
assert,
assertEquals,
assertNotEquals,
assertThrows,
unitTest,
} from "./test_util.ts";
unitTest({ perms: { env: true } }, function envSuccess(): void {
Deno.env.set("TEST_VAR", "A");
const env = Deno.env.toObject();
Deno.env.set("TEST_VAR", "B");
assertEquals(env["TEST_VAR"], "A");
assertNotEquals(Deno.env.get("TEST_VAR"), env["TEST_VAR"]);
});
unitTest({ perms: { env: true } }, function envNotFound(): void {
const r = Deno.env.get("env_var_does_not_exist!");
assertEquals(r, undefined);
});
unitTest(function envPermissionDenied1(): void {
let err;
try {
Deno.env.toObject();
} catch (e) {
err = e;
}
assertNotEquals(err, undefined);
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(function envPermissionDenied2(): void {
let err;
try {
Deno.env.get("PATH");
} catch (e) {
err = e;
}
assertNotEquals(err, undefined);
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
// This test verifies that on Windows, environment variables are
// case-insensitive. Case normalization needs be done using the collation
// that Windows uses, rather than naively using String.toLowerCase().
unitTest(
{
ignore: Deno.build.os !== "windows",
perms: { read: true, env: true, run: true },
},
async function envCaseInsensitive() {
// Utility function that runs a Deno subprocess with the environment
// specified in `inputEnv`. The subprocess reads the environment variables
// which are in the keys of `expectedEnv` and writes them to stdout as JSON.
// It is then verified that these match with the values of `expectedEnv`.
const checkChildEnv = async (
inputEnv: Record<string, string>,
expectedEnv: Record<string, string>
): Promise<void> => {
const src = `
console.log(
${JSON.stringify(Object.keys(expectedEnv))}.map(k => Deno.env.get(k))
)`;
const proc = Deno.run({
cmd: [Deno.execPath(), "eval", src],
env: inputEnv,
stdout: "piped",
});
const status = await proc.status();
assertEquals(status.success, true);
const expectedValues = Object.values(expectedEnv);
const actualValues = JSON.parse(
new TextDecoder().decode(await proc.output())
);
assertEquals(actualValues, expectedValues);
proc.close();
};
assertEquals(Deno.env.get("path"), Deno.env.get("PATH"));
assertEquals(Deno.env.get("Path"), Deno.env.get("PATH"));
// Check 'foo', 'Foo' and 'Foo' are case folded.
await checkChildEnv({ foo: "X" }, { foo: "X", Foo: "X", FOO: "X" });
// Check that 'µ' and 'Μ' are not case folded.
const lc1 = "µ";
const uc1 = lc1.toUpperCase();
assertNotEquals(lc1, uc1);
await checkChildEnv(
{ [lc1]: "mu", [uc1]: "MU" },
{ [lc1]: "mu", [uc1]: "MU" }
);
// Check that 'dž' and 'DŽ' are folded, but 'Dž' is preserved.
const c2 = "Dž";
const lc2 = c2.toLowerCase();
const uc2 = c2.toUpperCase();
assertNotEquals(c2, lc2);
assertNotEquals(c2, uc2);
await checkChildEnv(
{ [c2]: "Dz", [lc2]: "dz" },
{ [c2]: "Dz", [lc2]: "dz", [uc2]: "dz" }
);
await checkChildEnv(
{ [c2]: "Dz", [uc2]: "DZ" },
{ [c2]: "Dz", [uc2]: "DZ", [lc2]: "DZ" }
);
}
);
unitTest(function osPid(): void {
assert(Deno.pid > 0);
});
unitTest({ perms: { env: true } }, function getDir(): void {
type supportOS = "darwin" | "windows" | "linux";
interface Runtime {
os: supportOS;
shouldHaveValue: boolean;
}
interface Scenes {
kind: Deno.DirKind;
runtime: Runtime[];
}
const scenes: Scenes[] = [
{
kind: "config",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true },
],
},
{
kind: "cache",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true },
],
},
{
kind: "executable",
runtime: [
{ os: "darwin", shouldHaveValue: false },
{ os: "windows", shouldHaveValue: false },
{ os: "linux", shouldHaveValue: true },
],
},
{
kind: "data",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true },
],
},
{
kind: "data_local",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true },
],
},
{
kind: "audio",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false },
],
},
{
kind: "desktop",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false },
],
},
{
kind: "document",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false },
],
},
{
kind: "download",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false },
],
},
{
kind: "font",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: false },
{ os: "linux", shouldHaveValue: true },
],
},
{
kind: "picture",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false },
],
},
{
kind: "public",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false },
],
},
{
kind: "template",
runtime: [
{ os: "darwin", shouldHaveValue: false },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false },
],
},
{
kind: "tmp",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: true },
],
},
{
kind: "video",
runtime: [
{ os: "darwin", shouldHaveValue: true },
{ os: "windows", shouldHaveValue: true },
{ os: "linux", shouldHaveValue: false },
],
},
];
for (const s of scenes) {
for (const r of s.runtime) {
if (Deno.build.os !== r.os) continue;
if (r.shouldHaveValue) {
const d = Deno.dir(s.kind);
assert(d);
assert(d.length > 0);
}
}
}
});
unitTest(function getDirWithoutPermission(): void {
assertThrows(
() => Deno.dir("home"),
Deno.errors.PermissionDenied,
`run again with the --allow-env flag`
);
});
unitTest({ perms: { read: true } }, function execPath(): void {
assertNotEquals(Deno.execPath(), "");
});
unitTest({ perms: { read: false } }, function execPathPerm(): void {
let caughtError = false;
try {
Deno.execPath();
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
assert(caughtError);
});
unitTest({ perms: { env: true } }, function loadavgSuccess(): void {
const load = Deno.loadavg();
assertEquals(load.length, 3);
});
unitTest({ perms: { env: false } }, function loadavgPerm(): void {
let caughtError = false;
try {
Deno.loadavg();
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
assert(caughtError);
});
unitTest({ perms: { env: true } }, function hostnameDir(): void {
assertNotEquals(Deno.hostname(), "");
});
unitTest({ perms: { env: false } }, function hostnamePerm(): void {
let caughtError = false;
try {
Deno.hostname();
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
assert(caughtError);
});
unitTest({ perms: { env: true } }, function releaseDir(): void {
assertNotEquals(Deno.osRelease(), "");
});
unitTest({ perms: { env: false } }, function releasePerm(): void {
let caughtError = false;
try {
Deno.osRelease();
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
assert(caughtError);
});

View file

@ -1,15 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, createResolvable } from "./test_util.ts";
unitTest({ perms: { hrtime: false } }, async function performanceNow(): Promise<
void
> {
const resolvable = createResolvable();
const start = performance.now();
setTimeout((): void => {
const end = performance.now();
assert(end - start >= 10);
resolvable.resolve();
}, 10);
await resolvable;
});

View file

@ -1,27 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
unitTest(async function permissionInvalidName(): Promise<void> {
let thrown = false;
try {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
await Deno.permissions.query({ name: "foo" as any });
} catch (e) {
thrown = true;
assert(e instanceof Error);
} finally {
assert(thrown);
}
});
unitTest(async function permissionNetInvalidUrl(): Promise<void> {
let thrown = false;
try {
await Deno.permissions.query({ name: "net", url: ":" });
} catch (e) {
thrown = true;
assert(e instanceof URIError);
} finally {
assert(thrown);
}
});

View file

@ -1,386 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
assert,
assertEquals,
assertStrContains,
unitTest,
} from "./test_util.ts";
const {
kill,
run,
readFile,
open,
makeTempDir,
writeFile,
writeFileSync,
} = Deno;
unitTest(function runPermissions(): void {
let caughtError = false;
try {
run({ cmd: ["python", "-c", "print('hello world')"] });
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { run: true } }, async function runSuccess(): Promise<void> {
const p = run({
cmd: ["python", "-c", "print('hello world')"],
stdout: "piped",
stderr: "null",
});
const status = await p.status();
assertEquals(status.success, true);
assertEquals(status.code, 0);
assertEquals(status.signal, undefined);
p.stdout!.close();
p.close();
});
unitTest(
{ perms: { run: true } },
async function runCommandFailedWithCode(): Promise<void> {
const p = run({
cmd: ["python", "-c", "import sys;sys.exit(41 + 1)"],
});
const status = await p.status();
assertEquals(status.success, false);
assertEquals(status.code, 42);
assertEquals(status.signal, undefined);
p.close();
}
);
unitTest(
{
// No signals on windows.
ignore: Deno.build.os === "windows",
perms: { run: true },
},
async function runCommandFailedWithSignal(): Promise<void> {
const p = run({
cmd: ["python", "-c", "import os;os.kill(os.getpid(), 9)"],
});
const status = await p.status();
assertEquals(status.success, false);
assertEquals(status.code, undefined);
assertEquals(status.signal, 9);
p.close();
}
);
unitTest({ perms: { run: true } }, function runNotFound(): void {
let error;
try {
run({ cmd: ["this file hopefully doesn't exist"] });
} catch (e) {
error = e;
}
assert(error !== undefined);
assert(error instanceof Deno.errors.NotFound);
});
unitTest(
{ perms: { write: true, run: true } },
async function runWithCwdIsAsync(): Promise<void> {
const enc = new TextEncoder();
const cwd = await makeTempDir({ prefix: "deno_command_test" });
const exitCodeFile = "deno_was_here";
const pyProgramFile = "poll_exit.py";
const pyProgram = `
from sys import exit
from time import sleep
while True:
try:
with open("${exitCodeFile}", "r") as f:
line = f.readline()
code = int(line)
exit(code)
except IOError:
# Retry if we got here before deno wrote the file.
sleep(0.01)
pass
`;
writeFileSync(`${cwd}/${pyProgramFile}.py`, enc.encode(pyProgram));
const p = run({
cwd,
cmd: ["python", `${pyProgramFile}.py`],
});
// Write the expected exit code *after* starting python.
// This is how we verify that `run()` is actually asynchronous.
const code = 84;
writeFileSync(`${cwd}/${exitCodeFile}`, enc.encode(`${code}`));
const status = await p.status();
assertEquals(status.success, false);
assertEquals(status.code, code);
assertEquals(status.signal, undefined);
p.close();
}
);
unitTest({ perms: { run: true } }, async function runStdinPiped(): Promise<
void
> {
const p = run({
cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"],
stdin: "piped",
});
assert(p.stdin);
assert(!p.stdout);
assert(!p.stderr);
const msg = new TextEncoder().encode("hello");
const n = await p.stdin.write(msg);
assertEquals(n, msg.byteLength);
p.stdin!.close();
const status = await p.status();
assertEquals(status.success, true);
assertEquals(status.code, 0);
assertEquals(status.signal, undefined);
p.close();
});
unitTest({ perms: { run: true } }, async function runStdoutPiped(): Promise<
void
> {
const p = run({
cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"],
stdout: "piped",
});
assert(!p.stdin);
assert(!p.stderr);
const data = new Uint8Array(10);
let r = await p.stdout!.read(data);
if (r === null) {
throw new Error("p.stdout.read(...) should not be null");
}
assertEquals(r, 5);
const s = new TextDecoder().decode(data.subarray(0, r));
assertEquals(s, "hello");
r = await p.stdout!.read(data);
assertEquals(r, null);
p.stdout!.close();
const status = await p.status();
assertEquals(status.success, true);
assertEquals(status.code, 0);
assertEquals(status.signal, undefined);
p.close();
});
unitTest({ perms: { run: true } }, async function runStderrPiped(): Promise<
void
> {
const p = run({
cmd: ["python", "-c", "import sys; sys.stderr.write('hello')"],
stderr: "piped",
});
assert(!p.stdin);
assert(!p.stdout);
const data = new Uint8Array(10);
let r = await p.stderr!.read(data);
if (r === null) {
throw new Error("p.stderr.read should not return null here");
}
assertEquals(r, 5);
const s = new TextDecoder().decode(data.subarray(0, r));
assertEquals(s, "hello");
r = await p.stderr!.read(data);
assertEquals(r, null);
p.stderr!.close();
const status = await p.status();
assertEquals(status.success, true);
assertEquals(status.code, 0);
assertEquals(status.signal, undefined);
p.close();
});
unitTest({ perms: { run: true } }, async function runOutput(): Promise<void> {
const p = run({
cmd: ["python", "-c", "import sys; sys.stdout.write('hello')"],
stdout: "piped",
});
const output = await p.output();
const s = new TextDecoder().decode(output);
assertEquals(s, "hello");
p.close();
});
unitTest({ perms: { run: true } }, async function runStderrOutput(): Promise<
void
> {
const p = run({
cmd: ["python", "-c", "import sys; sys.stderr.write('error')"],
stderr: "piped",
});
const error = await p.stderrOutput();
const s = new TextDecoder().decode(error);
assertEquals(s, "error");
p.close();
});
unitTest(
{ perms: { run: true, write: true, read: true } },
async function runRedirectStdoutStderr(): Promise<void> {
const tempDir = await makeTempDir();
const fileName = tempDir + "/redirected_stdio.txt";
const file = await open(fileName, {
create: true,
write: true,
});
const p = run({
cmd: [
"python",
"-c",
"import sys; sys.stderr.write('error\\n'); sys.stdout.write('output\\n');",
],
stdout: file.rid,
stderr: file.rid,
});
await p.status();
p.close();
file.close();
const fileContents = await readFile(fileName);
const decoder = new TextDecoder();
const text = decoder.decode(fileContents);
assertStrContains(text, "error");
assertStrContains(text, "output");
}
);
unitTest(
{ perms: { run: true, write: true, read: true } },
async function runRedirectStdin(): Promise<void> {
const tempDir = await makeTempDir();
const fileName = tempDir + "/redirected_stdio.txt";
const encoder = new TextEncoder();
await writeFile(fileName, encoder.encode("hello"));
const file = await open(fileName);
const p = run({
cmd: ["python", "-c", "import sys; assert 'hello' == sys.stdin.read();"],
stdin: file.rid,
});
const status = await p.status();
assertEquals(status.code, 0);
p.close();
file.close();
}
);
unitTest({ perms: { run: true } }, async function runEnv(): Promise<void> {
const p = run({
cmd: [
"python",
"-c",
"import os, sys; sys.stdout.write(os.environ.get('FOO', '') + os.environ.get('BAR', ''))",
],
env: {
FOO: "0123",
BAR: "4567",
},
stdout: "piped",
});
const output = await p.output();
const s = new TextDecoder().decode(output);
assertEquals(s, "01234567");
p.close();
});
unitTest({ perms: { run: true } }, async function runClose(): Promise<void> {
const p = run({
cmd: [
"python",
"-c",
"from time import sleep; import sys; sleep(10000); sys.stderr.write('error')",
],
stderr: "piped",
});
assert(!p.stdin);
assert(!p.stdout);
p.close();
const data = new Uint8Array(10);
const r = await p.stderr!.read(data);
assertEquals(r, null);
p.stderr!.close();
});
unitTest(function signalNumbers(): void {
if (Deno.build.os === "darwin") {
assertEquals(Deno.Signal.SIGSTOP, 17);
} else if (Deno.build.os === "linux") {
assertEquals(Deno.Signal.SIGSTOP, 19);
}
});
unitTest(function killPermissions(): void {
let caughtError = false;
try {
// Unlike the other test cases, we don't have permission to spawn a
// subprocess we can safely kill. Instead we send SIGCONT to the current
// process - assuming that Deno does not have a special handler set for it
// and will just continue even if a signal is erroneously sent.
kill(Deno.pid, Deno.Signal.SIGCONT);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { run: true } }, async function killSuccess(): Promise<void> {
const p = run({
cmd: ["python", "-c", "from time import sleep; sleep(10000)"],
});
assertEquals(Deno.Signal.SIGINT, 2);
kill(p.pid, Deno.Signal.SIGINT);
const status = await p.status();
assertEquals(status.success, false);
// TODO(ry) On Linux, status.code is sometimes undefined and sometimes 1.
// The following assert is causing this test to be flaky. Investigate and
// re-enable when it can be made deterministic.
// assertEquals(status.code, 1);
// assertEquals(status.signal, Deno.Signal.SIGINT);
p.close();
});
unitTest({ perms: { run: true } }, function killFailed(): void {
const p = run({
cmd: ["python", "-c", "from time import sleep; sleep(10000)"],
});
assert(!p.stdin);
assert(!p.stdout);
let err;
try {
kill(p.pid, 12345);
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof TypeError);
p.close();
});

View file

@ -1,82 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
function assertSameContent(files: Deno.DirEntry[]): void {
let counter = 0;
for (const entry of files) {
if (entry.name === "subdir") {
assert(entry.isDirectory);
counter++;
}
}
assertEquals(counter, 1);
}
unitTest({ perms: { read: true } }, function readDirSyncSuccess(): void {
const files = [...Deno.readDirSync("cli/tests/")];
assertSameContent(files);
});
unitTest({ perms: { read: false } }, function readDirSyncPerm(): void {
let caughtError = false;
try {
Deno.readDirSync("tests/");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function readDirSyncNotDir(): void {
let caughtError = false;
let src;
try {
src = Deno.readDirSync("cli/tests/fixture.json");
} catch (err) {
caughtError = true;
assert(err instanceof Error);
}
assert(caughtError);
assertEquals(src, undefined);
});
unitTest({ perms: { read: true } }, function readDirSyncNotFound(): void {
let caughtError = false;
let src;
try {
src = Deno.readDirSync("bad_dir_name");
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.NotFound);
}
assert(caughtError);
assertEquals(src, undefined);
});
unitTest({ perms: { read: true } }, async function readDirSuccess(): Promise<
void
> {
const files = [];
for await (const dirEntry of Deno.readDir("cli/tests/")) {
files.push(dirEntry);
}
assertSameContent(files);
});
unitTest({ perms: { read: false } }, async function readDirPerm(): Promise<
void
> {
let caughtError = false;
try {
await Deno.readDir("tests/")[Symbol.asyncIterator]().next();
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});

View file

@ -1,65 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest({ perms: { read: true } }, function readFileSyncSuccess(): void {
const data = Deno.readFileSync("cli/tests/fixture.json");
assert(data.byteLength > 0);
const decoder = new TextDecoder("utf-8");
const json = decoder.decode(data);
const pkg = JSON.parse(json);
assertEquals(pkg.name, "deno");
});
unitTest({ perms: { read: false } }, function readFileSyncPerm(): void {
let caughtError = false;
try {
Deno.readFileSync("cli/tests/fixture.json");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function readFileSyncNotFound(): void {
let caughtError = false;
let data;
try {
data = Deno.readFileSync("bad_filename");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
assert(data === undefined);
});
unitTest({ perms: { read: true } }, async function readFileSuccess(): Promise<
void
> {
const data = await Deno.readFile("cli/tests/fixture.json");
assert(data.byteLength > 0);
const decoder = new TextDecoder("utf-8");
const json = decoder.decode(data);
const pkg = JSON.parse(json);
assertEquals(pkg.name, "deno");
});
unitTest({ perms: { read: false } }, async function readFilePerm(): Promise<
void
> {
let caughtError = false;
try {
await Deno.readFile("cli/tests/fixture.json");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function readFileSyncLoop(): void {
for (let i = 0; i < 256; i++) {
Deno.readFileSync("cli/tests/fixture.json");
}
});

View file

@ -1,73 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(
{ perms: { write: true, read: true } },
function readLinkSyncSuccess(): void {
const testDir = Deno.makeTempDirSync();
const target = testDir + "/target";
const symlink = testDir + "/symln";
Deno.mkdirSync(target);
// TODO Add test for Windows once symlink is implemented for Windows.
// See https://github.com/denoland/deno/issues/815.
if (Deno.build.os !== "windows") {
Deno.symlinkSync(target, symlink);
const targetPath = Deno.readLinkSync(symlink);
assertEquals(targetPath, target);
}
}
);
unitTest({ perms: { read: false } }, function readLinkSyncPerm(): void {
let caughtError = false;
try {
Deno.readLinkSync("/symlink");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function readLinkSyncNotFound(): void {
let caughtError = false;
let data;
try {
data = Deno.readLinkSync("bad_filename");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
assertEquals(data, undefined);
});
unitTest(
{ perms: { write: true, read: true } },
async function readLinkSuccess(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const target = testDir + "/target";
const symlink = testDir + "/symln";
Deno.mkdirSync(target);
// TODO Add test for Windows once symlink is implemented for Windows.
// See https://github.com/denoland/deno/issues/815.
if (Deno.build.os !== "windows") {
Deno.symlinkSync(target, symlink);
const targetPath = await Deno.readLink(symlink);
assertEquals(targetPath, target);
}
}
);
unitTest({ perms: { read: false } }, async function readLinkPerm(): Promise<
void
> {
let caughtError = false;
try {
await Deno.readLink("/symlink");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});

View file

@ -1,61 +0,0 @@
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest({ perms: { read: true } }, function readTextFileSyncSuccess(): void {
const data = Deno.readTextFileSync("cli/tests/fixture.json");
assert(data.length > 0);
const pkg = JSON.parse(data);
assertEquals(pkg.name, "deno");
});
unitTest({ perms: { read: false } }, function readTextFileSyncPerm(): void {
let caughtError = false;
try {
Deno.readTextFileSync("cli/tests/fixture.json");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function readTextFileSyncNotFound(): void {
let caughtError = false;
let data;
try {
data = Deno.readTextFileSync("bad_filename");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
assert(data === undefined);
});
unitTest(
{ perms: { read: true } },
async function readTextFileSuccess(): Promise<void> {
const data = await Deno.readTextFile("cli/tests/fixture.json");
assert(data.length > 0);
const pkg = JSON.parse(data);
assertEquals(pkg.name, "deno");
}
);
unitTest({ perms: { read: false } }, async function readTextFilePerm(): Promise<
void
> {
let caughtError = false;
try {
await Deno.readTextFile("cli/tests/fixture.json");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function readTextFileSyncLoop(): void {
for (let i = 0; i < 256; i++) {
Deno.readTextFileSync("cli/tests/fixture.json");
}
});

View file

@ -1,108 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
unitTest({ perms: { read: true } }, function realPathSyncSuccess(): void {
const incompletePath = "cli/tests/fixture.json";
const realPath = Deno.realPathSync(incompletePath);
if (Deno.build.os !== "windows") {
assert(realPath.startsWith("/"));
} else {
assert(/^[A-Z]/.test(realPath));
}
assert(realPath.endsWith(incompletePath));
});
unitTest(
{
ignore: Deno.build.os === "windows",
perms: { read: true, write: true },
},
function realPathSyncSymlink(): void {
const testDir = Deno.makeTempDirSync();
const target = testDir + "/target";
const symlink = testDir + "/symln";
Deno.mkdirSync(target);
Deno.symlinkSync(target, symlink);
const targetPath = Deno.realPathSync(symlink);
assert(targetPath.startsWith("/"));
assert(targetPath.endsWith("/target"));
}
);
unitTest({ perms: { read: false } }, function realPathSyncPerm(): void {
let caughtError = false;
try {
Deno.realPathSync("some_file");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function realPathSyncNotFound(): void {
let caughtError = false;
try {
Deno.realPathSync("bad_filename");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, async function realPathSuccess(): Promise<
void
> {
const incompletePath = "cli/tests/fixture.json";
const realPath = await Deno.realPath(incompletePath);
if (Deno.build.os !== "windows") {
assert(realPath.startsWith("/"));
} else {
assert(/^[A-Z]/.test(realPath));
}
assert(realPath.endsWith(incompletePath));
});
unitTest(
{
ignore: Deno.build.os === "windows",
perms: { read: true, write: true },
},
async function realPathSymlink(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const target = testDir + "/target";
const symlink = testDir + "/symln";
Deno.mkdirSync(target);
Deno.symlinkSync(target, symlink);
const targetPath = await Deno.realPath(symlink);
assert(targetPath.startsWith("/"));
assert(targetPath.endsWith("/target"));
}
);
unitTest({ perms: { read: false } }, async function realPathPerm(): Promise<
void
> {
let caughtError = false;
try {
await Deno.realPath("some_file");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, async function realPathNotFound(): Promise<
void
> {
let caughtError = false;
try {
await Deno.realPath("bad_filename");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
});

View file

@ -1,506 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
// SYNC
unitTest(
{ perms: { write: true, read: true } },
function removeSyncDirSuccess(): void {
// REMOVE EMPTY DIRECTORY
const path = Deno.makeTempDirSync() + "/subdir";
Deno.mkdirSync(path);
const pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory); // check exist first
Deno.removeSync(path); // remove
// We then check again after remove
let err;
try {
Deno.statSync(path);
} catch (e) {
err = e;
}
// Directory is gone
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
function removeSyncFileSuccess(): void {
// REMOVE FILE
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile); // check exist first
Deno.removeSync(filename); // remove
// We then check again after remove
let err;
try {
Deno.statSync(filename);
} catch (e) {
err = e;
}
// File is gone
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
function removeSyncFail(): void {
// NON-EMPTY DIRECTORY
const path = Deno.makeTempDirSync() + "/dir/subdir";
const subPath = path + "/subsubdir";
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(subPath);
const pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory); // check exist first
const subPathInfo = Deno.statSync(subPath);
assert(subPathInfo.isDirectory); // check exist first
let err;
try {
// Should not be able to recursively remove
Deno.removeSync(path);
} catch (e) {
err = e;
}
// TODO(ry) Is Other really the error we should get here? What would Go do?
assert(err instanceof Error);
// NON-EXISTENT DIRECTORY/FILE
try {
// Non-existent
Deno.removeSync("/baddir");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
function removeSyncDanglingSymlinkSuccess(): void {
const danglingSymlinkPath = Deno.makeTempDirSync() + "/dangling_symlink";
if (Deno.build.os === "windows") {
Deno.symlinkSync("unexistent_file", danglingSymlinkPath, {
type: "file",
});
} else {
Deno.symlinkSync("unexistent_file", danglingSymlinkPath);
}
const pathInfo = Deno.lstatSync(danglingSymlinkPath);
assert(pathInfo.isSymlink);
Deno.removeSync(danglingSymlinkPath);
let err;
try {
Deno.lstatSync(danglingSymlinkPath);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
function removeSyncValidSymlinkSuccess(): void {
const encoder = new TextEncoder();
const data = encoder.encode("Test");
const tempDir = Deno.makeTempDirSync();
const filePath = tempDir + "/test.txt";
const validSymlinkPath = tempDir + "/valid_symlink";
Deno.writeFileSync(filePath, data, { mode: 0o666 });
if (Deno.build.os === "windows") {
Deno.symlinkSync(filePath, validSymlinkPath, { type: "file" });
} else {
Deno.symlinkSync(filePath, validSymlinkPath);
}
const symlinkPathInfo = Deno.statSync(validSymlinkPath);
assert(symlinkPathInfo.isFile);
Deno.removeSync(validSymlinkPath);
let err;
try {
Deno.statSync(validSymlinkPath);
} catch (e) {
err = e;
}
Deno.removeSync(filePath);
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest({ perms: { write: false } }, function removeSyncPerm(): void {
let err;
try {
Deno.removeSync("/baddir");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{ perms: { write: true, read: true } },
function removeAllSyncDirSuccess(): void {
// REMOVE EMPTY DIRECTORY
let path = Deno.makeTempDirSync() + "/dir/subdir";
Deno.mkdirSync(path, { recursive: true });
let pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory); // check exist first
Deno.removeSync(path, { recursive: true }); // remove
// We then check again after remove
let err;
try {
Deno.statSync(path);
} catch (e) {
err = e;
}
// Directory is gone
assert(err instanceof Deno.errors.NotFound);
// REMOVE NON-EMPTY DIRECTORY
path = Deno.makeTempDirSync() + "/dir/subdir";
const subPath = path + "/subsubdir";
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(subPath);
pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory); // check exist first
const subPathInfo = Deno.statSync(subPath);
assert(subPathInfo.isDirectory); // check exist first
Deno.removeSync(path, { recursive: true }); // remove
// We then check parent directory again after remove
try {
Deno.statSync(path);
} catch (e) {
err = e;
}
// Directory is gone
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
function removeAllSyncFileSuccess(): void {
// REMOVE FILE
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile); // check exist first
Deno.removeSync(filename, { recursive: true }); // remove
// We then check again after remove
let err;
try {
Deno.statSync(filename);
} catch (e) {
err = e;
}
// File is gone
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest({ perms: { write: true } }, function removeAllSyncFail(): void {
// NON-EXISTENT DIRECTORY/FILE
let err;
try {
// Non-existent
Deno.removeSync("/baddir", { recursive: true });
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
});
unitTest({ perms: { write: false } }, function removeAllSyncPerm(): void {
let err;
try {
Deno.removeSync("/baddir", { recursive: true });
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
// ASYNC
unitTest(
{ perms: { write: true, read: true } },
async function removeDirSuccess(): Promise<void> {
// REMOVE EMPTY DIRECTORY
const path = Deno.makeTempDirSync() + "/dir/subdir";
Deno.mkdirSync(path, { recursive: true });
const pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory); // check exist first
await Deno.remove(path); // remove
// We then check again after remove
let err;
try {
Deno.statSync(path);
} catch (e) {
err = e;
}
// Directory is gone
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
async function removeFileSuccess(): Promise<void> {
// REMOVE FILE
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile); // check exist first
await Deno.remove(filename); // remove
// We then check again after remove
let err;
try {
Deno.statSync(filename);
} catch (e) {
err = e;
}
// File is gone
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
async function removeFail(): Promise<void> {
// NON-EMPTY DIRECTORY
const path = Deno.makeTempDirSync() + "/dir/subdir";
const subPath = path + "/subsubdir";
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(subPath);
const pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory); // check exist first
const subPathInfo = Deno.statSync(subPath);
assert(subPathInfo.isDirectory); // check exist first
let err;
try {
// Should not be able to recursively remove
await Deno.remove(path);
} catch (e) {
err = e;
}
assert(err instanceof Error);
// NON-EXISTENT DIRECTORY/FILE
try {
// Non-existent
await Deno.remove("/baddir");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
async function removeDanglingSymlinkSuccess(): Promise<void> {
const danglingSymlinkPath = Deno.makeTempDirSync() + "/dangling_symlink";
if (Deno.build.os === "windows") {
Deno.symlinkSync("unexistent_file", danglingSymlinkPath, {
type: "file",
});
} else {
Deno.symlinkSync("unexistent_file", danglingSymlinkPath);
}
const pathInfo = Deno.lstatSync(danglingSymlinkPath);
assert(pathInfo.isSymlink);
await Deno.remove(danglingSymlinkPath);
let err;
try {
Deno.lstatSync(danglingSymlinkPath);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
async function removeValidSymlinkSuccess(): Promise<void> {
const encoder = new TextEncoder();
const data = encoder.encode("Test");
const tempDir = Deno.makeTempDirSync();
const filePath = tempDir + "/test.txt";
const validSymlinkPath = tempDir + "/valid_symlink";
Deno.writeFileSync(filePath, data, { mode: 0o666 });
if (Deno.build.os === "windows") {
Deno.symlinkSync(filePath, validSymlinkPath, { type: "file" });
} else {
Deno.symlinkSync(filePath, validSymlinkPath);
}
const symlinkPathInfo = Deno.statSync(validSymlinkPath);
assert(symlinkPathInfo.isFile);
await Deno.remove(validSymlinkPath);
let err;
try {
Deno.statSync(validSymlinkPath);
} catch (e) {
err = e;
}
Deno.removeSync(filePath);
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest({ perms: { write: false } }, async function removePerm(): Promise<
void
> {
let err;
try {
await Deno.remove("/baddir");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{ perms: { write: true, read: true } },
async function removeAllDirSuccess(): Promise<void> {
// REMOVE EMPTY DIRECTORY
let path = Deno.makeTempDirSync() + "/dir/subdir";
Deno.mkdirSync(path, { recursive: true });
let pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory); // check exist first
await Deno.remove(path, { recursive: true }); // remove
// We then check again after remove
let err;
try {
Deno.statSync(path);
} catch (e) {
err = e;
}
// Directory is gone
assert(err instanceof Deno.errors.NotFound);
// REMOVE NON-EMPTY DIRECTORY
path = Deno.makeTempDirSync() + "/dir/subdir";
const subPath = path + "/subsubdir";
Deno.mkdirSync(path, { recursive: true });
Deno.mkdirSync(subPath);
pathInfo = Deno.statSync(path);
assert(pathInfo.isDirectory); // check exist first
const subPathInfo = Deno.statSync(subPath);
assert(subPathInfo.isDirectory); // check exist first
await Deno.remove(path, { recursive: true }); // remove
// We then check parent directory again after remove
try {
Deno.statSync(path);
} catch (e) {
err = e;
}
// Directory is gone
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { write: true, read: true } },
async function removeAllFileSuccess(): Promise<void> {
// REMOVE FILE
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const fileInfo = Deno.statSync(filename);
assert(fileInfo.isFile); // check exist first
await Deno.remove(filename, { recursive: true }); // remove
// We then check again after remove
let err;
try {
Deno.statSync(filename);
} catch (e) {
err = e;
}
// File is gone
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest({ perms: { write: true } }, async function removeAllFail(): Promise<
void
> {
// NON-EXISTENT DIRECTORY/FILE
let err;
try {
// Non-existent
await Deno.remove("/baddir", { recursive: true });
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
});
unitTest({ perms: { write: false } }, async function removeAllPerm(): Promise<
void
> {
let err;
try {
await Deno.remove("/baddir", { recursive: true });
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
if (Deno.build.os === "windows") {
unitTest(
{ perms: { run: true, write: true, read: true } },
async function removeFileSymlink(): Promise<void> {
const symlink = Deno.run({
cmd: ["cmd", "/c", "mklink", "file_link", "bar"],
stdout: "null",
});
assert(await symlink.status());
symlink.close();
await Deno.remove("file_link");
let err;
try {
await Deno.lstat("file_link");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest(
{ perms: { run: true, write: true, read: true } },
async function removeDirSymlink(): Promise<void> {
const symlink = Deno.run({
cmd: ["cmd", "/c", "mklink", "/d", "dir_link", "bar"],
stdout: "null",
});
assert(await symlink.status());
symlink.close();
await Deno.remove("dir_link");
let err;
try {
await Deno.lstat("dir_link");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
}

View file

@ -1,216 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals, assertThrows } from "./test_util.ts";
function assertMissing(path: string): void {
let caughtErr = false;
let info;
try {
info = Deno.lstatSync(path);
} catch (e) {
caughtErr = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtErr);
assertEquals(info, undefined);
}
function assertFile(path: string): void {
const info = Deno.lstatSync(path);
assert(info.isFile);
}
function assertDirectory(path: string, mode?: number): void {
const info = Deno.lstatSync(path);
assert(info.isDirectory);
if (Deno.build.os !== "windows" && mode !== undefined) {
assertEquals(info.mode! & 0o777, mode & ~Deno.umask());
}
}
unitTest(
{ perms: { read: true, write: true } },
function renameSyncSuccess(): void {
const testDir = Deno.makeTempDirSync();
const oldpath = testDir + "/oldpath";
const newpath = testDir + "/newpath";
Deno.mkdirSync(oldpath);
Deno.renameSync(oldpath, newpath);
assertDirectory(newpath);
assertMissing(oldpath);
}
);
unitTest(
{ perms: { read: false, write: true } },
function renameSyncReadPerm(): void {
let err;
try {
const oldpath = "/oldbaddir";
const newpath = "/newbaddir";
Deno.renameSync(oldpath, newpath);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
);
unitTest(
{ perms: { read: true, write: false } },
function renameSyncWritePerm(): void {
let err;
try {
const oldpath = "/oldbaddir";
const newpath = "/newbaddir";
Deno.renameSync(oldpath, newpath);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
}
);
unitTest(
{ perms: { read: true, write: true } },
async function renameSuccess(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const oldpath = testDir + "/oldpath";
const newpath = testDir + "/newpath";
Deno.mkdirSync(oldpath);
await Deno.rename(oldpath, newpath);
assertDirectory(newpath);
assertMissing(oldpath);
}
);
function readFileString(filename: string): string {
const dataRead = Deno.readFileSync(filename);
const dec = new TextDecoder("utf-8");
return dec.decode(dataRead);
}
function writeFileString(filename: string, s: string): void {
const enc = new TextEncoder();
const data = enc.encode(s);
Deno.writeFileSync(filename, data, { mode: 0o666 });
}
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
function renameSyncErrorsUnix(): void {
const testDir = Deno.makeTempDirSync();
const oldfile = testDir + "/oldfile";
const olddir = testDir + "/olddir";
const emptydir = testDir + "/empty";
const fulldir = testDir + "/dir";
const file = fulldir + "/file";
writeFileString(oldfile, "Hello");
Deno.mkdirSync(olddir);
Deno.mkdirSync(emptydir);
Deno.mkdirSync(fulldir);
writeFileString(file, "world");
assertThrows(
(): void => {
Deno.renameSync(oldfile, emptydir);
},
Error,
"Is a directory"
);
assertThrows(
(): void => {
Deno.renameSync(olddir, fulldir);
},
Error,
"Directory not empty"
);
assertThrows(
(): void => {
Deno.renameSync(olddir, file);
},
Error,
"Not a directory"
);
const fileLink = testDir + "/fileLink";
const dirLink = testDir + "/dirLink";
const danglingLink = testDir + "/danglingLink";
Deno.symlinkSync(file, fileLink);
Deno.symlinkSync(emptydir, dirLink);
Deno.symlinkSync(testDir + "/nonexistent", danglingLink);
assertThrows(
(): void => {
Deno.renameSync(olddir, fileLink);
},
Error,
"Not a directory"
);
assertThrows(
(): void => {
Deno.renameSync(olddir, dirLink);
},
Error,
"Not a directory"
);
assertThrows(
(): void => {
Deno.renameSync(olddir, danglingLink);
},
Error,
"Not a directory"
);
// should succeed on Unix
Deno.renameSync(olddir, emptydir);
Deno.renameSync(oldfile, dirLink);
Deno.renameSync(dirLink, danglingLink);
assertFile(danglingLink);
assertEquals("Hello", readFileString(danglingLink));
}
);
unitTest(
{ ignore: Deno.build.os !== "windows", perms: { read: true, write: true } },
function renameSyncErrorsWin(): void {
const testDir = Deno.makeTempDirSync();
const oldfile = testDir + "/oldfile";
const olddir = testDir + "/olddir";
const emptydir = testDir + "/empty";
const fulldir = testDir + "/dir";
const file = fulldir + "/file";
writeFileString(oldfile, "Hello");
Deno.mkdirSync(olddir);
Deno.mkdirSync(emptydir);
Deno.mkdirSync(fulldir);
writeFileString(file, "world");
assertThrows(
(): void => {
Deno.renameSync(oldfile, emptydir);
},
Deno.errors.PermissionDenied,
"Access is denied"
);
assertThrows(
(): void => {
Deno.renameSync(olddir, fulldir);
},
Deno.errors.PermissionDenied,
"Access is denied"
);
assertThrows(
(): void => {
Deno.renameSync(olddir, emptydir);
},
Deno.errors.PermissionDenied,
"Access is denied"
);
// should succeed on Windows
Deno.renameSync(olddir, file);
assertDirectory(file);
}
);

View file

@ -1,49 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(function fromInit(): void {
const req = new Request("https://example.com", {
body: "ahoyhoy",
method: "POST",
headers: {
"test-header": "value",
},
});
// @ts-ignore
assertEquals("ahoyhoy", req._bodySource);
assertEquals(req.url, "https://example.com");
assertEquals(req.headers.get("test-header"), "value");
});
unitTest(function fromRequest(): void {
const r = new Request("https://example.com");
// @ts-ignore
r._bodySource = "ahoyhoy";
r.headers.set("test-header", "value");
const req = new Request(r);
// @ts-ignore
assertEquals(req._bodySource, r._bodySource);
assertEquals(req.url, r.url);
assertEquals(req.headers.get("test-header"), r.headers.get("test-header"));
});
unitTest(async function cloneRequestBodyStream(): Promise<void> {
// hack to get a stream
const stream = new Request("", { body: "a test body" }).body;
const r1 = new Request("https://example.com", {
body: stream,
});
const r2 = r1.clone();
const b1 = await r1.text();
const b2 = await r2.text();
assertEquals(b1, b2);
// @ts-ignore
assert(r1._bodySource !== r2._bodySource);
});

View file

@ -1,61 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals, assert } from "./test_util.ts";
unitTest(function resourcesCloseBadArgs(): void {
let err;
try {
Deno.close((null as unknown) as number);
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.InvalidData);
});
unitTest(function resourcesStdio(): void {
const res = Deno.resources();
assertEquals(res[0], "stdin");
assertEquals(res[1], "stdout");
assertEquals(res[2], "stderr");
});
unitTest({ perms: { net: true } }, async function resourcesNet(): Promise<
void
> {
const listener = Deno.listen({ port: 4501 });
const dialerConn = await Deno.connect({ port: 4501 });
const listenerConn = await listener.accept();
const res = Deno.resources();
assertEquals(
Object.values(res).filter((r): boolean => r === "tcpListener").length,
1
);
const tcpStreams = Object.values(res).filter(
(r): boolean => r === "tcpStream"
);
assert(tcpStreams.length >= 2);
listenerConn.close();
dialerConn.close();
listener.close();
});
unitTest({ perms: { read: true } }, async function resourcesFile(): Promise<
void
> {
const resourcesBefore = Deno.resources();
const f = await Deno.open("cli/tests/hello.txt");
const resourcesAfter = Deno.resources();
f.close();
// check that exactly one new resource (file) was added
assertEquals(
Object.keys(resourcesAfter).length,
Object.keys(resourcesBefore).length + 1
);
const newRid = +Object.keys(resourcesAfter).find((rid): boolean => {
return !resourcesBefore.hasOwnProperty(rid);
})!;
assertEquals(resourcesAfter[newRid], "fsFile");
});

View file

@ -1,195 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
unitTest,
assert,
assertEquals,
assertThrows,
createResolvable,
} from "./test_util.ts";
function defer(n: number): Promise<void> {
return new Promise((resolve: () => void, _) => {
setTimeout(resolve, n);
});
}
unitTest(
{ ignore: Deno.build.os !== "windows" },
function signalsNotImplemented(): void {
assertThrows(
() => {
Deno.signal(1);
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.alarm(); // for SIGALRM
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.child(); // for SIGCHLD
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.hungup(); // for SIGHUP
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.interrupt(); // for SIGINT
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.io(); // for SIGIO
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.pipe(); // for SIGPIPE
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.quit(); // for SIGQUIT
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.terminate(); // for SIGTERM
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.userDefined1(); // for SIGUSR1
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.userDefined2(); // for SIGURS2
},
Error,
"not implemented"
);
assertThrows(
() => {
Deno.signals.windowChange(); // for SIGWINCH
},
Error,
"not implemented"
);
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { run: true, net: true } },
async function signalStreamTest(): Promise<void> {
const resolvable = createResolvable();
// This prevents the program from exiting.
const t = setInterval(() => {}, 1000);
let c = 0;
const sig = Deno.signal(Deno.Signal.SIGUSR1);
setTimeout(async () => {
await defer(20);
for (const _ of Array(3)) {
// Sends SIGUSR1 3 times.
Deno.kill(Deno.pid, Deno.Signal.SIGUSR1);
await defer(20);
}
sig.dispose();
resolvable.resolve();
});
for await (const _ of sig) {
c += 1;
}
assertEquals(c, 3);
clearInterval(t);
await resolvable;
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { run: true } },
async function signalPromiseTest(): Promise<void> {
const resolvable = createResolvable();
// This prevents the program from exiting.
const t = setInterval(() => {}, 1000);
const sig = Deno.signal(Deno.Signal.SIGUSR1);
setTimeout(() => {
Deno.kill(Deno.pid, Deno.Signal.SIGUSR1);
resolvable.resolve();
}, 20);
await sig;
sig.dispose();
clearInterval(t);
await resolvable;
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { run: true } },
function signalShorthandsTest(): void {
let s: Deno.SignalStream;
s = Deno.signals.alarm(); // for SIGALRM
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.child(); // for SIGCHLD
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.hungup(); // for SIGHUP
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.interrupt(); // for SIGINT
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.io(); // for SIGIO
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.pipe(); // for SIGPIPE
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.quit(); // for SIGQUIT
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.terminate(); // for SIGTERM
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.userDefined1(); // for SIGUSR1
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.userDefined2(); // for SIGURS2
assert(s instanceof Deno.SignalStream);
s.dispose();
s = Deno.signals.windowChange(); // for SIGWINCH
assert(s instanceof Deno.SignalStream);
s.dispose();
}
);

View file

@ -1,238 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(
{ perms: { read: true, write: true } },
function statSyncSuccess(): void {
const packageInfo = Deno.statSync("README.md");
assert(packageInfo.isFile);
assert(!packageInfo.isSymlink);
const modulesInfo = Deno.statSync("cli/tests/symlink_to_subdir");
assert(modulesInfo.isDirectory);
assert(!modulesInfo.isSymlink);
const testsInfo = Deno.statSync("cli/tests");
assert(testsInfo.isDirectory);
assert(!testsInfo.isSymlink);
const tempFile = Deno.makeTempFileSync();
const tempInfo = Deno.statSync(tempFile);
const now = Date.now();
assert(tempInfo.atime !== null && now - tempInfo.atime.valueOf() < 1000);
assert(tempInfo.mtime !== null && now - tempInfo.mtime.valueOf() < 1000);
assert(
tempInfo.birthtime === null || now - tempInfo.birthtime.valueOf() < 1000
);
}
);
unitTest({ perms: { read: false } }, function statSyncPerm(): void {
let caughtError = false;
try {
Deno.statSync("README.md");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function statSyncNotFound(): void {
let caughtError = false;
let badInfo;
try {
badInfo = Deno.statSync("bad_file_name");
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.NotFound);
}
assert(caughtError);
assertEquals(badInfo, undefined);
});
unitTest({ perms: { read: true } }, function lstatSyncSuccess(): void {
const packageInfo = Deno.lstatSync("README.md");
assert(packageInfo.isFile);
assert(!packageInfo.isSymlink);
const modulesInfo = Deno.lstatSync("cli/tests/symlink_to_subdir");
assert(!modulesInfo.isDirectory);
assert(modulesInfo.isSymlink);
const coreInfo = Deno.lstatSync("core");
assert(coreInfo.isDirectory);
assert(!coreInfo.isSymlink);
});
unitTest({ perms: { read: false } }, function lstatSyncPerm(): void {
let caughtError = false;
try {
Deno.lstatSync("README.md");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, function lstatSyncNotFound(): void {
let caughtError = false;
let badInfo;
try {
badInfo = Deno.lstatSync("bad_file_name");
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.NotFound);
}
assert(caughtError);
assertEquals(badInfo, undefined);
});
unitTest(
{ perms: { read: true, write: true } },
async function statSuccess(): Promise<void> {
const packageInfo = await Deno.stat("README.md");
assert(packageInfo.isFile);
assert(!packageInfo.isSymlink);
const modulesInfo = await Deno.stat("cli/tests/symlink_to_subdir");
assert(modulesInfo.isDirectory);
assert(!modulesInfo.isSymlink);
const testsInfo = await Deno.stat("cli/tests");
assert(testsInfo.isDirectory);
assert(!testsInfo.isSymlink);
const tempFile = await Deno.makeTempFile();
const tempInfo = await Deno.stat(tempFile);
const now = Date.now();
assert(tempInfo.atime !== null && now - tempInfo.atime.valueOf() < 1000);
assert(tempInfo.mtime !== null && now - tempInfo.mtime.valueOf() < 1000);
assert(
tempInfo.birthtime === null || now - tempInfo.birthtime.valueOf() < 1000
);
}
);
unitTest({ perms: { read: false } }, async function statPerm(): Promise<void> {
let caughtError = false;
try {
await Deno.stat("README.md");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, async function statNotFound(): Promise<
void
> {
let caughtError = false;
let badInfo;
try {
badInfo = await Deno.stat("bad_file_name");
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.NotFound);
}
assert(caughtError);
assertEquals(badInfo, undefined);
});
unitTest({ perms: { read: true } }, async function lstatSuccess(): Promise<
void
> {
const packageInfo = await Deno.lstat("README.md");
assert(packageInfo.isFile);
assert(!packageInfo.isSymlink);
const modulesInfo = await Deno.lstat("cli/tests/symlink_to_subdir");
assert(!modulesInfo.isDirectory);
assert(modulesInfo.isSymlink);
const coreInfo = await Deno.lstat("core");
assert(coreInfo.isDirectory);
assert(!coreInfo.isSymlink);
});
unitTest({ perms: { read: false } }, async function lstatPerm(): Promise<void> {
let caughtError = false;
try {
await Deno.lstat("README.md");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest({ perms: { read: true } }, async function lstatNotFound(): Promise<
void
> {
let caughtError = false;
let badInfo;
try {
badInfo = await Deno.lstat("bad_file_name");
} catch (err) {
caughtError = true;
assert(err instanceof Deno.errors.NotFound);
}
assert(caughtError);
assertEquals(badInfo, undefined);
});
unitTest(
{ ignore: Deno.build.os !== "windows", perms: { read: true, write: true } },
function statNoUnixFields(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const tempDir = Deno.makeTempDirSync();
const filename = tempDir + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
const s = Deno.statSync(filename);
assert(s.dev === null);
assert(s.ino === null);
assert(s.mode === null);
assert(s.nlink === null);
assert(s.uid === null);
assert(s.gid === null);
assert(s.rdev === null);
assert(s.blksize === null);
assert(s.blocks === null);
}
);
unitTest(
{ ignore: Deno.build.os === "windows", perms: { read: true, write: true } },
function statUnixFields(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const tempDir = Deno.makeTempDirSync();
const filename = tempDir + "/test.txt";
const filename2 = tempDir + "/test2.txt";
Deno.writeFileSync(filename, data, { mode: 0o666 });
// Create a link
Deno.linkSync(filename, filename2);
const s = Deno.statSync(filename);
assert(s.dev !== null);
assert(s.ino !== null);
assertEquals(s.mode! & 0o666, 0o666);
assertEquals(s.nlink, 2);
assert(s.uid !== null);
assert(s.gid !== null);
assert(s.rdev !== null);
assert(s.blksize !== null);
assert(s.blocks !== null);
}
);

View file

@ -1,131 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
import { assertThrowsAsync } from "../../../std/testing/asserts.ts";
unitTest(function streamPipeLocks() {
const rs = new ReadableStream();
const ws = new WritableStream();
assertEquals(rs.locked, false);
assertEquals(ws.locked, false);
rs.pipeTo(ws);
assert(rs.locked);
assert(ws.locked);
});
unitTest(async function streamPipeFinishUnlocks() {
const rs = new ReadableStream({
start(controller: ReadableStreamDefaultController): void {
controller.close();
},
});
const ws = new WritableStream();
await rs.pipeTo(ws);
assertEquals(rs.locked, false);
assertEquals(ws.locked, false);
});
unitTest(async function streamPipeReadableStreamLocked() {
const rs = new ReadableStream();
const ws = new WritableStream();
rs.getReader();
await assertThrowsAsync(async () => {
await rs.pipeTo(ws);
}, TypeError);
});
unitTest(async function streamPipeReadableStreamLocked() {
const rs = new ReadableStream();
const ws = new WritableStream();
ws.getWriter();
await assertThrowsAsync(async () => {
await rs.pipeTo(ws);
}, TypeError);
});
unitTest(async function streamPipeLotsOfChunks() {
const CHUNKS = 10;
const rs = new ReadableStream<number>({
start(c: ReadableStreamDefaultController): void {
for (let i = 0; i < CHUNKS; ++i) {
c.enqueue(i);
}
c.close();
},
});
const written: Array<string | number> = [];
const ws = new WritableStream(
{
write(chunk: number): void {
written.push(chunk);
},
close(): void {
written.push("closed");
},
},
new CountQueuingStrategy({ highWaterMark: CHUNKS })
);
await rs.pipeTo(ws);
const targetValues = [];
for (let i = 0; i < CHUNKS; ++i) {
targetValues.push(i);
}
targetValues.push("closed");
assertEquals(written, targetValues, "the correct values must be written");
// Ensure both readable and writable are closed by the time the pipe finishes.
await Promise.all([rs.getReader().closed, ws.getWriter().closed]);
});
for (const preventAbort of [true, false]) {
unitTest(function undefinedRejectionFromPull() {
const rs = new ReadableStream({
pull(): Promise<void> {
return Promise.reject(undefined);
},
});
return rs.pipeTo(new WritableStream(), { preventAbort }).then(
() => {
throw new Error("pipeTo promise should be rejected");
},
(value) =>
assertEquals(value, undefined, "rejection value should be undefined")
);
});
}
for (const preventCancel of [true, false]) {
unitTest(function undefinedRejectionWithPreventCancel() {
const rs = new ReadableStream({
pull(controller: ReadableStreamDefaultController<number>): void {
controller.enqueue(0);
},
});
const ws = new WritableStream({
write(): Promise<void> {
return Promise.reject(undefined);
},
});
return rs.pipeTo(ws, { preventCancel }).then(
() => {
throw new Error("pipeTo promise should be rejected");
},
(value) =>
assertEquals(value, undefined, "rejection value should be undefined")
);
});
}

View file

@ -1,562 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
unitTest,
assert,
assertEquals,
assertNotEquals,
assertThrows,
} from "./test_util.ts";
function delay(seconds: number): Promise<void> {
return new Promise<void>((resolve) => {
setTimeout(() => {
resolve();
}, seconds);
});
}
function readableStreamToArray<R>(
readable: { getReader(): ReadableStreamDefaultReader<R> },
reader?: ReadableStreamDefaultReader<R>
): Promise<R[]> {
if (reader === undefined) {
reader = readable.getReader();
}
const chunks: R[] = [];
return pump();
function pump(): Promise<R[]> {
return reader!.read().then((result) => {
if (result.done) {
return chunks;
}
chunks.push(result.value);
return pump();
});
}
}
unitTest(function transformStreamConstructedWithTransformFunction() {
new TransformStream({ transform(): void {} });
});
unitTest(function transformStreamConstructedNoTransform() {
new TransformStream();
new TransformStream({});
});
unitTest(function transformStreamIntstancesHaveProperProperties() {
const ts = new TransformStream({ transform(): void {} });
const proto = Object.getPrototypeOf(ts);
const writableStream = Object.getOwnPropertyDescriptor(proto, "writable");
assert(writableStream !== undefined, "it has a writable property");
assert(!writableStream.enumerable, "writable should be non-enumerable");
assertEquals(
typeof writableStream.get,
"function",
"writable should have a getter"
);
assertEquals(
writableStream.set,
undefined,
"writable should not have a setter"
);
assert(writableStream.configurable, "writable should be configurable");
assert(
ts.writable instanceof WritableStream,
"writable is an instance of WritableStream"
);
assert(
WritableStream.prototype.getWriter.call(ts.writable),
"writable should pass WritableStream brand check"
);
const readableStream = Object.getOwnPropertyDescriptor(proto, "readable");
assert(readableStream !== undefined, "it has a readable property");
assert(!readableStream.enumerable, "readable should be non-enumerable");
assertEquals(
typeof readableStream.get,
"function",
"readable should have a getter"
);
assertEquals(
readableStream.set,
undefined,
"readable should not have a setter"
);
assert(readableStream.configurable, "readable should be configurable");
assert(
ts.readable instanceof ReadableStream,
"readable is an instance of ReadableStream"
);
assertNotEquals(
ReadableStream.prototype.getReader.call(ts.readable),
undefined,
"readable should pass ReadableStream brand check"
);
});
unitTest(function transformStreamWritableStartsAsWritable() {
const ts = new TransformStream({ transform(): void {} });
const writer = ts.writable.getWriter();
assertEquals(writer.desiredSize, 1, "writer.desiredSize should be 1");
});
unitTest(async function transformStreamReadableCanReadOutOfWritable() {
const ts = new TransformStream();
const writer = ts.writable.getWriter();
writer.write("a");
assertEquals(
writer.desiredSize,
0,
"writer.desiredSize should be 0 after write()"
);
const result = await ts.readable.getReader().read();
assertEquals(
result.value,
"a",
"result from reading the readable is the same as was written to writable"
);
assert(!result.done, "stream should not be done");
await delay(0);
assert(writer.desiredSize === 1, "desiredSize should be 1 again");
});
unitTest(async function transformStreamCanReadWhatIsWritten() {
let c: TransformStreamDefaultController;
const ts = new TransformStream({
start(controller: TransformStreamDefaultController): void {
c = controller;
},
transform(chunk: string): void {
c.enqueue(chunk.toUpperCase());
},
});
const writer = ts.writable.getWriter();
writer.write("a");
const result = await ts.readable.getReader().read();
assertEquals(
result.value,
"A",
"result from reading the readable is the transformation of what was written to writable"
);
assert(!result.done, "stream should not be done");
});
unitTest(async function transformStreamCanReadBothChunks() {
let c: TransformStreamDefaultController;
const ts = new TransformStream({
start(controller: TransformStreamDefaultController): void {
c = controller;
},
transform(chunk: string): void {
c.enqueue(chunk.toUpperCase());
c.enqueue(chunk.toUpperCase());
},
});
const writer = ts.writable.getWriter();
writer.write("a");
const reader = ts.readable.getReader();
const result1 = await reader.read();
assertEquals(
result1.value,
"A",
"the first chunk read is the transformation of the single chunk written"
);
assert(!result1.done, "stream should not be done");
const result2 = await reader.read();
assertEquals(
result2.value,
"A",
"the second chunk read is also the transformation of the single chunk written"
);
assert(!result2.done, "stream should not be done");
});
unitTest(async function transformStreamCanReadWhatIsWritten() {
let c: TransformStreamDefaultController;
const ts = new TransformStream({
start(controller: TransformStreamDefaultController): void {
c = controller;
},
transform(chunk: string): Promise<void> {
return delay(0).then(() => c.enqueue(chunk.toUpperCase()));
},
});
const writer = ts.writable.getWriter();
writer.write("a");
const result = await ts.readable.getReader().read();
assertEquals(
result.value,
"A",
"result from reading the readable is the transformation of what was written to writable"
);
assert(!result.done, "stream should not be done");
});
unitTest(async function transformStreamAsyncReadMultipleChunks() {
let doSecondEnqueue: () => void;
let returnFromTransform: () => void;
const ts = new TransformStream({
transform(
chunk: string,
controller: TransformStreamDefaultController
): Promise<void> {
delay(0).then(() => controller.enqueue(chunk.toUpperCase()));
doSecondEnqueue = (): void => controller.enqueue(chunk.toUpperCase());
return new Promise((resolve) => {
returnFromTransform = resolve;
});
},
});
const reader = ts.readable.getReader();
const writer = ts.writable.getWriter();
writer.write("a");
const result1 = await reader.read();
assertEquals(
result1.value,
"A",
"the first chunk read is the transformation of the single chunk written"
);
assert(!result1.done, "stream should not be done");
doSecondEnqueue!();
const result2 = await reader.read();
assertEquals(
result2.value,
"A",
"the second chunk read is also the transformation of the single chunk written"
);
assert(!result2.done, "stream should not be done");
returnFromTransform!();
});
unitTest(function transformStreamClosingWriteClosesRead() {
const ts = new TransformStream({ transform(): void {} });
const writer = ts.writable.getWriter();
writer.close();
return Promise.all([writer.closed, ts.readable.getReader().closed]).then(
undefined
);
});
unitTest(async function transformStreamCloseWaitAwaitsTransforms() {
let transformResolve: () => void;
const transformPromise = new Promise<void>((resolve) => {
transformResolve = resolve;
});
const ts = new TransformStream(
{
transform(): Promise<void> {
return transformPromise;
},
},
undefined,
{ highWaterMark: 1 }
);
const writer = ts.writable.getWriter();
writer.write("a");
writer.close();
let rsClosed = false;
ts.readable.getReader().closed.then(() => {
rsClosed = true;
});
await delay(0);
assertEquals(rsClosed, false, "readable is not closed after a tick");
transformResolve!();
await writer.closed;
// TODO: Is this expectation correct?
assertEquals(rsClosed, true, "readable is closed at that point");
});
unitTest(async function transformStreamCloseWriteAfterSyncEnqueues() {
let c: TransformStreamDefaultController<string>;
const ts = new TransformStream<string, string>({
start(controller: TransformStreamDefaultController): void {
c = controller;
},
transform(): Promise<void> {
c.enqueue("x");
c.enqueue("y");
return delay(0);
},
});
const writer = ts.writable.getWriter();
writer.write("a");
writer.close();
const readableChunks = readableStreamToArray(ts.readable);
await writer.closed;
const chunks = await readableChunks;
assertEquals(
chunks,
["x", "y"],
"both enqueued chunks can be read from the readable"
);
});
unitTest(async function transformStreamWritableCloseAsyncAfterAsyncEnqueues() {
let c: TransformStreamDefaultController<string>;
const ts = new TransformStream<string, string>({
start(controller: TransformStreamDefaultController<string>): void {
c = controller;
},
transform(): Promise<void> {
return delay(0)
.then(() => c.enqueue("x"))
.then(() => c.enqueue("y"))
.then(() => delay(0));
},
});
const writer = ts.writable.getWriter();
writer.write("a");
writer.close();
const readableChunks = readableStreamToArray(ts.readable);
await writer.closed;
const chunks = await readableChunks;
assertEquals(
chunks,
["x", "y"],
"both enqueued chunks can be read from the readable"
);
});
unitTest(async function transformStreamTransformerMethodsCalledAsMethods() {
let c: TransformStreamDefaultController<string>;
const transformer = {
suffix: "-suffix",
start(controller: TransformStreamDefaultController<string>): void {
c = controller;
c.enqueue("start" + this.suffix);
},
transform(chunk: string): void {
c.enqueue(chunk + this.suffix);
},
flush(): void {
c.enqueue("flushed" + this.suffix);
},
};
const ts = new TransformStream(transformer);
const writer = ts.writable.getWriter();
writer.write("a");
writer.close();
const readableChunks = readableStreamToArray(ts.readable);
await writer.closed;
const chunks = await readableChunks;
assertEquals(
chunks,
["start-suffix", "a-suffix", "flushed-suffix"],
"all enqueued chunks have suffixes"
);
});
unitTest(async function transformStreamMethodsShouldNotBeAppliedOrCalled() {
function functionWithOverloads(): void {}
functionWithOverloads.apply = (): void => {
throw new Error("apply() should not be called");
};
functionWithOverloads.call = (): void => {
throw new Error("call() should not be called");
};
const ts = new TransformStream({
start: functionWithOverloads,
transform: functionWithOverloads,
flush: functionWithOverloads,
});
const writer = ts.writable.getWriter();
writer.write("a");
writer.close();
await readableStreamToArray(ts.readable);
});
unitTest(async function transformStreamCallTransformSync() {
let transformCalled = false;
const ts = new TransformStream(
{
transform(): void {
transformCalled = true;
},
},
undefined,
{ highWaterMark: Infinity }
);
// transform() is only called synchronously when there is no backpressure and
// all microtasks have run.
await delay(0);
const writePromise = ts.writable.getWriter().write(undefined);
assert(transformCalled, "transform() should have been called");
await writePromise;
});
unitTest(function transformStreamCloseWriteCloesesReadWithNoChunks() {
const ts = new TransformStream({}, undefined, { highWaterMark: 0 });
const writer = ts.writable.getWriter();
writer.close();
return Promise.all([writer.closed, ts.readable.getReader().closed]).then(
undefined
);
});
unitTest(function transformStreamEnqueueThrowsAfterTerminate() {
new TransformStream({
start(controller: TransformStreamDefaultController): void {
controller.terminate();
assertThrows(() => {
controller.enqueue(undefined);
}, TypeError);
},
});
});
unitTest(function transformStreamEnqueueThrowsAfterReadableCancel() {
let controller: TransformStreamDefaultController;
const ts = new TransformStream({
start(c: TransformStreamDefaultController): void {
controller = c;
},
});
const cancelPromise = ts.readable.cancel();
assertThrows(
() => controller.enqueue(undefined),
TypeError,
undefined,
"enqueue should throw"
);
return cancelPromise;
});
unitTest(function transformStreamSecondTerminateNoOp() {
new TransformStream({
start(controller: TransformStreamDefaultController): void {
controller.terminate();
controller.terminate();
},
});
});
unitTest(async function transformStreamTerminateAfterReadableCancelIsNoop() {
let controller: TransformStreamDefaultController;
const ts = new TransformStream({
start(c: TransformStreamDefaultController): void {
controller = c;
},
});
const cancelReason = { name: "cancelReason" };
const cancelPromise = ts.readable.cancel(cancelReason);
controller!.terminate();
await cancelPromise;
try {
await ts.writable.getWriter().closed;
} catch (e) {
assert(e === cancelReason);
return;
}
throw new Error("closed should have rejected");
});
unitTest(async function transformStreamStartCalledOnce() {
let calls = 0;
new TransformStream({
start(): void {
++calls;
},
});
await delay(0);
assertEquals(calls, 1, "start() should have been called exactly once");
});
unitTest(function transformStreamReadableTypeThrows() {
assertThrows(
// eslint-disable-next-line
() => new TransformStream({ readableType: "bytes" as any }),
RangeError,
undefined,
"constructor should throw"
);
});
unitTest(function transformStreamWirtableTypeThrows() {
assertThrows(
// eslint-disable-next-line
() => new TransformStream({ writableType: "bytes" as any }),
RangeError,
undefined,
"constructor should throw"
);
});
unitTest(function transformStreamSubclassable() {
class Subclass extends TransformStream {
extraFunction(): boolean {
return true;
}
}
assert(
Object.getPrototypeOf(Subclass.prototype) === TransformStream.prototype,
"Subclass.prototype's prototype should be TransformStream.prototype"
);
assert(
Object.getPrototypeOf(Subclass) === TransformStream,
"Subclass's prototype should be TransformStream"
);
const sub = new Subclass();
assert(
sub instanceof TransformStream,
"Subclass object should be an instance of TransformStream"
);
assert(
sub instanceof Subclass,
"Subclass object should be an instance of Subclass"
);
const readableGetter = Object.getOwnPropertyDescriptor(
TransformStream.prototype,
"readable"
)!.get;
assert(
readableGetter!.call(sub) === sub.readable,
"Subclass object should pass brand check"
);
assert(
sub.extraFunction(),
"extraFunction() should be present on Subclass object"
);
});

View file

@ -1,253 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals, assertThrows } from "./test_util.ts";
unitTest(function writableStreamDesiredSizeOnReleasedWriter() {
const ws = new WritableStream();
const writer = ws.getWriter();
writer.releaseLock();
assertThrows(() => {
writer.desiredSize;
}, TypeError);
});
unitTest(function writableStreamDesiredSizeInitialValue() {
const ws = new WritableStream();
const writer = ws.getWriter();
assertEquals(writer.desiredSize, 1);
});
unitTest(async function writableStreamDesiredSizeClosed() {
const ws = new WritableStream();
const writer = ws.getWriter();
await writer.close();
assertEquals(writer.desiredSize, 0);
});
unitTest(function writableStreamStartThrowsDesiredSizeNull() {
const ws = new WritableStream({
start(c): void {
c.error();
},
});
const writer = ws.getWriter();
assertEquals(writer.desiredSize, null, "desiredSize should be null");
});
unitTest(function getWriterOnClosingStream() {
const ws = new WritableStream({});
const writer = ws.getWriter();
writer.close();
writer.releaseLock();
ws.getWriter();
});
unitTest(async function getWriterOnClosedStream() {
const ws = new WritableStream({});
const writer = ws.getWriter();
await writer.close();
writer.releaseLock();
ws.getWriter();
});
unitTest(function getWriterOnAbortedStream() {
const ws = new WritableStream({});
const writer = ws.getWriter();
writer.abort();
writer.releaseLock();
ws.getWriter();
});
unitTest(function getWriterOnErroredStream() {
const ws = new WritableStream({
start(c): void {
c.error();
},
});
const writer = ws.getWriter();
return writer.closed.then(
(v) => {
throw new Error(`writer.closed fulfilled unexpectedly with: ${v}`);
},
() => {
writer.releaseLock();
ws.getWriter();
}
);
});
unitTest(function closedAndReadyOnReleasedWriter() {
const ws = new WritableStream({});
const writer = ws.getWriter();
writer.releaseLock();
return writer.closed.then(
(v) => {
throw new Error("writer.closed fulfilled unexpectedly with: " + v);
},
(closedRejection) => {
assertEquals(
closedRejection.name,
"TypeError",
"closed promise should reject with a TypeError"
);
return writer.ready.then(
(v) => {
throw new Error("writer.ready fulfilled unexpectedly with: " + v);
},
(readyRejection) =>
assertEquals(
readyRejection,
closedRejection,
"ready promise should reject with the same error"
)
);
}
);
});
unitTest(function sinkMethodsCalledAsMethods() {
let thisObject: Sink | null = null;
// Calls to Sink methods after the first are implicitly ignored. Only the
// first value that is passed to the resolver is used.
class Sink {
start(): void {
assertEquals(this, thisObject, "start should be called as a method");
}
write(): void {
assertEquals(this, thisObject, "write should be called as a method");
}
close(): void {
assertEquals(this, thisObject, "close should be called as a method");
}
abort(): void {
assertEquals(this, thisObject, "abort should be called as a method");
}
}
const theSink = new Sink();
thisObject = theSink;
const ws = new WritableStream(theSink);
const writer = ws.getWriter();
writer.write("a");
const closePromise = writer.close();
const ws2 = new WritableStream(theSink);
const writer2 = ws2.getWriter();
const abortPromise = writer2.abort();
return Promise.all([closePromise, abortPromise]).then(undefined);
});
unitTest(function sizeShouldNotBeCalledAsMethod() {
const strategy = {
size(): number {
if (this !== undefined) {
throw new Error("size called as a method");
}
return 1;
},
};
const ws = new WritableStream({}, strategy);
const writer = ws.getWriter();
return writer.write("a");
});
unitTest(function redundantReleaseLockIsNoOp() {
const ws = new WritableStream();
const writer1 = ws.getWriter();
assertEquals(
undefined,
writer1.releaseLock(),
"releaseLock() should return undefined"
);
const writer2 = ws.getWriter();
assertEquals(
undefined,
writer1.releaseLock(),
"no-op releaseLock() should return undefined"
);
// Calling releaseLock() on writer1 should not interfere with writer2. If it did, then the ready promise would be
// rejected.
return writer2.ready;
});
unitTest(function readyPromiseShouldFireBeforeReleaseLock() {
const events: string[] = [];
const ws = new WritableStream();
const writer = ws.getWriter();
return writer.ready.then(() => {
// Force the ready promise back to a pending state.
const writerPromise = writer.write("dummy");
const readyPromise = writer.ready.catch(() => events.push("ready"));
const closedPromise = writer.closed.catch(() => events.push("closed"));
writer.releaseLock();
return Promise.all([readyPromise, closedPromise]).then(() => {
assertEquals(
events,
["ready", "closed"],
"ready promise should fire before closed promise"
);
// Stop the writer promise hanging around after the test has finished.
return Promise.all([writerPromise, ws.abort()]).then(undefined);
});
});
});
unitTest(function subclassingWritableStream() {
class Subclass extends WritableStream {
extraFunction(): boolean {
return true;
}
}
assert(
Object.getPrototypeOf(Subclass.prototype) === WritableStream.prototype,
"Subclass.prototype's prototype should be WritableStream.prototype"
);
assert(
Object.getPrototypeOf(Subclass) === WritableStream,
"Subclass's prototype should be WritableStream"
);
const sub = new Subclass();
assert(
sub instanceof WritableStream,
"Subclass object should be an instance of WritableStream"
);
assert(
sub instanceof Subclass,
"Subclass object should be an instance of Subclass"
);
const lockedGetter = Object.getOwnPropertyDescriptor(
WritableStream.prototype,
"locked"
)!.get!;
assert(
lockedGetter.call(sub) === sub.locked,
"Subclass object should pass brand check"
);
assert(
sub.extraFunction(),
"extraFunction() should be present on Subclass object"
);
});
unitTest(function lockedGetterShouldReturnTrue() {
const ws = new WritableStream();
assert(!ws.locked, "stream should not be locked");
ws.getWriter();
assert(ws.locked, "stream should be locked");
});

View file

@ -1,44 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(
{ perms: { read: true, write: true } },
function symlinkSyncSuccess(): void {
const testDir = Deno.makeTempDirSync();
const oldname = testDir + "/oldname";
const newname = testDir + "/newname";
Deno.mkdirSync(oldname);
// Just for now, until we implement symlink for Windows.
Deno.symlinkSync(oldname, newname);
const newNameInfoLStat = Deno.lstatSync(newname);
const newNameInfoStat = Deno.statSync(newname);
assert(newNameInfoLStat.isSymlink);
assert(newNameInfoStat.isDirectory);
}
);
unitTest(function symlinkSyncPerm(): void {
let err;
try {
Deno.symlinkSync("oldbaddir", "newbaddir");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{ perms: { read: true, write: true } },
async function symlinkSuccess(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const oldname = testDir + "/oldname";
const newname = testDir + "/newname";
Deno.mkdirSync(oldname);
await Deno.symlink(oldname, newname);
const newNameInfoLStat = Deno.lstatSync(newname);
const newNameInfoStat = Deno.statSync(newname);
assert(newNameInfoLStat.isSymlink, "NOT SYMLINK");
assert(newNameInfoStat.isDirectory, "NOT DIRECTORY");
}
);

View file

@ -1,364 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { assert, assertEquals } from "../../../std/testing/asserts.ts";
export {
assert,
assertThrows,
assertEquals,
assertMatch,
assertNotEquals,
assertStrictEq,
assertStrContains,
unreachable,
fail,
} from "../../../std/testing/asserts.ts";
export { readLines } from "../../../std/io/bufio.ts";
export { parse as parseArgs } from "../../../std/flags/mod.ts";
export interface Permissions {
read: boolean;
write: boolean;
net: boolean;
env: boolean;
run: boolean;
plugin: boolean;
hrtime: boolean;
}
export function fmtPerms(perms: Permissions): string {
const p = Object.keys(perms)
.filter((e): boolean => perms[e as keyof Permissions] === true)
.map((key) => `--allow-${key}`);
if (p.length) {
return p.join(" ");
}
return "<no permissions>";
}
const isGranted = async (name: Deno.PermissionName): Promise<boolean> =>
(await Deno.permissions.query({ name })).state === "granted";
export async function getProcessPermissions(): Promise<Permissions> {
return {
run: await isGranted("run"),
read: await isGranted("read"),
write: await isGranted("write"),
net: await isGranted("net"),
env: await isGranted("env"),
plugin: await isGranted("plugin"),
hrtime: await isGranted("hrtime"),
};
}
export function permissionsMatch(
processPerms: Permissions,
requiredPerms: Permissions
): boolean {
for (const permName in processPerms) {
if (
processPerms[permName as keyof Permissions] !==
requiredPerms[permName as keyof Permissions]
) {
return false;
}
}
return true;
}
export const permissionCombinations: Map<string, Permissions> = new Map();
function permToString(perms: Permissions): string {
const r = perms.read ? 1 : 0;
const w = perms.write ? 1 : 0;
const n = perms.net ? 1 : 0;
const e = perms.env ? 1 : 0;
const u = perms.run ? 1 : 0;
const p = perms.plugin ? 1 : 0;
const h = perms.hrtime ? 1 : 0;
return `permR${r}W${w}N${n}E${e}U${u}P${p}H${h}`;
}
function registerPermCombination(perms: Permissions): void {
const key = permToString(perms);
if (!permissionCombinations.has(key)) {
permissionCombinations.set(key, perms);
}
}
export async function registerUnitTests(): Promise<void> {
const processPerms = await getProcessPermissions();
for (const unitTestDefinition of REGISTERED_UNIT_TESTS) {
if (!permissionsMatch(processPerms, unitTestDefinition.perms)) {
continue;
}
Deno.test(unitTestDefinition);
}
}
function normalizeTestPermissions(perms: UnitTestPermissions): Permissions {
return {
read: !!perms.read,
write: !!perms.write,
net: !!perms.net,
run: !!perms.run,
env: !!perms.env,
plugin: !!perms.plugin,
hrtime: !!perms.hrtime,
};
}
interface UnitTestPermissions {
read?: boolean;
write?: boolean;
net?: boolean;
env?: boolean;
run?: boolean;
plugin?: boolean;
hrtime?: boolean;
}
interface UnitTestOptions {
ignore?: boolean;
perms?: UnitTestPermissions;
}
interface UnitTestDefinition extends Deno.TestDefinition {
ignore: boolean;
perms: Permissions;
}
type TestFunction = () => void | Promise<void>;
export const REGISTERED_UNIT_TESTS: UnitTestDefinition[] = [];
export function unitTest(fn: TestFunction): void;
export function unitTest(options: UnitTestOptions, fn: TestFunction): void;
export function unitTest(
optionsOrFn: UnitTestOptions | TestFunction,
maybeFn?: TestFunction
): void {
assert(optionsOrFn, "At least one argument is required");
let options: UnitTestOptions;
let name: string;
let fn: TestFunction;
if (typeof optionsOrFn === "function") {
options = {};
fn = optionsOrFn;
name = fn.name;
assert(name, "Missing test function name");
} else {
options = optionsOrFn;
assert(maybeFn, "Missing test function definition");
assert(
typeof maybeFn === "function",
"Second argument should be test function definition"
);
fn = maybeFn;
name = fn.name;
assert(name, "Missing test function name");
}
const normalizedPerms = normalizeTestPermissions(options.perms || {});
registerPermCombination(normalizedPerms);
const unitTestDefinition: UnitTestDefinition = {
name,
fn,
ignore: !!options.ignore,
perms: normalizedPerms,
};
REGISTERED_UNIT_TESTS.push(unitTestDefinition);
}
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>;
}
const encoder = new TextEncoder();
// Replace functions with null, errors with their stack strings, and JSONify.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function serializeTestMessage(message: any): string {
return JSON.stringify({
start: message.start && {
...message.start,
tests: message.start.tests.map((test: Deno.TestDefinition) => ({
...test,
fn: null,
})),
},
testStart: message.testStart && { ...message.testStart, fn: null },
testEnd: message.testEnd && {
...message.testEnd,
error: String(message.testEnd.error?.stack),
},
end: message.end && {
...message.end,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
results: message.end.results.map((result: any) => ({
...result,
error: result.error?.stack,
})),
},
});
}
export async function reportToConn(
conn: Deno.Conn,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
message: any
): Promise<void> {
const line = serializeTestMessage(message);
const encodedMsg = encoder.encode(line + (message.end == null ? "\n" : ""));
await Deno.writeAll(conn, encodedMsg);
if (message.end != null) {
conn.closeWrite();
}
}
unitTest(function permissionsMatches(): void {
assert(
permissionsMatch(
{
read: true,
write: false,
net: false,
env: false,
run: false,
plugin: false,
hrtime: false,
},
normalizeTestPermissions({ read: true })
)
);
assert(
permissionsMatch(
{
read: false,
write: false,
net: false,
env: false,
run: false,
plugin: false,
hrtime: false,
},
normalizeTestPermissions({})
)
);
assertEquals(
permissionsMatch(
{
read: false,
write: true,
net: true,
env: true,
run: true,
plugin: true,
hrtime: true,
},
normalizeTestPermissions({ read: true })
),
false
);
assertEquals(
permissionsMatch(
{
read: true,
write: false,
net: true,
env: false,
run: false,
plugin: false,
hrtime: false,
},
normalizeTestPermissions({ read: true })
),
false
);
assert(
permissionsMatch(
{
read: true,
write: true,
net: true,
env: true,
run: true,
plugin: true,
hrtime: true,
},
{
read: true,
write: true,
net: true,
env: true,
run: true,
plugin: true,
hrtime: true,
}
)
);
});
/*
* Ensure all unit test files (e.g. xxx_test.ts) are present as imports in
* cli/js/tests/unit_tests.ts as it is easy to miss this out
*/
unitTest(
{ perms: { read: true } },
function assertAllUnitTestFilesImported(): void {
const directoryTestFiles = [...Deno.readDirSync("./cli/js/tests/")]
.map((k) => k.name)
.filter(
(file) =>
file!.endsWith(".ts") &&
!file!.endsWith("unit_tests.ts") &&
!file!.endsWith("test_util.ts") &&
!file!.endsWith("unit_test_runner.ts")
);
const unitTestsFile: Uint8Array = Deno.readFileSync(
"./cli/js/tests/unit_tests.ts"
);
const importLines = new TextDecoder("utf-8")
.decode(unitTestsFile)
.split("\n")
.filter((line) => line.startsWith("import"));
const importedTestFiles = importLines.map(
(relativeFilePath) => relativeFilePath.match(/\/([^\/]+)";/)![1]
);
directoryTestFiles.forEach((dirFile) => {
if (!importedTestFiles.includes(dirFile!)) {
throw new Error(
"cil/js/tests/unit_tests.ts is missing import of test file: cli/js/" +
dirFile
);
}
});
}
);

View file

@ -1,27 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { assertThrows, unitTest } from "./test_util.ts";
unitTest(function testFnOverloading(): void {
// just verifying that you can use this test definition syntax
Deno.test("test fn overloading", (): void => {});
});
unitTest(function nameOfTestCaseCantBeEmpty(): void {
assertThrows(
() => {
Deno.test("", () => {});
},
TypeError,
"The test name can't be empty"
);
assertThrows(
() => {
Deno.test({
name: "",
fn: () => {},
});
},
TypeError,
"The test name can't be empty"
);
});

View file

@ -1,206 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(function btoaSuccess(): void {
const text = "hello world";
const encoded = btoa(text);
assertEquals(encoded, "aGVsbG8gd29ybGQ=");
});
unitTest(function atobSuccess(): void {
const encoded = "aGVsbG8gd29ybGQ=";
const decoded = atob(encoded);
assertEquals(decoded, "hello world");
});
unitTest(function atobWithAsciiWhitespace(): void {
const encodedList = [
" aGVsbG8gd29ybGQ=",
" aGVsbG8gd29ybGQ=",
"aGVsbG8gd29ybGQ= ",
"aGVsbG8gd29ybGQ=\n",
"aGVsbG\t8gd29ybGQ=",
`aGVsbG\t8g
d29ybGQ=`,
];
for (const encoded of encodedList) {
const decoded = atob(encoded);
assertEquals(decoded, "hello world");
}
});
unitTest(function atobThrows(): void {
let threw = false;
try {
atob("aGVsbG8gd29ybGQ==");
} catch (e) {
threw = true;
}
assert(threw);
});
unitTest(function atobThrows2(): void {
let threw = false;
try {
atob("aGVsbG8gd29ybGQ===");
} catch (e) {
threw = true;
}
assert(threw);
});
unitTest(function btoaFailed(): void {
const text = "你好";
let err;
try {
btoa(text);
} catch (e) {
err = e;
}
assert(!!err);
assert(err instanceof TypeError);
});
unitTest(function textDecoder2(): void {
// prettier-ignore
const fixture = new Uint8Array([
0xf0, 0x9d, 0x93, 0xbd,
0xf0, 0x9d, 0x93, 0xae,
0xf0, 0x9d, 0x94, 0x81,
0xf0, 0x9d, 0x93, 0xbd
]);
const decoder = new TextDecoder();
assertEquals(decoder.decode(fixture), "𝓽𝓮𝔁𝓽");
});
unitTest(function textDecoderIgnoreBOM(): void {
// prettier-ignore
const fixture = new Uint8Array([
0xef, 0xbb, 0xbf,
0xf0, 0x9d, 0x93, 0xbd,
0xf0, 0x9d, 0x93, 0xae,
0xf0, 0x9d, 0x94, 0x81,
0xf0, 0x9d, 0x93, 0xbd
]);
const decoder = new TextDecoder("utf-8", { ignoreBOM: true });
assertEquals(decoder.decode(fixture), "𝓽𝓮𝔁𝓽");
});
unitTest(function textDecoderNotBOM(): void {
// prettier-ignore
const fixture = new Uint8Array([
0xef, 0xbb, 0x89,
0xf0, 0x9d, 0x93, 0xbd,
0xf0, 0x9d, 0x93, 0xae,
0xf0, 0x9d, 0x94, 0x81,
0xf0, 0x9d, 0x93, 0xbd
]);
const decoder = new TextDecoder("utf-8", { ignoreBOM: true });
assertEquals(decoder.decode(fixture), "ﻉ𝓽𝓮𝔁𝓽");
});
unitTest(function textDecoderASCII(): void {
const fixture = new Uint8Array([0x89, 0x95, 0x9f, 0xbf]);
const decoder = new TextDecoder("ascii");
assertEquals(decoder.decode(fixture), "‰•Ÿ¿");
});
unitTest(function textDecoderErrorEncoding(): void {
let didThrow = false;
try {
new TextDecoder("foo");
} catch (e) {
didThrow = true;
assertEquals(e.message, "The encoding label provided ('foo') is invalid.");
}
assert(didThrow);
});
unitTest(function textEncoder(): void {
const fixture = "𝓽𝓮𝔁𝓽";
const encoder = new TextEncoder();
// prettier-ignore
assertEquals(Array.from(encoder.encode(fixture)), [
0xf0, 0x9d, 0x93, 0xbd,
0xf0, 0x9d, 0x93, 0xae,
0xf0, 0x9d, 0x94, 0x81,
0xf0, 0x9d, 0x93, 0xbd
]);
});
unitTest(function textEncodeInto(): void {
const fixture = "text";
const encoder = new TextEncoder();
const bytes = new Uint8Array(5);
const result = encoder.encodeInto(fixture, bytes);
assertEquals(result.read, 4);
assertEquals(result.written, 4);
// prettier-ignore
assertEquals(Array.from(bytes), [
0x74, 0x65, 0x78, 0x74, 0x00,
]);
});
unitTest(function textEncodeInto2(): void {
const fixture = "𝓽𝓮𝔁𝓽";
const encoder = new TextEncoder();
const bytes = new Uint8Array(17);
const result = encoder.encodeInto(fixture, bytes);
assertEquals(result.read, 8);
assertEquals(result.written, 16);
// prettier-ignore
assertEquals(Array.from(bytes), [
0xf0, 0x9d, 0x93, 0xbd,
0xf0, 0x9d, 0x93, 0xae,
0xf0, 0x9d, 0x94, 0x81,
0xf0, 0x9d, 0x93, 0xbd, 0x00,
]);
});
unitTest(function textEncodeInto3(): void {
const fixture = "𝓽𝓮𝔁𝓽";
const encoder = new TextEncoder();
const bytes = new Uint8Array(5);
const result = encoder.encodeInto(fixture, bytes);
assertEquals(result.read, 2);
assertEquals(result.written, 4);
// prettier-ignore
assertEquals(Array.from(bytes), [
0xf0, 0x9d, 0x93, 0xbd, 0x00,
]);
});
unitTest(function textDecoderSharedUint8Array(): void {
const ab = new SharedArrayBuffer(6);
const dataView = new DataView(ab);
const charCodeA = "A".charCodeAt(0);
for (let i = 0; i < ab.byteLength; i++) {
dataView.setUint8(i, charCodeA + i);
}
const ui8 = new Uint8Array(ab);
const decoder = new TextDecoder();
const actual = decoder.decode(ui8);
assertEquals(actual, "ABCDEF");
});
unitTest(function textDecoderSharedInt32Array(): void {
const ab = new SharedArrayBuffer(8);
const dataView = new DataView(ab);
const charCodeA = "A".charCodeAt(0);
for (let i = 0; i < ab.byteLength; i++) {
dataView.setUint8(i, charCodeA + i);
}
const i32 = new Int32Array(ab);
const decoder = new TextDecoder();
const actual = decoder.decode(i32);
assertEquals(actual, "ABCDEFGH");
});
unitTest(function toStringShouldBeWebCompatibility(): void {
const encoder = new TextEncoder();
assertEquals(encoder.toString(), "[object TextEncoder]");
const decoder = new TextDecoder();
assertEquals(decoder.toString(), "[object TextDecoder]");
});

View file

@ -1,368 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
unitTest,
createResolvable,
assert,
assertEquals,
assertNotEquals,
} from "./test_util.ts";
function deferred(): {
promise: Promise<{}>;
resolve: (value?: {} | PromiseLike<{}>) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
reject: (reason?: any) => void;
} {
let resolve: (value?: {} | PromiseLike<{}>) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let reject: ((reason?: any) => void) | undefined = undefined;
const promise = new Promise<{}>((res, rej): void => {
resolve = res;
reject = rej;
});
return {
promise,
resolve: resolve!,
reject: reject!,
};
}
function waitForMs(ms: number): Promise<number> {
return new Promise((resolve: () => void): number => setTimeout(resolve, ms));
}
unitTest(async function timeoutSuccess(): Promise<void> {
const { promise, resolve } = deferred();
let count = 0;
setTimeout((): void => {
count++;
resolve();
}, 500);
await promise;
// count should increment
assertEquals(count, 1);
});
unitTest(async function timeoutArgs(): Promise<void> {
const { promise, resolve } = deferred();
const arg = 1;
setTimeout(
(a, b, c): void => {
assertEquals(a, arg);
assertEquals(b, arg.toString());
assertEquals(c, [arg]);
resolve();
},
10,
arg,
arg.toString(),
[arg]
);
await promise;
});
unitTest(async function timeoutCancelSuccess(): Promise<void> {
let count = 0;
const id = setTimeout((): void => {
count++;
}, 1);
// Cancelled, count should not increment
clearTimeout(id);
await waitForMs(600);
assertEquals(count, 0);
});
unitTest(async function timeoutCancelMultiple(): Promise<void> {
function uncalled(): never {
throw new Error("This function should not be called.");
}
// Set timers and cancel them in the same order.
const t1 = setTimeout(uncalled, 10);
const t2 = setTimeout(uncalled, 10);
const t3 = setTimeout(uncalled, 10);
clearTimeout(t1);
clearTimeout(t2);
clearTimeout(t3);
// Set timers and cancel them in reverse order.
const t4 = setTimeout(uncalled, 20);
const t5 = setTimeout(uncalled, 20);
const t6 = setTimeout(uncalled, 20);
clearTimeout(t6);
clearTimeout(t5);
clearTimeout(t4);
// Sleep until we're certain that the cancelled timers aren't gonna fire.
await waitForMs(50);
});
unitTest(async function timeoutCancelInvalidSilentFail(): Promise<void> {
// Expect no panic
const { promise, resolve } = deferred();
let count = 0;
const id = setTimeout((): void => {
count++;
// Should have no effect
clearTimeout(id);
resolve();
}, 500);
await promise;
assertEquals(count, 1);
// Should silently fail (no panic)
clearTimeout(2147483647);
});
unitTest(async function intervalSuccess(): Promise<void> {
const { promise, resolve } = deferred();
let count = 0;
const id = setInterval((): void => {
count++;
clearInterval(id);
resolve();
}, 100);
await promise;
// Clear interval
clearInterval(id);
// count should increment twice
assertEquals(count, 1);
// Similar false async leaking alarm.
// Force next round of polling.
await waitForMs(0);
});
unitTest(async function intervalCancelSuccess(): Promise<void> {
let count = 0;
const id = setInterval((): void => {
count++;
}, 1);
clearInterval(id);
await waitForMs(500);
assertEquals(count, 0);
});
unitTest(async function intervalOrdering(): Promise<void> {
const timers: number[] = [];
let timeouts = 0;
function onTimeout(): void {
++timeouts;
for (let i = 1; i < timers.length; i++) {
clearTimeout(timers[i]);
}
}
for (let i = 0; i < 10; i++) {
timers[i] = setTimeout(onTimeout, 1);
}
await waitForMs(500);
assertEquals(timeouts, 1);
});
unitTest(function intervalCancelInvalidSilentFail(): void {
// Should silently fail (no panic)
clearInterval(2147483647);
});
unitTest(async function fireCallbackImmediatelyWhenDelayOverMaxValue(): Promise<
void
> {
let count = 0;
setTimeout((): void => {
count++;
}, 2 ** 31);
await waitForMs(1);
assertEquals(count, 1);
});
unitTest(async function timeoutCallbackThis(): Promise<void> {
const { promise, resolve } = deferred();
const obj = {
foo(): void {
assertEquals(this, window);
resolve();
},
};
setTimeout(obj.foo, 1);
await promise;
});
unitTest(async function timeoutBindThis(): Promise<void> {
const thisCheckPassed = [null, undefined, window, globalThis];
const thisCheckFailed = [
0,
"",
true,
false,
{},
[],
"foo",
(): void => {},
Object.prototype,
];
for (const thisArg of thisCheckPassed) {
const resolvable = createResolvable();
let hasThrown = 0;
try {
setTimeout.call(thisArg, () => resolvable.resolve(), 1);
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
await resolvable;
assertEquals(hasThrown, 1);
}
for (const thisArg of thisCheckFailed) {
let hasThrown = 0;
try {
setTimeout.call(thisArg, () => {}, 1);
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
}
});
unitTest(function clearTimeoutShouldConvertToNumber(): void {
let called = false;
const obj = {
valueOf(): number {
called = true;
return 1;
},
};
clearTimeout((obj as unknown) as number);
assert(called);
});
unitTest(function setTimeoutShouldThrowWithBigint(): void {
let hasThrown = 0;
try {
setTimeout((): void => {}, (1n as unknown) as number);
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
});
unitTest(function clearTimeoutShouldThrowWithBigint(): void {
let hasThrown = 0;
try {
clearTimeout((1n as unknown) as number);
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
});
unitTest(function testFunctionName(): void {
assertEquals(clearTimeout.name, "clearTimeout");
assertEquals(clearInterval.name, "clearInterval");
});
unitTest(function testFunctionParamsLength(): void {
assertEquals(setTimeout.length, 1);
assertEquals(setInterval.length, 1);
assertEquals(clearTimeout.length, 0);
assertEquals(clearInterval.length, 0);
});
unitTest(function clearTimeoutAndClearIntervalNotBeEquals(): void {
assertNotEquals(clearTimeout, clearInterval);
});
unitTest(async function timerMaxCpuBug(): Promise<void> {
// There was a bug where clearing a timeout would cause Deno to use 100% CPU.
clearTimeout(setTimeout(() => {}, 1000));
// We can check this by counting how many ops have triggered in the interim.
// Certainly less than 10 ops should have been dispatched in next 100 ms.
const { opsDispatched } = Deno.metrics();
await waitForMs(100);
const opsDispatched_ = Deno.metrics().opsDispatched;
assert(opsDispatched_ - opsDispatched < 10);
});
unitTest(async function timerBasicMicrotaskOrdering(): Promise<void> {
let s = "";
let count = 0;
const { promise, resolve } = deferred();
setTimeout(() => {
Promise.resolve().then(() => {
count++;
s += "de";
if (count === 2) {
resolve();
}
});
});
setTimeout(() => {
count++;
s += "no";
if (count === 2) {
resolve();
}
});
await promise;
assertEquals(s, "deno");
});
unitTest(async function timerNestedMicrotaskOrdering(): Promise<void> {
let s = "";
const { promise, resolve } = deferred();
s += "0";
setTimeout(() => {
s += "4";
setTimeout(() => (s += "A"));
Promise.resolve()
.then(() => {
setTimeout(() => {
s += "B";
resolve();
});
})
.then(() => {
s += "5";
});
});
setTimeout(() => (s += "6"));
Promise.resolve().then(() => (s += "2"));
Promise.resolve().then(() =>
setTimeout(() => {
s += "7";
Promise.resolve()
.then(() => (s += "8"))
.then(() => {
s += "9";
});
})
);
Promise.resolve().then(() => Promise.resolve().then(() => (s += "3")));
s += "1";
await promise;
assertEquals(s, "0123456789AB");
});
unitTest(function testQueueMicrotask() {
assertEquals(typeof queueMicrotask, "function");
});

View file

@ -1,262 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import {
assert,
assertEquals,
createResolvable,
unitTest,
} from "./test_util.ts";
import { BufWriter, BufReader } from "../../../std/io/bufio.ts";
import { TextProtoReader } from "../../../std/textproto/mod.ts";
const encoder = new TextEncoder();
const decoder = new TextDecoder();
unitTest(async function connectTLSNoPerm(): Promise<void> {
let err;
try {
await Deno.connectTls({ hostname: "github.com", port: 443 });
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(async function connectTLSCertFileNoReadPerm(): Promise<void> {
let err;
try {
await Deno.connectTls({
hostname: "github.com",
port: 443,
certFile: "cli/tests/tls/RootCA.crt",
});
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{ perms: { read: true, net: true } },
function listenTLSNonExistentCertKeyFiles(): void {
let err;
const options = {
hostname: "localhost",
port: 3500,
certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key",
};
try {
Deno.listenTls({
...options,
certFile: "./non/existent/file",
});
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
try {
Deno.listenTls({
...options,
keyFile: "./non/existent/file",
});
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.NotFound);
}
);
unitTest({ perms: { net: true } }, function listenTLSNoReadPerm(): void {
let err;
try {
Deno.listenTls({
hostname: "localhost",
port: 3500,
certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key",
});
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest(
{
perms: { read: true, write: true, net: true },
},
function listenTLSEmptyKeyFile(): void {
let err;
const options = {
hostname: "localhost",
port: 3500,
certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key",
};
const testDir = Deno.makeTempDirSync();
const keyFilename = testDir + "/key.pem";
Deno.writeFileSync(keyFilename, new Uint8Array([]), {
mode: 0o666,
});
try {
Deno.listenTls({
...options,
keyFile: keyFilename,
});
} catch (e) {
err = e;
}
assert(err instanceof Error);
}
);
unitTest(
{ perms: { read: true, write: true, net: true } },
function listenTLSEmptyCertFile(): void {
let err;
const options = {
hostname: "localhost",
port: 3500,
certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key",
};
const testDir = Deno.makeTempDirSync();
const certFilename = testDir + "/cert.crt";
Deno.writeFileSync(certFilename, new Uint8Array([]), {
mode: 0o666,
});
try {
Deno.listenTls({
...options,
certFile: certFilename,
});
} catch (e) {
err = e;
}
assert(err instanceof Error);
}
);
unitTest(
{ perms: { read: true, net: true } },
async function dialAndListenTLS(): Promise<void> {
const resolvable = createResolvable();
const hostname = "localhost";
const port = 3500;
const listener = Deno.listenTls({
hostname,
port,
certFile: "cli/tests/tls/localhost.crt",
keyFile: "cli/tests/tls/localhost.key",
});
const response = encoder.encode(
"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nHello World\n"
);
listener.accept().then(
async (conn): Promise<void> => {
assert(conn.remoteAddr != null);
assert(conn.localAddr != null);
await conn.write(response);
// TODO(bartlomieju): this might be a bug
setTimeout(() => {
conn.close();
resolvable.resolve();
}, 0);
}
);
const conn = await Deno.connectTls({
hostname,
port,
certFile: "cli/tests/tls/RootCA.pem",
});
assert(conn.rid > 0);
const w = new BufWriter(conn);
const r = new BufReader(conn);
const body = `GET / HTTP/1.1\r\nHost: ${hostname}:${port}\r\n\r\n`;
const writeResult = await w.write(encoder.encode(body));
assertEquals(body.length, writeResult);
await w.flush();
const tpr = new TextProtoReader(r);
const statusLine = await tpr.readLine();
assert(statusLine !== null, `line must be read: ${String(statusLine)}`);
const m = statusLine.match(/^(.+?) (.+?) (.+?)$/);
assert(m !== null, "must be matched");
const [_, proto, status, ok] = m;
assertEquals(proto, "HTTP/1.1");
assertEquals(status, "200");
assertEquals(ok, "OK");
const headers = await tpr.readMIMEHeader();
assert(headers !== null);
const contentLength = parseInt(headers.get("content-length")!);
const bodyBuf = new Uint8Array(contentLength);
await r.readFull(bodyBuf);
assertEquals(decoder.decode(bodyBuf), "Hello World\n");
conn.close();
listener.close();
await resolvable;
}
);
unitTest(
{ perms: { read: true, net: true } },
async function startTls(): Promise<void> {
const hostname = "smtp.gmail.com";
const port = 587;
const encoder = new TextEncoder();
let conn = await Deno.connect({
hostname,
port,
});
let writer = new BufWriter(conn);
let reader = new TextProtoReader(new BufReader(conn));
let line: string | null = (await reader.readLine()) as string;
assert(line.startsWith("220"));
await writer.write(encoder.encode(`EHLO ${hostname}\r\n`));
await writer.flush();
while ((line = (await reader.readLine()) as string)) {
assert(line.startsWith("250"));
if (line.startsWith("250 ")) break;
}
await writer.write(encoder.encode("STARTTLS\r\n"));
await writer.flush();
line = await reader.readLine();
// Received the message that the server is ready to establish TLS
assertEquals(line, "220 2.0.0 Ready to start TLS");
conn = await Deno.startTls(conn, { hostname });
writer = new BufWriter(conn);
reader = new TextProtoReader(new BufReader(conn));
// After that use TLS communication again
await writer.write(encoder.encode(`EHLO ${hostname}\r\n`));
await writer.flush();
while ((line = (await reader.readLine()) as string)) {
assert(line.startsWith("250"));
if (line.startsWith("250 ")) break;
}
conn.close();
}
);

View file

@ -1,80 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals, assert } from "./test_util.ts";
function readDataSync(name: string): string {
const data = Deno.readFileSync(name);
const decoder = new TextDecoder("utf-8");
const text = decoder.decode(data);
return text;
}
async function readData(name: string): Promise<string> {
const data = await Deno.readFile(name);
const decoder = new TextDecoder("utf-8");
const text = decoder.decode(data);
return text;
}
unitTest(
{ perms: { read: true, write: true } },
function truncateSyncSuccess(): void {
const enc = new TextEncoder();
const d = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test_truncateSync.txt";
Deno.writeFileSync(filename, d);
Deno.truncateSync(filename, 20);
let data = readDataSync(filename);
assertEquals(data.length, 20);
Deno.truncateSync(filename, 5);
data = readDataSync(filename);
assertEquals(data.length, 5);
Deno.truncateSync(filename, -5);
data = readDataSync(filename);
assertEquals(data.length, 0);
Deno.removeSync(filename);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function truncateSuccess(): Promise<void> {
const enc = new TextEncoder();
const d = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test_truncate.txt";
await Deno.writeFile(filename, d);
await Deno.truncate(filename, 20);
let data = await readData(filename);
assertEquals(data.length, 20);
await Deno.truncate(filename, 5);
data = await readData(filename);
assertEquals(data.length, 5);
await Deno.truncate(filename, -5);
data = await readData(filename);
assertEquals(data.length, 0);
await Deno.remove(filename);
}
);
unitTest({ perms: { write: false } }, function truncateSyncPerm(): void {
let err;
try {
Deno.mkdirSync("/test_truncateSyncPermission.txt");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});
unitTest({ perms: { write: false } }, async function truncatePerm(): Promise<
void
> {
let err;
try {
await Deno.mkdir("/test_truncatePermission.txt");
} catch (e) {
err = e;
}
assert(err instanceof Deno.errors.PermissionDenied);
assertEquals(err.name, "PermissionDenied");
});

View file

@ -1,23 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
// Note tests for Deno.setRaw is in integration tests.
unitTest({ perms: { read: true } }, function isatty(): void {
// CI not under TTY, so cannot test stdin/stdout/stderr.
const f = Deno.openSync("cli/tests/hello.txt");
assert(!Deno.isatty(f.rid));
f.close();
});
unitTest(function isattyError(): void {
let caught = false;
try {
// Absurdly large rid.
Deno.isatty(0x7fffffff);
} catch (e) {
caught = true;
assert(e instanceof Deno.errors.BadResource);
}
assert(caught);
});

View file

@ -1,15 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assertEquals } from "./test_util.ts";
unitTest(
{
ignore: Deno.build.os === "windows",
},
function umaskSuccess(): void {
const prevMask = Deno.umask(0o020);
const newMask = Deno.umask(prevMask);
const finalMask = Deno.umask();
assertEquals(newMask, 0o020);
assertEquals(finalMask, prevMask);
}
);

View file

@ -1,309 +0,0 @@
#!/usr/bin/env -S deno run --reload --allow-run
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import "./unit_tests.ts";
import {
readLines,
permissionCombinations,
Permissions,
registerUnitTests,
fmtPerms,
parseArgs,
reportToConn,
} from "./test_util.ts";
// @ts-ignore
const internalObj = Deno[Deno.internal];
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const reportToConsole = internalObj.reportToConsole as (message: any) => void;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const runTests = internalObj.runTests as (options: any) => Promise<any>;
interface PermissionSetTestResult {
perms: Permissions;
passed: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
endMessage: any;
permsStr: string;
}
const PERMISSIONS: Deno.PermissionName[] = [
"read",
"write",
"net",
"env",
"run",
"plugin",
"hrtime",
];
/**
* Take a list of permissions and revoke missing permissions.
*/
async function dropWorkerPermissions(
requiredPermissions: Deno.PermissionName[]
): Promise<void> {
const permsToDrop = PERMISSIONS.filter((p): boolean => {
return !requiredPermissions.includes(p);
});
for (const perm of permsToDrop) {
await Deno.permissions.revoke({ name: perm });
}
}
async function workerRunnerMain(
addrStr: string,
permsStr: string,
filter?: string
): Promise<void> {
const [hostname, port] = addrStr.split(":");
const addr = { hostname, port: Number(port) };
let perms: Deno.PermissionName[] = [];
if (permsStr.length > 0) {
perms = permsStr.split(",") as Deno.PermissionName[];
}
// Setup reporter
const conn = await Deno.connect(addr);
// Drop current process permissions to requested set
await dropWorkerPermissions(perms);
// Register unit tests that match process permissions
await registerUnitTests();
// Execute tests
await runTests({
exitOnFail: false,
filter,
reportToConsole: false,
onMessage: reportToConn.bind(null, conn),
});
}
function spawnWorkerRunner(
verbose: boolean,
addr: string,
perms: Permissions,
filter?: string
): Deno.Process {
// run subsequent tests using same deno executable
const permStr = Object.keys(perms)
.filter((permName): boolean => {
return perms[permName as Deno.PermissionName] === true;
})
.join(",");
const cmd = [
Deno.execPath(),
"run",
"--unstable", // TODO(ry) be able to test stable vs unstable
"-A",
"cli/js/tests/unit_test_runner.ts",
"--worker",
`--addr=${addr}`,
`--perms=${permStr}`,
];
if (filter) {
cmd.push("--");
cmd.push(filter);
}
const ioMode = verbose ? "inherit" : "null";
const p = Deno.run({
cmd,
stdin: ioMode,
stdout: ioMode,
stderr: ioMode,
});
return p;
}
async function runTestsForPermissionSet(
listener: Deno.Listener,
addrStr: string,
verbose: boolean,
perms: Permissions,
filter?: string
): Promise<PermissionSetTestResult> {
const permsFmt = fmtPerms(perms);
console.log(`Running tests for: ${permsFmt}`);
const workerProcess = spawnWorkerRunner(verbose, addrStr, perms, filter);
// Wait for worker subprocess to go online
const conn = await listener.accept();
let expectedPassedTests;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
let endMessage: any;
try {
for await (const line of readLines(conn)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const message = JSON.parse(line) as any;
reportToConsole(message);
if (message.start != null) {
expectedPassedTests = message.start.tests.length;
} else if (message.end != null) {
endMessage = message.end;
}
}
} finally {
// Close socket to worker.
conn.close();
}
if (expectedPassedTests == null) {
throw new Error("Worker runner didn't report start");
}
if (endMessage == null) {
throw new Error("Worker runner didn't report end");
}
const workerStatus = await workerProcess.status();
if (!workerStatus.success) {
throw new Error(
`Worker runner exited with status code: ${workerStatus.code}`
);
}
workerProcess.close();
const passed = expectedPassedTests === endMessage.passed + endMessage.ignored;
return {
perms,
passed,
permsStr: permsFmt,
endMessage,
};
}
async function masterRunnerMain(
verbose: boolean,
filter?: string
): Promise<void> {
console.log(
"Discovered permission combinations for tests:",
permissionCombinations.size
);
for (const perms of permissionCombinations.values()) {
console.log("\t" + fmtPerms(perms));
}
const testResults = new Set<PermissionSetTestResult>();
const addr = { hostname: "127.0.0.1", port: 4510 };
const addrStr = `${addr.hostname}:${addr.port}`;
const listener = Deno.listen(addr);
for (const perms of permissionCombinations.values()) {
const result = await runTestsForPermissionSet(
listener,
addrStr,
verbose,
perms,
filter
);
testResults.add(result);
}
// if any run tests returned non-zero status then whole test
// run should fail
let testsPassed = true;
for (const testResult of testResults) {
const { permsStr, endMessage } = testResult;
console.log(`Summary for ${permsStr}`);
reportToConsole({ end: endMessage });
testsPassed = testsPassed && testResult.passed;
}
if (!testsPassed) {
console.error("Unit tests failed");
Deno.exit(1);
}
console.log("Unit tests passed");
}
const HELP = `Unit test runner
Run tests matching current process permissions:
deno --allow-write unit_test_runner.ts
deno --allow-net --allow-hrtime unit_test_runner.ts
deno --allow-write unit_test_runner.ts -- testWriteFile
Run "master" process that creates "worker" processes
for each discovered permission combination:
deno -A unit_test_runner.ts --master
Run worker process for given permissions:
deno -A unit_test_runner.ts --worker --perms=net,read,write --addr=127.0.0.1:4500
OPTIONS:
--master
Run in master mode, spawning worker processes for
each discovered permission combination
--worker
Run in worker mode, requires "perms" and "addr" flags,
should be run with "-A" flag; after setup worker will
drop permissions to required set specified in "perms"
--perms=<perm_name>...
Set of permissions this process should run tests with,
--addr=<addr>
Address of TCP socket for reporting
ARGS:
-- <filter>...
Run only tests with names matching filter, must
be used after "--"
`;
function assertOrHelp(expr: unknown): asserts expr {
if (!expr) {
console.log(HELP);
Deno.exit(1);
}
}
async function main(): Promise<void> {
const args = parseArgs(Deno.args, {
boolean: ["master", "worker", "verbose"],
"--": true,
});
if (args.help) {
console.log(HELP);
return;
}
const filter = args["--"][0];
// Master mode
if (args.master) {
return masterRunnerMain(args.verbose, filter);
}
// Worker mode
if (args.worker) {
assertOrHelp(typeof args.addr === "string");
assertOrHelp(typeof args.perms === "string");
return workerRunnerMain(args.addr, args.perms, filter);
}
// Running tests matching current process permissions
await registerUnitTests();
await runTests({ filter });
}
main();

View file

@ -1,72 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
// This test is executed as part of unit test suite.
//
// Test runner automatically spawns subprocesses for each required permissions combination.
import "./abort_controller_test.ts";
import "./blob_test.ts";
import "./body_test.ts";
import "./buffer_test.ts";
import "./build_test.ts";
import "./chmod_test.ts";
import "./chown_test.ts";
import "./console_test.ts";
import "./copy_file_test.ts";
import "./custom_event_test.ts";
import "./dir_test.ts";
import "./dispatch_minimal_test.ts";
import "./dispatch_json_test.ts";
import "./dom_exception_test.ts";
import "./error_stack_test.ts";
import "./event_test.ts";
import "./event_target_test.ts";
import "./fetch_test.ts";
import "./file_test.ts";
import "./files_test.ts";
import "./form_data_test.ts";
import "./format_error_test.ts";
import "./fs_events_test.ts";
import "./get_random_values_test.ts";
import "./globals_test.ts";
import "./headers_test.ts";
import "./internals_test.ts";
import "./io_test.ts";
import "./link_test.ts";
import "./make_temp_test.ts";
import "./metrics_test.ts";
import "./dom_iterable_test.ts";
import "./mkdir_test.ts";
import "./net_test.ts";
import "./os_test.ts";
import "./permissions_test.ts";
import "./process_test.ts";
import "./real_path_test.ts";
import "./read_dir_test.ts";
import "./read_text_file_test.ts";
import "./read_file_test.ts";
import "./read_link_test.ts";
import "./remove_test.ts";
import "./rename_test.ts";
import "./request_test.ts";
import "./resources_test.ts";
import "./signal_test.ts";
import "./stat_test.ts";
import "./streams_piping_test.ts";
import "./streams_transform_test.ts";
import "./streams_writable_test.ts";
import "./symlink_test.ts";
import "./text_encoding_test.ts";
import "./testing_test.ts";
import "./timers_test.ts";
import "./tls_test.ts";
import "./truncate_test.ts";
import "./tty_test.ts";
import "./umask_test.ts";
import "./url_test.ts";
import "./url_search_params_test.ts";
import "./utime_test.ts";
import "./write_file_test.ts";
import "./write_text_file_test.ts";
import "./performance_test.ts";
import "./version_test.ts";

View file

@ -1,275 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(function urlSearchParamsInitString(): void {
const init = "c=4&a=2&b=3&%C3%A1=1";
const searchParams = new URLSearchParams(init);
assert(
init === searchParams.toString(),
"The init query string does not match"
);
});
unitTest(function urlSearchParamsInitIterable(): void {
const init = [
["a", "54"],
["b", "true"],
];
const searchParams = new URLSearchParams(init);
assertEquals(searchParams.toString(), "a=54&b=true");
});
unitTest(function urlSearchParamsInitRecord(): void {
const init = { a: "54", b: "true" };
const searchParams = new URLSearchParams(init);
assertEquals(searchParams.toString(), "a=54&b=true");
});
unitTest(function urlSearchParamsInit(): void {
const params1 = new URLSearchParams("a=b");
assertEquals(params1.toString(), "a=b");
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const params2 = new URLSearchParams(params1 as any);
assertEquals(params2.toString(), "a=b");
});
unitTest(function urlSearchParamsAppendSuccess(): void {
const searchParams = new URLSearchParams();
searchParams.append("a", "true");
assertEquals(searchParams.toString(), "a=true");
});
unitTest(function urlSearchParamsDeleteSuccess(): void {
const init = "a=54&b=true";
const searchParams = new URLSearchParams(init);
searchParams.delete("b");
assertEquals(searchParams.toString(), "a=54");
});
unitTest(function urlSearchParamsGetAllSuccess(): void {
const init = "a=54&b=true&a=true";
const searchParams = new URLSearchParams(init);
assertEquals(searchParams.getAll("a"), ["54", "true"]);
assertEquals(searchParams.getAll("b"), ["true"]);
assertEquals(searchParams.getAll("c"), []);
});
unitTest(function urlSearchParamsGetSuccess(): void {
const init = "a=54&b=true&a=true";
const searchParams = new URLSearchParams(init);
assertEquals(searchParams.get("a"), "54");
assertEquals(searchParams.get("b"), "true");
assertEquals(searchParams.get("c"), null);
});
unitTest(function urlSearchParamsHasSuccess(): void {
const init = "a=54&b=true&a=true";
const searchParams = new URLSearchParams(init);
assert(searchParams.has("a"));
assert(searchParams.has("b"));
assert(!searchParams.has("c"));
});
unitTest(function urlSearchParamsSetReplaceFirstAndRemoveOthers(): void {
const init = "a=54&b=true&a=true";
const searchParams = new URLSearchParams(init);
searchParams.set("a", "false");
assertEquals(searchParams.toString(), "a=false&b=true");
});
unitTest(function urlSearchParamsSetAppendNew(): void {
const init = "a=54&b=true&a=true";
const searchParams = new URLSearchParams(init);
searchParams.set("c", "foo");
assertEquals(searchParams.toString(), "a=54&b=true&a=true&c=foo");
});
unitTest(function urlSearchParamsSortSuccess(): void {
const init = "c=4&a=2&b=3&a=1";
const searchParams = new URLSearchParams(init);
searchParams.sort();
assertEquals(searchParams.toString(), "a=2&a=1&b=3&c=4");
});
unitTest(function urlSearchParamsForEachSuccess(): void {
const init = [
["a", "54"],
["b", "true"],
];
const searchParams = new URLSearchParams(init);
let callNum = 0;
searchParams.forEach((value, key, parent): void => {
assertEquals(searchParams, parent);
assertEquals(value, init[callNum][1]);
assertEquals(key, init[callNum][0]);
callNum++;
});
assertEquals(callNum, init.length);
});
unitTest(function urlSearchParamsMissingName(): void {
const init = "=4";
const searchParams = new URLSearchParams(init);
assertEquals(searchParams.get(""), "4");
assertEquals(searchParams.toString(), "=4");
});
unitTest(function urlSearchParamsMissingValue(): void {
const init = "4=";
const searchParams = new URLSearchParams(init);
assertEquals(searchParams.get("4"), "");
assertEquals(searchParams.toString(), "4=");
});
unitTest(function urlSearchParamsMissingEqualSign(): void {
const init = "4";
const searchParams = new URLSearchParams(init);
assertEquals(searchParams.get("4"), "");
assertEquals(searchParams.toString(), "4=");
});
unitTest(function urlSearchParamsMissingPair(): void {
const init = "c=4&&a=54&";
const searchParams = new URLSearchParams(init);
assertEquals(searchParams.toString(), "c=4&a=54");
});
// If pair does not contain exactly two items, then throw a TypeError.
// ref https://url.spec.whatwg.org/#interface-urlsearchparams
unitTest(function urlSearchParamsShouldThrowTypeError(): void {
let hasThrown = 0;
try {
new URLSearchParams([["1"]]);
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
try {
new URLSearchParams([["1", "2", "3"]]);
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
});
unitTest(function urlSearchParamsAppendArgumentsCheck(): void {
const methodRequireOneParam = ["delete", "getAll", "get", "has", "forEach"];
const methodRequireTwoParams = ["append", "set"];
methodRequireOneParam
.concat(methodRequireTwoParams)
.forEach((method: string): void => {
const searchParams = new URLSearchParams();
let hasThrown = 0;
try {
// @ts-ignore
searchParams[method]();
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
});
methodRequireTwoParams.forEach((method: string): void => {
const searchParams = new URLSearchParams();
let hasThrown = 0;
try {
// @ts-ignore
searchParams[method]("foo");
hasThrown = 1;
} catch (err) {
if (err instanceof TypeError) {
hasThrown = 2;
} else {
hasThrown = 3;
}
}
assertEquals(hasThrown, 2);
});
});
// ref: https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-delete.any.js
unitTest(function urlSearchParamsDeletingAppendedMultiple(): void {
const params = new URLSearchParams();
params.append("first", (1 as unknown) as string);
assert(params.has("first"));
assertEquals(params.get("first"), "1");
params.delete("first");
assertEquals(params.has("first"), false);
params.append("first", (1 as unknown) as string);
params.append("first", (10 as unknown) as string);
params.delete("first");
assertEquals(params.has("first"), false);
});
// ref: https://github.com/web-platform-tests/wpt/blob/master/url/urlsearchparams-constructor.any.js#L176-L182
unitTest(function urlSearchParamsCustomSymbolIterator(): void {
const params = new URLSearchParams();
params[Symbol.iterator] = function* (): IterableIterator<[string, string]> {
yield ["a", "b"];
};
const params1 = new URLSearchParams((params as unknown) as string[][]);
assertEquals(params1.get("a"), "b");
});
unitTest(
function urlSearchParamsCustomSymbolIteratorWithNonStringParams(): void {
const params = {};
// @ts-ignore
params[Symbol.iterator] = function* (): IterableIterator<[number, number]> {
yield [1, 2];
};
const params1 = new URLSearchParams((params as unknown) as string[][]);
assertEquals(params1.get("1"), "2");
}
);
// If a class extends URLSearchParams, override one method should not change another's behavior.
unitTest(
function urlSearchParamsOverridingAppendNotChangeConstructorAndSet(): void {
let overridedAppendCalled = 0;
class CustomSearchParams extends URLSearchParams {
append(name: string, value: string): void {
++overridedAppendCalled;
super.append(name, value);
}
}
new CustomSearchParams("foo=bar");
new CustomSearchParams([["foo", "bar"]]);
new CustomSearchParams(new CustomSearchParams({ foo: "bar" }));
new CustomSearchParams().set("foo", "bar");
assertEquals(overridedAppendCalled, 0);
}
);
unitTest(function urlSearchParamsOverridingEntriesNotChangeForEach(): void {
class CustomSearchParams extends URLSearchParams {
*entries(): IterableIterator<[string, string]> {
yield* [];
}
}
let loopCount = 0;
const params = new CustomSearchParams({ foo: "bar" });
params.forEach(() => void ++loopCount);
assertEquals(loopCount, 1);
});

View file

@ -1,407 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals, assertThrows } from "./test_util.ts";
unitTest(function urlParsing(): void {
const url = new URL(
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
);
assertEquals(url.hash, "#qat");
assertEquals(url.host, "baz.qat:8000");
assertEquals(url.hostname, "baz.qat");
assertEquals(
url.href,
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
);
assertEquals(url.origin, "https://baz.qat:8000");
assertEquals(url.password, "bar");
assertEquals(url.pathname, "/qux/quux");
assertEquals(url.port, "8000");
assertEquals(url.protocol, "https:");
assertEquals(url.search, "?foo=bar&baz=12");
assertEquals(url.searchParams.getAll("foo"), ["bar"]);
assertEquals(url.searchParams.getAll("baz"), ["12"]);
assertEquals(url.username, "foo");
assertEquals(
String(url),
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
);
assertEquals(
JSON.stringify({ key: url }),
`{"key":"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"}`
);
});
unitTest(function urlModifications(): void {
const url = new URL(
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
);
url.hash = "";
assertEquals(
url.href,
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12"
);
url.host = "qat.baz:8080";
assertEquals(
url.href,
"https://foo:bar@qat.baz:8080/qux/quux?foo=bar&baz=12"
);
url.hostname = "foo.bar";
assertEquals(
url.href,
"https://foo:bar@foo.bar:8080/qux/quux?foo=bar&baz=12"
);
url.password = "qux";
assertEquals(
url.href,
"https://foo:qux@foo.bar:8080/qux/quux?foo=bar&baz=12"
);
url.pathname = "/foo/bar%qat";
assertEquals(
url.href,
"https://foo:qux@foo.bar:8080/foo/bar%qat?foo=bar&baz=12"
);
url.port = "";
assertEquals(url.href, "https://foo:qux@foo.bar/foo/bar%qat?foo=bar&baz=12");
url.protocol = "http:";
assertEquals(url.href, "http://foo:qux@foo.bar/foo/bar%qat?foo=bar&baz=12");
url.search = "?foo=bar&foo=baz";
assertEquals(url.href, "http://foo:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz");
assertEquals(url.searchParams.getAll("foo"), ["bar", "baz"]);
url.username = "foo@bar";
assertEquals(
url.href,
"http://foo%40bar:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz"
);
url.searchParams.set("bar", "qat");
assertEquals(
url.href,
"http://foo%40bar:qux@foo.bar/foo/bar%qat?foo=bar&foo=baz&bar=qat"
);
url.searchParams.delete("foo");
assertEquals(url.href, "http://foo%40bar:qux@foo.bar/foo/bar%qat?bar=qat");
url.searchParams.append("foo", "bar");
assertEquals(
url.href,
"http://foo%40bar:qux@foo.bar/foo/bar%qat?bar=qat&foo=bar"
);
});
unitTest(function urlModifyHref(): void {
const url = new URL("http://example.com/");
url.href = "https://foo:bar@example.com:8080/baz/qat#qux";
assertEquals(url.protocol, "https:");
assertEquals(url.username, "foo");
assertEquals(url.password, "bar");
assertEquals(url.host, "example.com:8080");
assertEquals(url.hostname, "example.com");
assertEquals(url.pathname, "/baz/qat");
assertEquals(url.hash, "#qux");
});
unitTest(function urlNormalize(): void {
const url = new URL("http://example.com");
assertEquals(url.pathname, "/");
assertEquals(url.href, "http://example.com/");
});
unitTest(function urlModifyPathname(): void {
const url = new URL("http://foo.bar/baz%qat/qux%quux");
assertEquals(url.pathname, "/baz%qat/qux%quux");
url.pathname = url.pathname;
assertEquals(url.pathname, "/baz%qat/qux%quux");
url.pathname = "baz#qat qux";
assertEquals(url.pathname, "/baz%23qat%20qux");
url.pathname = url.pathname;
assertEquals(url.pathname, "/baz%23qat%20qux");
});
unitTest(function urlModifyHash(): void {
const url = new URL("http://foo.bar");
url.hash = "%foo bar/qat%qux#bar";
assertEquals(url.hash, "#%foo%20bar/qat%qux#bar");
url.hash = url.hash;
assertEquals(url.hash, "#%foo%20bar/qat%qux#bar");
});
unitTest(function urlSearchParamsReuse(): void {
const url = new URL(
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
);
const sp = url.searchParams;
url.host = "baz.qat";
assert(sp === url.searchParams, "Search params should be reused.");
});
unitTest(function urlBackSlashes(): void {
const url = new URL(
"https:\\\\foo:bar@baz.qat:8000\\qux\\quux?foo=bar&baz=12#qat"
);
assertEquals(
url.href,
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
);
});
unitTest(function urlRequireHost(): void {
assertEquals(new URL("file:///").href, "file:///");
assertThrows(() => {
new URL("ftp:///");
});
assertThrows(() => {
new URL("http:///");
});
assertThrows(() => {
new URL("https:///");
});
assertThrows(() => {
new URL("ws:///");
});
assertThrows(() => {
new URL("wss:///");
});
});
unitTest(function urlDriveLetter() {
assertEquals(
new URL("file:///C:").href,
Deno.build.os == "windows" ? "file:///C:/" : "file:///C:"
);
assertEquals(new URL("http://example.com/C:").href, "http://example.com/C:");
});
unitTest(function urlHostnameUpperCase() {
assertEquals(new URL("https://EXAMPLE.COM").href, "https://example.com/");
});
unitTest(function urlTrim() {
assertEquals(new URL(" https://example.com ").href, "https://example.com/");
});
unitTest(function urlEncoding() {
assertEquals(
new URL("https://a !$&*()=,;+'\"@example.com").username,
"a%20!$&*()%3D,%3B+%27%22"
);
assertEquals(
new URL("https://:a !$&*()=,;+'\"@example.com").password,
"a%20!$&*()%3D,%3B+%27%22"
);
// FIXME: https://url.spec.whatwg.org/#idna
// assertEquals(
// new URL("https://a !$&*()=,+'\"").hostname,
// "a%20%21%24%26%2A%28%29%3D%2C+%27%22"
// );
assertEquals(
new URL("https://example.com/a ~!@$&*()=:/,;+'\"\\").pathname,
"/a%20~!@$&*()=:/,;+'%22/"
);
assertEquals(
new URL("https://example.com?a ~!@$&*()=:/,;?+'\"\\").search,
"?a%20~!@$&*()=:/,;?+%27%22\\"
);
assertEquals(
new URL("https://example.com#a ~!@#$&*()=:/,;?+'\"\\").hash,
"#a%20~!@#$&*()=:/,;?+'%22\\"
);
});
unitTest(function urlBaseURL(): void {
const base = new URL(
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
);
const url = new URL("/foo/bar?baz=foo#qux", base);
assertEquals(url.href, "https://foo:bar@baz.qat:8000/foo/bar?baz=foo#qux");
});
unitTest(function urlBaseString(): void {
const url = new URL(
"/foo/bar?baz=foo#qux",
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
);
assertEquals(url.href, "https://foo:bar@baz.qat:8000/foo/bar?baz=foo#qux");
});
unitTest(function urlRelativeWithBase(): void {
assertEquals(new URL("", "file:///a/a/a").href, "file:///a/a/a");
assertEquals(new URL(".", "file:///a/a/a").href, "file:///a/a/");
assertEquals(new URL("..", "file:///a/a/a").href, "file:///a/");
assertEquals(new URL("b", "file:///a/a/a").href, "file:///a/a/b");
assertEquals(new URL("b", "file:///a/a/a/").href, "file:///a/a/a/b");
assertEquals(new URL("b/", "file:///a/a/a").href, "file:///a/a/b/");
assertEquals(new URL("../b", "file:///a/a/a").href, "file:///a/b");
});
unitTest(function urlDriveLetterBase() {
assertEquals(
new URL("/b", "file:///C:/a/b").href,
Deno.build.os == "windows" ? "file:///C:/b" : "file:///b"
);
assertEquals(
new URL("D:", "file:///C:/a/b").href,
Deno.build.os == "windows" ? "file:///D:/" : "file:///C:/a/D:"
);
assertEquals(
new URL("/D:", "file:///C:/a/b").href,
Deno.build.os == "windows" ? "file:///D:/" : "file:///D:"
);
assertEquals(
new URL("D:/b", "file:///C:/a/b").href,
Deno.build.os == "windows" ? "file:///D:/b" : "file:///C:/a/D:/b"
);
});
unitTest(function emptyBasePath(): void {
assertEquals(new URL("", "http://example.com").href, "http://example.com/");
});
unitTest(function deletingAllParamsRemovesQuestionMarkFromURL(): void {
const url = new URL("http://example.com/?param1&param2");
url.searchParams.delete("param1");
url.searchParams.delete("param2");
assertEquals(url.href, "http://example.com/");
assertEquals(url.search, "");
});
unitTest(function removingNonExistentParamRemovesQuestionMarkFromURL(): void {
const url = new URL("http://example.com/?");
assertEquals(url.href, "http://example.com/?");
url.searchParams.delete("param1");
assertEquals(url.href, "http://example.com/");
assertEquals(url.search, "");
});
unitTest(function sortingNonExistentParamRemovesQuestionMarkFromURL(): void {
const url = new URL("http://example.com/?");
assertEquals(url.href, "http://example.com/?");
url.searchParams.sort();
assertEquals(url.href, "http://example.com/");
assertEquals(url.search, "");
});
unitTest(
{
// FIXME(bartlomieju)
ignore: true,
},
function customInspectFunction(): void {
const url = new URL("http://example.com/?");
assertEquals(
Deno.inspect(url),
'URL { href: "http://example.com/?", origin: "http://example.com", protocol: "http:", username: "", password: "", host: "example.com", hostname: "example.com", port: "", pathname: "/", hash: "", search: "?" }'
);
}
);
unitTest(function protocolNotHttpOrFile() {
const url = new URL("about:blank");
assertEquals(url.href, "about:blank");
assertEquals(url.protocol, "about:");
assertEquals(url.origin, "null");
});
unitTest(function createBadUrl(): void {
assertThrows(() => {
new URL("0.0.0.0:8080");
});
});
unitTest(function throwForInvalidPortConstructor(): void {
const urls = [
// If port is greater than 2^16 1, validation error, return failure.
`https://baz.qat:${2 ** 16}`,
"https://baz.qat:-32",
"https://baz.qat:deno",
"https://baz.qat:9land",
"https://baz.qat:10.5",
];
for (const url of urls) {
assertThrows(() => new URL(url), TypeError, "Invalid URL.");
}
// Do not throw for 0 & 65535
new URL("https://baz.qat:65535");
new URL("https://baz.qat:0");
});
unitTest(function throwForInvalidSchemeConstructor(): void {
assertThrows(
() => new URL("invalid_scheme://baz.qat"),
TypeError,
"Invalid URL."
);
});
unitTest(function doNotOverridePortIfInvalid(): void {
const initialPort = "3000";
const ports = [
// If port is greater than 2^16 1, validation error, return failure.
`${2 ** 16}`,
"-32",
"deno",
"9land",
"10.5",
];
for (const port of ports) {
const url = new URL(`https://deno.land:${initialPort}`);
url.port = port;
assertEquals(url.port, initialPort);
}
});
unitTest(function emptyPortForSchemeDefaultPort(): void {
const nonDefaultPort = "3500";
const urls = [
{ url: "ftp://baz.qat:21", port: "21", protocol: "ftp:" },
{ url: "https://baz.qat:443", port: "443", protocol: "https:" },
{ url: "wss://baz.qat:443", port: "443", protocol: "wss:" },
{ url: "http://baz.qat:80", port: "80", protocol: "http:" },
{ url: "ws://baz.qat:80", port: "80", protocol: "ws:" },
{ url: "file://home/index.html", port: "", protocol: "file:" },
{ url: "/foo", baseUrl: "ftp://baz.qat:21", port: "21", protocol: "ftp:" },
{
url: "/foo",
baseUrl: "https://baz.qat:443",
port: "443",
protocol: "https:",
},
{
url: "/foo",
baseUrl: "wss://baz.qat:443",
port: "443",
protocol: "wss:",
},
{
url: "/foo",
baseUrl: "http://baz.qat:80",
port: "80",
protocol: "http:",
},
{ url: "/foo", baseUrl: "ws://baz.qat:80", port: "80", protocol: "ws:" },
{
url: "/foo",
baseUrl: "file://home/index.html",
port: "",
protocol: "file:",
},
];
for (const { url: urlString, baseUrl, port, protocol } of urls) {
const url = new URL(urlString, baseUrl);
assertEquals(url.port, "");
url.port = nonDefaultPort;
assertEquals(url.port, nonDefaultPort);
url.port = port;
assertEquals(url.port, "");
// change scheme
url.protocol = "sftp:";
assertEquals(url.port, port);
url.protocol = protocol;
assertEquals(url.port, "");
}
});

View file

@ -1,230 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert } from "./test_util.ts";
// Allow 10 second difference.
// Note this might not be enough for FAT (but we are not testing on such fs).
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function assertFuzzyTimestampEquals(t1: Date | null, t2: Date): void {
assert(t1 instanceof Date);
assert(Math.abs(t1.valueOf() - t2.valueOf()) < 10_000);
}
unitTest(
{ perms: { read: true, write: true } },
function utimeSyncFileSuccess(): void {
const testDir = Deno.makeTempDirSync();
const filename = testDir + "/file.txt";
Deno.writeFileSync(filename, new TextEncoder().encode("hello"), {
mode: 0o666,
});
const atime = 1000;
const mtime = 50000;
Deno.utimeSync(filename, atime, mtime);
const fileInfo = Deno.statSync(filename);
assertFuzzyTimestampEquals(fileInfo.atime, new Date(atime * 1000));
assertFuzzyTimestampEquals(fileInfo.mtime, new Date(mtime * 1000));
}
);
unitTest(
{ perms: { read: true, write: true } },
function utimeSyncDirectorySuccess(): void {
const testDir = Deno.makeTempDirSync();
const atime = 1000;
const mtime = 50000;
Deno.utimeSync(testDir, atime, mtime);
const dirInfo = Deno.statSync(testDir);
assertFuzzyTimestampEquals(dirInfo.atime, new Date(atime * 1000));
assertFuzzyTimestampEquals(dirInfo.mtime, new Date(mtime * 1000));
}
);
unitTest(
{ perms: { read: true, write: true } },
function utimeSyncDateSuccess(): void {
const testDir = Deno.makeTempDirSync();
const atime = new Date(1000_000);
const mtime = new Date(50000_000);
Deno.utimeSync(testDir, atime, mtime);
const dirInfo = Deno.statSync(testDir);
assertFuzzyTimestampEquals(dirInfo.atime, atime);
assertFuzzyTimestampEquals(dirInfo.mtime, mtime);
}
);
unitTest(
{ perms: { read: true, write: true } },
function utimeSyncFileDateSuccess() {
const testDir = Deno.makeTempDirSync();
const filename = testDir + "/file.txt";
Deno.writeFileSync(filename, new TextEncoder().encode("hello"), {
mode: 0o666,
});
const atime = new Date();
const mtime = new Date();
Deno.utimeSync(filename, atime, mtime);
const fileInfo = Deno.statSync(filename);
assertFuzzyTimestampEquals(fileInfo.atime, atime);
assertFuzzyTimestampEquals(fileInfo.mtime, mtime);
}
);
unitTest(
{ perms: { read: true, write: true } },
function utimeSyncLargeNumberSuccess(): void {
const testDir = Deno.makeTempDirSync();
// There are Rust side caps (might be fs relate),
// so JUST make them slightly larger than UINT32_MAX.
const atime = 0x100000001;
const mtime = 0x100000002;
Deno.utimeSync(testDir, atime, mtime);
const dirInfo = Deno.statSync(testDir);
assertFuzzyTimestampEquals(dirInfo.atime, new Date(atime * 1000));
assertFuzzyTimestampEquals(dirInfo.mtime, new Date(mtime * 1000));
}
);
unitTest(
{ perms: { read: true, write: true } },
function utimeSyncNotFound(): void {
const atime = 1000;
const mtime = 50000;
let caughtError = false;
try {
Deno.utimeSync("/baddir", atime, mtime);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
}
);
unitTest(
{ perms: { read: true, write: false } },
function utimeSyncPerm(): void {
const atime = 1000;
const mtime = 50000;
let caughtError = false;
try {
Deno.utimeSync("/some_dir", atime, mtime);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function utimeFileSuccess(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const filename = testDir + "/file.txt";
Deno.writeFileSync(filename, new TextEncoder().encode("hello"), {
mode: 0o666,
});
const atime = 1000;
const mtime = 50000;
await Deno.utime(filename, atime, mtime);
const fileInfo = Deno.statSync(filename);
assertFuzzyTimestampEquals(fileInfo.atime, new Date(atime * 1000));
assertFuzzyTimestampEquals(fileInfo.mtime, new Date(mtime * 1000));
}
);
unitTest(
{ perms: { read: true, write: true } },
async function utimeDirectorySuccess(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const atime = 1000;
const mtime = 50000;
await Deno.utime(testDir, atime, mtime);
const dirInfo = Deno.statSync(testDir);
assertFuzzyTimestampEquals(dirInfo.atime, new Date(atime * 1000));
assertFuzzyTimestampEquals(dirInfo.mtime, new Date(mtime * 1000));
}
);
unitTest(
{ perms: { read: true, write: true } },
async function utimeDateSuccess(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const atime = new Date(100_000);
const mtime = new Date(5000_000);
await Deno.utime(testDir, atime, mtime);
const dirInfo = Deno.statSync(testDir);
assertFuzzyTimestampEquals(dirInfo.atime, atime);
assertFuzzyTimestampEquals(dirInfo.mtime, mtime);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function utimeFileDateSuccess(): Promise<void> {
const testDir = Deno.makeTempDirSync();
const filename = testDir + "/file.txt";
Deno.writeFileSync(filename, new TextEncoder().encode("hello"), {
mode: 0o666,
});
const atime = new Date();
const mtime = new Date();
await Deno.utime(filename, atime, mtime);
const fileInfo = Deno.statSync(filename);
assertFuzzyTimestampEquals(fileInfo.atime, atime);
assertFuzzyTimestampEquals(fileInfo.mtime, mtime);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function utimeNotFound(): Promise<void> {
const atime = 1000;
const mtime = 50000;
let caughtError = false;
try {
await Deno.utime("/baddir", atime, mtime);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
}
);
unitTest(
{ perms: { read: true, write: false } },
async function utimeSyncPerm(): Promise<void> {
const atime = 1000;
const mtime = 50000;
let caughtError = false;
try {
await Deno.utime("/some_dir", atime, mtime);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
}
);

View file

@ -1,8 +0,0 @@
import { unitTest, assert } from "./test_util.ts";
unitTest(function version(): void {
const pattern = /^\d+\.\d+\.\d+/;
assert(pattern.test(Deno.version.deno));
assert(pattern.test(Deno.version.v8));
assert(pattern.test(Deno.version.typescript));
});

View file

@ -1,228 +0,0 @@
// Copyright 2018-2020 the Deno authors. All rights reserved. MIT license.
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(
{ perms: { read: true, write: true } },
function writeFileSyncSuccess(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data);
const dataRead = Deno.readFileSync(filename);
const dec = new TextDecoder("utf-8");
const actual = dec.decode(dataRead);
assertEquals("Hello", actual);
}
);
unitTest({ perms: { write: true } }, function writeFileSyncFail(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = "/baddir/test.txt";
// The following should fail because /baddir doesn't exist (hopefully).
let caughtError = false;
try {
Deno.writeFileSync(filename, data);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
});
unitTest({ perms: { write: false } }, function writeFileSyncPerm(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = "/baddir/test.txt";
// The following should fail due to no write permission
let caughtError = false;
try {
Deno.writeFileSync(filename, data);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest(
{ perms: { read: true, write: true } },
function writeFileSyncUpdateMode(): void {
if (Deno.build.os !== "windows") {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data, { mode: 0o755 });
assertEquals(Deno.statSync(filename).mode! & 0o777, 0o755);
Deno.writeFileSync(filename, data, { mode: 0o666 });
assertEquals(Deno.statSync(filename).mode! & 0o777, 0o666);
}
}
);
unitTest(
{ perms: { read: true, write: true } },
function writeFileSyncCreate(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
let caughtError = false;
// if create turned off, the file won't be created
try {
Deno.writeFileSync(filename, data, { create: false });
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
// Turn on create, should have no error
Deno.writeFileSync(filename, data, { create: true });
Deno.writeFileSync(filename, data, { create: false });
const dataRead = Deno.readFileSync(filename);
const dec = new TextDecoder("utf-8");
const actual = dec.decode(dataRead);
assertEquals("Hello", actual);
}
);
unitTest(
{ perms: { read: true, write: true } },
function writeFileSyncAppend(): void {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeFileSync(filename, data);
Deno.writeFileSync(filename, data, { append: true });
let dataRead = Deno.readFileSync(filename);
const dec = new TextDecoder("utf-8");
let actual = dec.decode(dataRead);
assertEquals("HelloHello", actual);
// Now attempt overwrite
Deno.writeFileSync(filename, data, { append: false });
dataRead = Deno.readFileSync(filename);
actual = dec.decode(dataRead);
assertEquals("Hello", actual);
// append not set should also overwrite
Deno.writeFileSync(filename, data);
dataRead = Deno.readFileSync(filename);
actual = dec.decode(dataRead);
assertEquals("Hello", actual);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function writeFileSuccess(): Promise<void> {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
await Deno.writeFile(filename, data);
const dataRead = Deno.readFileSync(filename);
const dec = new TextDecoder("utf-8");
const actual = dec.decode(dataRead);
assertEquals("Hello", actual);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function writeFileNotFound(): Promise<void> {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = "/baddir/test.txt";
// The following should fail because /baddir doesn't exist (hopefully).
let caughtError = false;
try {
await Deno.writeFile(filename, data);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
}
);
unitTest(
{ perms: { read: true, write: false } },
async function writeFilePerm(): Promise<void> {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = "/baddir/test.txt";
// The following should fail due to no write permission
let caughtError = false;
try {
await Deno.writeFile(filename, data);
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function writeFileUpdateMode(): Promise<void> {
if (Deno.build.os !== "windows") {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
await Deno.writeFile(filename, data, { mode: 0o755 });
assertEquals(Deno.statSync(filename).mode! & 0o777, 0o755);
await Deno.writeFile(filename, data, { mode: 0o666 });
assertEquals(Deno.statSync(filename).mode! & 0o777, 0o666);
}
}
);
unitTest(
{ perms: { read: true, write: true } },
async function writeFileCreate(): Promise<void> {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
let caughtError = false;
// if create turned off, the file won't be created
try {
await Deno.writeFile(filename, data, { create: false });
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
// Turn on create, should have no error
await Deno.writeFile(filename, data, { create: true });
await Deno.writeFile(filename, data, { create: false });
const dataRead = Deno.readFileSync(filename);
const dec = new TextDecoder("utf-8");
const actual = dec.decode(dataRead);
assertEquals("Hello", actual);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function writeFileAppend(): Promise<void> {
const enc = new TextEncoder();
const data = enc.encode("Hello");
const filename = Deno.makeTempDirSync() + "/test.txt";
await Deno.writeFile(filename, data);
await Deno.writeFile(filename, data, { append: true });
let dataRead = Deno.readFileSync(filename);
const dec = new TextDecoder("utf-8");
let actual = dec.decode(dataRead);
assertEquals("HelloHello", actual);
// Now attempt overwrite
await Deno.writeFile(filename, data, { append: false });
dataRead = Deno.readFileSync(filename);
actual = dec.decode(dataRead);
assertEquals("Hello", actual);
// append not set should also overwrite
await Deno.writeFile(filename, data);
dataRead = Deno.readFileSync(filename);
actual = dec.decode(dataRead);
assertEquals("Hello", actual);
}
);

View file

@ -1,79 +0,0 @@
import { unitTest, assert, assertEquals } from "./test_util.ts";
unitTest(
{ perms: { read: true, write: true } },
function writeTextFileSyncSuccess(): void {
const filename = Deno.makeTempDirSync() + "/test.txt";
Deno.writeTextFileSync(filename, "Hello");
const dataRead = Deno.readTextFileSync(filename);
assertEquals("Hello", dataRead);
}
);
unitTest({ perms: { write: true } }, function writeTextFileSyncFail(): void {
const filename = "/baddir/test.txt";
// The following should fail because /baddir doesn't exist (hopefully).
let caughtError = false;
try {
Deno.writeTextFileSync(filename, "hello");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
});
unitTest({ perms: { write: false } }, function writeTextFileSyncPerm(): void {
const filename = "/baddir/test.txt";
// The following should fail due to no write permission
let caughtError = false;
try {
Deno.writeTextFileSync(filename, "Hello");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
});
unitTest(
{ perms: { read: true, write: true } },
async function writeTextFileSuccess(): Promise<void> {
const filename = Deno.makeTempDirSync() + "/test.txt";
await Deno.writeTextFile(filename, "Hello");
const dataRead = Deno.readTextFileSync(filename);
assertEquals("Hello", dataRead);
}
);
unitTest(
{ perms: { read: true, write: true } },
async function writeTextFileNotFound(): Promise<void> {
const filename = "/baddir/test.txt";
// The following should fail because /baddir doesn't exist (hopefully).
let caughtError = false;
try {
await Deno.writeTextFile(filename, "Hello");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.NotFound);
}
assert(caughtError);
}
);
unitTest(
{ perms: { write: false } },
async function writeTextFilePerm(): Promise<void> {
const filename = "/baddir/test.txt";
// The following should fail due to no write permission
let caughtError = false;
try {
await Deno.writeTextFile(filename, "Hello");
} catch (e) {
caughtError = true;
assert(e instanceof Deno.errors.PermissionDenied);
}
assert(caughtError);
}
);