@rcompat/test 0.11.3 → 0.12.1
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 +176 -37
- package/lib/private/Suite.d.ts +2 -1
- package/lib/private/Suite.js +9 -2
- package/lib/private/Test.d.ts +2 -1
- package/lib/private/Test.js +6 -1
- package/lib/private/fixtures/math.d.ts +2 -0
- package/lib/private/fixtures/math.js +5 -0
- package/lib/private/import.d.ts +2 -0
- package/lib/private/import.js +4 -0
- package/lib/private/index.d.ts +5 -0
- package/lib/private/index.js +7 -0
- package/lib/private/mock.d.ts +14 -0
- package/lib/private/mock.js +87 -0
- package/lib/private/repository.d.ts +3 -0
- package/lib/private/repository.js +15 -1
- package/package.json +13 -10
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@ Testing library for JavaScript runtimes.
|
|
|
5
5
|
## What is @rcompat/test?
|
|
6
6
|
|
|
7
7
|
A cross-runtime testing library with a fluent assertion API. Provides deep
|
|
8
|
-
equality checks, type assertions, exception testing,
|
|
9
|
-
Designed to work with the `proby` test runner. Works
|
|
10
|
-
Node, Deno, and Bun.
|
|
8
|
+
equality checks, type assertions, exception testing, fetch interception, and
|
|
9
|
+
module mocking. Designed to work with the `proby` test runner. Works
|
|
10
|
+
consistently across Node, Deno, and Bun.
|
|
11
11
|
|
|
12
12
|
## Installation
|
|
13
13
|
|
|
@@ -115,12 +115,12 @@ test.case("throws", assert => {
|
|
|
115
115
|
// check that function throws
|
|
116
116
|
assert(() => {
|
|
117
117
|
throw new Error("oops");
|
|
118
|
-
}).throws();
|
|
118
|
+
}).throws("oops");
|
|
119
119
|
|
|
120
|
-
// Check specific error
|
|
120
|
+
// Check specific error type
|
|
121
121
|
assert(() => {
|
|
122
|
-
throw new
|
|
123
|
-
}).throws(
|
|
122
|
+
throw new TypeError("invalid input");
|
|
123
|
+
}).throws(TypeError);
|
|
124
124
|
});
|
|
125
125
|
|
|
126
126
|
test.case("tries (does not throw)", assert => {
|
|
@@ -178,6 +178,106 @@ test.ended(async () => {
|
|
|
178
178
|
});
|
|
179
179
|
```
|
|
180
180
|
|
|
181
|
+
### Grouping tests
|
|
182
|
+
|
|
183
|
+
Use `test.group` to cluster related test cases together. Groups can be run
|
|
184
|
+
individually via proby.
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
import test from "@rcompat/test";
|
|
188
|
+
|
|
189
|
+
test.group("addition", () => {
|
|
190
|
+
test.case("integers", assert => {
|
|
191
|
+
assert(1 + 1).equals(2);
|
|
192
|
+
});
|
|
193
|
+
|
|
194
|
+
test.case("floats", assert => {
|
|
195
|
+
assert(0.1 + 0.2).equals(0.3);
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test.group("subtraction", () => {
|
|
200
|
+
test.case("integers", assert => {
|
|
201
|
+
assert(3 - 1).equals(2);
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
Run a specific group:
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
npx proby math.spec.ts addition
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Mocking modules
|
|
213
|
+
|
|
214
|
+
Use `test.mock` to replace a module's exports and `test.import` to import the
|
|
215
|
+
mocked module.
|
|
216
|
+
|
|
217
|
+
```js
|
|
218
|
+
import test from "@rcompat/test";
|
|
219
|
+
|
|
220
|
+
using math = test.mock("./math.ts", () => ({
|
|
221
|
+
add: (a, b) => 99,
|
|
222
|
+
}));
|
|
223
|
+
|
|
224
|
+
const { add } = await test.import("./math.ts");
|
|
225
|
+
|
|
226
|
+
test.case("returns mocked value", assert => {
|
|
227
|
+
assert(add(1, 2)).equals(99);
|
|
228
|
+
});
|
|
229
|
+
|
|
230
|
+
test.case("tracks calls", assert => {
|
|
231
|
+
add(1, 2);
|
|
232
|
+
assert(math.add.calls.length).equals(1);
|
|
233
|
+
assert(math.add.calls[0]).equals([1, 2]);
|
|
234
|
+
assert(math.add.called).true();
|
|
235
|
+
});
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Tracked mock functions record each call as a tuple of arguments in `calls`.
|
|
239
|
+
Call tracking resets between test cases.
|
|
240
|
+
|
|
241
|
+
### Static mocks with proby
|
|
242
|
+
|
|
243
|
+
When running tests with `proby`, you can preload mocks before a spec file is
|
|
244
|
+
evaluated by adding a sibling mock file.
|
|
245
|
+
|
|
246
|
+
- `foo.spec.ts` pairs with `foo.mock.ts`
|
|
247
|
+
- `foo.spec.js` pairs with `foo.mock.js`
|
|
248
|
+
|
|
249
|
+
`proby` loads the mock file before the spec file, so the spec's static imports
|
|
250
|
+
see the mocked module immediately.
|
|
251
|
+
|
|
252
|
+
```ts
|
|
253
|
+
// math.ts
|
|
254
|
+
export function add(a: number, b: number) {
|
|
255
|
+
return a + b;
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
// math.mock.ts
|
|
261
|
+
import test from "@rcompat/test";
|
|
262
|
+
|
|
263
|
+
test.mock("./math.ts", () => ({
|
|
264
|
+
add: (a: number, b: number) => 99,
|
|
265
|
+
}));
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
```ts
|
|
269
|
+
// math.spec.ts
|
|
270
|
+
import test from "@rcompat/test";
|
|
271
|
+
import { add } from "./math.ts";
|
|
272
|
+
|
|
273
|
+
test.case("static mock is loaded before the spec", assert => {
|
|
274
|
+
assert(add(1, 2)).equals(99);
|
|
275
|
+
});
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
Static mocks are file-scoped when run through `proby`; they do not leak into
|
|
279
|
+
later spec files.
|
|
280
|
+
|
|
181
281
|
### Intercepting fetch
|
|
182
282
|
|
|
183
283
|
Use `test.intercept` to block outbound fetch calls to a specific origin and
|
|
@@ -283,6 +383,45 @@ test.ended(callback: () => void | Promise<void>): void;
|
|
|
283
383
|
|
|
284
384
|
Register a cleanup callback to run after all tests in the file.
|
|
285
385
|
|
|
386
|
+
### `test.group`
|
|
387
|
+
|
|
388
|
+
```ts
|
|
389
|
+
test.group(name: string, fn: () => void): void;
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
Group test cases under a named scope. Groups can be targeted individually
|
|
393
|
+
when running proby.
|
|
394
|
+
|
|
395
|
+
| Parameter | Type | Description |
|
|
396
|
+
| --------- | ---------- | ----------------------------------- |
|
|
397
|
+
| `name` | `string` | Group name, used by proby to filter |
|
|
398
|
+
| `fn` | `function` | Function containing `test.case` calls |
|
|
399
|
+
|
|
400
|
+
### `test.mock`
|
|
401
|
+
|
|
402
|
+
```ts
|
|
403
|
+
test.mock<T extends object>(
|
|
404
|
+
specifier: string,
|
|
405
|
+
factory: (original: unknown) => T,
|
|
406
|
+
): MockHandle<T>;
|
|
407
|
+
```
|
|
408
|
+
|
|
409
|
+
Register a module mock and return a handle to the tracked mocked exports.
|
|
410
|
+
Function exports are wrapped so you can inspect `calls` and `called`.
|
|
411
|
+
|
|
412
|
+
| Parameter | Type | Description |
|
|
413
|
+
| ----------- | ---------- | -------------------------------------------- |
|
|
414
|
+
| `specifier` | `string` | Module specifier to mock |
|
|
415
|
+
| `factory` | `function` | Returns the mocked exports for that module |
|
|
416
|
+
|
|
417
|
+
### `test.import`
|
|
418
|
+
|
|
419
|
+
```ts
|
|
420
|
+
test.import(specifier: string): Promise<unknown>;
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
Import a module after mocks have been registered.
|
|
424
|
+
|
|
286
425
|
### `test.intercept`
|
|
287
426
|
|
|
288
427
|
```ts
|
|
@@ -295,32 +434,10 @@ test.intercept(
|
|
|
295
434
|
Intercept outbound fetch calls to `base_url`. Returns an `Intercept` object
|
|
296
435
|
for asserting on recorded requests.
|
|
297
436
|
|
|
298
|
-
| Parameter | Type | Description
|
|
299
|
-
| ---------- | ---------- |
|
|
300
|
-
| `base_url` | `string` | Origin to intercept, e.g. `"https://api.example.com"`
|
|
301
|
-
| `setup` | `function` | Register route handlers on the setup object
|
|
302
|
-
|
|
303
|
-
#### `Setup`
|
|
304
|
-
|
|
305
|
-
| Method | Description |
|
|
306
|
-
| ------------------------------- | ---------------------------- |
|
|
307
|
-
| `get(path, handler)` | Register a GET handler |
|
|
308
|
-
| `post(path, handler)` | Register a POST handler |
|
|
309
|
-
| `put(path, handler)` | Register a PUT handler |
|
|
310
|
-
| `patch(path, handler)` | Register a PATCH handler |
|
|
311
|
-
| `delete(path, handler)` | Register a DELETE handler |
|
|
312
|
-
|
|
313
|
-
Each handler receives the incoming `Request` and returns a plain object,
|
|
314
|
-
which is serialized into a `Response` automatically.
|
|
315
|
-
|
|
316
|
-
#### `Intercept`
|
|
317
|
-
|
|
318
|
-
| Method | Description |
|
|
319
|
-
| ------------------- | ---------------------------------------------------- |
|
|
320
|
-
| `calls(path)` | Number of times `path` was hit |
|
|
321
|
-
| `requests(path)` | Array of `Request` objects recorded for `path` |
|
|
322
|
-
| `restore()` | Reinstate the original `globalThis.fetch` |
|
|
323
|
-
| `[Symbol.asyncDispose]` | Called automatically by `await using` |
|
|
437
|
+
| Parameter | Type | Description |
|
|
438
|
+
| ---------- | ---------- | --------------------------------------------------------- |
|
|
439
|
+
| `base_url` | `string` | Origin to intercept, e.g. `"https://api.example.com"` |
|
|
440
|
+
| `setup` | `function` | Register route handlers on the setup object |
|
|
324
441
|
|
|
325
442
|
### `test.extend`
|
|
326
443
|
|
|
@@ -333,9 +450,31 @@ test.extend<Subject, Extensions>(
|
|
|
333
450
|
Create a new test object with custom assertion methods mixed into the
|
|
334
451
|
asserter.
|
|
335
452
|
|
|
336
|
-
| Parameter | Type | Description
|
|
337
|
-
| --------- | ---------- |
|
|
338
|
-
| `factory` | `function` | Returns extra methods to attach to each `Assert` instance
|
|
453
|
+
| Parameter | Type | Description |
|
|
454
|
+
| --------- | ---------- | ---------------------------------------------------------- |
|
|
455
|
+
| `factory` | `function` | Returns extra methods to attach to each `Assert` instance |
|
|
456
|
+
|
|
457
|
+
#### `Setup`
|
|
458
|
+
|
|
459
|
+
| Method | Description |
|
|
460
|
+
| ---------------------- | ------------------------- |
|
|
461
|
+
| `get(path, handler)` | Register a GET handler |
|
|
462
|
+
| `post(path, handler)` | Register a POST handler |
|
|
463
|
+
| `put(path, handler)` | Register a PUT handler |
|
|
464
|
+
| `patch(path, handler)` | Register a PATCH handler |
|
|
465
|
+
| `delete(path, handler)`| Register a DELETE handler |
|
|
466
|
+
|
|
467
|
+
Each handler receives the incoming `Request` and returns a plain object,
|
|
468
|
+
which is serialized into a `Response` automatically.
|
|
469
|
+
|
|
470
|
+
#### `Intercept`
|
|
471
|
+
|
|
472
|
+
| Method | Description |
|
|
473
|
+
| ----------------------- | ----------------------------------------------- |
|
|
474
|
+
| `calls(path)` | Number of times `path` was hit |
|
|
475
|
+
| `requests(path)` | Array of `Request` objects recorded for `path` |
|
|
476
|
+
| `restore()` | Reinstate the original `globalThis.fetch` |
|
|
477
|
+
| `[Symbol.asyncDispose]` | Called automatically by `await using` |
|
|
339
478
|
|
|
340
479
|
### `Asserter`
|
|
341
480
|
|
|
@@ -406,7 +545,7 @@ import E from "@rcompat/test/E";
|
|
|
406
545
|
E(error: unknown): { message: string };
|
|
407
546
|
```
|
|
408
547
|
|
|
409
|
-
Extract error
|
|
548
|
+
Extract error data from unknown error types.
|
|
410
549
|
|
|
411
550
|
## Examples
|
|
412
551
|
|
package/lib/private/Suite.d.ts
CHANGED
|
@@ -5,9 +5,10 @@ import type { FileRef } from "@rcompat/fs";
|
|
|
5
5
|
export default class Suite {
|
|
6
6
|
#private;
|
|
7
7
|
constructor(file: FileRef);
|
|
8
|
-
test(name: string, body: Body): void;
|
|
8
|
+
test(name: string, body: Body, group?: string): void;
|
|
9
9
|
ended(end: End): void;
|
|
10
10
|
get file(): FileRef;
|
|
11
|
+
between(fn: () => void): void;
|
|
11
12
|
run(): AsyncGenerator<Test, void, unknown>;
|
|
12
13
|
end(): Promise<void>;
|
|
13
14
|
}
|
package/lib/private/Suite.js
CHANGED
|
@@ -3,11 +3,12 @@ export default class Suite {
|
|
|
3
3
|
#file;
|
|
4
4
|
#tests = [];
|
|
5
5
|
#ends = [];
|
|
6
|
+
#between = [];
|
|
6
7
|
constructor(file) {
|
|
7
8
|
this.#file = file;
|
|
8
9
|
}
|
|
9
|
-
test(name, body) {
|
|
10
|
-
this.#tests.push(new Test(name, body));
|
|
10
|
+
test(name, body, group) {
|
|
11
|
+
this.#tests.push(new Test(name, body, group));
|
|
11
12
|
}
|
|
12
13
|
ended(end) {
|
|
13
14
|
this.#ends.push(end);
|
|
@@ -15,9 +16,15 @@ export default class Suite {
|
|
|
15
16
|
get file() {
|
|
16
17
|
return this.#file;
|
|
17
18
|
}
|
|
19
|
+
between(fn) {
|
|
20
|
+
this.#between.push(fn);
|
|
21
|
+
}
|
|
18
22
|
async *run() {
|
|
19
23
|
for (const test of this.#tests) {
|
|
20
24
|
yield await test.run();
|
|
25
|
+
for (const fn of this.#between) {
|
|
26
|
+
fn();
|
|
27
|
+
}
|
|
21
28
|
}
|
|
22
29
|
}
|
|
23
30
|
async end() {
|
package/lib/private/Test.d.ts
CHANGED
|
@@ -2,8 +2,9 @@ import type Body from "#Body";
|
|
|
2
2
|
import Result from "#Result";
|
|
3
3
|
export default class Test {
|
|
4
4
|
#private;
|
|
5
|
-
constructor(name: string, body: Body);
|
|
5
|
+
constructor(name: string, body: Body, group?: string);
|
|
6
6
|
get name(): string;
|
|
7
|
+
get group(): string | undefined;
|
|
7
8
|
get results(): Result<unknown>[];
|
|
8
9
|
report<T>(actual: T, expected: T, passed: boolean): void;
|
|
9
10
|
run(): Promise<this>;
|
package/lib/private/Test.js
CHANGED
|
@@ -4,13 +4,18 @@ export default class Test {
|
|
|
4
4
|
#name;
|
|
5
5
|
#body;
|
|
6
6
|
#results = [];
|
|
7
|
-
|
|
7
|
+
#group;
|
|
8
|
+
constructor(name, body, group) {
|
|
8
9
|
this.#name = name;
|
|
9
10
|
this.#body = body;
|
|
11
|
+
this.#group = group;
|
|
10
12
|
}
|
|
11
13
|
get name() {
|
|
12
14
|
return this.#name;
|
|
13
15
|
}
|
|
16
|
+
get group() {
|
|
17
|
+
return this.#group;
|
|
18
|
+
}
|
|
14
19
|
get results() {
|
|
15
20
|
return this.#results;
|
|
16
21
|
}
|
package/lib/private/index.d.ts
CHANGED
|
@@ -5,6 +5,8 @@ import type Env from "#Env";
|
|
|
5
5
|
import type Result from "#Result";
|
|
6
6
|
import type Test from "#Test";
|
|
7
7
|
import type { ExtendedTest, Factory } from "#extend";
|
|
8
|
+
import mock from "#mock";
|
|
9
|
+
import import_ from "#import";
|
|
8
10
|
declare const _default: {
|
|
9
11
|
intercept: (base_url: string, setup: (setup: {
|
|
10
12
|
get(path: string, handler: (request: Request) => unknown): void;
|
|
@@ -21,6 +23,9 @@ declare const _default: {
|
|
|
21
23
|
extend<Subject, Extensions>(factory: Factory<Subject, Extensions>): ExtendedTest<Extensions>;
|
|
22
24
|
case(name: string, body: Body): void;
|
|
23
25
|
ended(end: End): void;
|
|
26
|
+
group(name: string, fn: () => void): void;
|
|
27
|
+
mock: typeof mock;
|
|
28
|
+
import: typeof import_;
|
|
24
29
|
};
|
|
25
30
|
export default _default;
|
|
26
31
|
export type { Asserter, Env, ExtendedTest, Result, Test };
|
package/lib/private/index.js
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import extend from "#extend";
|
|
2
2
|
import repository from "#repository";
|
|
3
3
|
import intercept from "#intercept";
|
|
4
|
+
import mock from "#mock";
|
|
5
|
+
import import_ from "#import";
|
|
4
6
|
const base = {
|
|
5
7
|
case(name, body) {
|
|
6
8
|
repository.put(name, body);
|
|
@@ -8,6 +10,11 @@ const base = {
|
|
|
8
10
|
ended(end) {
|
|
9
11
|
repository.ended(end);
|
|
10
12
|
},
|
|
13
|
+
group(name, fn) {
|
|
14
|
+
repository.group(name, fn);
|
|
15
|
+
},
|
|
16
|
+
mock,
|
|
17
|
+
import: import_,
|
|
11
18
|
};
|
|
12
19
|
export default {
|
|
13
20
|
...base,
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
type AnyFn = (...args: any[]) => any;
|
|
2
|
+
type Tracked<F extends AnyFn> = F & {
|
|
3
|
+
calls: Parameters<F>[];
|
|
4
|
+
readonly called: boolean;
|
|
5
|
+
};
|
|
6
|
+
type MockHandle<T extends object> = {
|
|
7
|
+
[K in keyof T]: T[K] extends AnyFn ? Tracked<T[K]> : T[K];
|
|
8
|
+
} & {
|
|
9
|
+
restore(): void;
|
|
10
|
+
[Symbol.dispose](): void;
|
|
11
|
+
};
|
|
12
|
+
export default function mock<T extends object>(specifier: string, factory: (original: unknown) => T): MockHandle<T>;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=mock.d.ts.map
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import repository from "#repository";
|
|
2
|
+
import is from "@rcompat/is";
|
|
3
|
+
import module from "node:module";
|
|
4
|
+
let loader_registered = false;
|
|
5
|
+
const MARK = "std:test/mock";
|
|
6
|
+
const clean = (specifier) => specifier.split("?")[0];
|
|
7
|
+
const track = (fn) => {
|
|
8
|
+
const calls = [];
|
|
9
|
+
const tracked = ((...args) => {
|
|
10
|
+
calls.push(args);
|
|
11
|
+
return fn(...args);
|
|
12
|
+
});
|
|
13
|
+
tracked.calls = calls;
|
|
14
|
+
Object.defineProperty(tracked, "called", {
|
|
15
|
+
get: () => calls.length > 0,
|
|
16
|
+
});
|
|
17
|
+
return tracked;
|
|
18
|
+
};
|
|
19
|
+
const hooks = {
|
|
20
|
+
resolve(specifier, context, next) {
|
|
21
|
+
const id = clean(specifier);
|
|
22
|
+
if (!repository.mocks.has(id)) {
|
|
23
|
+
return next(specifier, context);
|
|
24
|
+
}
|
|
25
|
+
const resolved = next(id, context);
|
|
26
|
+
const url = new URL(resolved.url);
|
|
27
|
+
url.searchParams.set(MARK, id);
|
|
28
|
+
return {
|
|
29
|
+
...resolved,
|
|
30
|
+
shortCircuit: true,
|
|
31
|
+
url: url.href,
|
|
32
|
+
};
|
|
33
|
+
},
|
|
34
|
+
load(url, context, next) {
|
|
35
|
+
const parsed = new URL(url);
|
|
36
|
+
const id = parsed.searchParams.get(MARK);
|
|
37
|
+
if (id === null) {
|
|
38
|
+
return next(url, context);
|
|
39
|
+
}
|
|
40
|
+
const tracked = repository.mocks.get(id);
|
|
41
|
+
if (tracked === undefined)
|
|
42
|
+
throw new Error(`mock not found for ${id}`);
|
|
43
|
+
const exports = Object.keys(tracked);
|
|
44
|
+
const source = `
|
|
45
|
+
import repository from "@rcompat/test/repository";
|
|
46
|
+
const tracked = repository.mocks.get(${JSON.stringify(id)});
|
|
47
|
+
if (tracked === undefined) {
|
|
48
|
+
throw new Error(${JSON.stringify(`mock not found for ${id}`)});
|
|
49
|
+
}
|
|
50
|
+
${exports.map(k => `export const ${k} = tracked[${JSON.stringify(k)}];`).join("\n")}
|
|
51
|
+
`;
|
|
52
|
+
return {
|
|
53
|
+
format: "module",
|
|
54
|
+
shortCircuit: true,
|
|
55
|
+
source,
|
|
56
|
+
};
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
export default function mock(specifier, factory) {
|
|
60
|
+
if (!loader_registered) {
|
|
61
|
+
module.registerHooks(hooks);
|
|
62
|
+
loader_registered = true;
|
|
63
|
+
}
|
|
64
|
+
const id = clean(specifier);
|
|
65
|
+
const mocked = factory({});
|
|
66
|
+
const tracked = Object.fromEntries(Object.entries(mocked).map(([k, v]) => [
|
|
67
|
+
k,
|
|
68
|
+
is.function(v) ? track(v) : v,
|
|
69
|
+
]));
|
|
70
|
+
repository.mocks.set(id, tracked);
|
|
71
|
+
repository.between(() => {
|
|
72
|
+
for (const v of Object.values(tracked)) {
|
|
73
|
+
if (is.function(v) && "calls" in v) {
|
|
74
|
+
v.calls.length = 0;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
return Object.assign(tracked, {
|
|
79
|
+
restore() {
|
|
80
|
+
repository.mocks.delete(id);
|
|
81
|
+
},
|
|
82
|
+
[Symbol.dispose]() {
|
|
83
|
+
this.restore();
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=mock.js.map
|
|
@@ -4,7 +4,10 @@ import Suite from "#Suite";
|
|
|
4
4
|
import type { FileRef } from "@rcompat/fs";
|
|
5
5
|
declare class Repository {
|
|
6
6
|
#private;
|
|
7
|
+
get mocks(): Map<string, unknown>;
|
|
7
8
|
put(name: string, body: Body): void;
|
|
9
|
+
group(name: string, fn: () => void): void;
|
|
10
|
+
between(fn: () => void): void;
|
|
8
11
|
ended(end: End): void;
|
|
9
12
|
suite(file: FileRef): void;
|
|
10
13
|
reset(): void;
|
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
import Suite from "#Suite";
|
|
2
2
|
class Repository {
|
|
3
3
|
#suites = [];
|
|
4
|
+
#current_group;
|
|
5
|
+
#mocks = new Map();
|
|
4
6
|
get #suite() {
|
|
5
7
|
return this.#suites.at(-1);
|
|
6
8
|
}
|
|
9
|
+
get mocks() {
|
|
10
|
+
return this.#mocks;
|
|
11
|
+
}
|
|
7
12
|
put(name, body) {
|
|
8
|
-
this.#suite.test(name, body);
|
|
13
|
+
this.#suite.test(name, body, this.#current_group);
|
|
14
|
+
}
|
|
15
|
+
group(name, fn) {
|
|
16
|
+
this.#current_group = name;
|
|
17
|
+
fn();
|
|
18
|
+
this.#current_group = undefined;
|
|
19
|
+
}
|
|
20
|
+
between(fn) {
|
|
21
|
+
this.#suite.between(fn);
|
|
9
22
|
}
|
|
10
23
|
ended(end) {
|
|
11
24
|
this.#suite.ended(end);
|
|
@@ -15,6 +28,7 @@ class Repository {
|
|
|
15
28
|
}
|
|
16
29
|
reset() {
|
|
17
30
|
this.#suites = [];
|
|
31
|
+
this.#mocks = new Map();
|
|
18
32
|
}
|
|
19
33
|
*next() {
|
|
20
34
|
for (const suite of this.#suites) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rcompat/test",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.1",
|
|
4
4
|
"description": "Standard library testing",
|
|
5
5
|
"bugs": "https://github.com/rcompat/rcompat/issues",
|
|
6
6
|
"license": "MIT",
|
|
@@ -14,42 +14,45 @@
|
|
|
14
14
|
"url": "https://github.com/rcompat/rcompat",
|
|
15
15
|
"directory": "packages/test"
|
|
16
16
|
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"@rcompat/is": "^0.6.1"
|
|
19
|
+
},
|
|
17
20
|
"devDependencies": {
|
|
18
|
-
"@rcompat/fs": "^0.
|
|
19
|
-
"@rcompat/type": "^0.
|
|
21
|
+
"@rcompat/fs": "^0.28.1",
|
|
22
|
+
"@rcompat/type": "^0.11.1"
|
|
20
23
|
},
|
|
21
24
|
"type": "module",
|
|
22
25
|
"imports": {
|
|
23
26
|
"#mask/*": {
|
|
24
|
-
"
|
|
27
|
+
"@rcompat/source": "./src/private/mask/*.ts",
|
|
25
28
|
"default": "./lib/private/mask/*.js"
|
|
26
29
|
},
|
|
27
30
|
"#types/*": {
|
|
28
|
-
"
|
|
31
|
+
"@rcompat/source": "./src/private/types/*.ts",
|
|
29
32
|
"default": "./lib/private/types/*.js"
|
|
30
33
|
},
|
|
31
34
|
"#*": {
|
|
32
|
-
"
|
|
35
|
+
"@rcompat/source": "./src/private/*.ts",
|
|
33
36
|
"default": "./lib/private/*.js"
|
|
34
37
|
}
|
|
35
38
|
},
|
|
36
39
|
"exports": {
|
|
37
40
|
"./mask/*": {
|
|
38
|
-
"
|
|
41
|
+
"@rcompat/source": "./src/public/mask/*.ts",
|
|
39
42
|
"default": "./lib/public/mask/*.js"
|
|
40
43
|
},
|
|
41
44
|
"./*": {
|
|
42
|
-
"
|
|
45
|
+
"@rcompat/source": "./src/public/*.ts",
|
|
43
46
|
"default": "./lib/public/*.js"
|
|
44
47
|
},
|
|
45
48
|
".": {
|
|
46
|
-
"
|
|
49
|
+
"@rcompat/source": "./src/public/index.ts",
|
|
47
50
|
"default": "./lib/public/index.js"
|
|
48
51
|
}
|
|
49
52
|
},
|
|
50
53
|
"scripts": {
|
|
51
54
|
"build": "npm run clean && tsc",
|
|
52
|
-
"test": "
|
|
55
|
+
"test": "npx proby",
|
|
53
56
|
"clean": "rm -rf ./lib"
|
|
54
57
|
}
|
|
55
58
|
}
|