Skip to content

Commit bb05a44

Browse files
authored
Merge pull request #2 from monaqa/boolean
Support for comparing objects with boolean type in `isLike` function
2 parents 90e9f3f + a36f15b commit bb05a44

File tree

5 files changed

+139
-1
lines changed

5 files changed

+139
-1
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ The `unknownutil` provides the following predicate functions
1616

1717
- `isString(x: unknown): x is string`
1818
- `isNumber(x: unknown): x is number`
19+
- `isBoolean(x: unknown): x is boolean`
1920
- `isArray<T extends unknown>(x: unknown, pred?: Predicate<T>): x is T[]`
2021
- `isObject<T extends unknown>(x: unknown, pred?: Predicate<T>): x is Record<string, T>`
2122
- `isFunction(x: unknown): x is (...args: unknown[]) => unknown`
@@ -93,6 +94,7 @@ The `unknownutil` provides the following ensure functions which will raise
9394

9495
- `ensureString(x: unknown): assert x is string`
9596
- `ensureNumber(x: unknown): assert x is string`
97+
- `ensureBoolean(x: unknown): assert x is boolean`
9698
- `ensureArray<T extends unknown>(x: unknown, pred?: Predicate<T>): assert x is T[]`
9799
- `ensureObject<T extends unknown>(x: unknown, pred?: Predicate<T>): x ensure Record<string, T>`
98100
- `ensureFunction(x: unknown): x ensure (...args: unknown[]) => unknown`

ensure.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
22
isArray,
3+
isBoolean,
34
isFunction,
45
isLike,
56
isNone,
@@ -50,6 +51,13 @@ export function ensureNumber(x: unknown): asserts x is number {
5051
return ensure(x, isNumber, "The value must be number");
5152
}
5253

54+
/**
55+
* Ensure if `x` is boolean by raising an `EnsureError` when it's not.
56+
*/
57+
export function ensureBoolean(x: unknown): asserts x is boolean {
58+
return ensure(x, isBoolean, "The value must be boolean");
59+
}
60+
5361
/**
5462
* Ensure if `x` is array by raising an `EnsureError` when it's not.
5563
*/

ensure_test.ts

Lines changed: 52 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { assertThrows } from "./deps_test.ts";
22
import {
33
ensure,
44
ensureArray,
5+
ensureBoolean,
56
ensureFunction,
67
ensureLike,
78
ensureNone,
@@ -11,7 +12,7 @@ import {
1112
ensureString,
1213
ensureUndefined,
1314
} from "./ensure.ts";
14-
import { isNumber, isString } from "./is.ts";
15+
import { isBoolean, isNumber, isString } from "./is.ts";
1516

1617
Deno.test("ensure does nothing when pred return true", () => {
1718
ensure("a", isString);
@@ -27,6 +28,8 @@ Deno.test("ensureString does nothing on string", () => {
2728
});
2829
Deno.test("ensureString throws error on non string", () => {
2930
assertThrows(() => ensureString(0));
31+
assertThrows(() => ensureString(true));
32+
assertThrows(() => ensureString(false));
3033
assertThrows(() => ensureString([]));
3134
assertThrows(() => ensureString({}));
3235
assertThrows(() => ensureString(function () {}));
@@ -41,13 +44,29 @@ Deno.test("ensureNumber does nothing on number", () => {
4144
});
4245
Deno.test("ensureNumber throws error on non number", () => {
4346
assertThrows(() => ensureNumber("a"));
47+
assertThrows(() => ensureNumber(true));
48+
assertThrows(() => ensureNumber(false));
4449
assertThrows(() => ensureNumber([]));
4550
assertThrows(() => ensureNumber({}));
4651
assertThrows(() => ensureNumber(function () {}));
4752
assertThrows(() => ensureNumber(undefined));
4853
assertThrows(() => ensureNumber(null));
4954
});
5055

56+
Deno.test("ensureBoolean does nothing on boolean", () => {
57+
ensureBoolean(true);
58+
ensureBoolean(false);
59+
});
60+
Deno.test("ensureBoolean throws error on non boolean", () => {
61+
assertThrows(() => ensureBoolean(0));
62+
assertThrows(() => ensureBoolean("a"));
63+
assertThrows(() => ensureBoolean([]));
64+
assertThrows(() => ensureBoolean({}));
65+
assertThrows(() => ensureBoolean(function () {}));
66+
assertThrows(() => ensureBoolean(undefined));
67+
assertThrows(() => ensureBoolean(null));
68+
});
69+
5170
Deno.test("ensureArray does nothing on array", () => {
5271
ensureArray([]);
5372
ensureArray([0, 1, 2]);
@@ -56,6 +75,8 @@ Deno.test("ensureArray does nothing on array", () => {
5675
Deno.test("ensureArray throws error on non array", () => {
5776
assertThrows(() => ensureArray("a"));
5877
assertThrows(() => ensureArray(0));
78+
assertThrows(() => ensureArray(true));
79+
assertThrows(() => ensureArray(false));
5980
assertThrows(() => ensureArray({}));
6081
assertThrows(() => ensureArray(function () {}));
6182
assertThrows(() => ensureArray(undefined));
@@ -64,10 +85,12 @@ Deno.test("ensureArray throws error on non array", () => {
6485
Deno.test("ensureArray<T> does nothing on T array", () => {
6586
ensureArray([0, 1, 2], isNumber);
6687
ensureArray(["a", "b", "c"], isString);
88+
ensureArray([true, false, true], isBoolean);
6789
});
6890
Deno.test("ensureArray<T> throws error on non T array", () => {
6991
assertThrows(() => ensureArray([0, 1, 2], isString));
7092
assertThrows(() => ensureArray(["a", "b", "c"], isNumber));
93+
assertThrows(() => ensureArray([true, false, true], isString));
7194
});
7295

7396
Deno.test("ensureObject does nothing on object", () => {
@@ -78,6 +101,8 @@ Deno.test("ensureObject does nothing on object", () => {
78101
Deno.test("ensureObject throws error on non object", () => {
79102
assertThrows(() => ensureObject("a"));
80103
assertThrows(() => ensureObject(0));
104+
assertThrows(() => ensureObject(true));
105+
assertThrows(() => ensureObject(false));
81106
assertThrows(() => ensureObject([]));
82107
assertThrows(() => ensureObject(function () {}));
83108
assertThrows(() => ensureObject(undefined));
@@ -86,10 +111,12 @@ Deno.test("ensureObject throws error on non object", () => {
86111
Deno.test("ensureObject<T> does nothing on T object", () => {
87112
ensureObject({ a: 0 }, isNumber);
88113
ensureObject({ a: "a" }, isString);
114+
ensureObject({ a: true }, isBoolean);
89115
});
90116
Deno.test("ensureObject<T> throws error on non T object", () => {
91117
assertThrows(() => ensureObject({ a: 0 }, isString));
92118
assertThrows(() => ensureObject({ a: "a" }, isNumber));
119+
assertThrows(() => ensureObject({ a: true }, isString));
93120
});
94121

95122
Deno.test("ensureFunction does nothing on function", () => {
@@ -101,6 +128,8 @@ Deno.test("ensureFunction does nothing on function", () => {
101128
Deno.test("ensureFunction throws error on non function", () => {
102129
assertThrows(() => ensureFunction("a"));
103130
assertThrows(() => ensureFunction(0));
131+
assertThrows(() => ensureFunction(true));
132+
assertThrows(() => ensureFunction(false));
104133
assertThrows(() => ensureFunction([]));
105134
assertThrows(() => ensureFunction({}));
106135
assertThrows(() => ensureFunction(undefined));
@@ -113,6 +142,8 @@ Deno.test("ensureNull does nothing on null", () => {
113142
Deno.test("ensureNull throws error on non null", () => {
114143
assertThrows(() => ensureNull("a"));
115144
assertThrows(() => ensureNull(0));
145+
assertThrows(() => ensureNull(true));
146+
assertThrows(() => ensureNull(false));
116147
assertThrows(() => ensureNull([]));
117148
assertThrows(() => ensureNull({}));
118149
assertThrows(() => ensureNull(function () {}));
@@ -125,6 +156,8 @@ Deno.test("ensureUndefined does nothing on undefined", () => {
125156
Deno.test("ensureUndefined throws error on non undefined", () => {
126157
assertThrows(() => ensureUndefined("a"));
127158
assertThrows(() => ensureUndefined(0));
159+
assertThrows(() => ensureUndefined(true));
160+
assertThrows(() => ensureUndefined(false));
128161
assertThrows(() => ensureUndefined([]));
129162
assertThrows(() => ensureUndefined({}));
130163
assertThrows(() => ensureUndefined(function () {}));
@@ -138,6 +171,8 @@ Deno.test("ensureNone does nothing on null or undefined", () => {
138171
Deno.test("ensureNone throws error on non null nor undefined", () => {
139172
assertThrows(() => ensureNone("a"));
140173
assertThrows(() => ensureNone(0));
174+
assertThrows(() => ensureNone(true));
175+
assertThrows(() => ensureNone(false));
141176
assertThrows(() => ensureNone([]));
142177
assertThrows(() => ensureNone({}));
143178
assertThrows(() => ensureNone(function () {}));
@@ -148,6 +183,8 @@ Deno.test("ensureLike does it's job on string", () => {
148183
ensureLike(ref, "Hello");
149184

150185
assertThrows(() => ensureLike(ref, 0));
186+
assertThrows(() => ensureLike(ref, true));
187+
assertThrows(() => ensureLike(ref, false));
151188
assertThrows(() => ensureLike(ref, []));
152189
assertThrows(() => ensureLike(ref, {}));
153190
assertThrows(() => ensureLike(ref, function () {}));
@@ -161,6 +198,8 @@ Deno.test("ensureLike does it's job on number", () => {
161198
ensureLike(ref, 0.1);
162199

163200
assertThrows(() => ensureLike(ref, "a"));
201+
assertThrows(() => ensureLike(ref, true));
202+
assertThrows(() => ensureLike(ref, false));
164203
assertThrows(() => ensureLike(ref, []));
165204
assertThrows(() => ensureLike(ref, {}));
166205
assertThrows(() => ensureLike(ref, function () {}));
@@ -184,9 +223,11 @@ Deno.test("ensureLike does it's job on T array", () => {
184223
const ref: unknown[] = [];
185224
ensureLike(ref, [0, 1, 2], isNumber);
186225
ensureLike(ref, ["a", "b", "c"], isString);
226+
ensureLike(ref, [true, false, true], isBoolean);
187227

188228
assertThrows(() => ensureLike(ref, [0, 1, 2], isString));
189229
assertThrows(() => ensureLike(ref, ["a", "b", "c"], isNumber));
230+
assertThrows(() => ensureLike(ref, [true, false, true], isString));
190231
});
191232
Deno.test("ensureLike does it's job on tuple", () => {
192233
const ref = ["", 0, ""];
@@ -206,6 +247,8 @@ Deno.test("ensureLike does it's job on object", () => {
206247

207248
assertThrows(() => ensureLike(ref, "a"));
208249
assertThrows(() => ensureLike(ref, 0));
250+
assertThrows(() => ensureLike(ref, true));
251+
assertThrows(() => ensureLike(ref, false));
209252
assertThrows(() => ensureLike(ref, []));
210253
assertThrows(() => ensureLike(ref, function () {}));
211254
assertThrows(() => ensureLike(ref, undefined));
@@ -215,9 +258,11 @@ Deno.test("ensureLike does it's job on T object", () => {
215258
const ref = {};
216259
ensureLike(ref, { a: 0 }, isNumber);
217260
ensureLike(ref, { a: "a" }, isString);
261+
ensureLike(ref, { a: true }, isBoolean);
218262

219263
assertThrows(() => ensureLike(ref, { a: 0 }, isString));
220264
assertThrows(() => ensureLike(ref, { a: "a" }, isNumber));
265+
assertThrows(() => ensureLike(ref, { a: true }, isString));
221266
});
222267
Deno.test("ensureLike does it's job on struct", () => {
223268
const ref = { foo: "", bar: 0 };
@@ -237,6 +282,8 @@ Deno.test("ensureLike does it's job on function", () => {
237282

238283
assertThrows(() => ensureLike(ref, "a"));
239284
assertThrows(() => ensureLike(ref, 0));
285+
assertThrows(() => ensureLike(ref, true));
286+
assertThrows(() => ensureLike(ref, false));
240287
assertThrows(() => ensureLike(ref, []));
241288
assertThrows(() => ensureLike(ref, {}));
242289
assertThrows(() => ensureLike(ref, undefined));
@@ -248,6 +295,8 @@ Deno.test("ensureLike does it's job on null", () => {
248295

249296
assertThrows(() => ensureLike(ref, "a"));
250297
assertThrows(() => ensureLike(ref, 0));
298+
assertThrows(() => ensureLike(ref, true));
299+
assertThrows(() => ensureLike(ref, false));
251300
assertThrows(() => ensureLike(ref, []));
252301
assertThrows(() => ensureLike(ref, {}));
253302
assertThrows(() => ensureLike(ref, function () {}));
@@ -259,6 +308,8 @@ Deno.test("ensureLike does it's job on undefined", () => {
259308

260309
assertThrows(() => ensureLike(ref, "a"));
261310
assertThrows(() => ensureLike(ref, 0));
311+
assertThrows(() => ensureLike(ref, true));
312+
assertThrows(() => ensureLike(ref, false));
262313
assertThrows(() => ensureLike(ref, []));
263314
assertThrows(() => ensureLike(ref, {}));
264315
assertThrows(() => ensureLike(ref, function () {}));

is.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,13 @@ export function isNumber(x: unknown): x is number {
1414
return typeof x === "number";
1515
}
1616

17+
/**
18+
* Return true if the value is boolean
19+
*/
20+
export function isBoolean(x: unknown): x is boolean {
21+
return typeof x === "boolean";
22+
}
23+
1724
/**
1825
* Return true if the value is array
1926
*/
@@ -81,6 +88,9 @@ export function isLike<R, T extends unknown>(
8188
if (isNumber(ref) && isNumber(x)) {
8289
return true;
8390
}
91+
if (isBoolean(ref) && isBoolean(x)) {
92+
return true;
93+
}
8494
if (isArray(ref, pred) && isArray(x, pred)) {
8595
return ref.length === 0 || (
8696
ref.length === x.length &&

0 commit comments

Comments
 (0)