Skip to content

Commit 0981e0d

Browse files
authored
Merge pull request #120 from jsr-core/improve-tests
test: add proper test cases
2 parents 123572a + 20a84c2 commit 0981e0d

File tree

8 files changed

+106
-5
lines changed

8 files changed

+106
-5
lines changed

_testutil.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ export type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends
5757
export function stringify(x: unknown): string {
5858
if (x instanceof Date) return `Date(${x.valueOf()})`;
5959
if (x instanceof Promise) return "Promise";
60+
if (x instanceof Set) return `Set(${stringify([...x.values()])})`;
61+
if (x instanceof Map) return `Map(${stringify([...x.entries()])})`;
6062
if (typeof x === "function") return x.toString();
6163
if (typeof x === "bigint") return `${x}n`;
6264
if (typeof x === "symbol") return x.toString();

as/optional_test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { assertEquals } from "@std/assert";
22
import { assertType } from "@std/testing/types";
33
import { type Equal, testWithExamples } from "../_testutil.ts";
44
import { is } from "../is/mod.ts";
5-
import { asOptional, asUnoptional } from "./optional.ts";
5+
import type { AsOptional } from "../_annotation.ts";
6+
import { asOptional, asUnoptional, hasOptional } from "./optional.ts";
67

78
Deno.test("asOptional<T>", async (t) => {
89
await t.step("returns a property named predicate function", () => {
@@ -153,3 +154,23 @@ Deno.test("asUnoptional<T>", async (t) => {
153154
});
154155
});
155156
});
157+
158+
Deno.test("hasOptional<P>", async (t) => {
159+
await t.step("returns true on AsOptional<T> predicate", () => {
160+
const pred = asOptional(is.Number);
161+
assertEquals(hasOptional(pred), true);
162+
});
163+
164+
await t.step("returns true on non AsOptional<T> predicate", () => {
165+
const pred = is.Number;
166+
assertEquals(hasOptional(pred), false);
167+
});
168+
169+
await t.step("predicated type is correct", () => {
170+
const pred = asOptional(is.Number);
171+
type P = typeof pred;
172+
if (hasOptional(pred)) {
173+
assertType<Equal<typeof pred, P & AsOptional<number>>>(true);
174+
}
175+
});
176+
});

as/readonly_test.ts

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import { assertEquals } from "@std/assert";
22
import { assertType } from "@std/testing/types";
33
import { type Equal, testWithExamples } from "../_testutil.ts";
44
import { is } from "../is/mod.ts";
5-
import { asReadonly, asUnreadonly } from "./readonly.ts";
5+
import type { AsReadonly } from "../_annotation.ts";
6+
import { asReadonly, asUnreadonly, hasReadonly } from "./readonly.ts";
67

78
Deno.test("asReadonly<T>", async (t) => {
89
await t.step("returns a property named predicate function", () => {
@@ -155,3 +156,23 @@ Deno.test("asUnreadonly<T>", async (t) => {
155156
});
156157
});
157158
});
159+
160+
Deno.test("hasReadonly<P>", async (t) => {
161+
await t.step("returns true on AsReadonly<T> predicate", () => {
162+
const pred = asReadonly(is.Number);
163+
assertEquals(hasReadonly(pred), true);
164+
});
165+
166+
await t.step("returns true on non AsReadonly<T> predicate", () => {
167+
const pred = is.Number;
168+
assertEquals(hasReadonly(pred), false);
169+
});
170+
171+
await t.step("predicated type is correct", () => {
172+
const pred = asReadonly(is.Number);
173+
type P = typeof pred;
174+
if (hasReadonly(pred)) {
175+
assertType<Equal<typeof pred, P & AsReadonly>>(true);
176+
}
177+
});
178+
});

assert_test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,17 @@ Deno.test("assert", async (t) => {
2929
);
3030
});
3131

32+
await t.step(
33+
"throws an `AssertError` on false predicate with an anonymous predicate",
34+
() => {
35+
assertThrows(
36+
() => assert(x, (_x: unknown): _x is string => false),
37+
AssertError,
38+
`Expected a value that satisfies the predicate anonymous predicate, got symbol: undefined`,
39+
);
40+
},
41+
);
42+
3243
await t.step(
3344
"throws an `AssertError` on false predicate with a custom name",
3445
() => {

is/parameters_of_test.ts

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,13 @@ Deno.test("isParametersOf<T>", async (t) => {
3535
const predTup = [is.Number, is.String, as.Optional(is.Boolean)] as const;
3636
assertEquals(isParametersOf(predTup)([0, "a", true]), true);
3737
assertEquals(isParametersOf(predTup)([0, "a"]), true);
38+
assertEquals(isParametersOf(predTup)([0, "a", undefined]), true);
3839
});
3940

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

@@ -107,17 +109,42 @@ Deno.test("isParametersOf<T, R>", async (t) => {
107109
await t.step("returns false on non T tuple", () => {
108110
const predTup = [is.Number, is.String, as.Optional(is.Boolean)] as const;
109111
const predRest = is.ArrayOf(is.String);
110-
assertEquals(isParametersOf(predTup, predRest)([0, 1, 2, 0, 1, 2]), false);
111-
assertEquals(isParametersOf(predTup, predRest)([0, "a", 0, 1, 2]), false);
112+
assertEquals(isParametersOf(predTup, predRest)("a"), false, "Not an array");
113+
assertEquals(
114+
isParametersOf(predTup, predRest)([0]),
115+
false,
116+
"Less than `predTup.length` - optional-count",
117+
);
118+
assertEquals(
119+
isParametersOf(predTup, predRest)([0, 1, 2]),
120+
false,
121+
"Not match `predTup` and no rest elements",
122+
);
123+
assertEquals(
124+
isParametersOf(predTup, predRest)([0, 1, 2, 0, 1, 2]),
125+
false,
126+
"Not match `predTup` and `predRest`",
127+
);
112128
assertEquals(
113129
isParametersOf(predTup, predRest)([0, "a", true, 0, 1, 2]),
114130
false,
131+
"Match `predTup` but not match `predRest`",
115132
);
116133
assertEquals(
117134
isParametersOf(predTup, predRest)([0, "a", undefined, 0, 1, 2]),
118135
false,
136+
"Match `predTup` but not match `predRest`",
137+
);
138+
assertEquals(
139+
isParametersOf(predTup, predRest)([0, "a", "b", "a", "b", "c"]),
140+
false,
141+
"Match `predRest` but not match `predTup`",
142+
);
143+
assertEquals(
144+
isParametersOf(predTup, predRest)([0, "a", "a", "b", "c"]),
145+
false,
146+
"Match `predRest` but no optional parameters",
119147
);
120-
assertEquals(isParametersOf(predTup, predRest)([0, "a", "b"]), false);
121148
});
122149

123150
await t.step("predicated type is correct", () => {

is/record_object_of_test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Deno.test("isRecordObjectOf<T>", async (t) => {
1818
});
1919

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

9394
await t.step("returns false on non K record", () => {
95+
assertEquals(
96+
isRecordObjectOf(is.String, is.String)("a"),
97+
false,
98+
"Not a Record",
99+
);
94100
assertEquals(isRecordObjectOf(is.Number, is.Number)({ a: 0 }), false);
95101
assertEquals(isRecordObjectOf(is.String, is.Number)({ a: "a" }), false);
96102
assertEquals(isRecordObjectOf(is.Boolean, is.Number)({ a: true }), false);
@@ -161,6 +167,11 @@ Deno.test("isRecordObjectOf<T, K>", async (t) => {
161167
});
162168

163169
await t.step("returns false on non T record", () => {
170+
assertEquals(
171+
isRecordObjectOf(is.String, is.Symbol)("a"),
172+
false,
173+
"Not a Record",
174+
);
164175
assertEquals(isRecordObjectOf(is.String, is.Symbol)({ [a]: 0 }), false);
165176
assertEquals(isRecordObjectOf(is.Number, is.Symbol)({ [a]: "a" }), false);
166177
assertEquals(

is/record_of_test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Deno.test("isRecordOf<T>", async (t) => {
1818
});
1919

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

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

160162
await t.step("returns false on non T record", () => {
163+
assertEquals(
164+
isRecordOf(is.String, is.Symbol)("a"),
165+
false,
166+
"Not a Record",
167+
);
161168
assertEquals(isRecordOf(is.String, is.Symbol)({ [a]: 0 }), false);
162169
assertEquals(isRecordOf(is.Number, is.Symbol)({ [a]: "a" }), false);
163170
assertEquals(isRecordOf(is.String, is.Symbol)({ [a]: true }), false);

is/set_of_test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ Deno.test("isSetOf<T>", async (t) => {
1818
});
1919

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

0 commit comments

Comments
 (0)