diff options
author | Ryan Dahl <ry@tinyclouds.org> | 2018-08-09 14:48:17 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-09 14:48:17 -0700 |
commit | 9d90c4ae955d789d2895b8efc153aa55be6ec376 (patch) | |
tree | d4483fa3a0ddf27ede0131d32f0e9be282982063 /js/testing/testing.ts | |
parent | 413bcf20425992762a9a5a6e19caddc5ff160303 (diff) |
Adds js/unit_tests.ts (#448)
Diffstat (limited to 'js/testing/testing.ts')
-rw-r--r-- | js/testing/testing.ts | 96 |
1 files changed, 96 insertions, 0 deletions
diff --git a/js/testing/testing.ts b/js/testing/testing.ts new file mode 100644 index 000000000..828ebec2f --- /dev/null +++ b/js/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.ts"; + +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); |