1
0
Fork 0
mirror of https://github.com/denoland/deno.git synced 2024-11-25 15:29:32 -05:00

Add ability to unit test by permissions.

This commit is contained in:
Ryan Dahl 2018-08-23 19:47:43 -04:00
parent 722c7e4a1b
commit e13f3c10ca
7 changed files with 113 additions and 25 deletions

View file

@ -1,5 +1,5 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license. // Copyright 2018 the Deno authors. All rights reserved. MIT license.
import { test, assert, assertEqual } from "./testing/testing.ts"; import { test, assert, assertEqual } from "./test_util.ts";
import * as compiler from "compiler"; import * as compiler from "compiler";
import * as ts from "typescript"; import * as ts from "typescript";

View file

@ -1,6 +1,6 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license. // Copyright 2018 the Deno authors. All rights reserved. MIT license.
import { test, assert, assertEqual } from "./testing/testing.ts"; import { test, assert, assertEqual } from "./test_util.ts";
import { stringifyArgs } from "./console.ts"; import { stringifyArgs } from "./console.ts";
// tslint:disable-next-line:no-any // tslint:disable-next-line:no-any

70
js/test_util.ts Normal file
View file

@ -0,0 +1,70 @@
// Copyright 2018 the Deno authors. All rights reserved. MIT license.
//
// We want to test many ops in deno which have different behavior depending on
// the permissions set. These tests can specify which permissions they expect,
// which appends a special string like "permW1N0" to the end of the test name.
// Here we run several copies of deno with different permissions, filtering the
// tests by the special string. permW0N0 means allow-write but not allow-net.
// See tools/unit_tests.py for more details.
import * as deno from "deno";
import * as testing from "./testing/testing.ts";
export { assert, assertEqual } from "./testing/testing.ts";
// testing.setFilter must be run before any tests are defined.
const permFilter = deno.argv[1];
permFromString(permFilter);
testing.setFilter(permFilter);
interface DenoPermissions {
write?: boolean;
net?: boolean;
}
function permToString(perms: DenoPermissions): string {
const w = perms.write ? 1 : 0;
const n = perms.net ? 1 : 0;
return `permW${w}N${n}`;
}
function permFromString(s: string): DenoPermissions {
const re = /^permW([01])N([01])$/;
const found = s.match(re);
if (!found) {
throw Error("Not a permission string");
}
return {
write: Boolean(Number(found[1])),
net: Boolean(Number(found[2]))
};
}
export function testPerm(perms: DenoPermissions, fn: testing.TestFunction) {
const name = `${fn.name}_${permToString(perms)}`;
testing.test({ fn, name });
}
export function test(fn: testing.TestFunction) {
testPerm({ write: false, net: false }, fn);
}
test(function permSerialization() {
for (let write of [true, false]) {
for (let net of [true, false]) {
let perms: DenoPermissions = { write, net };
testing.assertEqual(perms, permFromString(permToString(perms)));
}
}
});
// To better catch internal errors, permFromString should throw if it gets an
// invalid permission string.
test(function permFromStringThrows() {
let threw = false;
try {
permFromString("bad");
} catch (e) {
threw = true;
}
testing.assert(threw);
});

View file

@ -24,22 +24,14 @@ export interface TestDefinition {
export const exitOnFail = true; export const exitOnFail = true;
/* A subset of the tests can be ran by providing a filter expression. let filterRegExp: RegExp | null;
* In Node.js the filter is specified on the command line:
*
* ts-node test_node log # all tests with 'log' in the name
* ts-node test_node ^util # tests starting with 'util'
*
* In the browser, the filter is specified as part of the url:
*
* http://localhost:9876/test.html#script=some/script.js&filter=log
* http://localhost:9876/test.html#script=some/script.js&filter=^util
*/
let filterExpr: string = null;
const filterRegExp = filterExpr ? new RegExp(filterExpr, "i") : null;
const tests: TestDefinition[] = []; const tests: TestDefinition[] = [];
// Must be called before any test() that needs to be filtered.
export function setFilter(s: string): void {
filterRegExp = new RegExp(s, "i");
}
export function test(t: TestDefinition | TestFunction): void { export function test(t: TestDefinition | TestFunction): void {
const fn: TestFunction = typeof t === "function" ? t : t.fn; const fn: TestFunction = typeof t === "function" ? t : t.fn;
const name: string = t.name; const name: string = t.name;

View file

@ -3,8 +3,7 @@
// But it can also be run manually: // But it can also be run manually:
// ./deno tests.ts // ./deno tests.ts
import { test, assert, assertEqual } from "./testing/testing.ts"; import { test, testPerm, assert, assertEqual } from "./test_util.ts";
import { readFileSync } from "deno";
import * as deno from "deno"; import * as deno from "deno";
import "./compiler_test.ts"; import "./compiler_test.ts";
@ -15,7 +14,7 @@ test(async function tests_test() {
}); });
test(async function tests_readFileSync() { test(async function tests_readFileSync() {
const data = readFileSync("package.json"); const data = deno.readFileSync("package.json");
if (!data.byteLength) { if (!data.byteLength) {
throw Error( throw Error(
`Expected positive value for data.byteLength ${data.byteLength}` `Expected positive value for data.byteLength ${data.byteLength}`
@ -32,7 +31,7 @@ test(function tests_readFileSync_NotFound() {
let caughtError = false; let caughtError = false;
let data; let data;
try { try {
data = readFileSync("bad_filename"); data = deno.readFileSync("bad_filename");
} catch (e) { } catch (e) {
caughtError = true; caughtError = true;
assert(e instanceof deno.NotFound); assert(e instanceof deno.NotFound);
@ -48,14 +47,14 @@ test(function writeFileSyncSuccess() {
const dataWritten = enc.encode("Hello"); const dataWritten = enc.encode("Hello");
const filename = "TEMPDIR/test.txt"; const filename = "TEMPDIR/test.txt";
deno.writeFileSync(filename, dataWritten, 0o666); deno.writeFileSync(filename, dataWritten, 0o666);
const dataRead = readFileSync(filename); const dataRead = deno.readFileSync(filename);
assertEqual(dataRead, dataWritten); assertEqual(dataRead, dataWritten);
}); });
*/ */
// For this test to pass we need --allow-write permission. // For this test to pass we need --allow-write permission.
// Otherwise it will fail with deno.PermissionDenied instead of deno.NotFound. // Otherwise it will fail with deno.PermissionDenied instead of deno.NotFound.
test(function writeFileSyncFail() { testPerm({ write: true }, function writeFileSyncFail() {
const enc = new TextEncoder(); const enc = new TextEncoder();
const data = enc.encode("Hello"); const data = enc.encode("Hello");
const filename = "/baddir/test.txt"; const filename = "/baddir/test.txt";
@ -71,7 +70,7 @@ test(function writeFileSyncFail() {
assert(caughtError); assert(caughtError);
}); });
test(async function tests_fetch() { testPerm({ net: true }, async function tests_fetch() {
const response = await fetch("http://localhost:4545/package.json"); const response = await fetch("http://localhost:4545/package.json");
const json = await response.json(); const json = await response.json();
assertEqual(json.name, "deno"); assertEqual(json.name, "deno");
@ -84,7 +83,7 @@ test(async function tests_writeFileSync() {
// TODO need ability to get tmp dir. // TODO need ability to get tmp dir.
const fn = "/tmp/test.txt"; const fn = "/tmp/test.txt";
writeFileSync("/tmp/test.txt", data, 0o666); writeFileSync("/tmp/test.txt", data, 0o666);
const dataRead = readFileSync("/tmp/test.txt"); const dataRead = deno.readFileSync("/tmp/test.txt");
const dec = new TextDecoder("utf-8"); const dec = new TextDecoder("utf-8");
const actual = dec.decode(dataRead); const actual = dec.decode(dataRead);
assertEqual("Hello", actual); assertEqual("Hello", actual);

View file

@ -5,6 +5,7 @@ import os
import sys import sys
from check_output_test import check_output_test from check_output_test import check_output_test
from util import executable_suffix, run, build_path from util import executable_suffix, run, build_path
from unit_tests import unit_tests
from util_test import util_test from util_test import util_test
import subprocess import subprocess
import http_server import http_server
@ -41,7 +42,7 @@ def main(argv):
deno_exe = os.path.join(build_dir, "deno" + executable_suffix) deno_exe = os.path.join(build_dir, "deno" + executable_suffix)
check_exists(deno_exe) check_exists(deno_exe)
run([deno_exe, "js/unit_tests.ts", "--allow-write"]) unit_tests(deno_exe)
check_exists(deno_exe) check_exists(deno_exe)
check_output_test(deno_exe) check_output_test(deno_exe)

26
tools/unit_tests.py Executable file
View file

@ -0,0 +1,26 @@
#!/usr/bin/env python
from util import run
import sys
# We want to test many ops in deno which have different behavior depending on
# the permissions set. These tests can specify which permissions they expect,
# which appends a special string like "permW1N0" to the end of the test name.
# Here we run several copies of deno with different permissions, filtering the
# tests by the special string. permW0N0 means allow-write but not allow-net.
# See js/test_util.ts for more details.
def unit_tests(deno_exe):
run([deno_exe, "js/unit_tests.ts", "permW0N0"])
run([deno_exe, "js/unit_tests.ts", "permW1N0", "--allow-write"])
run([deno_exe, "js/unit_tests.ts", "permW0N1", "--allow-net"])
run([
deno_exe, "js/unit_tests.ts", "permW1N1", "--allow-write",
"--allow-net"
])
if __name__ == '__main__':
if len(sys.argv) < 2:
print "Usage ./tools/unit_tests.py out/debug/deno"
sys.exit(1)
unit_tests(sys.argv[1])