From 413a16dfa2be69b230489026ac6d33accad87d1b Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 01:33:25 +0000 Subject: [PATCH 01/11] refactor(testing): prepare for noUncheckedIndexedAccess --- testing/bdd_test.ts | 312 +++++++++++++++++++++---------------------- testing/mock.ts | 34 +++-- testing/mock_test.ts | 36 ++--- testing/time_test.ts | 2 +- 4 files changed, 196 insertions(+), 188 deletions(-) diff --git a/testing/bdd_test.ts b/testing/bdd_test.ts index 650a059ebe2a..35339b0445f9 100644 --- a/testing/bdd_test.ts +++ b/testing/bdd_test.ts @@ -130,15 +130,15 @@ Deno.test("global", async (t) => { beforeEach(beforeEachFn); afterEach(afterEachFn); - assertEquals(it({ name: "example 1", fn: fns[0] }), undefined); - assertEquals(it({ name: "example 2", fn: fns[1] }), undefined); + assertEquals(it({ name: "example 1", fn: fns[0]! }), undefined); + assertEquals(it({ name: "example 2", fn: fns[1]! }), undefined); - assertSpyCalls(fns[0], 0); - assertSpyCalls(fns[1], 0); + assertSpyCalls(fns[0]!, 0); + assertSpyCalls(fns[1]!, 0); assertSpyCall(test, 0); const call = test.calls[0]; - const options = call.args[0] as Deno.TestDefinition; + const options = call?.args[0] as Deno.TestDefinition; assertEquals(Object.keys(options).sort(), ["fn", "name"]); assertEquals(options.name, "global"); @@ -151,7 +151,7 @@ Deno.test("global", async (t) => { test.restore(); } - let fn = fns[0]; + let fn = fns[0]!; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 2 }, args: [context.steps[0]], @@ -159,7 +159,7 @@ Deno.test("global", async (t) => { }); assertSpyCalls(fn, 1); - fn = fns[1]; + fn = fns[1]!; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 3 }, args: [context.steps[1]], @@ -190,7 +190,7 @@ Deno.test("global", async (t) => { assertSpyCalls(fn, 0); assertSpyCall(test, 0); const call = test.calls[0]; - const options = call.args[0] as Deno.TestDefinition; + const options = call?.args[0] as Deno.TestDefinition; assertEquals( Object.keys(options).sort(), ["name", "fn", ...Object.keys(expectedOptions)].sort(), @@ -692,7 +692,7 @@ Deno.test("global", async (t) => { assertSpyCall(test, 0); const call = test.calls[0]; - const options = call.args[0] as Deno.TestDefinition; + const options = call?.args[0] as Deno.TestDefinition; assertEquals( Object.keys(options).sort(), ["name", "fn", ...Object.keys(expectedOptions)].sort(), @@ -702,8 +702,8 @@ Deno.test("global", async (t) => { ...expectedOptions, }); - assertSpyCalls(fns[0], 0); - assertSpyCalls(fns[1], 0); + assertSpyCalls(fns[0]!, 0); + assertSpyCalls(fns[1]!, 0); const context = new TestContext("example"); const result = options.fn(context); @@ -711,14 +711,14 @@ Deno.test("global", async (t) => { assertEquals(await result, undefined); assertSpyCalls(context.spies.step, 2); - let fn = fns[0]; + let fn = fns[0]!; assertSpyCall(fn, 0, { self: {}, args: [context.steps[0]], returned: undefined, }); - fn = fns[1]; + fn = fns[1]!; assertSpyCall(fn, 0, { self: {}, args: [context.steps[1]], @@ -760,8 +760,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe({ name: "example" }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -770,12 +770,12 @@ Deno.test("global", async (t) => { const suite = describe({ name: "example", fn: () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); })); }); @@ -785,8 +785,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe("example"); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -797,8 +797,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe("example", {}); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -806,12 +806,12 @@ Deno.test("global", async (t) => { await assertAllOptions((fns) => { const suite = describe("example", { fn: () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); })); }); @@ -820,10 +820,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -832,10 +832,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe(function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -845,10 +845,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe("example", {}, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -857,10 +857,10 @@ Deno.test("global", async (t) => { const suite = describe("example", { ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); })); }); @@ -870,10 +870,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe({ name: "example" }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -883,10 +883,10 @@ Deno.test("global", async (t) => { name: "example", ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); })); }); @@ -896,10 +896,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe({}, function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -908,10 +908,10 @@ Deno.test("global", async (t) => { const suite = describe({ ...baseOptions, }, function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); })); }); @@ -945,8 +945,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.only({ name: "example" }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -957,12 +957,12 @@ Deno.test("global", async (t) => { const suite = describe.only({ name: "example", fn: () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -973,8 +973,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.only("example"); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -985,8 +985,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.only("example", {}); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -996,12 +996,12 @@ Deno.test("global", async (t) => { await assertAllOptions((fns) => { const suite = describe.only("example", { fn: () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1011,10 +1011,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only("example", () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1023,10 +1023,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only(function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1036,10 +1036,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only("example", {}, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1050,10 +1050,10 @@ Deno.test("global", async (t) => { const suite = describe.only("example", { ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1064,10 +1064,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only({ name: "example" }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1079,10 +1079,10 @@ Deno.test("global", async (t) => { name: "example", ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1093,10 +1093,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only({}, function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1107,10 +1107,10 @@ Deno.test("global", async (t) => { const suite = describe.only({ ...baseOptions, }, function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1146,8 +1146,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.ignore({ name: "example" }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1158,12 +1158,12 @@ Deno.test("global", async (t) => { const suite = describe.ignore({ name: "example", fn: () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1174,8 +1174,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.ignore("example"); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1186,8 +1186,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.ignore("example", {}); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1197,12 +1197,12 @@ Deno.test("global", async (t) => { await assertAllOptions((fns) => { const suite = describe.ignore("example", { fn: () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1212,10 +1212,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore("example", () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1224,10 +1224,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore(function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1237,10 +1237,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore("example", {}, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1251,10 +1251,10 @@ Deno.test("global", async (t) => { const suite = describe.ignore("example", { ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1265,10 +1265,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore({ name: "example" }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1280,10 +1280,10 @@ Deno.test("global", async (t) => { name: "example", ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1294,10 +1294,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore({}, function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); @@ -1308,10 +1308,10 @@ Deno.test("global", async (t) => { const suite = describe.ignore({ ...baseOptions, }, function example() { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); }), ); }); @@ -1336,7 +1336,7 @@ Deno.test("global", async (t) => { assertSpyCall(test, 0); const call = test.calls[0]; - const options = call.args[0] as Deno.TestDefinition; + const options = call?.args[0] as Deno.TestDefinition; assertEquals( Object.keys(options).sort(), ["name", "only", "fn"].sort(), @@ -1346,8 +1346,8 @@ Deno.test("global", async (t) => { only: true, }); - assertSpyCalls(fns[0], 0); - assertSpyCalls(fns[1], 0); + assertSpyCalls(fns[0]!, 0); + assertSpyCalls(fns[1]!, 0); const context = new TestContext("example"); const result = options.fn(context); @@ -1355,17 +1355,17 @@ Deno.test("global", async (t) => { assertEquals(await result, undefined); assertSpyCalls(context.spies.step, 1); - let fn = fns[0]; + let fn = fns[0]!; assertSpyCalls(fn, 0); - fn = fns[1]; + fn = fns[1]!; assertSpyCall(fn, 0, { self: {}, returned: undefined, }); assertSpyCalls(fn, 1); - fn = fns[2]; + fn = fns[2]!; assertSpyCalls(fn, 0); } finally { TestSuiteInternal.reset(); @@ -1376,44 +1376,44 @@ Deno.test("global", async (t) => { await t.step("it", async () => await assertOnly((fns) => { describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); - assertEquals(it.only({ name: "b", fn: fns[1] }), undefined); - assertEquals(it({ name: "c", fn: fns[2] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it.only({ name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ name: "c", fn: fns[2]! }), undefined); }); })); await t.step("nested it", async () => await assertOnly((fns) => { describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); describe("nested", () => { - assertEquals(it.only({ name: "b", fn: fns[1] }), undefined); + assertEquals(it.only({ name: "b", fn: fns[1]! }), undefined); }); - assertEquals(it({ name: "c", fn: fns[2] }), undefined); + assertEquals(it({ name: "c", fn: fns[2]! }), undefined); }); })); await t.step("describe", async () => await assertOnly((fns) => { describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); describe.only("nested", () => { - assertEquals(it({ name: "b", fn: fns[1] }), undefined); + assertEquals(it({ name: "b", fn: fns[1]! }), undefined); }); - assertEquals(it({ name: "c", fn: fns[2] }), undefined); + assertEquals(it({ name: "c", fn: fns[2]! }), undefined); }); })); await t.step("nested describe", async () => await assertOnly((fns) => { describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it({ name: "a", fn: fns[0]! }), undefined); describe("nested", () => { describe.only("nested 2", () => { - assertEquals(it({ name: "b", fn: fns[1] }), undefined); + assertEquals(it({ name: "b", fn: fns[1]! }), undefined); }); }); - assertEquals(it({ name: "c", fn: fns[2] }), undefined); + assertEquals(it({ name: "c", fn: fns[2]! }), undefined); }); })); }); @@ -1434,7 +1434,7 @@ Deno.test("global", async (t) => { assertSpyCall(test, 0); const call = test.calls[0]; - const options = call.args[0] as Deno.TestDefinition; + const options = call?.args[0] as Deno.TestDefinition; assertEquals( Object.keys(options).sort(), ["name", "fn"].sort(), @@ -1443,8 +1443,8 @@ Deno.test("global", async (t) => { name: "example", }); - assertSpyCalls(fns[0], 0); - assertSpyCalls(fns[1], 0); + assertSpyCalls(fns[0]!, 0); + assertSpyCalls(fns[1]!, 0); const context = new TestContext("example"); const result = options.fn(context); @@ -1452,17 +1452,17 @@ Deno.test("global", async (t) => { assertEquals(await result, undefined); assertSpyCalls(context.spies.step, 1); - let fn = fns[0]; + let fn = fns[0]!; assertSpyCalls(fn, 0); - fn = fns[1]; + fn = fns[1]!; assertSpyCall(fn, 0, { self: {}, returned: undefined, }); assertSpyCalls(fn, 1); - fn = fns[2]; + fn = fns[2]!; assertSpyCalls(fn, 0); } finally { TestSuiteInternal.reset(); @@ -1473,33 +1473,33 @@ Deno.test("global", async (t) => { await t.step("it", async () => await assertOnly((fns) => { const suite = describe("example"); - assertEquals(it({ name: "a", suite, fn: fns[0] }), undefined); - assertEquals(it.only({ name: "b", suite, fn: fns[1] }), undefined); - assertEquals(it({ name: "c", suite, fn: fns[2] }), undefined); + assertEquals(it({ name: "a", suite, fn: fns[0]! }), undefined); + assertEquals(it.only({ name: "b", suite, fn: fns[1]! }), undefined); + assertEquals(it({ name: "c", suite, fn: fns[2]! }), undefined); })); await t.step("deep child it", async () => await assertOnly((fns) => { const suite = describe("example"); - assertEquals(it({ name: "a", suite, fn: fns[0] }), undefined); + assertEquals(it({ name: "a", suite, fn: fns[0]! }), undefined); const childSuite = describe(suite, "child"); assertEquals( - it.only({ name: "b", suite: childSuite, fn: fns[1] }), + it.only({ name: "b", suite: childSuite, fn: fns[1]! }), undefined, ); - assertEquals(it({ name: "c", suite, fn: fns[2] }), undefined); + assertEquals(it({ name: "c", suite, fn: fns[2]! }), undefined); })); await t.step("describe", async () => await assertOnly((fns) => { const suite = describe("example"); - assertEquals(it({ name: "a", suite, fn: fns[0] }), undefined); + assertEquals(it({ name: "a", suite, fn: fns[0]! }), undefined); const childSuite = describe.only(suite, "child"); assertEquals( - it({ name: "b", suite: childSuite, fn: fns[1] }), + it({ name: "b", suite: childSuite, fn: fns[1]! }), undefined, ); - assertEquals(it({ name: "c", suite, fn: fns[2] }), undefined); + assertEquals(it({ name: "c", suite, fn: fns[2]! }), undefined); })); await t.step( @@ -1507,14 +1507,14 @@ Deno.test("global", async (t) => { async () => await assertOnly((fns) => { const suite = describe("example"); - assertEquals(it({ name: "a", suite, fn: fns[0] }), undefined); + assertEquals(it({ name: "a", suite, fn: fns[0]! }), undefined); const childSuite = describe(suite, "child"); const child2Suite = describe.only(childSuite, "child 2"); assertEquals( - it({ name: "b", suite: child2Suite, fn: fns[1] }), + it({ name: "b", suite: child2Suite, fn: fns[1]! }), undefined, ); - assertEquals(it({ name: "c", suite, fn: fns[2] }), undefined); + assertEquals(it({ name: "c", suite, fn: fns[2]! }), undefined); }), ); }); @@ -1543,12 +1543,12 @@ Deno.test("global", async (t) => { try { cb({ beforeAllFn, afterAllFn, beforeEachFn, afterEachFn, fns }); - assertSpyCalls(fns[0], 0); - assertSpyCalls(fns[1], 0); + assertSpyCalls(fns[0]!, 0); + assertSpyCalls(fns[1]!, 0); assertSpyCall(test, 0); const call = test.calls[0]; - const options = call.args[0] as Deno.TestDefinition; + const options = call?.args[0] as Deno.TestDefinition; assertEquals(Object.keys(options).sort(), ["fn", "name"]); assertEquals(options.name, "example"); @@ -1561,7 +1561,7 @@ Deno.test("global", async (t) => { test.restore(); } - let fn = fns[0]; + let fn = fns[0]!; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 2 }, args: [context.steps[0]], @@ -1569,7 +1569,7 @@ Deno.test("global", async (t) => { }); assertSpyCalls(fn, 1); - fn = fns[1]; + fn = fns[1]!; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 3 }, args: [context.steps[1]], @@ -1595,8 +1595,8 @@ Deno.test("global", async (t) => { beforeEach(beforeEachFn); afterEach(afterEachFn); - assertEquals(it({ name: "example 1", fn: fns[0] }), undefined); - assertEquals(it({ name: "example 2", fn: fns[1] }), undefined); + assertEquals(it({ name: "example 1", fn: fns[0]! }), undefined); + assertEquals(it({ name: "example 2", fn: fns[1]! }), undefined); }); }, ), @@ -1615,11 +1615,11 @@ Deno.test("global", async (t) => { afterEach: afterEachFn, fn: () => { assertEquals( - it({ name: "example 1", fn: fns[0] }), + it({ name: "example 1", fn: fns[0]! }), undefined, ); assertEquals( - it({ name: "example 2", fn: fns[1] }), + it({ name: "example 2", fn: fns[1]! }), undefined, ); }, @@ -1645,17 +1645,17 @@ Deno.test("global", async (t) => { afterEach(afterEachFn); describe("nested", () => { - assertEquals(it({ name: "example 1", fn: fns[0] }), undefined); - assertEquals(it({ name: "example 2", fn: fns[1] }), undefined); + assertEquals(it({ name: "example 1", fn: fns[0]! }), undefined); + assertEquals(it({ name: "example 2", fn: fns[1]! }), undefined); }); }); - assertSpyCalls(fns[0], 0); - assertSpyCalls(fns[1], 0); + assertSpyCalls(fns[0]!, 0); + assertSpyCalls(fns[1]!, 0); assertSpyCall(test, 0); const call = test.calls[0]; - const options = call.args[0] as Deno.TestDefinition; + const options = call?.args[0] as Deno.TestDefinition; assertEquals(Object.keys(options).sort(), ["fn", "name"]); assertEquals(options.name, "example"); @@ -1666,24 +1666,24 @@ Deno.test("global", async (t) => { assertStrictEquals(Promise.resolve(result), result); assertEquals(await result, undefined); - assertSpyCalls(context.steps[0].spies.step, 2); + assertSpyCalls(context.steps[0]!.spies.step, 2); } finally { TestSuiteInternal.reset(); test.restore(); } - let fn = fns[0]; + let fn = fns[0]!; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 2 }, - args: [context.steps[0].steps[0]], + args: [context.steps[0]!.steps[0]], returned: undefined, }); assertSpyCalls(fn, 1); - fn = fns[1]; + fn = fns[1]!; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 3 }, - args: [context.steps[0].steps[1]], + args: [context.steps[0]!.steps[1]], returned: undefined, }); assertSpyCalls(fn, 1); @@ -1762,17 +1762,17 @@ Deno.test("global", async (t) => { beforeEach(beforeEachFnNested); afterEach(afterEachFnNested); - assertEquals(it({ name: "example 1", fn: fns[0] }), undefined); - assertEquals(it({ name: "example 2", fn: fns[1] }), undefined); + assertEquals(it({ name: "example 1", fn: fns[0]! }), undefined); + assertEquals(it({ name: "example 2", fn: fns[1]! }), undefined); }); }); - assertSpyCalls(fns[0], 0); - assertSpyCalls(fns[1], 0); + assertSpyCalls(fns[0]!, 0); + assertSpyCalls(fns[1]!, 0); assertSpyCall(test, 0); const call = test.calls[0]; - const options = call.args[0] as Deno.TestDefinition; + const options = call?.args[0] as Deno.TestDefinition; assertEquals(Object.keys(options).sort(), ["fn", "name"]); assertEquals(options.name, "example"); @@ -1783,13 +1783,13 @@ Deno.test("global", async (t) => { assertStrictEquals(Promise.resolve(result), result); assertEquals(await result, undefined); - assertSpyCalls(context.steps[0].spies.step, 2); + assertSpyCalls(context.steps[0]!.spies.step, 2); } finally { TestSuiteInternal.reset(); test.restore(); } - let fn = fns[0]; + let fn = fns[0]!; assertSpyCall(fn, 0, { self: { allTimer: 1, @@ -1799,12 +1799,12 @@ Deno.test("global", async (t) => { x: 2, y: 2, }, - args: [context.steps[0].steps[0]], + args: [context.steps[0]!.steps[0]], returned: undefined, }); assertSpyCalls(fn, 1); - fn = fns[1]; + fn = fns[1]!; assertSpyCall(fn, 0, { self: { allTimer: 1, @@ -1814,7 +1814,7 @@ Deno.test("global", async (t) => { x: 1, y: 3, }, - args: [context.steps[0].steps[1]], + args: [context.steps[0]!.steps[1]], returned: undefined, }); assertSpyCalls(fn, 1); diff --git a/testing/mock.ts b/testing/mock.ts index e3c9f7615aa8..961c68b34b48 100644 --- a/testing/mock.ts +++ b/testing/mock.ts @@ -349,7 +349,7 @@ const sessions: Set>[] = []; // deno-lint-ignore no-explicit-any function getSession(): Set> { if (sessions.length === 0) sessions.push(new Set()); - return sessions[sessions.length - 1]; + return sessions[sessions.length - 1]!; } // deno-lint-ignore no-explicit-any function registerMock(spy: Spy) { @@ -808,6 +808,19 @@ export interface ExpectedSpyCall< }; } +function getSpyCall< + Self, + Args extends unknown[], + Return, +>( + spy: SpyLike, + callIndex: number, +): SpyCall { + if (spy.calls.length < (callIndex + 1)) { + throw new AssertionError("spy not called as much as expected"); + } + return spy.calls[callIndex]!; +} /** * Asserts that a spy is called as expected. */ @@ -820,10 +833,7 @@ export function assertSpyCall< callIndex: number, expected?: ExpectedSpyCall, ) { - if (spy.calls.length < (callIndex + 1)) { - throw new AssertionError("spy not called as much as expected"); - } - const call: SpyCall = spy.calls[callIndex]; + const call = getSpyCall(spy, callIndex); if (expected) { if (expected.args) { try { @@ -905,7 +915,7 @@ export async function assertSpyCallAsync< delete expectedSync.error; } assertSpyCall(spy, callIndex, expectedSync); - const call = spy.calls[callIndex]; + const call = getSpyCall(spy, callIndex); if (call.error) { throw new AssertionError( @@ -981,9 +991,8 @@ export function assertSpyCallArg< argIndex: number, expected: ExpectedArg, ): ExpectedArg { - assertSpyCall(spy, callIndex); - const call = spy.calls[callIndex]; - const arg = call.args[argIndex]; + const call = getSpyCall(spy, callIndex); + const arg = call?.args[argIndex]; assertEquals(arg, expected); return arg as ExpectedArg; } @@ -1039,8 +1048,7 @@ export function assertSpyCallArgs< argsEnd?: number | ExpectedArgs, expected?: ExpectedArgs, ): ExpectedArgs { - assertSpyCall(spy, callIndex); - const call = spy.calls[callIndex]; + const call = getSpyCall(spy, callIndex); if (!expected) { expected = argsEnd as ExpectedArgs; argsEnd = undefined; @@ -1074,8 +1082,8 @@ export function returnsThis< // deno-lint-ignore no-explicit-any export function returnsArg( idx: number, -): (this: Self, ...args: Arg[]) => Arg { - return function (...args: Arg[]): Arg { +): (this: Self, ...args: Arg[]) => Arg | undefined { + return function (...args: Arg[]): Arg | undefined { return args[idx]; }; } diff --git a/testing/mock_test.ts b/testing/mock_test.ts index fcd038341a65..9d74a2b00f50 100644 --- a/testing/mock_test.ts +++ b/testing/mock_test.ts @@ -571,21 +571,21 @@ Deno.test("mockSession and mockSessionAsync", async () => { assertEquals(actions.map((action) => action.restored), expected); } await mockSessionAsync(async () => { - actions.push(spy(points[0], "action")); + actions.push(spy(points[0]!, "action")); assertRestored([false]); await mockSessionAsync(async () => { await Promise.resolve(); - actions.push(spy(points[1], "action")); + actions.push(spy(points[1]!, "action")); assertRestored([false, false]); mockSession(() => { - actions.push(spy(points[2], "action")); - actions.push(spy(points[3], "action")); + actions.push(spy(points[2]!, "action")); + actions.push(spy(points[3]!, "action")); assertRestored([false, false, false, false]); })(); - actions.push(spy(points[4], "action")); + actions.push(spy(points[4]!, "action")); assertRestored([false, false, true, true, false]); })(); - actions.push(spy(points[5], "action")); + actions.push(spy(points[5]!, "action")); assertRestored([false, true, true, true, true, false]); })(); assertRestored(Array(6).fill(true)); @@ -619,24 +619,24 @@ Deno.test("mockSession and restore current session", () => { actions = []; try { - actions.push(spy(points[0], "action")); + actions.push(spy(points[0]!, "action")); try { mockSession(); - actions.push(spy(points[1], "action")); + actions.push(spy(points[1]!, "action")); try { mockSession(); - actions.push(spy(points[2], "action")); - actions.push(spy(points[3], "action")); + actions.push(spy(points[2]!, "action")); + actions.push(spy(points[3]!, "action")); } finally { assertRestored([false, false, false, false]); restore(); } - actions.push(spy(points[4], "action")); + actions.push(spy(points[4]!, "action")); } finally { assertRestored([false, false, true, true, false]); restore(); } - actions.push(spy(points[5], "action")); + actions.push(spy(points[5]!, "action")); } finally { assertRestored([false, true, true, true, true, false]); restore(); @@ -665,19 +665,19 @@ Deno.test("mockSession and restore multiple sessions", () => { try { actions = []; try { - actions.push(spy(points[0], "action")); + actions.push(spy(points[0]!, "action")); const id = mockSession(); try { - actions.push(spy(points[1], "action")); - actions.push(spy(points[2], "action")); + actions.push(spy(points[1]!, "action")); + actions.push(spy(points[2]!, "action")); mockSession(); - actions.push(spy(points[3], "action")); - actions.push(spy(points[4], "action")); + actions.push(spy(points[3]!, "action")); + actions.push(spy(points[4]!, "action")); } finally { assertRestored([false, false, false, false, false]); restore(id); } - actions.push(spy(points[5], "action")); + actions.push(spy(points[5]!, "action")); } finally { assertRestored([false, true, true, true, true, false]); restore(); diff --git a/testing/time_test.ts b/testing/time_test.ts index 496fe62f60f0..b13033ef03ba 100644 --- a/testing/time_test.ts +++ b/testing/time_test.ts @@ -78,7 +78,7 @@ Deno.test("Fake Date instance methods passthrough to real Date instance methods" args: [], returned: "2020-05-25T05:00:00.123Z", }); - assertInstanceOf(func1.calls[0].self, _internals.Date); + assertInstanceOf(func1.calls?.[0]?.self, _internals.Date); } finally { func1.restore(); } From d412a7c41aedaad0b43e45662498b7d9f7609537 Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Thu, 4 Jan 2024 15:27:46 +1100 Subject: [PATCH 02/11] tweaks --- testing/bdd_test.ts | 6 +++--- testing/mock_test.ts | 9 ++++++++- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/testing/bdd_test.ts b/testing/bdd_test.ts index 35339b0445f9..c7beb305f22a 100644 --- a/testing/bdd_test.ts +++ b/testing/bdd_test.ts @@ -118,9 +118,9 @@ Deno.test("global", async (t) => { } await t.step("global hooks", async () => { - const test = stub(Deno, "test"), - fns = [spy(), spy()], - { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = hookFns(); + const test = stub(Deno, "test"); + const fns = [spy(), spy()] as const; + const { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = hookFns(); const context = new TestContext("global"); try { diff --git a/testing/mock_test.ts b/testing/mock_test.ts index 9d74a2b00f50..62d2b51b6fe3 100644 --- a/testing/mock_test.ts +++ b/testing/mock_test.ts @@ -565,7 +565,14 @@ Deno.test("stub types", () => { }); Deno.test("mockSession and mockSessionAsync", async () => { - const points = Array(6).fill(undefined).map(() => new Point(2, 3)); + const points = [ + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + ] as const; let actions: Spy[] = []; function assertRestored(expected: boolean[]) { assertEquals(actions.map((action) => action.restored), expected); From e867e0767264e63bf80244cbc1d4bc9638814a20 Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 09:01:32 +0000 Subject: [PATCH 03/11] fix(testing): returnsArg throws when no arg at index --- testing/mock.ts | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/testing/mock.ts b/testing/mock.ts index 961c68b34b48..ed2d7ece57e4 100644 --- a/testing/mock.ts +++ b/testing/mock.ts @@ -1082,8 +1082,11 @@ export function returnsThis< // deno-lint-ignore no-explicit-any export function returnsArg( idx: number, -): (this: Self, ...args: Arg[]) => Arg | undefined { - return function (...args: Arg[]): Arg | undefined { +): (this: Self, ...args: Arg[]) => Arg { + return function (...args: Arg[]): Arg { + if (!(idx in args)) { + throw new TypeError(""); + } return args[idx]; }; } From eea3bf223a57e4e7a3456f5ca59806f0c07f8c0c Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 09:03:25 +0000 Subject: [PATCH 04/11] refactor(testing): sessions to use .at(-1) to get last item Co-authored-by: Asher Gomez --- testing/mock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mock.ts b/testing/mock.ts index ed2d7ece57e4..c6d191367af3 100644 --- a/testing/mock.ts +++ b/testing/mock.ts @@ -349,7 +349,7 @@ const sessions: Set>[] = []; // deno-lint-ignore no-explicit-any function getSession(): Set> { if (sessions.length === 0) sessions.push(new Set()); - return sessions[sessions.length - 1]!; + return sessions.at(-1)!; } // deno-lint-ignore no-explicit-any function registerMock(spy: Spy) { From ede3fbd939e1666ab6df784d3a1a16dee8d68812 Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 09:13:19 +0000 Subject: [PATCH 05/11] non-null after check --- testing/mock.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/mock.ts b/testing/mock.ts index c6d191367af3..48311a698a65 100644 --- a/testing/mock.ts +++ b/testing/mock.ts @@ -1087,7 +1087,7 @@ export function returnsArg( if (!(idx in args)) { throw new TypeError(""); } - return args[idx]; + return args[idx]!; }; } From de229096a7ac0a859cd4a83e0a66dcac9d6be30c Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 09:18:07 +0000 Subject: [PATCH 06/11] swap non-null assertions for as const --- testing/bdd_test.ts | 399 ++++++++++++++++++++++---------------------- 1 file changed, 201 insertions(+), 198 deletions(-) diff --git a/testing/bdd_test.ts b/testing/bdd_test.ts index c7beb305f22a..125a7d872651 100644 --- a/testing/bdd_test.ts +++ b/testing/bdd_test.ts @@ -130,11 +130,11 @@ Deno.test("global", async (t) => { beforeEach(beforeEachFn); afterEach(afterEachFn); - assertEquals(it({ name: "example 1", fn: fns[0]! }), undefined); - assertEquals(it({ name: "example 2", fn: fns[1]! }), undefined); + assertEquals(it({ name: "example 1", fn: fns[0] }), undefined); + assertEquals(it({ name: "example 2", fn: fns[1] }), undefined); - assertSpyCalls(fns[0]!, 0); - assertSpyCalls(fns[1]!, 0); + assertSpyCalls(fns[0], 0); + assertSpyCalls(fns[1], 0); assertSpyCall(test, 0); const call = test.calls[0]; @@ -151,7 +151,7 @@ Deno.test("global", async (t) => { test.restore(); } - let fn = fns[0]!; + let fn = fns[0]; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 2 }, args: [context.steps[0]], @@ -159,7 +159,7 @@ Deno.test("global", async (t) => { }); assertSpyCalls(fn, 1); - fn = fns[1]!; + fn = fns[1]; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 3 }, args: [context.steps[1]], @@ -683,10 +683,10 @@ Deno.test("global", async (t) => { */ async function assertOptions( expectedOptions: Omit, - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy]) => void, ) { const test = stub(Deno, "test"); - const fns = [spy(), spy()]; + const fns = [spy(), spy()] as const; try { cb(fns); @@ -702,8 +702,8 @@ Deno.test("global", async (t) => { ...expectedOptions, }); - assertSpyCalls(fns[0]!, 0); - assertSpyCalls(fns[1]!, 0); + assertSpyCalls(fns[0], 0); + assertSpyCalls(fns[1], 0); const context = new TestContext("example"); const result = options.fn(context); @@ -711,14 +711,14 @@ Deno.test("global", async (t) => { assertEquals(await result, undefined); assertSpyCalls(context.spies.step, 2); - let fn = fns[0]!; + let fn = fns[0]; assertSpyCall(fn, 0, { self: {}, args: [context.steps[0]], returned: undefined, }); - fn = fns[1]!; + fn = fns[1]; assertSpyCall(fn, 0, { self: {}, args: [context.steps[1]], @@ -737,7 +737,7 @@ Deno.test("global", async (t) => { * This is used to reduce code duplication when testing calling `describe` with different call signatures. */ async function assertMinimumOptions( - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy]) => void, ) { await assertOptions({}, cb); } @@ -748,7 +748,7 @@ Deno.test("global", async (t) => { * This is used to reduce code duplication when testing calling `describe` with different call signatures. */ async function assertAllOptions( - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy]) => void, ) { await assertOptions({ ...baseOptions }, cb); } @@ -760,8 +760,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe({ name: "example" }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -770,12 +770,12 @@ Deno.test("global", async (t) => { const suite = describe({ name: "example", fn: () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); })); }); @@ -785,8 +785,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe("example"); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -797,8 +797,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe("example", {}); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -806,12 +806,12 @@ Deno.test("global", async (t) => { await assertAllOptions((fns) => { const suite = describe("example", { fn: () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); })); }); @@ -820,10 +820,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -832,10 +832,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe(function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -845,10 +845,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe("example", {}, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -857,10 +857,10 @@ Deno.test("global", async (t) => { const suite = describe("example", { ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); })); }); @@ -870,10 +870,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe({ name: "example" }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -883,10 +883,10 @@ Deno.test("global", async (t) => { name: "example", ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); })); }); @@ -896,10 +896,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe({}, function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -908,10 +908,10 @@ Deno.test("global", async (t) => { const suite = describe({ ...baseOptions, }, function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); })); }); @@ -922,7 +922,7 @@ Deno.test("global", async (t) => { * This is used to reduce code duplication when testing calling `describe.only` with different call signatures. */ async function assertMinimumOptions( - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy]) => void, ) { await assertOptions({ only: true }, cb); } @@ -933,7 +933,7 @@ Deno.test("global", async (t) => { * This is used to reduce code duplication when testing calling `describe.only` with different call signatures. */ async function assertAllOptions( - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy]) => void, ) { await assertOptions({ ...baseOptions, only: true }, cb); } @@ -945,8 +945,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.only({ name: "example" }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -957,12 +957,12 @@ Deno.test("global", async (t) => { const suite = describe.only({ name: "example", fn: () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -973,8 +973,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.only("example"); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -985,8 +985,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.only("example", {}); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -996,12 +996,12 @@ Deno.test("global", async (t) => { await assertAllOptions((fns) => { const suite = describe.only("example", { fn: () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1011,10 +1011,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only("example", () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1023,10 +1023,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only(function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1036,10 +1036,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only("example", {}, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1050,10 +1050,10 @@ Deno.test("global", async (t) => { const suite = describe.only("example", { ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1064,10 +1064,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only({ name: "example" }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1079,10 +1079,10 @@ Deno.test("global", async (t) => { name: "example", ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1093,10 +1093,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.only({}, function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1107,10 +1107,10 @@ Deno.test("global", async (t) => { const suite = describe.only({ ...baseOptions, }, function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1123,7 +1123,7 @@ Deno.test("global", async (t) => { * This is used to reduce code duplication when testing calling `describe.ignore` with different call signatures. */ async function assertMinimumOptions( - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy]) => void, ) { await assertOptions({ ignore: true }, cb); } @@ -1134,7 +1134,7 @@ Deno.test("global", async (t) => { * This is used to reduce code duplication when testing calling `describe.ignore` with different call signatures. */ async function assertAllOptions( - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy]) => void, ) { await assertOptions({ ...baseOptions, ignore: true }, cb); } @@ -1146,8 +1146,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.ignore({ name: "example" }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1158,12 +1158,12 @@ Deno.test("global", async (t) => { const suite = describe.ignore({ name: "example", fn: () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1174,8 +1174,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.ignore("example"); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1186,8 +1186,8 @@ Deno.test("global", async (t) => { await assertMinimumOptions((fns) => { const suite = describe.ignore("example", {}); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "a", fn: fns[0]! }), undefined); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "a", fn: fns[0] }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1197,12 +1197,12 @@ Deno.test("global", async (t) => { await assertAllOptions((fns) => { const suite = describe.ignore("example", { fn: () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }, ...baseOptions, }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1212,10 +1212,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore("example", () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1224,10 +1224,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore(function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1237,10 +1237,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore("example", {}, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1251,10 +1251,10 @@ Deno.test("global", async (t) => { const suite = describe.ignore("example", { ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1265,10 +1265,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore({ name: "example" }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1280,10 +1280,10 @@ Deno.test("global", async (t) => { name: "example", ...baseOptions, }, () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1294,10 +1294,10 @@ Deno.test("global", async (t) => { async () => await assertMinimumOptions((fns) => { const suite = describe.ignore({}, function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); @@ -1308,10 +1308,10 @@ Deno.test("global", async (t) => { const suite = describe.ignore({ ...baseOptions, }, function example() { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); }); assert(suite && typeof suite.symbol === "symbol"); - assertEquals(it({ suite, name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ suite, name: "b", fn: fns[1] }), undefined); }), ); }); @@ -1327,10 +1327,10 @@ Deno.test("global", async (t) => { * This is used to reduce code duplication when testing calling `describe.ignore` with different call signatures. */ async function assertOnly( - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy, Spy]) => void, ) { const test = stub(Deno, "test"); - const fns = [spy(), spy(), spy()]; + const fns = [spy(), spy(), spy()] as const; try { cb(fns); @@ -1346,8 +1346,8 @@ Deno.test("global", async (t) => { only: true, }); - assertSpyCalls(fns[0]!, 0); - assertSpyCalls(fns[1]!, 0); + assertSpyCalls(fns[0], 0); + assertSpyCalls(fns[1], 0); const context = new TestContext("example"); const result = options.fn(context); @@ -1355,17 +1355,17 @@ Deno.test("global", async (t) => { assertEquals(await result, undefined); assertSpyCalls(context.spies.step, 1); - let fn = fns[0]!; + let fn = fns[0]; assertSpyCalls(fn, 0); - fn = fns[1]!; + fn = fns[1]; assertSpyCall(fn, 0, { self: {}, returned: undefined, }); assertSpyCalls(fn, 1); - fn = fns[2]!; + fn = fns[2]; assertSpyCalls(fn, 0); } finally { TestSuiteInternal.reset(); @@ -1376,44 +1376,44 @@ Deno.test("global", async (t) => { await t.step("it", async () => await assertOnly((fns) => { describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); - assertEquals(it.only({ name: "b", fn: fns[1]! }), undefined); - assertEquals(it({ name: "c", fn: fns[2]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); + assertEquals(it.only({ name: "b", fn: fns[1] }), undefined); + assertEquals(it({ name: "c", fn: fns[2] }), undefined); }); })); await t.step("nested it", async () => await assertOnly((fns) => { describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); describe("nested", () => { - assertEquals(it.only({ name: "b", fn: fns[1]! }), undefined); + assertEquals(it.only({ name: "b", fn: fns[1] }), undefined); }); - assertEquals(it({ name: "c", fn: fns[2]! }), undefined); + assertEquals(it({ name: "c", fn: fns[2] }), undefined); }); })); await t.step("describe", async () => await assertOnly((fns) => { describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); describe.only("nested", () => { - assertEquals(it({ name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ name: "b", fn: fns[1] }), undefined); }); - assertEquals(it({ name: "c", fn: fns[2]! }), undefined); + assertEquals(it({ name: "c", fn: fns[2] }), undefined); }); })); await t.step("nested describe", async () => await assertOnly((fns) => { describe("example", () => { - assertEquals(it({ name: "a", fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", fn: fns[0] }), undefined); describe("nested", () => { describe.only("nested 2", () => { - assertEquals(it({ name: "b", fn: fns[1]! }), undefined); + assertEquals(it({ name: "b", fn: fns[1] }), undefined); }); }); - assertEquals(it({ name: "c", fn: fns[2]! }), undefined); + assertEquals(it({ name: "c", fn: fns[2] }), undefined); }); })); }); @@ -1425,10 +1425,10 @@ Deno.test("global", async (t) => { * This is used to reduce code duplication when testing calling `describe.ignore` with different call signatures. */ async function assertOnly( - cb: (fns: Spy[]) => void, + cb: (fns: readonly [Spy, Spy, Spy]) => void, ) { const test = stub(Deno, "test"); - const fns = [spy(), spy(), spy()]; + const fns = [spy(), spy(), spy()] as const; try { cb(fns); @@ -1443,8 +1443,8 @@ Deno.test("global", async (t) => { name: "example", }); - assertSpyCalls(fns[0]!, 0); - assertSpyCalls(fns[1]!, 0); + assertSpyCalls(fns[0], 0); + assertSpyCalls(fns[1], 0); const context = new TestContext("example"); const result = options.fn(context); @@ -1452,17 +1452,17 @@ Deno.test("global", async (t) => { assertEquals(await result, undefined); assertSpyCalls(context.spies.step, 1); - let fn = fns[0]!; + let fn = fns[0]; assertSpyCalls(fn, 0); - fn = fns[1]!; + fn = fns[1]; assertSpyCall(fn, 0, { self: {}, returned: undefined, }); assertSpyCalls(fn, 1); - fn = fns[2]!; + fn = fns[2]; assertSpyCalls(fn, 0); } finally { TestSuiteInternal.reset(); @@ -1473,33 +1473,33 @@ Deno.test("global", async (t) => { await t.step("it", async () => await assertOnly((fns) => { const suite = describe("example"); - assertEquals(it({ name: "a", suite, fn: fns[0]! }), undefined); - assertEquals(it.only({ name: "b", suite, fn: fns[1]! }), undefined); - assertEquals(it({ name: "c", suite, fn: fns[2]! }), undefined); + assertEquals(it({ name: "a", suite, fn: fns[0] }), undefined); + assertEquals(it.only({ name: "b", suite, fn: fns[1] }), undefined); + assertEquals(it({ name: "c", suite, fn: fns[2] }), undefined); })); await t.step("deep child it", async () => await assertOnly((fns) => { const suite = describe("example"); - assertEquals(it({ name: "a", suite, fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", suite, fn: fns[0] }), undefined); const childSuite = describe(suite, "child"); assertEquals( - it.only({ name: "b", suite: childSuite, fn: fns[1]! }), + it.only({ name: "b", suite: childSuite, fn: fns[1] }), undefined, ); - assertEquals(it({ name: "c", suite, fn: fns[2]! }), undefined); + assertEquals(it({ name: "c", suite, fn: fns[2] }), undefined); })); await t.step("describe", async () => await assertOnly((fns) => { const suite = describe("example"); - assertEquals(it({ name: "a", suite, fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", suite, fn: fns[0] }), undefined); const childSuite = describe.only(suite, "child"); assertEquals( - it({ name: "b", suite: childSuite, fn: fns[1]! }), + it({ name: "b", suite: childSuite, fn: fns[1] }), undefined, ); - assertEquals(it({ name: "c", suite, fn: fns[2]! }), undefined); + assertEquals(it({ name: "c", suite, fn: fns[2] }), undefined); })); await t.step( @@ -1507,14 +1507,14 @@ Deno.test("global", async (t) => { async () => await assertOnly((fns) => { const suite = describe("example"); - assertEquals(it({ name: "a", suite, fn: fns[0]! }), undefined); + assertEquals(it({ name: "a", suite, fn: fns[0] }), undefined); const childSuite = describe(suite, "child"); const child2Suite = describe.only(childSuite, "child 2"); assertEquals( - it({ name: "b", suite: child2Suite, fn: fns[1]! }), + it({ name: "b", suite: child2Suite, fn: fns[1] }), undefined, ); - assertEquals(it({ name: "c", suite, fn: fns[2]! }), undefined); + assertEquals(it({ name: "c", suite, fn: fns[2] }), undefined); }), ); }); @@ -1531,20 +1531,21 @@ Deno.test("global", async (t) => { afterAllFn: Spy; beforeEachFn: Spy; afterEachFn: Spy; - fns: Spy[]; + fns: readonly [Spy, Spy]; }, ) => void, ) { - const test = stub(Deno, "test"), - fns = [spy(), spy()], - { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = hookFns(); + const test = stub(Deno, "test"); + const fns = [spy(), spy()] as const; + const { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = + hookFns(); const context = new TestContext("example"); try { cb({ beforeAllFn, afterAllFn, beforeEachFn, afterEachFn, fns }); - assertSpyCalls(fns[0]!, 0); - assertSpyCalls(fns[1]!, 0); + assertSpyCalls(fns[0], 0); + assertSpyCalls(fns[1], 0); assertSpyCall(test, 0); const call = test.calls[0]; @@ -1561,7 +1562,7 @@ Deno.test("global", async (t) => { test.restore(); } - let fn = fns[0]!; + let fn = fns[0]; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 2 }, args: [context.steps[0]], @@ -1569,7 +1570,7 @@ Deno.test("global", async (t) => { }); assertSpyCalls(fn, 1); - fn = fns[1]!; + fn = fns[1]; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 3 }, args: [context.steps[1]], @@ -1595,8 +1596,8 @@ Deno.test("global", async (t) => { beforeEach(beforeEachFn); afterEach(afterEachFn); - assertEquals(it({ name: "example 1", fn: fns[0]! }), undefined); - assertEquals(it({ name: "example 2", fn: fns[1]! }), undefined); + assertEquals(it({ name: "example 1", fn: fns[0] }), undefined); + assertEquals(it({ name: "example 2", fn: fns[1] }), undefined); }); }, ), @@ -1615,11 +1616,11 @@ Deno.test("global", async (t) => { afterEach: afterEachFn, fn: () => { assertEquals( - it({ name: "example 1", fn: fns[0]! }), + it({ name: "example 1", fn: fns[0] }), undefined, ); assertEquals( - it({ name: "example 2", fn: fns[1]! }), + it({ name: "example 2", fn: fns[1] }), undefined, ); }, @@ -1631,9 +1632,10 @@ Deno.test("global", async (t) => { await t.step( "nested", async () => { - const test = stub(Deno, "test"), - fns = [spy(), spy()], - { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = hookFns(); + const test = stub(Deno, "test"); + const fns = [spy(), spy()] as readonly [Spy, Spy]; + const { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = + hookFns(); const context = new TestContext("example"); try { @@ -1645,13 +1647,13 @@ Deno.test("global", async (t) => { afterEach(afterEachFn); describe("nested", () => { - assertEquals(it({ name: "example 1", fn: fns[0]! }), undefined); - assertEquals(it({ name: "example 2", fn: fns[1]! }), undefined); + assertEquals(it({ name: "example 1", fn: fns[0] }), undefined); + assertEquals(it({ name: "example 2", fn: fns[1] }), undefined); }); }); - assertSpyCalls(fns[0]!, 0); - assertSpyCalls(fns[1]!, 0); + assertSpyCalls(fns[0], 0); + assertSpyCalls(fns[1], 0); assertSpyCall(test, 0); const call = test.calls[0]; @@ -1672,7 +1674,7 @@ Deno.test("global", async (t) => { test.restore(); } - let fn = fns[0]!; + let fn = fns[0]; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 2 }, args: [context.steps[0]!.steps[0]], @@ -1680,7 +1682,7 @@ Deno.test("global", async (t) => { }); assertSpyCalls(fn, 1); - fn = fns[1]!; + fn = fns[1]; assertSpyCall(fn, 0, { self: { allTimer: 1, eachTimer: 3 }, args: [context.steps[0]!.steps[1]], @@ -1705,46 +1707,47 @@ Deno.test("global", async (t) => { await t.step( "nested with hooks", async () => { - const test = stub(Deno, "test"), - fns = [ - spy(function (this: NestedContext) { - this.x = 2; - }), - spy(function (this: NestedContext) { - this.y = 3; - }), - ], - { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = hookFns(), - beforeAllFnNested = spy(async function (this: NestedContext) { - await Promise.resolve(); - this.x = 1; - this.allTimerNested = timerIdx++; - timers.set( - this.allTimerNested, - setTimeout(() => {}, 10000), - ); + const test = stub(Deno, "test"); + const fns = [ + spy(function (this: NestedContext) { + this.x = 2; }), - afterAllFnNested = spy( - async function (this: NestedContext) { - await Promise.resolve(); - clearTimeout(timers.get(this.allTimerNested)); - }, - ), - beforeEachFnNested = spy(async function (this: NestedContext) { - await Promise.resolve(); - this.y = 2; - this.eachTimerNested = timerIdx++; - timers.set( - this.eachTimerNested, - setTimeout(() => {}, 10000), - ); + spy(function (this: NestedContext) { + this.y = 3; }), - afterEachFnNested = spy( - async function (this: NestedContext) { - await Promise.resolve(); - clearTimeout(timers.get(this.eachTimerNested)); - }, + ] as const; + const { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = + hookFns(); + const beforeAllFnNested = spy(async function (this: NestedContext) { + await Promise.resolve(); + this.x = 1; + this.allTimerNested = timerIdx++; + timers.set( + this.allTimerNested, + setTimeout(() => {}, 10000), + ); + }); + const afterAllFnNested = spy( + async function (this: NestedContext) { + await Promise.resolve(); + clearTimeout(timers.get(this.allTimerNested)); + }, + ); + const beforeEachFnNested = spy(async function (this: NestedContext) { + await Promise.resolve(); + this.y = 2; + this.eachTimerNested = timerIdx++; + timers.set( + this.eachTimerNested, + setTimeout(() => {}, 10000), ); + }); + const afterEachFnNested = spy( + async function (this: NestedContext) { + await Promise.resolve(); + clearTimeout(timers.get(this.eachTimerNested)); + }, + ); const context = new TestContext("example"); try { @@ -1762,13 +1765,13 @@ Deno.test("global", async (t) => { beforeEach(beforeEachFnNested); afterEach(afterEachFnNested); - assertEquals(it({ name: "example 1", fn: fns[0]! }), undefined); - assertEquals(it({ name: "example 2", fn: fns[1]! }), undefined); + assertEquals(it({ name: "example 1", fn: fns[0] }), undefined); + assertEquals(it({ name: "example 2", fn: fns[1] }), undefined); }); }); - assertSpyCalls(fns[0]!, 0); - assertSpyCalls(fns[1]!, 0); + assertSpyCalls(fns[0], 0); + assertSpyCalls(fns[1], 0); assertSpyCall(test, 0); const call = test.calls[0]; @@ -1789,7 +1792,7 @@ Deno.test("global", async (t) => { test.restore(); } - let fn = fns[0]!; + let fn = fns[0]; assertSpyCall(fn, 0, { self: { allTimer: 1, @@ -1804,7 +1807,7 @@ Deno.test("global", async (t) => { }); assertSpyCalls(fn, 1); - fn = fns[1]!; + fn = fns[1]; assertSpyCall(fn, 0, { self: { allTimer: 1, From d6226ab53139e019f397f3f2d9d28ba09c96063c Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 09:23:12 +0000 Subject: [PATCH 07/11] proper error message --- testing/mock.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/testing/mock.ts b/testing/mock.ts index 48311a698a65..59c1d97038ff 100644 --- a/testing/mock.ts +++ b/testing/mock.ts @@ -1085,7 +1085,9 @@ export function returnsArg( ): (this: Self, ...args: Arg[]) => Arg { return function (...args: Arg[]): Arg { if (!(idx in args)) { - throw new TypeError(""); + throw new TypeError( + `Could not get argument at ${idx} as there were only ${args.length} arguments`, + ); } return args[idx]!; }; From 34212a0e19b54b5e168dc6f450b61e4a262c0014 Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 09:27:55 +0000 Subject: [PATCH 08/11] more as const in the mock_test file --- testing/mock_test.ts | 54 ++++++++++++++++++++++++++++---------------- 1 file changed, 34 insertions(+), 20 deletions(-) diff --git a/testing/mock_test.ts b/testing/mock_test.ts index 62d2b51b6fe3..636c19410464 100644 --- a/testing/mock_test.ts +++ b/testing/mock_test.ts @@ -578,21 +578,21 @@ Deno.test("mockSession and mockSessionAsync", async () => { assertEquals(actions.map((action) => action.restored), expected); } await mockSessionAsync(async () => { - actions.push(spy(points[0]!, "action")); + actions.push(spy(points[0], "action")); assertRestored([false]); await mockSessionAsync(async () => { await Promise.resolve(); - actions.push(spy(points[1]!, "action")); + actions.push(spy(points[1], "action")); assertRestored([false, false]); mockSession(() => { - actions.push(spy(points[2]!, "action")); - actions.push(spy(points[3]!, "action")); + actions.push(spy(points[2], "action")); + actions.push(spy(points[3], "action")); assertRestored([false, false, false, false]); })(); - actions.push(spy(points[4]!, "action")); + actions.push(spy(points[4], "action")); assertRestored([false, false, true, true, false]); })(); - actions.push(spy(points[5]!, "action")); + actions.push(spy(points[5], "action")); assertRestored([false, true, true, true, true, false]); })(); assertRestored(Array(6).fill(true)); @@ -610,7 +610,14 @@ Deno.test("mockSession and mockSessionAsync", async () => { }); Deno.test("mockSession and restore current session", () => { - const points = Array(6).fill(undefined).map(() => new Point(2, 3)); + const points = [ + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + ] as const; let actions: Spy[]; function assertRestored(expected: boolean[]) { assertEquals(actions.map((action) => action.restored), expected); @@ -626,24 +633,24 @@ Deno.test("mockSession and restore current session", () => { actions = []; try { - actions.push(spy(points[0]!, "action")); + actions.push(spy(points[0], "action")); try { mockSession(); - actions.push(spy(points[1]!, "action")); + actions.push(spy(points[1], "action")); try { mockSession(); - actions.push(spy(points[2]!, "action")); - actions.push(spy(points[3]!, "action")); + actions.push(spy(points[2], "action")); + actions.push(spy(points[3], "action")); } finally { assertRestored([false, false, false, false]); restore(); } - actions.push(spy(points[4]!, "action")); + actions.push(spy(points[4], "action")); } finally { assertRestored([false, false, true, true, false]); restore(); } - actions.push(spy(points[5]!, "action")); + actions.push(spy(points[5], "action")); } finally { assertRestored([false, true, true, true, true, false]); restore(); @@ -664,7 +671,14 @@ Deno.test("mockSession and restore current session", () => { }); Deno.test("mockSession and restore multiple sessions", () => { - const points = Array(6).fill(undefined).map(() => new Point(2, 3)); + const points = [ + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + new Point(2, 3), + ] as const; let actions: Spy[]; function assertRestored(expected: boolean[]) { assertEquals(actions.map((action) => action.restored), expected); @@ -672,19 +686,19 @@ Deno.test("mockSession and restore multiple sessions", () => { try { actions = []; try { - actions.push(spy(points[0]!, "action")); + actions.push(spy(points[0], "action")); const id = mockSession(); try { - actions.push(spy(points[1]!, "action")); - actions.push(spy(points[2]!, "action")); + actions.push(spy(points[1], "action")); + actions.push(spy(points[2], "action")); mockSession(); - actions.push(spy(points[3]!, "action")); - actions.push(spy(points[4]!, "action")); + actions.push(spy(points[3], "action")); + actions.push(spy(points[4], "action")); } finally { assertRestored([false, false, false, false, false]); restore(id); } - actions.push(spy(points[5]!, "action")); + actions.push(spy(points[5], "action")); } finally { assertRestored([false, true, true, true, true, false]); restore(); From 44182f84d85bc0ea1e9ae52842c721956fbabe26 Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 10:12:10 +0000 Subject: [PATCH 09/11] fix tests for new behaviour --- testing/mock_test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/testing/mock_test.ts b/testing/mock_test.ts index 636c19410464..f0efcb4660b2 100644 --- a/testing/mock_test.ts +++ b/testing/mock_test.ts @@ -1782,12 +1782,12 @@ Deno.test("returnsThis", () => { Deno.test("returnsArg", () => { let callback = returnsArg(0); - assertEquals(callback(), undefined); + assertThrows(() => callback()); assertEquals(callback("a"), "a"); assertEquals(callback("b", "c"), "b"); callback = returnsArg(1); - assertEquals(callback(), undefined); - assertEquals(callback("a"), undefined); + assertThrows(() => callback()); + assertThrows(() => callback("a")); assertEquals(callback("b", "c"), "c"); assertEquals(callback("d", "e", "f"), "e"); }); From 06f22594df6365a76128af8bedd199b4b1f22b3f Mon Sep 17 00:00:00 2001 From: Asher Gomez Date: Thu, 4 Jan 2024 22:15:15 +1100 Subject: [PATCH 10/11] tweak --- testing/bdd_test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/bdd_test.ts b/testing/bdd_test.ts index 125a7d872651..c3a27530bec5 100644 --- a/testing/bdd_test.ts +++ b/testing/bdd_test.ts @@ -1633,7 +1633,7 @@ Deno.test("global", async (t) => { "nested", async () => { const test = stub(Deno, "test"); - const fns = [spy(), spy()] as readonly [Spy, Spy]; + const fns = [spy(), spy()] as const; const { beforeAllFn, afterAllFn, beforeEachFn, afterEachFn } = hookFns(); From 76dc2eab84c9b0c4bbcb75a73af3b7a24db6c368 Mon Sep 17 00:00:00 2001 From: Simon Holloway Date: Thu, 4 Jan 2024 13:13:03 +0000 Subject: [PATCH 11/11] revert returnsArg handling back to `| undefined` --- testing/mock.ts | 11 +++-------- testing/mock_test.ts | 6 +++--- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/testing/mock.ts b/testing/mock.ts index 59c1d97038ff..06c6ba56140a 100644 --- a/testing/mock.ts +++ b/testing/mock.ts @@ -1082,14 +1082,9 @@ export function returnsThis< // deno-lint-ignore no-explicit-any export function returnsArg( idx: number, -): (this: Self, ...args: Arg[]) => Arg { - return function (...args: Arg[]): Arg { - if (!(idx in args)) { - throw new TypeError( - `Could not get argument at ${idx} as there were only ${args.length} arguments`, - ); - } - return args[idx]!; +): (this: Self, ...args: Arg[]) => Arg | undefined { + return function (...args: Arg[]): Arg | undefined { + return args[idx]; }; } diff --git a/testing/mock_test.ts b/testing/mock_test.ts index f0efcb4660b2..636c19410464 100644 --- a/testing/mock_test.ts +++ b/testing/mock_test.ts @@ -1782,12 +1782,12 @@ Deno.test("returnsThis", () => { Deno.test("returnsArg", () => { let callback = returnsArg(0); - assertThrows(() => callback()); + assertEquals(callback(), undefined); assertEquals(callback("a"), "a"); assertEquals(callback("b", "c"), "b"); callback = returnsArg(1); - assertThrows(() => callback()); - assertThrows(() => callback("a")); + assertEquals(callback(), undefined); + assertEquals(callback("a"), undefined); assertEquals(callback("b", "c"), "c"); assertEquals(callback("d", "e", "f"), "e"); });