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 CHANGED
@@ -1,10 +1,10 @@
1
1
  <h5 align="center">
2
- <pre>
3
- _____ _____ _____ _____ _____ _____
4
- | _ | __|___|_ _| __| __|_ _|
5
- | |__ |___| | | | __|__ | | |
6
- |__|__|_____| |_| |_____|_____| |_|
7
- v0.0.2
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
- describe("Should create suite", () => {
27
- expect("foo").toBe("foo");
28
- expect(3.14).toBeGreaterThan(0.0);
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
- run();
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 { Verdict } from "./src/result";
5
- import { formatTime } from "./util";
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
- * // Tests go here
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
- export function run(): void {
45
- console.log(rainbow.boldMk(rainbow.blue(
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.bgGreen(" PASS ") + " " + rainbow.dimMk(suite.description) + "\n");
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
- public right!: T;
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
- toBeNull(): Expectation<T> {
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.right = null;
25
-
31
+ store<T>(changetype<usize>(this), null, offsetof<Expectation<T>>("right"));
32
+
26
33
  this.op = "="
27
34
 
28
- return this;
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 - Expectation
44
+ * @returns - void
34
45
  */
35
- toBeGreaterThan(value: T): Expectation<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.right = value;
50
+ store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
40
51
 
41
52
  this.op = ">";
42
53
 
43
- return this;
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 - Expectation
63
+ * @returns - void
49
64
  */
50
- toBeGreaterOrEqualTo(value: T): Expectation<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.right = value;
69
+ store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
55
70
 
56
71
  this.op = ">=";
57
72
 
58
- return this;
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 - Expectation
82
+ * @returns - void
64
83
  */
65
- toBeLessThan(value: T): Expectation<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.right = value;
88
+ store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
70
89
 
71
90
  this.op = "<";
72
91
 
73
- return this;
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 - Expectation
101
+ * @returns - void
79
102
  */
80
- toBeLessThanOrEqualTo(value: T): Expectation<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.right = value;
107
+ store<T>(changetype<usize>(this), value, offsetof<Expectation<T>>("right"));
85
108
 
86
109
  this.op = "<=";
87
110
 
88
- return this;
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 any equals - The value to test
93
- * @returns - Expectation
290
+ * @param {T} equals - The value to test
291
+ * @returns - void
94
292
  */
95
- toBe(equals: T): Expectation<T> {
96
- this.right = equals;
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 === this.right
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 === this.right
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 === this.right
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
- return this;
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.right);
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;
@@ -1,6 +1,6 @@
1
+ import { Verdict } from "..";
1
2
  import { Expectation } from "./expectation";
2
3
  import { Node } from "./node";
3
- import { Verdict } from "./result";
4
4
  export class TestGroup {
5
5
  public results: Node[] = [];
6
6
 
@@ -1,4 +1,4 @@
1
- import { Verdict } from "./result";
1
+ import { Verdict } from "..";
2
2
 
3
3
  export class Node {
4
4
  public verdict: Verdict = Verdict.Unreachable;
package/assembly/test.ts CHANGED
@@ -1,13 +1,69 @@
1
- import { describe, expect, run } from ".";
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
- describe("Should create suite successfully", () => {
4
- expect("foo joe momma joe mommmmma").toBe("booq2132132312");
5
- expect("abcdefg").not.toBe("abcdefg");
6
- expect("hello").toBe("hello");
7
- expect<Nullable | null>(null).toBeNull();
8
- expect(5).toBeGreaterOrEqualTo(9)
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
- class Nullable { }
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
@@ -1,5 +1,5 @@
1
1
  describe("Should create suite successfully", () => {
2
2
  expect("foo joe momma joe mommmmma").toBe("booq2132132312");
3
3
  expect("abcdefg").not.toBe("abcdefg");
4
- expect("hello").toBe("hello")
4
+ expect("hello").toBe("hello");
5
5
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "as-test",
3
- "version": "0.0.2",
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
  },
@@ -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
- }
@@ -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
- }