diff --git a/.ci/check_source_file_changes.ts b/.ci/check_source_file_changes.ts new file mode 100644 index 000000000000..e96a16b626b4 --- /dev/null +++ b/.ci/check_source_file_changes.ts @@ -0,0 +1,32 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { xrun } from "../prettier/util.ts"; +import { red, green } from "../colors/mod.ts"; + +/** + * Checks whether any source file is changed since the given start time. + * If some files are changed, this function exits with 1. + */ +async function main(startTime: number): Promise { + console.log("test checkSourceFileChanges ..."); + const changed = new TextDecoder() + .decode(await xrun({ args: ["git", "ls-files"], stdout: "piped" }).output()) + .trim() + .split("\n") + .filter(file => { + const stat = Deno.lstatSync(file); + if (stat != null) { + return (stat as any).modified * 1000 > startTime; + } + }); + if (changed.length > 0) { + console.log(red("FAILED")); + console.log( + `Error: Some source files are modified during test: ${changed.join(", ")}` + ); + Deno.exit(1); + } else { + console.log(green("ok")); + } +} + +main(parseInt(Deno.args[1])); diff --git a/.ci/template.common.yml b/.ci/template.common.yml index 37813cd4e7c0..19ac964a0ec7 100644 --- a/.ci/template.common.yml +++ b/.ci/template.common.yml @@ -3,4 +3,6 @@ parameters: steps: - bash: deno${{ parameters.exe_suffix }} run --allow-run --allow-write --allow-read --allow-env ./format.ts --check - - bash: deno${{ parameters.exe_suffix }} run --allow-run --allow-net --allow-write --allow-read --allow-env --config=tsconfig.test.json ./test.ts \ No newline at end of file + - bash: export START_TIME=$(date +%s) + - bash: deno${{ parameters.exe_suffix }} run --allow-run --allow-net --allow-write --allow-read --allow-env --config=tsconfig.test.json ./testing/runner.ts --exclude node_modules + - bash: deno${{ parameters.exe_suffix }} run --allow-run --allow-read .ci/check_source_file_changes.ts $START_TIME \ No newline at end of file diff --git a/encoding/test.ts b/encoding/test.ts deleted file mode 100644 index c7a1c9716007..000000000000 --- a/encoding/test.ts +++ /dev/null @@ -1,4 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./hex_test.ts"; -import "./toml_test.ts"; -import "./csv_test.ts"; diff --git a/flags/test.ts b/flags/test.ts deleted file mode 100644 index f8e928555bd8..000000000000 --- a/flags/test.ts +++ /dev/null @@ -1,14 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./all_bool_test.ts"; -import "./bool_test.ts"; -import "./dash_test.ts"; -import "./default_bool_test.ts"; -import "./dotted_test.ts"; -import "./kv_short_test.ts"; -import "./long_test.ts"; -import "./num_test.ts"; -import "./parse_test.ts"; -import "./short_test.ts"; -import "./stop_early_test.ts"; -import "./unknown_test.ts"; -import "./whitespace_test.ts"; diff --git a/fs/test.ts b/fs/test.ts deleted file mode 100644 index 43d6550b89b1..000000000000 --- a/fs/test.ts +++ /dev/null @@ -1,19 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./path/test.ts"; -import "./walk_test.ts"; -import "./globrex_test.ts"; -import "./glob_test.ts"; -import "./exists_test.ts"; -import "./eol_test.ts"; -import "./empty_dir_test.ts"; -import "./ensure_dir_test.ts"; -import "./ensure_file_test.ts"; -import "./ensure_symlink_test.ts"; -import "./ensure_link_test.ts"; -import "./move_test.ts"; -import "./copy_test.ts"; -import "./read_json_test.ts"; -import "./write_json_test.ts"; -import "./read_file_str_test.ts"; -import "./write_file_str_test.ts"; -import "./utils_test.ts"; diff --git a/http/test.ts b/http/test.ts deleted file mode 100644 index 7226ad40fea4..000000000000 --- a/http/test.ts +++ /dev/null @@ -1,5 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./cookie_test.ts"; -import "./server_test.ts"; -import "./file_server_test.ts"; -import "./racing_server_test.ts"; diff --git a/io/test.ts b/io/test.ts deleted file mode 100644 index a5c942aef9ea..000000000000 --- a/io/test.ts +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./bufio_test.ts"; -import "./ioutil_test.ts"; -import "./util_test.ts"; -import "./writers_test.ts"; -import "./readers_test.ts"; diff --git a/log/test.ts b/log/test.ts index 9be1ec2a1f59..5a17f9a358b8 100644 --- a/log/test.ts +++ b/log/test.ts @@ -4,9 +4,6 @@ import { assertEquals } from "../testing/asserts.ts"; import * as log from "./mod.ts"; import { LogLevel } from "./levels.ts"; -import "./handlers_test.ts"; -import "./logger_test.ts"; - class TestHandler extends log.handlers.BaseHandler { public messages: string[] = []; diff --git a/mime/test.ts b/mime/test.ts deleted file mode 100644 index e8bbfada9604..000000000000 --- a/mime/test.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./multipart_test.ts"; diff --git a/multipart/test.ts b/multipart/test.ts deleted file mode 100644 index 9adde5158e09..000000000000 --- a/multipart/test.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./formfile_test.ts"; diff --git a/prettier/test.ts b/prettier/test.ts deleted file mode 100644 index d2d1eabd75df..000000000000 --- a/prettier/test.ts +++ /dev/null @@ -1 +0,0 @@ -import "./main_test.ts"; diff --git a/strings/test.ts b/strings/test.ts deleted file mode 100644 index d0d96aa08345..000000000000 --- a/strings/test.ts +++ /dev/null @@ -1,2 +0,0 @@ -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./pad_test.ts"; diff --git a/test.ts b/test.ts deleted file mode 100755 index 8e292191e4ef..000000000000 --- a/test.ts +++ /dev/null @@ -1,65 +0,0 @@ -#!/usr/bin/env -S deno run -A -// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./archive/tar_test.ts"; -import "./bytes/test.ts"; -import "./bundle/test.ts"; -import "./colors/test.ts"; -import "./datetime/test.ts"; -import "./encoding/test.ts"; -import "./examples/test.ts"; -import "./flags/test.ts"; -import "./fs/test.ts"; -import "./http/test.ts"; -import "./io/test.ts"; -import "./installer/test.ts"; -import "./log/test.ts"; -import "./media_types/test.ts"; -import "./mime/test.ts"; -import "./multipart/test.ts"; -import "./prettier/test.ts"; -import "./strings/test.ts"; -import "./testing/test.ts"; -import "./textproto/test.ts"; -import "./util/test.ts"; -import "./uuid/test.ts"; -import "./ws/test.ts"; -import "./encoding/test.ts"; - -import { xrun } from "./prettier/util.ts"; -import { red, green } from "./colors/mod.ts"; -import { runTests } from "./testing/mod.ts"; - -async function run(): Promise { - const startTime = Date.now(); - await runTests(); - await checkSourceFileChanges(startTime); -} - -/** - * Checks whether any source file is changed since the given start time. - * If some files are changed, this function exits with 1. - */ -async function checkSourceFileChanges(startTime: number): Promise { - console.log("test checkSourceFileChanges ..."); - const changed = new TextDecoder() - .decode(await xrun({ args: ["git", "ls-files"], stdout: "piped" }).output()) - .trim() - .split("\n") - .filter(file => { - const stat = Deno.lstatSync(file); - if (stat != null) { - return (stat as any).modified * 1000 > startTime; - } - }); - if (changed.length > 0) { - console.log(red("FAILED")); - console.log( - `Error: Some source files are modified during test: ${changed.join(", ")}` - ); - Deno.exit(1); - } else { - console.log(green("ok")); - } -} - -run(); diff --git a/testing/mod.ts b/testing/mod.ts index fa6fda246dc3..d1ddb9c8ce7b 100644 --- a/testing/mod.ts +++ b/testing/mod.ts @@ -315,6 +315,8 @@ export interface RunOptions { * Runs specified test cases. * Parallel execution can be enabled via the boolean option; default: serial. */ +// TODO: change return type to `Promise` - ie. don't +// exit but return value export async function runTests({ parallel = false, exitOnFail = false, diff --git a/testing/runner.ts b/testing/runner.ts new file mode 100755 index 000000000000..eda28e02eb4d --- /dev/null +++ b/testing/runner.ts @@ -0,0 +1,127 @@ +#!/usr/bin/env deno -A +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { parse } from "../flags/mod.ts"; +import { glob, isGlob, walk } from "../fs/mod.ts"; +import { runTests } from "./mod.ts"; +const { args, cwd } = Deno; + +const DEFAULT_GLOBS = [ + "**/*_test.ts", + "**/*_test.js", + "**/test.ts", + "**/test.js" +]; + +/* eslint-disable max-len */ +function showHelp(): void { + console.log(`Deno test runner + +USAGE: + deno -A https://deno.land/std/testing/runner.ts [OPTIONS] [FILES...] + +OPTIONS: + -q, --quiet Don't show output from test cases + -f, --failfast Stop test suite on first error + -e, --exclude List of file names to exclude from run. If this options is + used files to match must be specified after "--". + +ARGS: + [FILES...] List of file names to run. Defaults to: ${DEFAULT_GLOBS.join( + "," + )} +`); +} +/* eslint-enable max-len */ + +function filePathToRegExp(str: string): RegExp { + if (isGlob(str)) { + return glob(str); + } + + return RegExp(str); +} + +/** + * This function runs matching test files in `root` directory. + * + * File matching and excluding supports glob syntax, ie. if encountered arg is + * a glob it will be expanded using `glob` method from `fs` module. + * + * Note that your shell may expand globs for you: + * $ deno -A ./runner.ts **\/*_test.ts **\/test.ts + * + * Expanding using `fs.glob`: + * $ deno -A ./runner.ts \*\*\/\*_test.ts \*\*\/test.ts + * + * `**\/*_test.ts` and `**\/test.ts"` are arguments that will be parsed and + * expanded as: [glob("**\/*_test.ts"), glob("**\/test.ts")] + */ +// TODO: change return type to `Promise` once, `runTests` is updated +// to return boolean instead of exiting +export async function main(root: string = cwd()): Promise { + const parsedArgs = parse(args.slice(1), { + boolean: ["quiet", "failfast", "help"], + string: ["exclude"], + alias: { + help: ["h"], + quiet: ["q"], + failfast: ["f"], + exclude: ["e"] + } + }); + + if (parsedArgs.help) { + return showHelp(); + } + + let includeFiles: string[]; + let excludeFiles: string[]; + + if (parsedArgs._.length) { + includeFiles = (parsedArgs._ as string[]) + .map( + (fileGlob: string): string[] => { + return fileGlob.split(","); + } + ) + .flat(); + } else { + includeFiles = DEFAULT_GLOBS; + } + + if (parsedArgs.exclude) { + excludeFiles = (parsedArgs.exclude as string).split(","); + } else { + excludeFiles = []; + } + + const filesIterator = walk(root, { + match: includeFiles.map((f: string): RegExp => filePathToRegExp(f)), + skip: excludeFiles.map((f: string): RegExp => filePathToRegExp(f)) + }); + + const foundTestFiles: string[] = []; + for await (const { filename } of filesIterator) { + foundTestFiles.push(filename); + } + + if (foundTestFiles.length === 0) { + console.error("No matching test files found."); + return; + } + + console.log(`Found ${foundTestFiles.length} matching test files.`); + + for (const filename of foundTestFiles) { + await import(filename); + } + + await runTests({ + exitOnFail: !!parsedArgs.failfast, + disableLog: !!parsedArgs.quiet + }); +} + +if (import.meta.main) { + main(); +} diff --git a/testing/test.ts b/testing/test.ts index 3a35be1e9893..93233f7cc9fb 100644 --- a/testing/test.ts +++ b/testing/test.ts @@ -7,10 +7,6 @@ import { assertThrows, assertThrowsAsync } from "./asserts.ts"; -import "./format_test.ts"; -import "./diff_test.ts"; -import "./asserts_test.ts"; -import "./bench_test.ts"; test(function testingAssertEqualActualUncoercable(): void { let didThrow = false; diff --git a/textproto/test.ts b/textproto/test.ts index 71caddef9a01..bdb9293699a0 100644 --- a/textproto/test.ts +++ b/textproto/test.ts @@ -6,7 +6,6 @@ import { append } from "./mod.ts"; import { assertEquals } from "../testing/asserts.ts"; import { test } from "../testing/mod.ts"; -import "./reader_test.ts"; test(async function textprotoAppend(): Promise { const enc = new TextEncoder(); diff --git a/util/test.ts b/util/test.ts deleted file mode 100644 index ede984904f0d..000000000000 --- a/util/test.ts +++ /dev/null @@ -1,2 +0,0 @@ -import "./async_test.ts"; -import "./deep_assign_test.ts"; diff --git a/ws/test.ts b/ws/test.ts index e14af1d559bd..b8eb42803ec9 100644 --- a/ws/test.ts +++ b/ws/test.ts @@ -1,5 +1,4 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. -import "./sha1_test.ts"; import { BufReader } from "../io/bufio.ts"; import { assert, assertEquals } from "../testing/asserts.ts"; import { runIfMain, test } from "../testing/mod.ts";