From f81e666dd0aeaba38200b798a5026dedbf4c074e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 20 Jun 2019 22:13:37 +0200 Subject: [PATCH 01/19] prototype test runner --- testing/runner.ts | 74 ++++++++++++++++++++++++++++++++++++++++ testing/runner_util.ts | 77 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 151 insertions(+) create mode 100755 testing/runner.ts create mode 100644 testing/runner_util.ts diff --git a/testing/runner.ts b/testing/runner.ts new file mode 100755 index 000000000000..54541c1cc85f --- /dev/null +++ b/testing/runner.ts @@ -0,0 +1,74 @@ +#!/usr/bin/env deno -A +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { glob, walk } from "../fs/mod.ts"; +import * as path from "../fs/path/mod.ts"; +import { chunks } from "./runner_util.ts"; +const { run, exit, writeFile, execPath, remove } = Deno; + +const testingModPath = path.join( + path.dirname(window.location.pathname), + "./mod.ts" +); +const runTemplate = ` +import { runTests } from "${testingModPath}"; + +async function run(): Promise { + console.log("running tests"); + await runTests(); +} + +run(); +`; + +const { cwd } = Deno; +const DEFAULT_GLOB = "**/*_test.ts"; + +async function main(): Promise { + // TODO: find all files matching _test.js/.ts pattern + // find all files matching `pattern` glob + const iterator = walk(cwd(), { + match: [glob(DEFAULT_GLOB)] + }); + + console.log("iterator", walk); + const foundTestFiles = []; + + for await (const { filename, info } of iterator) { + // console.log("found path: ", filename); + foundTestFiles.push(filename); + } + + console.log("found " + foundTestFiles.length + " matching files"); + + let testFile = ""; + + foundTestFiles.forEach( + (filename: string): void => { + testFile += `import "${filename}";\n`; + } + ); + testFile += runTemplate; + + const testFileName = `test-${new Date().getTime()}.ts`; + const encoder = new TextEncoder(); + await writeFile(testFileName, encoder.encode(testFile)); + const p = run({ + args: [execPath, "-A", testFileName], + stdout: "piped" + }); + + for await (const line of chunks(p.stdout, "\n")) { + console.log("DEBUG: ", line); + } + + try { + await p.status(); + } catch (e) { + console.error(e); + exit(1); + } finally { + await remove(testFileName); + } +} + +main(); diff --git a/testing/runner_util.ts b/testing/runner_util.ts new file mode 100644 index 000000000000..3e081eebd379 --- /dev/null +++ b/testing/runner_util.ts @@ -0,0 +1,77 @@ +async function writeAll(buffer: Deno.Buffer, arr: Uint8Array): Promise { + let bytesWritten = 0; + while (bytesWritten < arr.length) { + try { + const nwritten = await buffer.write(arr.subarray(bytesWritten)); + bytesWritten += nwritten; + } catch { + return; + } + } +} + +// TODO(bartlomieju): Copied from //deno/js/xeval.ts +// this module one supposed to be moved to std lib anyway +// Read from reader until EOF and emit string chunks separated +// by the given delimiter. +export async function* chunks( + reader: Deno.Reader, + delim: string +): AsyncIterableIterator { + const inputBuffer = new Deno.Buffer(); + const inspectArr = new Uint8Array(1024); + const encoder = new TextEncoder(); + const decoder = new TextDecoder(); + // Avoid unicode problems + const delimArr = encoder.encode(delim); + + // Record how far we have gone with delimiter matching. + let nextMatchIndex = 0; + while (true) { + const rr = await reader.read(inspectArr); + if (rr.nread < 0) { + // Silently fail. + break; + } + const sliceRead = inspectArr.subarray(0, rr.nread); + // Remember how far we have scanned through inspectArr. + let nextSliceStartIndex = 0; + for (let i = 0; i < sliceRead.length; i++) { + if (sliceRead[i] == delimArr[nextMatchIndex]) { + // One byte matches with delimiter, move 1 step forward. + nextMatchIndex++; + } else { + // Match delimiter failed. Start from beginning. + nextMatchIndex = 0; + } + // A complete match is found. + if (nextMatchIndex === delimArr.length) { + nextMatchIndex = 0; // Reset delim match index. + const sliceToJoin = sliceRead.subarray(nextSliceStartIndex, i + 1); + // Record where to start next chunk when a subsequent match is found. + nextSliceStartIndex = i + 1; + // Write slice to buffer before processing, since potentially + // part of the delimiter is stored in the buffer. + await writeAll(inputBuffer, sliceToJoin); + + let readyBytes = inputBuffer.bytes(); + inputBuffer.reset(); + // Remove delimiter from buffer bytes. + readyBytes = readyBytes.subarray( + 0, + readyBytes.length - delimArr.length + ); + let readyChunk = decoder.decode(readyBytes); + yield readyChunk; + } + } + // Write all unprocessed chunk to buffer for future inspection. + await writeAll(inputBuffer, sliceRead.subarray(nextSliceStartIndex)); + if (rr.eof) { + // Flush the remainder unprocessed chunk. + const lastChunk = inputBuffer.toString(); + yield lastChunk; + break; + } + } +} From 79c6777ef31a8b57f57384f1c0f606df28f1666f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Thu, 20 Jun 2019 22:21:47 +0200 Subject: [PATCH 02/19] more prototyping --- testing/runner.ts | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/testing/runner.ts b/testing/runner.ts index 54541c1cc85f..79df863291e5 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -1,29 +1,50 @@ #!/usr/bin/env deno -A // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. +import { parse } from "../flags/mod.ts"; import { glob, walk } from "../fs/mod.ts"; import * as path from "../fs/path/mod.ts"; import { chunks } from "./runner_util.ts"; -const { run, exit, writeFile, execPath, remove } = Deno; +import {RunOptions} from "./mod.ts"; +const { run, exit, writeFile, execPath, remove, args } = Deno; const testingModPath = path.join( path.dirname(window.location.pathname), "./mod.ts" ); -const runTemplate = ` -import { runTests } from "${testingModPath}"; -async function run(): Promise { - console.log("running tests"); - await runTests(); +function createTestRuntime(options: RunOptions): string { + return `import { runTests } from "${testingModPath}"; + + async function run(): Promise { + console.log("running tests"); + await runTests({ + parallel: ${options.parallel}, + exitOnFail: ${options.exitOnFail}, + disableLog: ${options.disableLog}, + }); + } + + run(); + `; } -run(); -`; const { cwd } = Deno; const DEFAULT_GLOB = "**/*_test.ts"; async function main(): Promise { + const parsedArgs = parse(args.slice(1)); + + console.log(parsedArgs); + + const testRuntime = createTestRuntime({ + parallel: parsedArgs.parallel || parsedArgs.p, + exitOnFail: parsedArgs.failfast || parsedArgs.f, + only: parsedArgs.only || parsedArgs.o, + skip: parsedArgs.skip || parsedArgs.s, + disableLog: parsedArgs.quiet || parsedArgs.q, + }); + // TODO: find all files matching _test.js/.ts pattern // find all files matching `pattern` glob const iterator = walk(cwd(), { @@ -47,7 +68,7 @@ async function main(): Promise { testFile += `import "${filename}";\n`; } ); - testFile += runTemplate; + testFile += testRuntime; const testFileName = `test-${new Date().getTime()}.ts`; const encoder = new TextEncoder(); From 9d407151bc5d42aec940ab4a01c6000bcca9498d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Fri, 9 Aug 2019 16:05:31 +0200 Subject: [PATCH 03/19] cleanup --- testing/runner.ts | 69 ++++++----------------------------------------- 1 file changed, 8 insertions(+), 61 deletions(-) diff --git a/testing/runner.ts b/testing/runner.ts index 79df863291e5..10195337ef12 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -2,31 +2,8 @@ // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { parse } from "../flags/mod.ts"; import { glob, walk } from "../fs/mod.ts"; -import * as path from "../fs/path/mod.ts"; -import { chunks } from "./runner_util.ts"; -import {RunOptions} from "./mod.ts"; -const { run, exit, writeFile, execPath, remove, args } = Deno; - -const testingModPath = path.join( - path.dirname(window.location.pathname), - "./mod.ts" -); - -function createTestRuntime(options: RunOptions): string { - return `import { runTests } from "${testingModPath}"; - - async function run(): Promise { - console.log("running tests"); - await runTests({ - parallel: ${options.parallel}, - exitOnFail: ${options.exitOnFail}, - disableLog: ${options.disableLog}, - }); - } - - run(); - `; -} +import { runTests } from "./mod.ts"; +const { args } = Deno; const { cwd } = Deno; @@ -37,21 +14,12 @@ async function main(): Promise { console.log(parsedArgs); - const testRuntime = createTestRuntime({ - parallel: parsedArgs.parallel || parsedArgs.p, - exitOnFail: parsedArgs.failfast || parsedArgs.f, - only: parsedArgs.only || parsedArgs.o, - skip: parsedArgs.skip || parsedArgs.s, - disableLog: parsedArgs.quiet || parsedArgs.q, - }); - // TODO: find all files matching _test.js/.ts pattern // find all files matching `pattern` glob const iterator = walk(cwd(), { match: [glob(DEFAULT_GLOB)] }); - console.log("iterator", walk); const foundTestFiles = []; for await (const { filename, info } of iterator) { @@ -61,35 +29,14 @@ async function main(): Promise { console.log("found " + foundTestFiles.length + " matching files"); - let testFile = ""; - - foundTestFiles.forEach( - (filename: string): void => { - testFile += `import "${filename}";\n`; - } - ); - testFile += testRuntime; - - const testFileName = `test-${new Date().getTime()}.ts`; - const encoder = new TextEncoder(); - await writeFile(testFileName, encoder.encode(testFile)); - const p = run({ - args: [execPath, "-A", testFileName], - stdout: "piped" - }); - - for await (const line of chunks(p.stdout, "\n")) { - console.log("DEBUG: ", line); + for (const filename of foundTestFiles) { + await import(filename); } - try { - await p.status(); - } catch (e) { - console.error(e); - exit(1); - } finally { - await remove(testFileName); - } + await runTests({ + exitOnFail: !!parsedArgs.exitOnFail, + disableLog: !!parsedArgs.silent, + }); } main(); From f4c8fc3e26a0cf2b9cf0a4473032eeac85fa3f2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Mon, 12 Aug 2019 18:46:38 +0200 Subject: [PATCH 04/19] add help, glob flag --- testing/runner.ts | 60 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 44 insertions(+), 16 deletions(-) diff --git a/testing/runner.ts b/testing/runner.ts index 10195337ef12..fb6345249899 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -3,39 +3,67 @@ import { parse } from "../flags/mod.ts"; import { glob, walk } from "../fs/mod.ts"; import { runTests } from "./mod.ts"; -const { args } = Deno; +const { args, cwd } = Deno; +// TODO: settle on list of default globs +const DEFAULT_GLOBS = ["**/*_test.ts", "**/*_test.js"]; -const { cwd } = Deno; -const DEFAULT_GLOB = "**/*_test.ts"; +// TODO: upgrade it +function showHelp() { + console.log(`deno test-runner + Test runner -async function main(): Promise { - const parsedArgs = parse(args.slice(1)); +USAGE: + deno -A https://deno.land/std/testing/runner.ts [OPTIONS] - console.log(parsedArgs); +OPTIONS: + -q, --quiet Don't show output from test cases + -f, --failfast Stop test suite on first error + -g, --glob List of globs for test files, defaults to: **/*_test.ts,**/*_test.js +`); +} - // TODO: find all files matching _test.js/.ts pattern - // find all files matching `pattern` glob - const iterator = walk(cwd(), { - match: [glob(DEFAULT_GLOB)] +async function main(): Promise { + const parsedArgs = parse(args.slice(1), { + boolean: ["quiet", "failfast", "help"], + string: ["glob"], + alias: { + help: ["h"], + quiet: ["q"], + failfast: ["f"], + glob: ["g"] + } }); - const foundTestFiles = []; + if (parsedArgs.help) { + return showHelp(); + } + + let fileGlobs; + if (parsedArgs.glob) { + fileGlobs = (parsedArgs.glob as string).split(","); + } else { + fileGlobs = DEFAULT_GLOBS; + } + + const filesIterator = walk(cwd(), { + match: fileGlobs.map(glob) + }); - for await (const { filename, info } of iterator) { - // console.log("found path: ", filename); + const foundTestFiles: Array = []; + for await (const { filename } of filesIterator) { foundTestFiles.push(filename); } - console.log("found " + foundTestFiles.length + " matching files"); + console.log(`Found ${foundTestFiles.length} matching files.`); for (const filename of foundTestFiles) { await import(filename); } await runTests({ - exitOnFail: !!parsedArgs.exitOnFail, - disableLog: !!parsedArgs.silent, + exitOnFail: !!parsedArgs.failfast, + disableLog: !!parsedArgs.quiet }); } From eb5efa6a4244f6c619f8eed435f2605ee005c8a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 02:19:34 +0200 Subject: [PATCH 05/19] reset CI From 751440b00ed190835e35626190daa69627e2c2e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 02:25:27 +0200 Subject: [PATCH 06/19] lint --- testing/runner.ts | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/testing/runner.ts b/testing/runner.ts index fb6345249899..ad4d16a04041 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -9,7 +9,8 @@ const { args, cwd } = Deno; const DEFAULT_GLOBS = ["**/*_test.ts", "**/*_test.js"]; // TODO: upgrade it -function showHelp() { +/* eslint-disable max-len */ +function showHelp(): void { console.log(`deno test-runner Test runner @@ -22,6 +23,7 @@ OPTIONS: -g, --glob List of globs for test files, defaults to: **/*_test.ts,**/*_test.js `); } +/* eslint-enable max-len */ async function main(): Promise { const parsedArgs = parse(args.slice(1), { @@ -50,7 +52,7 @@ async function main(): Promise { match: fileGlobs.map(glob) }); - const foundTestFiles: Array = []; + const foundTestFiles: string[] = []; for await (const { filename } of filesIterator) { foundTestFiles.push(filename); } From c4a5727a7a79ad3329a026e016eecc33684b7216 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 18:50:39 +0200 Subject: [PATCH 07/19] upgrade --- .ci/template.common.yml | 2 +- testing/runner.ts | 64 +++++++++++++++++++++++++--------- testing/runner_util.ts | 77 ----------------------------------------- 3 files changed, 48 insertions(+), 95 deletions(-) delete mode 100644 testing/runner_util.ts diff --git a/.ci/template.common.yml b/.ci/template.common.yml index 37813cd4e7c0..8bb77f3ede0f 100644 --- a/.ci/template.common.yml +++ b/.ci/template.common.yml @@ -3,4 +3,4 @@ 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: deno${{ parameters.exe_suffix }} run --allow-run --allow-net --allow-write --allow-read --allow-env --config=tsconfig.test.json ./testing/runner.ts \!node_modules/,**/*_test.ts \ No newline at end of file diff --git a/testing/runner.ts b/testing/runner.ts index ad4d16a04041..5b48fc8e0e84 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -5,22 +5,28 @@ import { glob, walk } from "../fs/mod.ts"; import { runTests } from "./mod.ts"; const { args, cwd } = Deno; -// TODO: settle on list of default globs -const DEFAULT_GLOBS = ["**/*_test.ts", "**/*_test.js"]; +const DEFAULT_GLOBS = [ + "**/*_test.ts", + "**/*_test.js", + "**/test.ts", + "**/test.js" +]; -// TODO: upgrade it /* eslint-disable max-len */ function showHelp(): void { - console.log(`deno test-runner - Test runner + console.log(`Deno test runner USAGE: - deno -A https://deno.land/std/testing/runner.ts [OPTIONS] + 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 - -g, --glob List of globs for test files, defaults to: **/*_test.ts,**/*_test.js + -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 */ @@ -28,12 +34,12 @@ OPTIONS: async function main(): Promise { const parsedArgs = parse(args.slice(1), { boolean: ["quiet", "failfast", "help"], - string: ["glob"], + string: ["exclude"], alias: { help: ["h"], quiet: ["q"], failfast: ["f"], - glob: ["g"] + exclude: ["e"] } }); @@ -41,15 +47,33 @@ async function main(): Promise { return showHelp(); } - let fileGlobs; - if (parsedArgs.glob) { - fileGlobs = (parsedArgs.glob as string).split(","); + let includeFiles; + let excludeFiles; + + 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 { - fileGlobs = DEFAULT_GLOBS; + excludeFiles = []; } + console.log("includeFiles", includeFiles); + console.log("excludeFiles", excludeFiles); + const filesIterator = walk(cwd(), { - match: fileGlobs.map(glob) + match: includeFiles.map(glob), + skip: excludeFiles.map(glob) }); const foundTestFiles: string[] = []; @@ -57,7 +81,13 @@ async function main(): Promise { foundTestFiles.push(filename); } - console.log(`Found ${foundTestFiles.length} matching files.`); + if (foundTestFiles.length === 0) { + console.error("No matching test files found."); + Deno.exit(0); + } + + console.log(`Found ${foundTestFiles.length} matching test files.`); + foundTestFiles.map(e => console.log(e)); for (const filename of foundTestFiles) { await import(filename); diff --git a/testing/runner_util.ts b/testing/runner_util.ts deleted file mode 100644 index 3e081eebd379..000000000000 --- a/testing/runner_util.ts +++ /dev/null @@ -1,77 +0,0 @@ -async function writeAll(buffer: Deno.Buffer, arr: Uint8Array): Promise { - let bytesWritten = 0; - while (bytesWritten < arr.length) { - try { - const nwritten = await buffer.write(arr.subarray(bytesWritten)); - bytesWritten += nwritten; - } catch { - return; - } - } -} - -// TODO(bartlomieju): Copied from //deno/js/xeval.ts -// this module one supposed to be moved to std lib anyway -// Read from reader until EOF and emit string chunks separated -// by the given delimiter. -export async function* chunks( - reader: Deno.Reader, - delim: string -): AsyncIterableIterator { - const inputBuffer = new Deno.Buffer(); - const inspectArr = new Uint8Array(1024); - const encoder = new TextEncoder(); - const decoder = new TextDecoder(); - // Avoid unicode problems - const delimArr = encoder.encode(delim); - - // Record how far we have gone with delimiter matching. - let nextMatchIndex = 0; - while (true) { - const rr = await reader.read(inspectArr); - if (rr.nread < 0) { - // Silently fail. - break; - } - const sliceRead = inspectArr.subarray(0, rr.nread); - // Remember how far we have scanned through inspectArr. - let nextSliceStartIndex = 0; - for (let i = 0; i < sliceRead.length; i++) { - if (sliceRead[i] == delimArr[nextMatchIndex]) { - // One byte matches with delimiter, move 1 step forward. - nextMatchIndex++; - } else { - // Match delimiter failed. Start from beginning. - nextMatchIndex = 0; - } - // A complete match is found. - if (nextMatchIndex === delimArr.length) { - nextMatchIndex = 0; // Reset delim match index. - const sliceToJoin = sliceRead.subarray(nextSliceStartIndex, i + 1); - // Record where to start next chunk when a subsequent match is found. - nextSliceStartIndex = i + 1; - // Write slice to buffer before processing, since potentially - // part of the delimiter is stored in the buffer. - await writeAll(inputBuffer, sliceToJoin); - - let readyBytes = inputBuffer.bytes(); - inputBuffer.reset(); - // Remove delimiter from buffer bytes. - readyBytes = readyBytes.subarray( - 0, - readyBytes.length - delimArr.length - ); - let readyChunk = decoder.decode(readyBytes); - yield readyChunk; - } - } - // Write all unprocessed chunk to buffer for future inspection. - await writeAll(inputBuffer, sliceRead.subarray(nextSliceStartIndex)); - if (rr.eof) { - // Flush the remainder unprocessed chunk. - const lastChunk = inputBuffer.toString(); - yield lastChunk; - break; - } - } -} From 059f0830cc82bab09fa420ff1b394e863cf2f898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 18:54:39 +0200 Subject: [PATCH 08/19] lint --- testing/runner.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/testing/runner.ts b/testing/runner.ts index 5b48fc8e0e84..05c06afda4e2 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -68,9 +68,6 @@ async function main(): Promise { excludeFiles = []; } - console.log("includeFiles", includeFiles); - console.log("excludeFiles", excludeFiles); - const filesIterator = walk(cwd(), { match: includeFiles.map(glob), skip: excludeFiles.map(glob) @@ -87,7 +84,6 @@ async function main(): Promise { } console.log(`Found ${foundTestFiles.length} matching test files.`); - foundTestFiles.map(e => console.log(e)); for (const filename of foundTestFiles) { await import(filename); From 9fcc32107101f951dc18be33124cdc0eb327592d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 19:03:07 +0200 Subject: [PATCH 09/19] remove unneeded test files --- .ci/template.common.yml | 2 +- encoding/test.ts | 4 --- flags/test.ts | 14 --------- fs/test.ts | 19 ------------ http/test.ts | 5 ---- io/test.ts | 6 ---- log/test.ts | 3 -- mime/test.ts | 2 -- multipart/test.ts | 2 -- prettier/test.ts | 1 - strings/test.ts | 2 -- test.ts | 65 ----------------------------------------- testing/runner.ts | 4 ++- testing/test.ts | 5 ---- textproto/test.ts | 1 - util/test.ts | 2 -- ws/test.ts | 1 - 17 files changed, 4 insertions(+), 134 deletions(-) delete mode 100644 encoding/test.ts delete mode 100644 flags/test.ts delete mode 100644 fs/test.ts delete mode 100644 http/test.ts delete mode 100644 io/test.ts delete mode 100644 mime/test.ts delete mode 100644 multipart/test.ts delete mode 100644 prettier/test.ts delete mode 100644 strings/test.ts delete mode 100755 test.ts delete mode 100644 util/test.ts diff --git a/.ci/template.common.yml b/.ci/template.common.yml index 8bb77f3ede0f..abd181006717 100644 --- a/.ci/template.common.yml +++ b/.ci/template.common.yml @@ -3,4 +3,4 @@ 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 ./testing/runner.ts \!node_modules/,**/*_test.ts \ No newline at end of file + - 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/\* -- **/*_test.ts **/test.ts \ 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/runner.ts b/testing/runner.ts index 05c06afda4e2..4ba413b10919 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -26,7 +26,9 @@ OPTIONS: used files to match must be specified after "--". ARGS: - [FILES...] List of file names to run. Defaults to: ${DEFAULT_GLOBS.join(",")} + [FILES...] List of file names to run. Defaults to: ${DEFAULT_GLOBS.join( + "," + )} `); } /* eslint-enable max-len */ diff --git a/testing/test.ts b/testing/test.ts index c726ffb1abe8..65bf4ee57903 100644 --- a/testing/test.ts +++ b/testing/test.ts @@ -7,11 +7,6 @@ import { assertThrows, assertThrowsAsync } from "./asserts.ts"; -import "./format_test.ts"; -import "./diff_test.ts"; -import "./pretty_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"; From 881af2c5ea23a4bbada3e8f753de46fddf8ff38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 19:16:22 +0200 Subject: [PATCH 10/19] add script to check for file changes --- .ci/check_source_file_changes.ts | 31 +++++++++++++++++++++++++++++++ .ci/template.common.yml | 4 +++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 .ci/check_source_file_changes.ts diff --git a/.ci/check_source_file_changes.ts b/.ci/check_source_file_changes.ts new file mode 100644 index 000000000000..1e062717a8ab --- /dev/null +++ b/.ci/check_source_file_changes.ts @@ -0,0 +1,31 @@ +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 abd181006717..41767f8ff2b7 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 ./testing/runner.ts --exclude node_modules/\* -- **/*_test.ts **/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/\* -- **/*_test.ts **/test.ts + - bash: deno${{ parameters.exe_suffix }} run --allow-run .ci/check_source_file_changes.ts $START_TIME \ No newline at end of file From 3d741d4bcec782a7dfb94189c253dd063b9bc744 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 19:19:01 +0200 Subject: [PATCH 11/19] reset CI From a8920633e43e1182642c58007d9df52b55451a96 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 19:24:24 +0200 Subject: [PATCH 12/19] fix permission for check script --- .ci/check_source_file_changes.ts | 1 + .ci/template.common.yml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.ci/check_source_file_changes.ts b/.ci/check_source_file_changes.ts index 1e062717a8ab..e96a16b626b4 100644 --- a/.ci/check_source_file_changes.ts +++ b/.ci/check_source_file_changes.ts @@ -1,3 +1,4 @@ +// Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { xrun } from "../prettier/util.ts"; import { red, green } from "../colors/mod.ts"; diff --git a/.ci/template.common.yml b/.ci/template.common.yml index 41767f8ff2b7..302209170247 100644 --- a/.ci/template.common.yml +++ b/.ci/template.common.yml @@ -5,4 +5,4 @@ steps: - bash: deno${{ parameters.exe_suffix }} run --allow-run --allow-write --allow-read --allow-env ./format.ts --check - 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/\* -- **/*_test.ts **/test.ts - - bash: deno${{ parameters.exe_suffix }} run --allow-run .ci/check_source_file_changes.ts $START_TIME \ No newline at end of file + - bash: deno${{ parameters.exe_suffix }} run --allow-run --allow-read .ci/check_source_file_changes.ts $START_TIME \ No newline at end of file From b255038a249ed50452b31b35942f651b83c09014 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 20:45:35 +0200 Subject: [PATCH 13/19] reset CI From 527c2a891bbfb69442bb84f4bac7dadd2cad05f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 21:22:11 +0200 Subject: [PATCH 14/19] address feedback --- testing/runner.ts | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/testing/runner.ts b/testing/runner.ts index 4ba413b10919..5350f836f8b4 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -1,7 +1,7 @@ #!/usr/bin/env deno -A // Copyright 2018-2019 the Deno authors. All rights reserved. MIT license. import { parse } from "../flags/mod.ts"; -import { glob, walk } from "../fs/mod.ts"; +import { glob, isGlob, walk } from "../fs/mod.ts"; import { runTests } from "./mod.ts"; const { args, cwd } = Deno; @@ -33,7 +33,15 @@ ARGS: } /* eslint-enable max-len */ -async function main(): Promise { +function filePathToRegExp(str: string): RegExp { + if (isGlob(str)) { + return glob(str); + } + + return RegExp(str); +} + +async function main(root: string = cwd()): Promise { const parsedArgs = parse(args.slice(1), { boolean: ["quiet", "failfast", "help"], string: ["exclude"], @@ -49,8 +57,8 @@ async function main(): Promise { return showHelp(); } - let includeFiles; - let excludeFiles; + let includeFiles: string[]; + let excludeFiles: string[]; if (parsedArgs._.length) { includeFiles = (parsedArgs._ as string[]) @@ -70,9 +78,9 @@ async function main(): Promise { excludeFiles = []; } - const filesIterator = walk(cwd(), { - match: includeFiles.map(glob), - skip: excludeFiles.map(glob) + const filesIterator = walk(root, { + match: includeFiles.map(f => filePathToRegExp(f)), + skip: excludeFiles.map(f => filePathToRegExp(f)) }); const foundTestFiles: string[] = []; @@ -82,7 +90,7 @@ async function main(): Promise { if (foundTestFiles.length === 0) { console.error("No matching test files found."); - Deno.exit(0); + return; } console.log(`Found ${foundTestFiles.length} matching test files.`); @@ -97,4 +105,6 @@ async function main(): Promise { }); } -main(); +if (import.meta.main) { + main(); +} From 39b5d733dbbb6873513dcd608efcfb857b181e3e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 21:25:16 +0200 Subject: [PATCH 15/19] export runner main function --- testing/runner.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/runner.ts b/testing/runner.ts index 5350f836f8b4..7ce7c334bbeb 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -41,7 +41,7 @@ function filePathToRegExp(str: string): RegExp { return RegExp(str); } -async function main(root: string = cwd()): Promise { +export async function main(root: string = cwd()): Promise { const parsedArgs = parse(args.slice(1), { boolean: ["quiet", "failfast", "help"], string: ["exclude"], From b33d282702bc8677f4be741ee73df00a3f38a4f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 21:27:02 +0200 Subject: [PATCH 16/19] add TODOs regarding return types --- testing/mod.ts | 1 + testing/runner.ts | 2 ++ 2 files changed, 3 insertions(+) diff --git a/testing/mod.ts b/testing/mod.ts index 462c13fb1691..a5b4da0d2039 100644 --- a/testing/mod.ts +++ b/testing/mod.ts @@ -300,6 +300,7 @@ 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 index 7ce7c334bbeb..0b421c581c81 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -41,6 +41,8 @@ function filePathToRegExp(str: string): RegExp { return RegExp(str); } +// 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"], From ddbfc1104364ed1a3dff5dcb6d6eb808b7c75132 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 21:30:17 +0200 Subject: [PATCH 17/19] lint --- testing/mod.ts | 3 ++- testing/runner.ts | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/testing/mod.ts b/testing/mod.ts index a5b4da0d2039..58fffdab0f60 100644 --- a/testing/mod.ts +++ b/testing/mod.ts @@ -300,7 +300,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 +// 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 index 0b421c581c81..1e08b787bbb9 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -81,8 +81,8 @@ export async function main(root: string = cwd()): Promise { } const filesIterator = walk(root, { - match: includeFiles.map(f => filePathToRegExp(f)), - skip: excludeFiles.map(f => filePathToRegExp(f)) + match: includeFiles.map((f: string): RegExp => filePathToRegExp(f)), + skip: excludeFiles.map((f: string): RegExp => filePathToRegExp(f)) }); const foundTestFiles: string[] = []; From fd517bc77ac679fe45b7fc2b06c8c8ede5c6b5f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 21:43:19 +0200 Subject: [PATCH 18/19] describe glob behavior --- testing/runner.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/testing/runner.ts b/testing/runner.ts index 1e08b787bbb9..2affaf434c56 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -41,6 +41,21 @@ function filePathToRegExp(str: string): RegExp { 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,**\/test.ts" is a string argument 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 { From a3313a08f397af8ee7d447fcfaf3ee17725e4b0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Wed, 14 Aug 2019 21:48:38 +0200 Subject: [PATCH 19/19] update CI script --- .ci/template.common.yml | 2 +- testing/runner.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.ci/template.common.yml b/.ci/template.common.yml index 302209170247..19ac964a0ec7 100644 --- a/.ci/template.common.yml +++ b/.ci/template.common.yml @@ -4,5 +4,5 @@ parameters: steps: - bash: deno${{ parameters.exe_suffix }} run --allow-run --allow-write --allow-read --allow-env ./format.ts --check - 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/\* -- **/*_test.ts **/test.ts + - 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/testing/runner.ts b/testing/runner.ts index 2affaf434c56..eda28e02eb4d 100755 --- a/testing/runner.ts +++ b/testing/runner.ts @@ -44,16 +44,16 @@ function filePathToRegExp(str: string): RegExp { /** * 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. + * 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 + * $ deno -A ./runner.ts **\/*_test.ts **\/test.ts * * Expanding using `fs.glob`: - * $ deno -A ./runner.ts **\/*_test.ts,**\/test.ts + * $ deno -A ./runner.ts \*\*\/\*_test.ts \*\*\/test.ts * - * "**\/*_test.ts,**\/test.ts" is a string argument that will be parsed and + * `**\/*_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