as-test 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +96 -11
- package/assembly/index.ts +187 -18
- package/assembly/src/expectation.ts +237 -36
- package/assembly/src/group.ts +1 -1
- package/assembly/src/node.ts +1 -1
- package/assembly/test.ts +65 -9
- package/assembly/util.ts +6 -0
- package/jest.test.js +1 -1
- package/package.json +2 -2
- package/assembly/src/it.ts +0 -90
- package/assembly/src/result.ts +0 -23
package/README.md
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<h5 align="center">
|
|
2
|
-
<pre>
|
|
3
|
-
_____
|
|
4
|
-
| _
|
|
5
|
-
|
|
|
6
|
-
|__|__
|
|
7
|
-
v0.0.
|
|
2
|
+
<pre>
|
|
3
|
+
_____ _____ _____ _____ _____ _____
|
|
4
|
+
| _ || __| ___|_ _|| __|| __||_ _|
|
|
5
|
+
| ||__ ||___| | | | __||__ | | |
|
|
6
|
+
|__|__||_____| |_| |_____||_____| |_|
|
|
7
|
+
v0.0.3
|
|
8
8
|
</pre>
|
|
9
9
|
</h5>
|
|
10
10
|
|
|
@@ -20,16 +20,101 @@ npm install as-test
|
|
|
20
20
|
import {
|
|
21
21
|
describe,
|
|
22
22
|
expect,
|
|
23
|
+
test,
|
|
24
|
+
beforeAll,
|
|
25
|
+
afterAll,
|
|
26
|
+
beforeEach,
|
|
27
|
+
afterEach,
|
|
28
|
+
log,
|
|
23
29
|
run
|
|
24
30
|
} from "as-test";
|
|
25
31
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
expect("a").toBe("b");
|
|
32
|
+
// Shared setup for all tests (executed once before all tests)
|
|
33
|
+
beforeAll(() => {
|
|
34
|
+
log("Setting up test environment...");
|
|
30
35
|
});
|
|
31
36
|
|
|
32
|
-
|
|
37
|
+
// Shared teardown for all tests (executed once after all tests)
|
|
38
|
+
afterAll(() => {
|
|
39
|
+
log("Tearing down test environment...");
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
describe("Math operations", () => {
|
|
43
|
+
// Setup before each test in this group (optional)
|
|
44
|
+
beforeEach(() => {
|
|
45
|
+
log("Initializing test...");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
// Teardown after each test in this group (optional)
|
|
49
|
+
afterEach(() => {
|
|
50
|
+
log("Cleaning up after test...");
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
test("Addition", () => {
|
|
54
|
+
expect(1 + 2).toBe(3);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test("Comparison", () => {
|
|
58
|
+
expect(5).toBeGreaterThan(3);
|
|
59
|
+
expect(2).toBeLessThan(4);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("Type checking", () => {
|
|
63
|
+
expect("hello").toBeString();
|
|
64
|
+
expect(true).toBeBoolean();
|
|
65
|
+
expect(10.5).toBeNumber();
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
describe("Array manipulation", () => {
|
|
70
|
+
let myArray;
|
|
71
|
+
|
|
72
|
+
beforeAll(() => {
|
|
73
|
+
myArray = [1, 2, 3];
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
test("Array length", () => {
|
|
77
|
+
expect(myArray).toHaveLength(3);
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test("Array inclusion", () => {
|
|
81
|
+
expect(myArray).toContain(2);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
run({
|
|
86
|
+
log: false
|
|
87
|
+
});
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
_____ _____ _____ _____ _____ _____
|
|
92
|
+
| _ || __| ___|_ _|| __|| __||_ _|
|
|
93
|
+
| ||__ ||___| | | | __||__ | | |
|
|
94
|
+
|__|__||_____| |_| |_____||_____| |_|
|
|
95
|
+
|
|
96
|
+
-----------------------------------------
|
|
97
|
+
|
|
98
|
+
[PASS] Math operations
|
|
99
|
+
|
|
100
|
+
[PASS] Array manipulation
|
|
101
|
+
|
|
102
|
+
[PASS] Addition
|
|
103
|
+
|
|
104
|
+
[PASS] Comparison
|
|
105
|
+
|
|
106
|
+
[PASS] Type checking
|
|
107
|
+
|
|
108
|
+
[PASS] Array length
|
|
109
|
+
|
|
110
|
+
[PASS] Array inclusion
|
|
111
|
+
|
|
112
|
+
-----------------------------------------
|
|
113
|
+
|
|
114
|
+
Test Suites: 0 failed, 2 total
|
|
115
|
+
Tests: 0 failed, 8 total
|
|
116
|
+
Snapshots: 0 total
|
|
117
|
+
Time: 101.812μs
|
|
33
118
|
```
|
|
34
119
|
|
|
35
120
|
If you use this project in your codebase, consider dropping a [⭐ HERE](https://github.com/JairusSW/as-test). I would really appreciate it!
|
package/assembly/index.ts
CHANGED
|
@@ -1,24 +1,43 @@
|
|
|
1
1
|
import { rainbow } from "as-rainbow";
|
|
2
2
|
import { TestGroup } from "./src/group";
|
|
3
3
|
import { Expectation } from "./src/expectation";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
4
|
+
import { colorText, formatTime } from "./util";
|
|
5
|
+
import { stringify } from "as-console/assembly";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Enumeration representing the verdict of a test case.
|
|
9
|
+
*/
|
|
10
|
+
export enum Verdict {
|
|
11
|
+
Unreachable,
|
|
12
|
+
Ok,
|
|
13
|
+
Fail
|
|
14
|
+
}
|
|
6
15
|
|
|
7
16
|
// Globals
|
|
8
17
|
let current_group: TestGroup | null = null;
|
|
9
18
|
let groups: TestGroup[] = [];
|
|
10
19
|
|
|
20
|
+
let before_all_callback: (() => void) | null = null;
|
|
21
|
+
let after_all_callback: (() => void) | null = null;
|
|
22
|
+
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
@global let before_each_callback: (() => void) | null = null;
|
|
25
|
+
// @ts-ignore
|
|
26
|
+
@global let after_each_callback: (() => void) | null = null;
|
|
27
|
+
// @ts-ignore
|
|
28
|
+
@global let __test_options!: RunOptions;
|
|
29
|
+
|
|
11
30
|
/**
|
|
12
|
-
* Creates a test group containing multiple test cases
|
|
31
|
+
* Creates a test group containing multiple test cases.
|
|
13
32
|
*
|
|
14
33
|
* @param {string} description - The name of the test group
|
|
15
|
-
* @param callback - The block containing the test cases for this group
|
|
34
|
+
* @param {() => void} callback - The block containing the test cases for this group
|
|
16
35
|
*
|
|
17
36
|
* @example
|
|
18
|
-
*
|
|
19
37
|
* ```ts
|
|
20
38
|
* describe("my test suite", () => {
|
|
21
|
-
*
|
|
39
|
+
* expect(1 + 3).toBe(4);
|
|
40
|
+
* // More tests here
|
|
22
41
|
* });
|
|
23
42
|
* ```
|
|
24
43
|
*/
|
|
@@ -29,24 +48,172 @@ export function describe(description: string, callback: () => void): void {
|
|
|
29
48
|
groups.push(group);
|
|
30
49
|
}
|
|
31
50
|
|
|
51
|
+
/**
|
|
52
|
+
* Creates a test group containing multiple test cases
|
|
53
|
+
*
|
|
54
|
+
* @param {string} description - The name of the test group
|
|
55
|
+
* @param {() => void} callback - The block containing the test cases for this group
|
|
56
|
+
*
|
|
57
|
+
* @example
|
|
58
|
+
*
|
|
59
|
+
* ```ts
|
|
60
|
+
* test("1 + 3 = 4", () => {
|
|
61
|
+
* expect(1 + 3).toBe(4);
|
|
62
|
+
* });
|
|
63
|
+
* ```
|
|
64
|
+
*/
|
|
65
|
+
export function test(description: string, callback: () => void): void {
|
|
66
|
+
const group = new TestGroup(description, callback);
|
|
67
|
+
|
|
68
|
+
current_group = group;
|
|
69
|
+
groups.push(group);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a test group containing multiple test cases
|
|
74
|
+
*
|
|
75
|
+
* @param {string} description - The name of the test group
|
|
76
|
+
* @param {() => void} callback - The block containing the test cases for this group
|
|
77
|
+
*
|
|
78
|
+
* @example
|
|
79
|
+
*
|
|
80
|
+
* ```ts
|
|
81
|
+
* it("should perform additions", () => {
|
|
82
|
+
* expect(1 + 3).toBe(4);
|
|
83
|
+
* });
|
|
84
|
+
* ```
|
|
85
|
+
*/
|
|
86
|
+
export function it(description: string, callback: () => void): void {
|
|
87
|
+
const group = new TestGroup(description, callback);
|
|
88
|
+
|
|
89
|
+
current_group = group;
|
|
90
|
+
groups.push(group);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Creates an expectation object for making assertions within a test case.
|
|
95
|
+
*
|
|
96
|
+
* Use this function to chain assertions about a specific value.
|
|
97
|
+
* The returned expectation object provides various methods for testing
|
|
98
|
+
* different properties and conditions of the value.
|
|
99
|
+
*
|
|
100
|
+
* @param {T} value - The value to be asserted against.
|
|
101
|
+
* @returns {Expectation<T>} - The expectation object for chaining assertions.
|
|
102
|
+
*
|
|
103
|
+
* @example
|
|
104
|
+
* ```ts
|
|
105
|
+
* test("number comparison", () => {
|
|
106
|
+
* expect(1 + 2).toBe(3);
|
|
107
|
+
* expect(5).toBeGreaterThan(3);
|
|
108
|
+
* });
|
|
109
|
+
* ```
|
|
110
|
+
*/
|
|
32
111
|
export function expect<T>(value: T): Expectation<T> {
|
|
33
112
|
const result = new Expectation<T>(value);
|
|
34
|
-
|
|
35
113
|
current_group!.addExpectation(result);
|
|
36
114
|
|
|
37
|
-
//if (!result.tested) {
|
|
38
|
-
//
|
|
39
|
-
//}
|
|
40
|
-
|
|
41
115
|
return result;
|
|
42
116
|
}
|
|
43
117
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
118
|
+
/**
|
|
119
|
+
* Formats and prints content to the terminal
|
|
120
|
+
* Can be disabled like so:
|
|
121
|
+
*
|
|
122
|
+
* ```js
|
|
123
|
+
* // ...
|
|
124
|
+
*
|
|
125
|
+
* run({ log: false });
|
|
126
|
+
* ```
|
|
127
|
+
*
|
|
128
|
+
* @param {T} data - The data to format and print
|
|
129
|
+
*/
|
|
130
|
+
export function log<T>(data: T): void {
|
|
131
|
+
if (!__test_options.log) return;
|
|
132
|
+
const formatted = stringify(data);
|
|
133
|
+
if (formatted) {
|
|
134
|
+
const lines = formatted.split("\n");
|
|
135
|
+
for (let i = 0; i < lines.length; i++) {
|
|
136
|
+
const line = unchecked(lines[i]);
|
|
137
|
+
console.log(" " + rainbow.bgYellow(" LOG ") + " " + line);
|
|
138
|
+
}
|
|
139
|
+
console.log("");
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Registers a callback function to be executed before each test group is run.
|
|
145
|
+
*
|
|
146
|
+
* @param {() => void} callback - The function to be executed before each test group.
|
|
147
|
+
*/
|
|
148
|
+
export function beforeAll(callback: () => void): void {
|
|
149
|
+
before_all_callback = callback;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Registers a callback function to be executed after each test group is run.
|
|
154
|
+
*
|
|
155
|
+
* @param {() => void} callback - The function to be executed after each test group.
|
|
156
|
+
*/
|
|
157
|
+
export function afterAll(callback: () => void): void {
|
|
158
|
+
after_all_callback = callback;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Registers a callback function to be executed before each test case is run.
|
|
163
|
+
*
|
|
164
|
+
* @param {() => void} callback - The function to be executed before each test case.
|
|
165
|
+
*/
|
|
166
|
+
export function beforeEach(callback: () => void): void {
|
|
167
|
+
before_each_callback = callback;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Registers a callback function to be executed after each test case is run.
|
|
172
|
+
*
|
|
173
|
+
* @param {() => void} callback - The function to be executed after each test case.
|
|
174
|
+
*/
|
|
175
|
+
export function afterEach(callback: () => void): void {
|
|
176
|
+
after_each_callback = callback;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Class defining options that can be passed to the `run` function.
|
|
181
|
+
*
|
|
182
|
+
* Currently, it offers a single option:
|
|
183
|
+
*
|
|
184
|
+
* - `log` (boolean, default: true): Controls whether enable the log() function
|
|
185
|
+
**/
|
|
186
|
+
class RunOptions {
|
|
187
|
+
log: boolean = true
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Runs all the test suites defined within the current test scope.
|
|
192
|
+
*
|
|
193
|
+
* This function executes all the test cases you've defined in your test suites.
|
|
194
|
+
* It iterates through each suite, runs the tests within the suite, and tracks results.
|
|
195
|
+
* Finally, it prints a colorful summary of the test execution.
|
|
196
|
+
*
|
|
197
|
+
* @param {RunOptions} [options] - Optional options for running tests.
|
|
198
|
+
*
|
|
199
|
+
* @example
|
|
200
|
+
* ```javascript
|
|
201
|
+
* describe("Math operations", () => {
|
|
202
|
+
* test("Addition", () => {
|
|
203
|
+
* expect(1 + 2).toBe(3);
|
|
204
|
+
* });
|
|
205
|
+
* // ... other tests
|
|
206
|
+
* });
|
|
207
|
+
*
|
|
208
|
+
* run(); // Executes all tests in the "Math operations" suite
|
|
209
|
+
* ```
|
|
210
|
+
*/
|
|
211
|
+
export function run(options: RunOptions = new RunOptions()): void {
|
|
212
|
+
__test_options = options;
|
|
213
|
+
console.log(rainbow.boldMk(rainbow.green(` _____ _____ _____ _____ _____ _____ `)));
|
|
214
|
+
console.log(rainbow.boldMk(rainbow.green(`| _ || __| ___|_ _|| __|| __||_ _|`)));
|
|
215
|
+
console.log(rainbow.boldMk(rainbow.green(`| ||__ ||___| | | | __||__ | | | `)));
|
|
216
|
+
console.log(rainbow.boldMk(rainbow.green(`|__|__||_____| |_| |_____||_____| |_| `)));
|
|
50
217
|
console.log(rainbow.dimMk("\n-----------------------------------------\n"));
|
|
51
218
|
const suites = groups.length;
|
|
52
219
|
let failed = 0;
|
|
@@ -54,6 +221,7 @@ export function run(): void {
|
|
|
54
221
|
let failed_tests = 0;
|
|
55
222
|
const start = performance.now();
|
|
56
223
|
for (let i = 0; i < groups.length; i++) {
|
|
224
|
+
if (before_all_callback) before_all_callback();
|
|
57
225
|
const suite = unchecked(groups[i]);
|
|
58
226
|
suite.run();
|
|
59
227
|
for (let i = 0; i < suite.results.length; i++) {
|
|
@@ -70,7 +238,7 @@ export function run(): void {
|
|
|
70
238
|
}
|
|
71
239
|
if (suite.verdict == Verdict.Unreachable) {
|
|
72
240
|
suite.verdict = Verdict.Ok;
|
|
73
|
-
console.log(rainbow.
|
|
241
|
+
console.log(rainbow.bgGreenBright(" PASS ") + " " + rainbow.dimMk(suite.description) + "\n");
|
|
74
242
|
} else {
|
|
75
243
|
failed++;
|
|
76
244
|
console.log(rainbow.bgRed(" FAIL ") + " " + rainbow.dimMk(suite.description) + "\n");
|
|
@@ -78,6 +246,7 @@ export function run(): void {
|
|
|
78
246
|
|
|
79
247
|
const report = suite.report();
|
|
80
248
|
if (report) console.log(report);
|
|
249
|
+
if (after_all_callback) after_all_callback();
|
|
81
250
|
}
|
|
82
251
|
const ms = performance.now() - start;
|
|
83
252
|
console.log(rainbow.dimMk("-----------------------------------------\n"));
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import { Verdict } from "./result";
|
|
2
1
|
import { rainbow } from "as-rainbow";
|
|
3
2
|
import { diff, visualize } from "../util";
|
|
4
3
|
import { Node } from "./node";
|
|
4
|
+
import { Verdict } from "..";
|
|
5
5
|
|
|
6
6
|
export class Expectation<T> extends Node {
|
|
7
7
|
public verdict: Verdict = Verdict.Unreachable;
|
|
8
8
|
public left: T;
|
|
9
|
-
|
|
9
|
+
private _left: string | null = null;
|
|
10
|
+
public right: u64 = 0;
|
|
11
|
+
private _right: string | null = null;
|
|
10
12
|
private _not: boolean = false;
|
|
11
13
|
private op: string = "=";
|
|
12
14
|
constructor(left: T) {
|
|
@@ -17,94 +19,290 @@ export class Expectation<T> extends Node {
|
|
|
17
19
|
this._not = true;
|
|
18
20
|
return this;
|
|
19
21
|
}
|
|
20
|
-
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Tests if a == null
|
|
25
|
+
* @returns - void
|
|
26
|
+
*/
|
|
27
|
+
toBeNull(): void {
|
|
21
28
|
this.verdict = (isNullable<T>() && changetype<usize>(this.left)) ? Verdict.Ok : Verdict.Fail;
|
|
22
29
|
|
|
23
30
|
// @ts-ignore
|
|
24
|
-
this
|
|
25
|
-
|
|
31
|
+
store<T>(changetype<usize>(this), null, offsetof<Expectation<T>>("right"));
|
|
32
|
+
|
|
26
33
|
this.op = "="
|
|
27
34
|
|
|
28
|
-
|
|
35
|
+
// @ts-ignore
|
|
36
|
+
if (after_each_callback) after_each_callback();
|
|
37
|
+
// @ts-ignore
|
|
38
|
+
if (before_each_callback) before_each_callback();
|
|
29
39
|
}
|
|
40
|
+
|
|
30
41
|
/**
|
|
31
42
|
* Tests if a > b
|
|
32
43
|
* @param number equals - The value to test
|
|
33
|
-
* @returns -
|
|
44
|
+
* @returns - void
|
|
34
45
|
*/
|
|
35
|
-
toBeGreaterThan(value: T):
|
|
46
|
+
toBeGreaterThan(value: T): void {
|
|
36
47
|
if (!isInteger<T>() && !isFloat<T>()) throw new Error("toBeGreaterThan() can only be used on number types. Received " + nameof<T>() + " instead!");
|
|
37
|
-
|
|
48
|
+
|
|
38
49
|
this.verdict = this.left > value ? Verdict.Ok : Verdict.Fail;
|
|
39
|
-
this
|
|
50
|
+
store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
|
|
40
51
|
|
|
41
52
|
this.op = ">";
|
|
42
53
|
|
|
43
|
-
|
|
54
|
+
// @ts-ignore
|
|
55
|
+
if (after_each_callback) after_each_callback();
|
|
56
|
+
// @ts-ignore
|
|
57
|
+
if (before_each_callback) before_each_callback();
|
|
44
58
|
}
|
|
59
|
+
|
|
45
60
|
/**
|
|
46
61
|
* Tests if a >= b
|
|
47
62
|
* @param number equals - The value to test
|
|
48
|
-
* @returns -
|
|
63
|
+
* @returns - void
|
|
49
64
|
*/
|
|
50
|
-
toBeGreaterOrEqualTo(value: T):
|
|
65
|
+
toBeGreaterOrEqualTo(value: T): void {
|
|
51
66
|
if (!isInteger<T>() && !isFloat<T>()) throw new Error("toBeGreaterOrEqualTo() can only be used on number types. Received " + nameof<T>() + " instead!");
|
|
52
|
-
|
|
67
|
+
|
|
53
68
|
this.verdict = this.left >= value ? Verdict.Ok : Verdict.Fail;
|
|
54
|
-
this
|
|
69
|
+
store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
|
|
55
70
|
|
|
56
71
|
this.op = ">=";
|
|
57
72
|
|
|
58
|
-
|
|
73
|
+
// @ts-ignore
|
|
74
|
+
if (after_each_callback) after_each_callback();
|
|
75
|
+
// @ts-ignore
|
|
76
|
+
if (before_each_callback) before_each_callback();
|
|
59
77
|
}
|
|
78
|
+
|
|
60
79
|
/**
|
|
61
80
|
* Tests if a < b
|
|
62
81
|
* @param number equals - The value to test
|
|
63
|
-
* @returns -
|
|
82
|
+
* @returns - void
|
|
64
83
|
*/
|
|
65
|
-
toBeLessThan(value: T):
|
|
84
|
+
toBeLessThan(value: T): void {
|
|
66
85
|
if (!isInteger<T>() && !isFloat<T>()) throw new Error("toBeLessThan() can only be used on number types. Received " + nameof<T>() + " instead!");
|
|
67
|
-
|
|
86
|
+
|
|
68
87
|
this.verdict = this.left < value ? Verdict.Ok : Verdict.Fail;
|
|
69
|
-
this
|
|
88
|
+
store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
|
|
70
89
|
|
|
71
90
|
this.op = "<";
|
|
72
91
|
|
|
73
|
-
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
if (after_each_callback) after_each_callback();
|
|
94
|
+
// @ts-ignore
|
|
95
|
+
if (before_each_callback) before_each_callback();
|
|
74
96
|
}
|
|
97
|
+
|
|
75
98
|
/**
|
|
76
99
|
* Tests if a <= b
|
|
77
100
|
* @param number equals - The value to test
|
|
78
|
-
* @returns -
|
|
101
|
+
* @returns - void
|
|
79
102
|
*/
|
|
80
|
-
toBeLessThanOrEqualTo(value: T):
|
|
103
|
+
toBeLessThanOrEqualTo(value: T): void {
|
|
81
104
|
if (!isInteger<T>() && !isFloat<T>()) throw new Error("toBeLessThanOrEqualTo() can only be used on number types. Received " + nameof<T>() + " instead!");
|
|
82
|
-
|
|
105
|
+
|
|
83
106
|
this.verdict = this.left <= value ? Verdict.Ok : Verdict.Fail;
|
|
84
|
-
this
|
|
107
|
+
store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
|
|
85
108
|
|
|
86
109
|
this.op = "<=";
|
|
87
110
|
|
|
88
|
-
|
|
111
|
+
// @ts-ignore
|
|
112
|
+
if (after_each_callback) after_each_callback();
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
if (before_each_callback) before_each_callback();
|
|
89
115
|
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Tests if a is string
|
|
119
|
+
* @returns - void
|
|
120
|
+
*/
|
|
121
|
+
toBeString(): void {
|
|
122
|
+
this.verdict = isString<T>() ? Verdict.Ok : Verdict.Fail;
|
|
123
|
+
|
|
124
|
+
this._left = nameof<T>();
|
|
125
|
+
this._right = "string";
|
|
126
|
+
|
|
127
|
+
this.op = "type";
|
|
128
|
+
|
|
129
|
+
// @ts-ignore
|
|
130
|
+
if (after_each_callback) after_each_callback();
|
|
131
|
+
// @ts-ignore
|
|
132
|
+
if (before_each_callback) before_each_callback();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* Tests if a is boolean
|
|
137
|
+
* @returns - void
|
|
138
|
+
*/
|
|
139
|
+
toBeBoolean(): void {
|
|
140
|
+
this.verdict = isBoolean<T>() ? Verdict.Ok : Verdict.Fail;
|
|
141
|
+
|
|
142
|
+
this._left = nameof<T>();
|
|
143
|
+
this._right = "boolean";
|
|
144
|
+
|
|
145
|
+
this.op = "type";
|
|
146
|
+
|
|
147
|
+
// @ts-ignore
|
|
148
|
+
if (after_each_callback) after_each_callback();
|
|
149
|
+
// @ts-ignore
|
|
150
|
+
if (before_each_callback) before_each_callback();
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Tests if a is array
|
|
155
|
+
* @returns - void
|
|
156
|
+
*/
|
|
157
|
+
toBeArray(): void {
|
|
158
|
+
this.verdict = isArray<T>() ? Verdict.Ok : Verdict.Fail;
|
|
159
|
+
|
|
160
|
+
this._left = nameof<T>();
|
|
161
|
+
this._right = "Array<any>";
|
|
162
|
+
|
|
163
|
+
this.op = "type";
|
|
164
|
+
|
|
165
|
+
// @ts-ignore
|
|
166
|
+
if (after_each_callback) after_each_callback();
|
|
167
|
+
// @ts-ignore
|
|
168
|
+
if (before_each_callback) before_each_callback();
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Tests if a is number
|
|
173
|
+
* @returns - void
|
|
174
|
+
*/
|
|
175
|
+
toBeNumber(): void {
|
|
176
|
+
this.verdict = (isFloat<T>() || isInteger<T>()) ? Verdict.Ok : Verdict.Fail;
|
|
177
|
+
|
|
178
|
+
this._left = nameof<T>();
|
|
179
|
+
this._right = "number";
|
|
180
|
+
|
|
181
|
+
this.op = "type";
|
|
182
|
+
|
|
183
|
+
// @ts-ignore
|
|
184
|
+
if (after_each_callback) after_each_callback();
|
|
185
|
+
// @ts-ignore
|
|
186
|
+
if (before_each_callback) before_each_callback();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Tests if a is integer
|
|
191
|
+
* @returns - void
|
|
192
|
+
*/
|
|
193
|
+
toBeInteger(): void {
|
|
194
|
+
this.verdict = isInteger<T>() ? Verdict.Ok : Verdict.Fail;
|
|
195
|
+
|
|
196
|
+
this._left = nameof<T>();
|
|
197
|
+
this._right = "float";
|
|
198
|
+
|
|
199
|
+
this.op = "type";
|
|
200
|
+
|
|
201
|
+
// @ts-ignore
|
|
202
|
+
if (after_each_callback) after_each_callback();
|
|
203
|
+
// @ts-ignore
|
|
204
|
+
if (before_each_callback) before_each_callback();
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Tests if a is float
|
|
209
|
+
* @returns - void
|
|
210
|
+
*/
|
|
211
|
+
toBeFloat(): void {
|
|
212
|
+
this.verdict = isFloat<T>() ? Verdict.Ok : Verdict.Fail;
|
|
213
|
+
|
|
214
|
+
this._left = nameof<T>();
|
|
215
|
+
this._right = "integer";
|
|
216
|
+
|
|
217
|
+
this.op = "type";
|
|
218
|
+
|
|
219
|
+
// @ts-ignore
|
|
220
|
+
if (after_each_callback) after_each_callback();
|
|
221
|
+
// @ts-ignore
|
|
222
|
+
if (before_each_callback) before_each_callback();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Tests if a is finite
|
|
227
|
+
* @returns - void
|
|
228
|
+
*/
|
|
229
|
+
toBeFinite(): void {
|
|
230
|
+
// @ts-ignore
|
|
231
|
+
this.verdict = ((isFloat<T>() || isInteger<T>()) && isFinite(this.left)) ? Verdict.Ok : Verdict.Fail;
|
|
232
|
+
|
|
233
|
+
this._left = "Infinity";
|
|
234
|
+
this._right = "Finite";
|
|
235
|
+
|
|
236
|
+
this.op = "=";
|
|
237
|
+
|
|
238
|
+
// @ts-ignore
|
|
239
|
+
if (after_each_callback) after_each_callback();
|
|
240
|
+
// @ts-ignore
|
|
241
|
+
if (before_each_callback) before_each_callback();
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
/**
|
|
245
|
+
* Tests if an array has length x
|
|
246
|
+
*
|
|
247
|
+
* @param {i32} value - The value to check
|
|
248
|
+
* @returns - void
|
|
249
|
+
*/
|
|
250
|
+
toHaveLength(value: i32): void {
|
|
251
|
+
// @ts-ignore
|
|
252
|
+
this.verdict = (isArray<T>() && this.left.length == value) ? Verdict.Ok : Verdict.Fail;
|
|
253
|
+
|
|
254
|
+
// @ts-ignore
|
|
255
|
+
this._left = this.left.length.toString();
|
|
256
|
+
this._right = value.toString();
|
|
257
|
+
|
|
258
|
+
this.op = "length";
|
|
259
|
+
|
|
260
|
+
// @ts-ignore
|
|
261
|
+
if (after_each_callback) after_each_callback();
|
|
262
|
+
// @ts-ignore
|
|
263
|
+
if (before_each_callback) before_each_callback();
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/**
|
|
267
|
+
* Tests if an array contains an element
|
|
268
|
+
*
|
|
269
|
+
* @param { valueof<T> } value - The value to check
|
|
270
|
+
* @returns - void
|
|
271
|
+
*/
|
|
272
|
+
// @ts-ignore
|
|
273
|
+
toContain(value: valueof<T>): void {
|
|
274
|
+
// @ts-ignore
|
|
275
|
+
this.verdict = (isArray<T>() && this.left.includes(value)) ? Verdict.Ok : Verdict.Fail;
|
|
276
|
+
|
|
277
|
+
// @ts-ignore
|
|
278
|
+
this._left = "includes value";
|
|
279
|
+
this._right = "does not include value";
|
|
280
|
+
this.op = "=";
|
|
281
|
+
|
|
282
|
+
// @ts-ignore
|
|
283
|
+
if (after_each_callback) after_each_callback();
|
|
284
|
+
// @ts-ignore
|
|
285
|
+
if (before_each_callback) before_each_callback();
|
|
286
|
+
}
|
|
287
|
+
|
|
90
288
|
/**
|
|
91
289
|
* Tests for equality
|
|
92
|
-
* @param
|
|
93
|
-
* @returns -
|
|
290
|
+
* @param {T} equals - The value to test
|
|
291
|
+
* @returns - void
|
|
94
292
|
*/
|
|
95
|
-
toBe(equals: T):
|
|
96
|
-
this
|
|
293
|
+
toBe(equals: T): void {
|
|
294
|
+
store<T>(changetype<usize>(this), equals, offsetof<Expectation<T>>("right"));
|
|
97
295
|
if (isBoolean<T>()) {
|
|
98
|
-
this.verdict = this.left ===
|
|
296
|
+
this.verdict = this.left === equals
|
|
99
297
|
? Verdict.Ok
|
|
100
298
|
: Verdict.Fail;
|
|
101
299
|
|
|
102
300
|
} else if (isString<T>()) {
|
|
103
|
-
this.verdict = this.left ===
|
|
301
|
+
this.verdict = this.left === equals
|
|
104
302
|
? Verdict.Ok
|
|
105
303
|
: Verdict.Fail;
|
|
106
304
|
} else if (isInteger<T>() || isFloat<T>()) {
|
|
107
|
-
this.verdict = this.left ===
|
|
305
|
+
this.verdict = this.left === equals
|
|
108
306
|
? Verdict.Ok
|
|
109
307
|
: Verdict.Fail;
|
|
110
308
|
} else if (isArray<T>()) {
|
|
@@ -115,14 +313,17 @@ export class Expectation<T> extends Node {
|
|
|
115
313
|
|
|
116
314
|
this.op = "=";
|
|
117
315
|
|
|
118
|
-
|
|
316
|
+
// @ts-ignore
|
|
317
|
+
if (after_each_callback) after_each_callback();
|
|
318
|
+
// @ts-ignore
|
|
319
|
+
if (before_each_callback) before_each_callback();
|
|
119
320
|
}
|
|
120
321
|
|
|
121
322
|
report(): string | null {
|
|
122
323
|
if (!this._not && this.verdict === Verdict.Ok) return null;
|
|
123
324
|
|
|
124
|
-
const left = visualize(this.left);
|
|
125
|
-
const right = visualize(this
|
|
325
|
+
const left = this._left || visualize(this.left);
|
|
326
|
+
const right = this._right || visualize(load<T>(changetype<usize>(this), offsetof<Expectation<T>>("right")));
|
|
126
327
|
|
|
127
328
|
if (this._not) {
|
|
128
329
|
if (this.verdict === Verdict.Fail) return null;
|
package/assembly/src/group.ts
CHANGED
package/assembly/src/node.ts
CHANGED
package/assembly/test.ts
CHANGED
|
@@ -1,13 +1,69 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
describe,
|
|
3
|
+
expect,
|
|
4
|
+
test, // Alias for `it`
|
|
5
|
+
beforeAll,
|
|
6
|
+
afterAll,
|
|
7
|
+
beforeEach,
|
|
8
|
+
afterEach,
|
|
9
|
+
log,
|
|
10
|
+
run
|
|
11
|
+
} from ".";
|
|
2
12
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
13
|
+
|
|
14
|
+
// Shared setup for all tests (executed once before all tests)
|
|
15
|
+
beforeAll(() => {
|
|
16
|
+
log("Setting up test environment...");
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Shared teardown for all tests (executed once after all tests)
|
|
20
|
+
afterAll(() => {
|
|
21
|
+
log("Tearing down test environment...");
|
|
9
22
|
});
|
|
10
23
|
|
|
11
|
-
|
|
24
|
+
describe("Math operations", () => {
|
|
25
|
+
// Setup before each test in this group (optional)
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
log("Initializing test...");
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
// Teardown after each test in this group (optional)
|
|
31
|
+
afterEach(() => {
|
|
32
|
+
log("Cleaning up after test...");
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
test("Addition", () => {
|
|
36
|
+
expect(1 + 2).toBe(3);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
test("Comparison", () => {
|
|
40
|
+
expect(5).toBeGreaterThan(3);
|
|
41
|
+
expect(2).toBeLessThan(4);
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
test("Type checking", () => {
|
|
45
|
+
expect("hello").toBeString();
|
|
46
|
+
expect(true).toBeBoolean();
|
|
47
|
+
expect(10.5).toBeNumber();
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
let myArray: i32[] = [];
|
|
52
|
+
|
|
53
|
+
describe("Array manipulation", () => {
|
|
54
|
+
beforeAll(() => {
|
|
55
|
+
myArray = [1, 2, 3];
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
test("Array length", () => {
|
|
59
|
+
expect(myArray).toHaveLength(3);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("Array inclusion", () => {
|
|
63
|
+
expect(myArray).toContain(2);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
12
66
|
|
|
13
|
-
run(
|
|
67
|
+
run({
|
|
68
|
+
log: false
|
|
69
|
+
});
|
package/assembly/util.ts
CHANGED
|
@@ -107,4 +107,10 @@ export function formatTime(ms: number): string {
|
|
|
107
107
|
}
|
|
108
108
|
|
|
109
109
|
return `${us}us`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// @ts-ignore
|
|
113
|
+
@inline
|
|
114
|
+
export function colorText(format: i32[], text: string): string {
|
|
115
|
+
return `\u001b[${format[0].toString()}m${text}\u001b[${format[1].toString()}m`
|
|
110
116
|
}
|
package/jest.test.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "as-test",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Testing framework for AssemblyScript. Compatible with WASI or Bindings ",
|
|
5
5
|
"types": "assembly/index.ts",
|
|
6
6
|
"author": "Jairus Tanaka",
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"typescript": "^5.3.3",
|
|
23
23
|
"visitor-as": "^0.11.4"
|
|
24
24
|
},
|
|
25
|
-
"dependencies": { "as-convert-seconds": "^1.0.0", "as-rainbow": "^0.1.0", "as-string-sink": "^0.5.3", "as-variant": "^0.4.1", "json-as": "^0.9.6" },
|
|
25
|
+
"dependencies": { "as-console": "^6.0.2", "as-convert-seconds": "^1.0.0", "as-rainbow": "^0.1.0", "as-string-sink": "^0.5.3", "as-variant": "^0.4.1", "json-as": "^0.9.6" },
|
|
26
26
|
"overrides": {
|
|
27
27
|
"assemblyscript": "$assemblyscript"
|
|
28
28
|
},
|
package/assembly/src/it.ts
DELETED
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { Variant } from "as-variant/assembly";
|
|
2
|
-
import { Verdict } from "./result";
|
|
3
|
-
import { rainbow } from "as-rainbow";
|
|
4
|
-
import { visualize } from "../util";
|
|
5
|
-
import { StringSink } from "as-string-sink/assembly";
|
|
6
|
-
|
|
7
|
-
export class It {
|
|
8
|
-
public verdict: Verdict = Verdict.Unreachable;
|
|
9
|
-
public left: Variant;
|
|
10
|
-
public right!: Variant;
|
|
11
|
-
private _not: boolean = false;
|
|
12
|
-
constructor(left: Variant) {
|
|
13
|
-
this.left = left;
|
|
14
|
-
}
|
|
15
|
-
not(): It {
|
|
16
|
-
this._not = true;
|
|
17
|
-
return this;
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Tests for strict equality
|
|
21
|
-
* @param any equals - The value to test
|
|
22
|
-
* @returns - Expectation
|
|
23
|
-
*/
|
|
24
|
-
toBe<T>(equals: T): It {
|
|
25
|
-
this.right = Variant.from(equals);
|
|
26
|
-
if (this.left.id !== this.right.id) throw "cannot compare different types";
|
|
27
|
-
|
|
28
|
-
if (isBoolean<T>()) {
|
|
29
|
-
this.verdict = this.left.getUnchecked<T>() === this.right.getUnchecked<T>()
|
|
30
|
-
? Verdict.Ok
|
|
31
|
-
: Verdict.Fail;
|
|
32
|
-
|
|
33
|
-
} else if (isString<T>()) {
|
|
34
|
-
this.verdict = this.left.getUnchecked<T>() === this.right.getUnchecked<T>()
|
|
35
|
-
? Verdict.Ok
|
|
36
|
-
: Verdict.Fail;
|
|
37
|
-
} else if (isInteger<T>() || isFloat<T>()) {
|
|
38
|
-
this.verdict = this.left.getUnchecked<T>() === this.right.getUnchecked<T>()
|
|
39
|
-
? Verdict.Ok
|
|
40
|
-
: Verdict.Fail;
|
|
41
|
-
} else if (isArray<T>()) {
|
|
42
|
-
// getArrayDepth<T>();
|
|
43
|
-
} else {
|
|
44
|
-
this.verdict = Verdict.Unreachable;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
console.log(this.report<T>());
|
|
48
|
-
|
|
49
|
-
return this;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
report<T>(): string {
|
|
53
|
-
if (!this.not && this.verdict === Verdict.Ok) {
|
|
54
|
-
return rainbow.green(" - Test completed successfully");
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
const left = visualize<T>(this.left.getUnchecked<T>());
|
|
58
|
-
const right = visualize<T>(this.right.getUnchecked<T>());
|
|
59
|
-
|
|
60
|
-
if (this._not) {
|
|
61
|
-
if (this.verdict === Verdict.Fail) return rainbow.green(" - Test completed successfully");
|
|
62
|
-
return rainbow.red(" - Test failed") + "\n" + rainbow.italicMk(` ${rainbow.dimMk("(expected) ->")} ${rainbow.bgGreen(left.toString())}\n ${rainbow.dimMk("(recieved) ->")} ${rainbow.bgRed(right.toString())}`);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
let leftDiff = StringSink.withCapacity(left.length);
|
|
66
|
-
let rightDiff = StringSink.withCapacity(right.length);
|
|
67
|
-
|
|
68
|
-
let i = 0
|
|
69
|
-
|
|
70
|
-
for (; i < min(left.length, right.length); i++) {
|
|
71
|
-
const lChar = left.charAt(i);
|
|
72
|
-
const rChar = right.charAt(i);
|
|
73
|
-
if (lChar != rChar) {
|
|
74
|
-
leftDiff.write(rainbow.bgGreen(lChar));
|
|
75
|
-
rightDiff.write(rainbow.bgRed(rChar));
|
|
76
|
-
} else {
|
|
77
|
-
leftDiff.write(lChar);
|
|
78
|
-
rightDiff.write(rChar);
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
for (; i < left.length; i++) {
|
|
83
|
-
leftDiff.write(rainbow.bgGreen(left.charAt(i)));
|
|
84
|
-
rightDiff.write(rainbow.bgRed(" "));
|
|
85
|
-
}
|
|
86
|
-
for (; i < right.length; i++) rightDiff.write(rainbow.bgRed(right.charAt(i)));
|
|
87
|
-
|
|
88
|
-
return rainbow.red(" - Test failed") + "\n" + rainbow.italicMk(` ${rainbow.dimMk("(expected) ->")} ${leftDiff.toString()}\n ${rainbow.dimMk("(recieved) ->")} ${rightDiff.toString()}`);
|
|
89
|
-
}
|
|
90
|
-
}
|
package/assembly/src/result.ts
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Variant } from "as-variant/assembly";
|
|
2
|
-
|
|
3
|
-
export enum Verdict {
|
|
4
|
-
Unreachable,
|
|
5
|
-
Ok,
|
|
6
|
-
Fail,
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export class TestResult {
|
|
10
|
-
public verdict: Verdict = Verdict.Unreachable;
|
|
11
|
-
public left: Variant;
|
|
12
|
-
public right!: Variant;
|
|
13
|
-
constructor(left: Variant) {
|
|
14
|
-
this.left = left;
|
|
15
|
-
}
|
|
16
|
-
toBe<T>(equals: T): TestResult {
|
|
17
|
-
return this;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
report(): string {
|
|
21
|
-
|
|
22
|
-
}
|
|
23
|
-
}
|