Skip to content

Commit a87f4b0

Browse files
committed
Added assert package and added basic asserts
1 parent 800413b commit a87f4b0

File tree

13 files changed

+302
-0
lines changed

13 files changed

+302
-0
lines changed

assert/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# @stdext/assert
2+
3+
The assert package, contains validators and assertions
4+
5+
```ts
6+
import { assertIsString, isString } from "@stdext/assert";
7+
8+
if (isString(someVar)) {
9+
// Returns true if a value is a string
10+
// someVar will typewise be a string from now on
11+
}
12+
13+
assertIsString(someVar); // Throws if the value is not a string
14+
// someVar will typewise be a string from now on
15+
```

assert/deno.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"version": "0.0.1",
3+
"name": "@stdext/assert",
4+
"exports": {
5+
".": "./mod.ts",
6+
"./is_number": "./is_number.ts",
7+
"./is_record": "./is_record.ts",
8+
"./is_string": "./is_string.ts"
9+
}
10+
}

assert/is_number.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { assert, assertFalse, AssertionError, assertThrows } from "@std/assert";
2+
import { assertIsNumber, isNumber } from "./is_number.ts";
3+
4+
const VALID = [
5+
0,
6+
1,
7+
1.123,
8+
1_123_12_3,
9+
-1,
10+
-1_1234,
11+
-1.123,
12+
NaN,
13+
];
14+
15+
const INVALID = [
16+
"",
17+
"asdf",
18+
undefined,
19+
null,
20+
{},
21+
[],
22+
[""],
23+
new Number(),
24+
];
25+
26+
Deno.test("isNumber > can detect numbers", () => {
27+
for (const v of VALID) {
28+
assert(isNumber(v), `Value of '${v}' is not valid`);
29+
}
30+
for (const v of INVALID) {
31+
assertFalse(isNumber(v), `Value of '${v}' is not invalid`);
32+
}
33+
});
34+
35+
Deno.test("assertIsNumber > can detect numbers", () => {
36+
for (const v of VALID) {
37+
assertIsNumber(v);
38+
}
39+
for (const v of INVALID) {
40+
assertThrows(
41+
() => assertIsNumber(v),
42+
AssertionError,
43+
undefined,
44+
`Value of '${v}' did not throw`,
45+
);
46+
}
47+
});

assert/is_number.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { AssertionError } from "@std/assert";
2+
3+
/**
4+
* Checks if a value is a number
5+
*/
6+
export function isNumber(value: unknown): value is number {
7+
return typeof value === "number";
8+
}
9+
10+
/**
11+
* Asserts that a value is a number
12+
*/
13+
export function assertIsNumber(value: unknown): asserts value is number {
14+
if (!isNumber(value)) {
15+
throw new AssertionError(`Value is not a number, was '${value}'`);
16+
}
17+
}

assert/is_numeric.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { assert, assertFalse, AssertionError, assertThrows } from "@std/assert";
2+
import { assertIsNumeric, isNumeric } from "./is_numeric.ts";
3+
4+
const VALID = [
5+
0,
6+
1,
7+
1.123,
8+
1_123_12_3,
9+
-1,
10+
-1_1234,
11+
-1.123,
12+
];
13+
14+
const INVALID = [
15+
NaN,
16+
"",
17+
"asdf",
18+
undefined,
19+
null,
20+
{},
21+
[],
22+
[""],
23+
new Number(),
24+
];
25+
26+
Deno.test("isNumeric > can detect numerics", () => {
27+
for (const v of VALID) {
28+
assert(isNumeric(v), `Value of '${v}' is not valid`);
29+
}
30+
for (const v of INVALID) {
31+
assertFalse(isNumeric(v), `Value of '${v}' is not invalid`);
32+
}
33+
});
34+
35+
Deno.test("assertIsNumeric > can detect numerics", () => {
36+
for (const v of VALID) {
37+
assertIsNumeric(v);
38+
}
39+
for (const v of INVALID) {
40+
assertThrows(
41+
() => assertIsNumeric(v),
42+
AssertionError,
43+
undefined,
44+
`Value of '${v}' did not throw`,
45+
);
46+
}
47+
});

assert/is_numeric.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { AssertionError } from "@std/assert";
2+
import { isNumber } from "./is_number.ts";
3+
4+
/**
5+
* Checks if a value is a number and not NaN
6+
*/
7+
export function isNumeric(value: unknown): value is number {
8+
return isNumber(value) && !Number.isNaN(value);
9+
}
10+
11+
/**
12+
* Asserts that a value is a number and not NaN
13+
*/
14+
export function assertIsNumeric(value: unknown): asserts value is number {
15+
if (!isNumeric(value)) {
16+
throw new AssertionError(`Value is not a numeric, was '${value}'`);
17+
}
18+
}

assert/is_record.test.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { assert, assertFalse, AssertionError, assertThrows } from "@std/assert";
2+
import { assertIsRecord, isRecord } from "./is_record.ts";
3+
4+
const VALID = [
5+
{},
6+
{ a: 1 },
7+
{ 1: "a" },
8+
];
9+
10+
const INVALID = [
11+
{ [Symbol.dispose]: "" },
12+
"",
13+
1,
14+
undefined,
15+
null,
16+
[],
17+
[""],
18+
new Map(),
19+
];
20+
21+
Deno.test("isRecord > can detect records", () => {
22+
for (const v of VALID) {
23+
assert(isRecord(v), `Value of '${v}' is not valid`);
24+
}
25+
for (const v of INVALID) {
26+
assertFalse(isRecord(v), `Value of '${v}' is not invalid`);
27+
}
28+
});
29+
30+
Deno.test("assertIsRecord > can detect records", () => {
31+
for (const v of VALID) {
32+
assertIsRecord(v);
33+
}
34+
for (const v of INVALID) {
35+
assertThrows(
36+
() => assertIsRecord(v),
37+
AssertionError,
38+
undefined,
39+
`Value of '${v}' did not throw`,
40+
);
41+
}
42+
});

assert/is_record.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { AssertionError } from "@std/assert";
2+
import { objectToStringEquals } from "./utils.ts";
3+
4+
/**
5+
* Checks if a value is a Record<string, unknown>
6+
*/
7+
export function isRecord(value: unknown): value is Record<string, unknown> {
8+
if (!objectToStringEquals("Object", value)) {
9+
return false;
10+
}
11+
12+
if (typeof value !== "object") {
13+
return false;
14+
}
15+
16+
if (Array.isArray(value)) {
17+
return false;
18+
}
19+
20+
if (Object.getOwnPropertySymbols(value).length > 0) {
21+
return false;
22+
}
23+
24+
return true;
25+
}
26+
27+
/**
28+
* Asserts that a value is a record
29+
*/
30+
export function assertIsRecord(
31+
value: unknown,
32+
): asserts value is Record<string, unknown> {
33+
if (!isRecord(value)) {
34+
throw new AssertionError(`Value is not a Record, was '${value}'`);
35+
}
36+
}

assert/is_string.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { assert, assertFalse, AssertionError, assertThrows } from "@std/assert";
2+
import { assertIsString, isString } from "./is_string.ts";
3+
4+
const VALID = [
5+
"",
6+
"asdf",
7+
];
8+
9+
const INVALID = [
10+
1,
11+
undefined,
12+
null,
13+
{},
14+
[],
15+
[""],
16+
new String(),
17+
];
18+
19+
Deno.test("isString > can detect strings", () => {
20+
for (const v of VALID) {
21+
assert(isString(v), `Value of '${v}' is not valid`);
22+
}
23+
for (const v of INVALID) {
24+
assertFalse(isString(v), `Value of '${v}' is not invalid`);
25+
}
26+
});
27+
28+
Deno.test("assertIsString > can detect strings", () => {
29+
for (const v of VALID) {
30+
assertIsString(v);
31+
}
32+
for (const v of INVALID) {
33+
assertThrows(
34+
() => assertIsString(v),
35+
AssertionError,
36+
undefined,
37+
`Value of '${v}' did not throw`,
38+
);
39+
}
40+
});

assert/is_string.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { AssertionError } from "@std/assert";
2+
3+
/**
4+
* Checks if a value is a string
5+
*/
6+
export function isString(value: unknown): value is string {
7+
return typeof value === "string";
8+
}
9+
10+
/**
11+
* Asserts that a value is a string
12+
*/
13+
export function assertIsString(value: unknown): asserts value is string {
14+
if (!isString(value)) {
15+
throw new AssertionError(`Value is not a string, was '${value}'`);
16+
}
17+
}

0 commit comments

Comments
 (0)