-
Notifications
You must be signed in to change notification settings - Fork 639
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add setUp and tearDown to simplify tests. #108
Changes from all commits
48735a8
dfe51ed
8c13462
5427afe
630c98e
bcd1d2c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,51 +1,49 @@ | ||
import { readFile } from "deno"; | ||
import { readFile, run } from "deno"; | ||
|
||
import { test, assert, assertEqual } from "../testing/mod.ts"; | ||
import { test, assert, assertEqual, setUp, tearDown } from "../testing/mod.ts"; | ||
import { BufReader } from "../io/bufio.ts"; | ||
import { TextProtoReader } from "../textproto/mod.ts"; | ||
|
||
// Promise to completeResolve when all tests completes | ||
let completeResolve; | ||
export const completePromise = new Promise(res => (completeResolve = res)); | ||
let completedTestCount = 0; | ||
|
||
function maybeCompleteTests() { | ||
completedTestCount++; | ||
// Change this when adding more tests | ||
if (completedTestCount === 3) { | ||
completeResolve(); | ||
} | ||
} | ||
|
||
export function runTests(serverReadyPromise: Promise<any>) { | ||
test(async function serveFile() { | ||
await serverReadyPromise; | ||
const res = await fetch("http://localhost:4500/azure-pipelines.yml"); | ||
assert(res.headers.has("access-control-allow-origin")); | ||
assert(res.headers.has("access-control-allow-headers")); | ||
assertEqual(res.headers.get("content-type"), "text/yaml; charset=utf-8"); | ||
const downloadedFile = await res.text(); | ||
const localFile = new TextDecoder().decode( | ||
await readFile("./azure-pipelines.yml") | ||
); | ||
assertEqual(downloadedFile, localFile); | ||
maybeCompleteTests(); | ||
let fileServer; | ||
setUp(async function startFileServer() { | ||
fileServer = run({ | ||
args: ["deno", "--allow-net", "http/file_server.ts", ".", "--cors"], | ||
stdout: "piped" | ||
}); | ||
// Once fileServer is ready it will write to its stdout. | ||
const r = new TextProtoReader(new BufReader(fileServer.stdout)); | ||
const [s, err] = await r.readLine(); | ||
assert(err == null); | ||
assert(s.includes("server listening")); | ||
}); | ||
tearDown(function killFileServer() { | ||
fileServer.close(); | ||
fileServer.stdout.close(); | ||
}); | ||
|
||
test(async function serveDirectory() { | ||
await serverReadyPromise; | ||
const res = await fetch("http://localhost:4500/"); | ||
assert(res.headers.has("access-control-allow-origin")); | ||
assert(res.headers.has("access-control-allow-headers")); | ||
const page = await res.text(); | ||
assert(page.includes("azure-pipelines.yml")); | ||
maybeCompleteTests(); | ||
}); | ||
test(async function serveFile() { | ||
const res = await fetch("http://localhost:4500/azure-pipelines.yml"); | ||
assert(res.headers.has("access-control-allow-origin")); | ||
assert(res.headers.has("access-control-allow-headers")); | ||
assertEqual(res.headers.get("content-type"), "text/yaml; charset=utf-8"); | ||
const downloadedFile = await res.text(); | ||
const localFile = new TextDecoder().decode( | ||
await readFile("./azure-pipelines.yml") | ||
); | ||
assertEqual(downloadedFile, localFile); | ||
}); | ||
|
||
test(async function serveFallback() { | ||
await serverReadyPromise; | ||
const res = await fetch("http://localhost:4500/badfile.txt"); | ||
assert(res.headers.has("access-control-allow-origin")); | ||
assert(res.headers.has("access-control-allow-headers")); | ||
assertEqual(res.status, 404); | ||
maybeCompleteTests(); | ||
}); | ||
} | ||
test(async function serveDirectory() { | ||
const res = await fetch("http://localhost:4500/"); | ||
assert(res.headers.has("access-control-allow-origin")); | ||
assert(res.headers.has("access-control-allow-headers")); | ||
const page = await res.text(); | ||
assert(page.includes("azure-pipelines.yml")); | ||
}); | ||
|
||
test(async function serveFallback() { | ||
const res = await fetch("http://localhost:4500/badfile.txt"); | ||
assert(res.headers.has("access-control-allow-origin")); | ||
assert(res.headers.has("access-control-allow-headers")); | ||
assertEqual(res.status, 404); | ||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { args } from "deno"; | ||
import { runTests, cancelTests, setFilter } from "./mod.ts"; | ||
import { parse } from "../flags/mod.ts"; | ||
import { resolve } from "../fs/path.ts"; | ||
|
||
cancelTests(); | ||
|
||
const a = parse(args); | ||
const filter = a.grep || ".*"; | ||
// TODO support globs and recursive. | ||
const test_files = a._.slice(1).map(p => resolve(p)); | ||
|
||
setFilter(filter); | ||
|
||
(async () => { | ||
for (let fn of test_files) { | ||
await import(fn); | ||
} | ||
await runTests(); | ||
})(); |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -73,11 +73,20 @@ export const exitOnFail = true; | |
|
||
let filterRegExp: RegExp | null; | ||
const tests: TestDefinition[] = []; | ||
const setUps: TestFunction[] = []; | ||
const tearDowns: TestFunction[] = []; | ||
|
||
let filtered = 0; | ||
const ignored = 0; | ||
const measured = 0; | ||
|
||
export function setUp(t: TestFunction): void { | ||
setUps.push(t); | ||
} | ||
export function tearDown(t: TestFunction): void { | ||
tearDowns.push(t); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can we just fix timer for starting fileServer in this PR and leave out the setUP and tearDown stuff? Because modifying testing will effect all of deno, this needs to be considered very carefully. I'm not sure I agree with setting a global setUp/tearDown. Please just manually do the setUP and tearDown for each of the fileServer tests with the new initialization. After that's landed let's discuss these testing changes (in gitter if you have time) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I would prefer this was per-file, but am not sure on the trick to make this work. I also want to improve this across all of deno / have it considered carefully. I could tease it apart:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Let's do just this in this PR.
Yeah. I think we should get rid of the "automatic" run behavior that we currently have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @hayd I'm very interested in having your improvements here. I do think they should be split up into different PRs tho. For simplicity, I'm going to close this one. |
||
|
||
// Must be called before any test() that needs to be filtered. | ||
export function setFilter(s: string): void { | ||
filterRegExp = new RegExp(s, "i"); | ||
|
@@ -117,13 +126,16 @@ function green_ok() { | |
return FG_GREEN + "ok" + RESET; | ||
} | ||
|
||
async function runTests() { | ||
export async function runTests() { | ||
let passed = 0; | ||
let failed = 0; | ||
|
||
for (let s of setUps) { | ||
await s(); | ||
} | ||
console.log("running", tests.length, "tests"); | ||
for (let i = 0; i < tests.length; i++) { | ||
const { fn, name } = tests[i]; | ||
for (let t of tests) { | ||
const { fn, name } = t; | ||
let result = green_ok(); | ||
// See https://github.com/denoland/deno/pull/1452 | ||
// about this usage of groupCollapsed | ||
|
@@ -144,6 +156,9 @@ async function runTests() { | |
} | ||
} | ||
} | ||
for (let t of tearDowns) { | ||
await t(); | ||
} | ||
|
||
// Attempting to match the output of Rust's test runner. | ||
const result = failed > 0 ? red_failed() : green_ok(); | ||
|
@@ -163,4 +178,7 @@ async function runTests() { | |
} | ||
} | ||
|
||
setTimeout(runTests, 0); | ||
const t = setTimeout(runTests, 0); | ||
export function cancelTests() { | ||
clearTimeout(t); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While you're fixing this, can we cat a smaller file? I've noticed this is flooding the log
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The piped stops it flooding the log.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍