Skip to content

Commit 4750817

Browse files
authored
Merge pull request #23 from lambdalisue/imp-tests
🌿 Improve tests of `is` module
2 parents 3cd5ff5 + 63ab076 commit 4750817

File tree

1 file changed

+95
-168
lines changed

1 file changed

+95
-168
lines changed

is_test.ts

Lines changed: 95 additions & 168 deletions
Original file line numberDiff line numberDiff line change
@@ -17,95 +17,66 @@ import is, {
1717
isString,
1818
isTupleOf,
1919
isUndefined,
20+
Predicate,
2021
} from "./is.ts";
2122

22-
Deno.test("is defines aliases of functions", () => {
23-
assertStrictEquals(is.String, isString);
24-
assertStrictEquals(is.Number, isNumber);
25-
assertStrictEquals(is.Boolean, isBoolean);
26-
assertStrictEquals(is.Array, isArray);
27-
assertStrictEquals(is.ArrayOf, isArrayOf);
28-
assertStrictEquals(is.TupleOf, isTupleOf);
29-
assertStrictEquals(is.Record, isRecord);
30-
assertStrictEquals(is.RecordOf, isRecordOf);
31-
assertStrictEquals(is.ObjectOf, isObjectOf);
32-
assertStrictEquals(is.Function, isFunction);
33-
assertStrictEquals(is.Null, isNull);
34-
assertStrictEquals(is.Undefined, isUndefined);
35-
assertStrictEquals(is.Nullish, isNullish);
36-
assertStrictEquals(is.OneOf, isOneOf);
37-
});
23+
const examples = {
24+
string: ["", "Hello world"],
25+
number: [0, 1234567890],
26+
boolean: [true, false],
27+
array: [[], [0, 1, 2], ["a", "b", "c"], [0, "a", true]],
28+
record: [{}, { a: 0, b: 1, c: 2 }, { a: "a", b: "b", c: "c" }],
29+
function: [function () {}],
30+
null: [null],
31+
undefined: [undefined],
32+
};
33+
34+
function stringify(x: unknown): string {
35+
if (typeof x === "function") return x.toString();
36+
return JSON.stringify(x);
37+
}
38+
39+
async function testWithExamples<T>(
40+
t: Deno.TestContext,
41+
pred: Predicate<T>,
42+
validExamples: (keyof typeof examples)[],
43+
): Promise<void> {
44+
for (const [name, example] of Object.entries(examples)) {
45+
const expect = validExamples.includes(name as keyof typeof examples);
46+
for (const v of example) {
47+
await t.step(
48+
`returns ${expect} on ${stringify(v)}`,
49+
() => {
50+
assertEquals(pred(v), expect);
51+
},
52+
);
53+
}
54+
}
55+
}
3856

3957
Deno.test("isString", async (t) => {
40-
await t.step("returns true on array", () => {
41-
assertEquals(isString(""), true);
42-
assertEquals(isString("Hello World"), true);
43-
});
44-
await t.step("returns false on non array", () => {
45-
assertEquals(isString(0), false);
46-
assertEquals(isString(true), false);
47-
assertEquals(isString(false), false);
48-
assertEquals(isString([]), false);
49-
assertEquals(isString({}), false);
50-
assertEquals(isString(function () {}), false);
51-
assertEquals(isString(null), false);
52-
assertEquals(isString(undefined), false);
53-
});
58+
await testWithExamples(t, isString, ["string"]);
5459
});
5560

5661
Deno.test("isNumber", async (t) => {
57-
await t.step("returns true on array", () => {
58-
assertEquals(isNumber(0), true);
59-
assertEquals(isNumber(1234567890), true);
60-
});
61-
await t.step("returns false on non array", () => {
62-
assertEquals(isNumber(""), false);
63-
assertEquals(isNumber(true), false);
64-
assertEquals(isNumber(false), false);
65-
assertEquals(isNumber([]), false);
66-
assertEquals(isNumber({}), false);
67-
assertEquals(isNumber(function () {}), false);
68-
assertEquals(isNumber(null), false);
69-
assertEquals(isNumber(undefined), false);
70-
});
62+
await testWithExamples(t, isNumber, ["number"]);
7163
});
7264

7365
Deno.test("isBoolean", async (t) => {
74-
await t.step("returns true on boolean", () => {
75-
assertEquals(isBoolean(true), true);
76-
assertEquals(isBoolean(false), true);
77-
});
78-
await t.step("returns false on non boolean", () => {
79-
assertEquals(isBoolean(0), false);
80-
assertEquals(isBoolean(""), false);
81-
assertEquals(isBoolean([]), false);
82-
assertEquals(isBoolean({}), false);
83-
assertEquals(isBoolean(function () {}), false);
84-
assertEquals(isBoolean(null), false);
85-
assertEquals(isBoolean(undefined), false);
86-
});
66+
await testWithExamples(t, isBoolean, ["boolean"]);
8767
});
8868

8969
Deno.test("isArray", async (t) => {
90-
await t.step("returns true on array", () => {
91-
assertEquals(isArray([]), true);
92-
assertEquals(isArray([0, 1, 2]), true);
93-
assertEquals(isArray(["a", "b", "c"]), true);
94-
assertEquals(isArray([0, "a", 1]), true);
95-
});
96-
await t.step("returns false on non array", () => {
97-
assertEquals(isArray(""), false);
98-
assertEquals(isArray(0), false);
99-
assertEquals(isArray(true), false);
100-
assertEquals(isArray(false), false);
101-
assertEquals(isArray({}), false);
102-
assertEquals(isArray(function () {}), false);
103-
assertEquals(isArray(null), false);
104-
assertEquals(isArray(undefined), false);
105-
});
70+
await testWithExamples(t, isArray, ["array"]);
10671
});
10772

10873
Deno.test("isArrayOf<T>", async (t) => {
74+
await t.step("returns proper type predicate", () => {
75+
const a: unknown = [0, 1, 2];
76+
if (isArrayOf(isNumber)(a)) {
77+
const _: number[] = a;
78+
}
79+
});
10980
await t.step("returns true on T array", () => {
11081
assertEquals(isArrayOf(isNumber)([0, 1, 2]), true);
11182
assertEquals(isArrayOf(isString)(["a", "b", "c"]), true);
@@ -119,6 +90,13 @@ Deno.test("isArrayOf<T>", async (t) => {
11990
});
12091

12192
Deno.test("isTupleOf<T>", async (t) => {
93+
await t.step("returns proper type predicate", () => {
94+
const predTup = [isNumber, isString, isBoolean] as const;
95+
const a: unknown = [0, "a", true];
96+
if (isTupleOf(predTup)(a)) {
97+
const _: [number, string, boolean] = a;
98+
}
99+
});
122100
await t.step("returns true on T tuple", () => {
123101
const predTup = [isNumber, isString, isBoolean] as const;
124102
assertEquals(isTupleOf(predTup)([0, "a", true]), true);
@@ -129,34 +107,19 @@ Deno.test("isTupleOf<T>", async (t) => {
129107
assertEquals(isTupleOf(predTup)([0, "a"]), false);
130108
assertEquals(isTupleOf(predTup)([0, "a", true, 0]), false);
131109
});
132-
await t.step("returns proper type predicate", () => {
133-
const predTup = [isNumber, isString, isBoolean] as const;
134-
const a: unknown = [0, "a", true];
135-
if (isTupleOf(predTup)(a)) {
136-
const _: [number, string, boolean] = a;
137-
}
138-
});
139110
});
140111

141112
Deno.test("isRecord", async (t) => {
142-
await t.step("returns true on record", () => {
143-
assertEquals(isRecord({}), true);
144-
assertEquals(isRecord({ a: 0 }), true);
145-
assertEquals(isRecord({ a: "a" }), true);
146-
});
147-
await t.step("returns false on non record", () => {
148-
assertEquals(isRecord(""), false);
149-
assertEquals(isRecord(0), false);
150-
assertEquals(isRecord(true), false);
151-
assertEquals(isRecord(false), false);
152-
assertEquals(isRecord([]), false);
153-
assertEquals(isRecord(function () {}), false);
154-
assertEquals(isRecord(null), false);
155-
assertEquals(isRecord(undefined), false);
156-
});
113+
await testWithExamples(t, isRecord, ["record"]);
157114
});
158115

159116
Deno.test("isRecordOf<T>", async (t) => {
117+
await t.step("returns proper type predicate", () => {
118+
const a: unknown = { a: 0 };
119+
if (isRecordOf(isNumber)(a)) {
120+
const _: Record<string | number | symbol, number> = a;
121+
}
122+
});
160123
await t.step("returns true on T record", () => {
161124
assertEquals(isRecordOf(isNumber)({ a: 0 }), true);
162125
assertEquals(isRecordOf(isString)({ a: "a" }), true);
@@ -170,6 +133,17 @@ Deno.test("isRecordOf<T>", async (t) => {
170133
});
171134

172135
Deno.test("isObjectOf<T>", async (t) => {
136+
await t.step("returns proper type predicate", () => {
137+
const predObj = {
138+
a: isNumber,
139+
b: isString,
140+
c: isBoolean,
141+
};
142+
const a: unknown = { a: 0, b: "a", c: true };
143+
if (isObjectOf(predObj)(a)) {
144+
const _: { a: number; b: string; c: boolean } = a;
145+
}
146+
});
173147
await t.step("returns true on T object", () => {
174148
const predObj = {
175149
a: isNumber,
@@ -200,87 +174,32 @@ Deno.test("isObjectOf<T>", async (t) => {
200174
false,
201175
);
202176
});
203-
await t.step("returns proper type predicate", () => {
204-
const predObj = {
205-
a: isNumber,
206-
b: isString,
207-
c: isBoolean,
208-
};
209-
const a: unknown = { a: 0, b: "a", c: true };
210-
if (isObjectOf(predObj)(a)) {
211-
const _: { a: number; b: string; c: boolean } = a;
212-
}
213-
});
214177
});
215178

216179
Deno.test("isFunction", async (t) => {
217-
await t.step("returns true on function", () => {
218-
assertEquals(isFunction(isFunction), true);
219-
assertEquals(isFunction(function () {}), true);
220-
assertEquals(isFunction(() => {}), true);
221-
assertEquals(isFunction(setTimeout), true);
222-
});
223-
await t.step("returns false on non function", () => {
224-
assertEquals(isFunction(""), false);
225-
assertEquals(isFunction(0), false);
226-
assertEquals(isFunction(true), false);
227-
assertEquals(isFunction(false), false);
228-
assertEquals(isFunction([]), false);
229-
assertEquals(isFunction({}), false);
230-
assertEquals(isFunction(null), false);
231-
assertEquals(isFunction(undefined), false);
232-
});
180+
await testWithExamples(t, isFunction, ["function"]);
233181
});
234182

235183
Deno.test("isNull", async (t) => {
236-
await t.step("returns true on null", () => {
237-
assertEquals(isNull(null), true);
238-
});
239-
await t.step("returns false on non null", () => {
240-
assertEquals(isNull(""), false);
241-
assertEquals(isNull(0), false);
242-
assertEquals(isNull(true), false);
243-
assertEquals(isNull(false), false);
244-
assertEquals(isNull([]), false);
245-
assertEquals(isNull({}), false);
246-
assertEquals(isNull(function () {}), false);
247-
assertEquals(isNull(undefined), false);
248-
});
184+
await testWithExamples(t, isNull, ["null"]);
249185
});
250186

251187
Deno.test("isUndefined", async (t) => {
252-
await t.step("returns true on null", () => {
253-
assertEquals(isUndefined(undefined), true);
254-
});
255-
await t.step("returns false on non null", () => {
256-
assertEquals(isUndefined(""), false);
257-
assertEquals(isUndefined(0), false);
258-
assertEquals(isUndefined(true), false);
259-
assertEquals(isUndefined(false), false);
260-
assertEquals(isUndefined([]), false);
261-
assertEquals(isUndefined({}), false);
262-
assertEquals(isUndefined(function () {}), false);
263-
assertEquals(isUndefined(null), false);
264-
});
188+
await testWithExamples(t, isUndefined, ["undefined"]);
265189
});
266190

267191
Deno.test("isNullish", async (t) => {
268-
await t.step("returns true on null/undefined", () => {
269-
assertEquals(isNullish(null), true);
270-
assertEquals(isNullish(undefined), true);
271-
});
272-
await t.step("returns false on non null/undefined", () => {
273-
assertEquals(isNullish(""), false);
274-
assertEquals(isNullish(0), false);
275-
assertEquals(isNullish(true), false);
276-
assertEquals(isNullish(false), false);
277-
assertEquals(isNullish([]), false);
278-
assertEquals(isNullish({}), false);
279-
assertEquals(isNullish(function () {}), false);
280-
});
192+
await testWithExamples(t, isNullish, ["null", "undefined"]);
281193
});
282194

283195
Deno.test("isOneOf<T>", async (t) => {
196+
await t.step("returns proper type predicate", () => {
197+
const preds = [isNumber, isString, isBoolean];
198+
const a: unknown = [0, "a", true];
199+
if (isOneOf(preds)(a)) {
200+
const _: number | string | boolean = a;
201+
}
202+
});
284203
await t.step("returns true on one of T", () => {
285204
const preds = [isNumber, isString, isBoolean];
286205
assertEquals(isOneOf(preds)(0), true);
@@ -295,11 +214,19 @@ Deno.test("isOneOf<T>", async (t) => {
295214
assertEquals(isOneOf(preds)(null), false);
296215
assertEquals(isOneOf(preds)(undefined), false);
297216
});
298-
await t.step("returns proper type predicate", () => {
299-
const preds = [isNumber, isString, isBoolean];
300-
const a: unknown = [0, "a", true];
301-
if (isOneOf(preds)(a)) {
302-
const _: number | string | boolean = a;
303-
}
304-
});
217+
});
218+
219+
Deno.test("is defines aliases of functions", async () => {
220+
const mod = await import("./is.ts");
221+
const cases = Object.entries(mod)
222+
.filter(([k, _]) => k.startsWith("is"))
223+
.map(([k, v]) => [k.slice(2), v] as const);
224+
for (const [alias, fn] of cases) {
225+
assertStrictEquals(is[alias as keyof typeof is], fn);
226+
}
227+
assertEquals(
228+
Object.keys(is).length,
229+
cases.length,
230+
"The number of entries in `is` is not equal to `is*` functions",
231+
);
305232
});

0 commit comments

Comments
 (0)