summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyan Dahl <ry@tinyclouds.org>2018-05-28 11:16:38 -0400
committerRyan Dahl <ry@tinyclouds.org>2018-05-28 13:27:05 -0400
commit08d3850fa88df2319300874c701da1415b7372a0 (patch)
tree2646ad5482e2c3c5402bafd37f8340e93c70cc39
parent844f565cc053b188473a209e8642772ad42b43bd (diff)
Add tests.ts for fast unit tests.
Also deno_testing/ which will be released as a standalone module.
-rw-r--r--deno_testing/testing.ts96
-rw-r--r--deno_testing/util.ts60
-rw-r--r--deno_testing/util_test.ts32
-rw-r--r--integration_test.go11
-rw-r--r--runtime.ts5
-rw-r--r--tests.ts5
-rw-r--r--tsconfig.json3
7 files changed, 211 insertions, 1 deletions
diff --git a/deno_testing/testing.ts b/deno_testing/testing.ts
new file mode 100644
index 000000000..969c15704
--- /dev/null
+++ b/deno_testing/testing.ts
@@ -0,0 +1,96 @@
+/*!
+ Copyright 2018 Propel http://propel.site/. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+
+export { assert, assertEqual, equal } from "./util";
+
+export type TestFunction = () => void | Promise<void>;
+
+export interface TestDefinition {
+ fn: TestFunction;
+ name: string;
+}
+
+export const exitOnFail = true;
+
+/* A subset of the tests can be ran by providing a filter expression.
+ * 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[] = [];
+
+export function test(t: TestDefinition | TestFunction): void {
+ const fn: TestFunction = typeof t === "function" ? t : t.fn;
+ const name: string = t.name;
+
+ if (!name) {
+ throw new Error("Test function may not be anonymous");
+ }
+ if (filter(name)) {
+ tests.push({ fn, name });
+ }
+}
+
+function filter(name: string): boolean {
+ if (filterRegExp) {
+ return filterRegExp.test(name);
+ } else {
+ return true;
+ }
+}
+
+async function runTests() {
+ let passed = 0;
+ let failed = 0;
+
+ for (let i = 0; i < tests.length; i++) {
+ const { fn, name } = tests[i];
+ console.log(`${i+1}/${tests.length} +${passed} -${failed}: ${name}`);
+ try {
+ await fn();
+ passed++;
+ } catch (e) {
+ console.error("\nTest FAIL", name);
+ console.error((e && e.stack) || e);
+ failed++;
+ if (exitOnFail) {
+ break;
+ }
+ }
+ }
+
+ console.log(`\nDONE. Test passed: ${passed}, failed: ${failed}`);
+
+ if (failed === 0) {
+ // All good.
+ } else {
+ // Use setTimeout to avoid the error being ignored due to unhandled
+ // promise rejections being swallowed.
+ setTimeout(() => {
+ throw new Error(`There were ${failed} test failures.`);
+ }, 0);
+ }
+}
+
+setTimeout(runTests, 0);
diff --git a/deno_testing/util.ts b/deno_testing/util.ts
new file mode 100644
index 000000000..509713005
--- /dev/null
+++ b/deno_testing/util.ts
@@ -0,0 +1,60 @@
+/*!
+ Copyright 2018 Propel http://propel.site/. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+// tslint:disable-next-line:no-any
+export function assertEqual(actual: any, expected: any, msg?: string) {
+ if (!msg) { msg = `actual: ${actual} expected: ${expected}`; }
+ if (!equal(actual, expected)) {
+ console.error(
+ "assertEqual failed. actual = ", actual, "expected =", expected);
+ throw new Error(msg);
+ }
+}
+
+export function assert(expr: boolean, msg = "") {
+ if (!expr) {
+ throw new Error(msg);
+ }
+}
+
+// tslint:disable-next-line:no-any
+export function equal(c: any, d: any): boolean {
+ const seen = new Map();
+ return (function compare(a, b) {
+ if (a === b) {
+ return true;
+ }
+ if (typeof a === "number" && typeof b === "number" &&
+ isNaN(a) && isNaN(b)) {
+ return true;
+ }
+ if (a && typeof a === "object" && b && typeof b === "object") {
+ if (seen.get(a) === b) {
+ return true;
+ }
+ if (Object.keys(a).length !== Object.keys(b).length) {
+ return false;
+ }
+ for (const key in { ...a, ...b }) {
+ if (!compare(a[key], b[key])) {
+ return false;
+ }
+ }
+ seen.set(a, b);
+ return true;
+ }
+ return false;
+ })(c, d);
+}
diff --git a/deno_testing/util_test.ts b/deno_testing/util_test.ts
new file mode 100644
index 000000000..44f61f9c4
--- /dev/null
+++ b/deno_testing/util_test.ts
@@ -0,0 +1,32 @@
+/*!
+ Copyright 2018 Propel http://propel.site/. All rights reserved.
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+import { test } from "./index";
+import { assert } from "./util";
+import * as util from "./util";
+
+test(async function util_equal() {
+ assert(util.equal("world", "world"));
+ assert(!util.equal("hello", "world"));
+ assert(util.equal(5, 5));
+ assert(!util.equal(5, 6));
+ assert(util.equal(NaN, NaN));
+ assert(util.equal({ hello: "world" }, { hello: "world" }));
+ assert(!util.equal({ world: "hello" }, { hello: "world" }));
+ assert(util.equal({ hello: "world", hi: { there: "everyone" } },
+ { hello: "world", hi: { there: "everyone" } }));
+ assert(!util.equal({ hello: "world", hi: { there: "everyone" } },
+ { hello: "world", hi: { there: "everyone else" } }));
+});
diff --git a/integration_test.go b/integration_test.go
index 37c87f30a..a3f8f16ce 100644
--- a/integration_test.go
+++ b/integration_test.go
@@ -144,3 +144,14 @@ func TestErrors(t *testing.T) {
t.Fatalf("Expected error.")
}
}
+
+func TestTestsTs(t *testing.T) {
+ integrationTestSetup()
+ cmd := exec.Command(denoFn, "tests.ts")
+ cmd.Stdout = os.Stdout
+ cmd.Stderr = os.Stderr
+ err := cmd.Run()
+ if err != nil {
+ t.Fatal(err.Error())
+ }
+}
diff --git a/runtime.ts b/runtime.ts
index ca2e40ba0..7d91484ab 100644
--- a/runtime.ts
+++ b/runtime.ts
@@ -29,6 +29,11 @@ type AmdDefine = (deps: string[], factory: AmdFactory) => void;
// Uncaught exceptions are sent to window.onerror by v8worker2.
window.onerror = (message, source, lineno, colno, error) => {
+ // TODO Currently there is a bug in v8_source_maps.ts that causes a segfault
+ // if it is used within window.onerror. To workaround we uninstall the
+ // Error.prepareStackTrace handler. Users will get unmapped stack traces on
+ // uncaught exceptions until this issue is fixed.
+ Error.prepareStackTrace = null;
console.log(error.message, error.stack);
os.exit(1);
};
diff --git a/tests.ts b/tests.ts
new file mode 100644
index 000000000..b9fcbf37f
--- /dev/null
+++ b/tests.ts
@@ -0,0 +1,5 @@
+import { test, assert } from "./deno_testing/testing.ts";
+
+test(async function test_matchTesters() {
+ assert(false, "assert failed on purpose.");
+});
diff --git a/tsconfig.json b/tsconfig.json
index 4de82936c..769d75b46 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -20,5 +20,6 @@
"allowUnreachableCode": false,
"experimentalDecorators": true
},
- "include": ["*.ts", "*.js"]
+ "include": ["*.ts", "*.js"],
+ "exclude": ["tests.ts"]
}