Skip to content

Commit

Permalink
Merge pull request #120 from jsr-core/improve-tests
Browse files Browse the repository at this point in the history
test: add proper test cases
  • Loading branch information
lambdalisue authored Aug 13, 2024
2 parents 123572a + 20a84c2 commit 0981e0d
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 5 deletions.
2 changes: 2 additions & 0 deletions _testutil.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends
export function stringify(x: unknown): string {
if (x instanceof Date) return `Date(${x.valueOf()})`;
if (x instanceof Promise) return "Promise";
if (x instanceof Set) return `Set(${stringify([...x.values()])})`;
if (x instanceof Map) return `Map(${stringify([...x.entries()])})`;
if (typeof x === "function") return x.toString();
if (typeof x === "bigint") return `${x}n`;
if (typeof x === "symbol") return x.toString();
Expand Down
23 changes: 22 additions & 1 deletion as/optional_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { assertEquals } from "@std/assert";
import { assertType } from "@std/testing/types";
import { type Equal, testWithExamples } from "../_testutil.ts";
import { is } from "../is/mod.ts";
import { asOptional, asUnoptional } from "./optional.ts";
import type { AsOptional } from "../_annotation.ts";
import { asOptional, asUnoptional, hasOptional } from "./optional.ts";

Deno.test("asOptional<T>", async (t) => {
await t.step("returns a property named predicate function", () => {
Expand Down Expand Up @@ -153,3 +154,23 @@ Deno.test("asUnoptional<T>", async (t) => {
});
});
});

Deno.test("hasOptional<P>", async (t) => {
await t.step("returns true on AsOptional<T> predicate", () => {
const pred = asOptional(is.Number);
assertEquals(hasOptional(pred), true);
});

await t.step("returns true on non AsOptional<T> predicate", () => {
const pred = is.Number;
assertEquals(hasOptional(pred), false);
});

await t.step("predicated type is correct", () => {
const pred = asOptional(is.Number);
type P = typeof pred;
if (hasOptional(pred)) {
assertType<Equal<typeof pred, P & AsOptional<number>>>(true);
}
});
});
23 changes: 22 additions & 1 deletion as/readonly_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import { assertEquals } from "@std/assert";
import { assertType } from "@std/testing/types";
import { type Equal, testWithExamples } from "../_testutil.ts";
import { is } from "../is/mod.ts";
import { asReadonly, asUnreadonly } from "./readonly.ts";
import type { AsReadonly } from "../_annotation.ts";
import { asReadonly, asUnreadonly, hasReadonly } from "./readonly.ts";

Deno.test("asReadonly<T>", async (t) => {
await t.step("returns a property named predicate function", () => {
Expand Down Expand Up @@ -155,3 +156,23 @@ Deno.test("asUnreadonly<T>", async (t) => {
});
});
});

Deno.test("hasReadonly<P>", async (t) => {
await t.step("returns true on AsReadonly<T> predicate", () => {
const pred = asReadonly(is.Number);
assertEquals(hasReadonly(pred), true);
});

await t.step("returns true on non AsReadonly<T> predicate", () => {
const pred = is.Number;
assertEquals(hasReadonly(pred), false);
});

await t.step("predicated type is correct", () => {
const pred = asReadonly(is.Number);
type P = typeof pred;
if (hasReadonly(pred)) {
assertType<Equal<typeof pred, P & AsReadonly>>(true);
}
});
});
11 changes: 11 additions & 0 deletions assert_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ Deno.test("assert", async (t) => {
);
});

await t.step(
"throws an `AssertError` on false predicate with an anonymous predicate",
() => {
assertThrows(
() => assert(x, (_x: unknown): _x is string => false),
AssertError,
`Expected a value that satisfies the predicate anonymous predicate, got symbol: undefined`,
);
},
);

await t.step(
"throws an `AssertError` on false predicate with a custom name",
() => {
Expand Down
33 changes: 30 additions & 3 deletions is/parameters_of_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,13 @@ Deno.test("isParametersOf<T>", async (t) => {
const predTup = [is.Number, is.String, as.Optional(is.Boolean)] as const;
assertEquals(isParametersOf(predTup)([0, "a", true]), true);
assertEquals(isParametersOf(predTup)([0, "a"]), true);
assertEquals(isParametersOf(predTup)([0, "a", undefined]), true);
});

await t.step("returns false on non T tuple", () => {
const predTup = [is.Number, is.String, as.Optional(is.Boolean)] as const;
assertEquals(isParametersOf(predTup)([0, 1, 2]), false);
assertEquals(isParametersOf(predTup)([0]), false);
assertEquals(isParametersOf(predTup)([0, "a", true, 0]), false);
});

Expand Down Expand Up @@ -107,17 +109,42 @@ Deno.test("isParametersOf<T, R>", async (t) => {
await t.step("returns false on non T tuple", () => {
const predTup = [is.Number, is.String, as.Optional(is.Boolean)] as const;
const predRest = is.ArrayOf(is.String);
assertEquals(isParametersOf(predTup, predRest)([0, 1, 2, 0, 1, 2]), false);
assertEquals(isParametersOf(predTup, predRest)([0, "a", 0, 1, 2]), false);
assertEquals(isParametersOf(predTup, predRest)("a"), false, "Not an array");
assertEquals(
isParametersOf(predTup, predRest)([0]),
false,
"Less than `predTup.length` - optional-count",
);
assertEquals(
isParametersOf(predTup, predRest)([0, 1, 2]),
false,
"Not match `predTup` and no rest elements",
);
assertEquals(
isParametersOf(predTup, predRest)([0, 1, 2, 0, 1, 2]),
false,
"Not match `predTup` and `predRest`",
);
assertEquals(
isParametersOf(predTup, predRest)([0, "a", true, 0, 1, 2]),
false,
"Match `predTup` but not match `predRest`",
);
assertEquals(
isParametersOf(predTup, predRest)([0, "a", undefined, 0, 1, 2]),
false,
"Match `predTup` but not match `predRest`",
);
assertEquals(
isParametersOf(predTup, predRest)([0, "a", "b", "a", "b", "c"]),
false,
"Match `predRest` but not match `predTup`",
);
assertEquals(
isParametersOf(predTup, predRest)([0, "a", "a", "b", "c"]),
false,
"Match `predRest` but no optional parameters",
);
assertEquals(isParametersOf(predTup, predRest)([0, "a", "b"]), false);
});

await t.step("predicated type is correct", () => {
Expand Down
11 changes: 11 additions & 0 deletions is/record_object_of_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Deno.test("isRecordObjectOf<T>", async (t) => {
});

await t.step("returns false on non T record", () => {
assertEquals(isRecordObjectOf(is.String)("a"), false, "Not a Record");
assertEquals(isRecordObjectOf(is.String)({ a: 0 }), false);
assertEquals(isRecordObjectOf(is.Number)({ a: "a" }), false);
assertEquals(isRecordObjectOf(is.String)({ a: true }), false);
Expand Down Expand Up @@ -91,6 +92,11 @@ Deno.test("isRecordObjectOf<T, K>", async (t) => {
});

await t.step("returns false on non K record", () => {
assertEquals(
isRecordObjectOf(is.String, is.String)("a"),
false,
"Not a Record",
);
assertEquals(isRecordObjectOf(is.Number, is.Number)({ a: 0 }), false);
assertEquals(isRecordObjectOf(is.String, is.Number)({ a: "a" }), false);
assertEquals(isRecordObjectOf(is.Boolean, is.Number)({ a: true }), false);
Expand Down Expand Up @@ -161,6 +167,11 @@ Deno.test("isRecordObjectOf<T, K>", async (t) => {
});

await t.step("returns false on non T record", () => {
assertEquals(
isRecordObjectOf(is.String, is.Symbol)("a"),
false,
"Not a Record",
);
assertEquals(isRecordObjectOf(is.String, is.Symbol)({ [a]: 0 }), false);
assertEquals(isRecordObjectOf(is.Number, is.Symbol)({ [a]: "a" }), false);
assertEquals(
Expand Down
7 changes: 7 additions & 0 deletions is/record_of_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Deno.test("isRecordOf<T>", async (t) => {
});

await t.step("returns false on non T record", () => {
assertEquals(isRecordOf(is.String)("a"), false, "Not a Record");
assertEquals(isRecordOf(is.String)({ a: 0 }), false);
assertEquals(isRecordOf(is.Number)({ a: "a" }), false);
assertEquals(isRecordOf(is.String)({ a: true }), false);
Expand Down Expand Up @@ -85,6 +86,7 @@ Deno.test("isRecordOf<T, K>", async (t) => {
});

await t.step("returns false on non T record", () => {
assertEquals(isRecordOf(is.String, is.String)("a"), false, "Not a Record");
assertEquals(isRecordOf(is.String, is.String)({ a: 0 }), false);
assertEquals(isRecordOf(is.Number, is.String)({ a: "a" }), false);
assertEquals(isRecordOf(is.String, is.String)({ a: true }), false);
Expand Down Expand Up @@ -158,6 +160,11 @@ Deno.test("isRecordOf<T, K>", async (t) => {
});

await t.step("returns false on non T record", () => {
assertEquals(
isRecordOf(is.String, is.Symbol)("a"),
false,
"Not a Record",
);
assertEquals(isRecordOf(is.String, is.Symbol)({ [a]: 0 }), false);
assertEquals(isRecordOf(is.Number, is.Symbol)({ [a]: "a" }), false);
assertEquals(isRecordOf(is.String, is.Symbol)({ [a]: true }), false);
Expand Down
1 change: 1 addition & 0 deletions is/set_of_test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ Deno.test("isSetOf<T>", async (t) => {
});

await t.step("returns false on non T set", () => {
assertEquals(isSetOf(is.String)("a"), false, "Not a Set");
assertEquals(isSetOf(is.String)(new Set([0, 1, 2])), false);
assertEquals(isSetOf(is.Number)(new Set(["a", "b", "c"])), false);
assertEquals(isSetOf(is.String)(new Set([true, false, true])), false);
Expand Down

0 comments on commit 0981e0d

Please sign in to comment.