Skip to content

Commit cd86013

Browse files
committed
WIP
1 parent 00b8fcd commit cd86013

12 files changed

Lines changed: 177 additions & 65 deletions

File tree

.gitignore

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -130,4 +130,7 @@ dist
130130
.pnp.*
131131

132132
.npmrc
133-
.deno.lock
133+
deno.lock
134+
bun.lockb
135+
package.json
136+
bunfig.toml

README.md

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,15 @@ Truly cross runtime minimal testing framework working in collaboration with @std
88

99
## Install
1010

11-
Example for deno and node
11+
Node:
1212

1313
```
1414
npx jsr add @cross/test @std/assert
15+
```
16+
17+
Deno:
18+
19+
```
1520
deno add @cross/test @std/assert
1621
```
1722

@@ -23,16 +28,32 @@ my.test.js
2328
import { test } from "@cross/test";
2429
import { assertEquals, assertNotEquals } from "@std/assert";
2530

26-
test("Addition", {}, () => {
27-
assertEquals(2 + 3, 5);
28-
assertEquals(10 + -5, 5);
31+
// Simple test
32+
test("Multiplication", () => {
33+
assertEquals(5 * 4, 20);
2934
});
3035

31-
test("Multiplication", {}, () => {
32-
assertNotEquals(5 * 5, 20);
36+
// Simple test with timeout
37+
test("Multiplication with timeout", () => {
38+
assertEquals(5 * 4, 20);
39+
}, { timeout: 1000 });
40+
41+
// Test with done callback (useful for async operations)
42+
test("Async test", (context, done) => {
43+
setTimeout(() => {
44+
done(); // Signal test completion
45+
}, 500);
46+
47+
assertEquals(2 + 2, 4);
3348
});
3449
```
3550

3651
## Running the tests
3752

38-
Deno: `deno test` Node: `node --test`
53+
Node:
54+
55+
`node --test`
56+
57+
Deno:
58+
59+
`deno test`

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@cross/test",
3-
"version": "0.0.5",
3+
"version": "0.0.6",
44
"exports": "./mod.ts",
55
"fmt": {
66
"lineWidth": 200

deno.lock

Lines changed: 7 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

mod.test.js

Lines changed: 0 additions & 15 deletions
This file was deleted.

mod.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { test } from "./mod.ts";
2+
import { assertEquals, assertNotEquals, assertThrows } from "@std/assert";
3+
4+
// Simple test
5+
test("Multiplication", () => {
6+
assertEquals(5 * 4, 20);
7+
});
8+
9+
// Simple test with timeout
10+
test("Multiplication with timeout", () => {
11+
assertEquals(5 * 4, 20);
12+
}, { timeout: 1000 });
13+
14+
// Test with done callback (useful for async operations)
15+
test("Async test", (_context, done) => {
16+
setTimeout(() => {
17+
assertNotEquals(2 + 2, 4);
18+
done(); // Signal test completion
19+
}, 500);
20+
}, { waitForCallback: true});

mod.ts

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,15 @@
11
import { CurrentRuntime, Runtime } from "@cross/runtime";
22

3+
/**
4+
* Test subject
5+
*/
6+
export type TestSubject = (context: unknown | undefined, done: (value?: unknown) => void) => void | Promise<void>;
7+
38
/**
49
* Runtime independent test function
510
*/
611
export interface WrappedTest {
7-
(name: string, options: WrappedTestOptions, testFn: () => Promise<void>): Promise<void>;
12+
(name: string, testFn: TestSubject, options?: WrappedTestOptions): Promise<void>;
813
}
914

1015
/**
@@ -13,26 +18,31 @@ export interface WrappedTest {
1318
export interface WrappedTestOptions {
1419
timeout?: number; // Timeout duration in milliseconds (optional)
1520
skip?: boolean; // Whether to skip the test (optional)
21+
waitForCallback?: boolean; // Whether to wait for the done-callback to be called
1622
}
1723

18-
let wrappedTestToUse: WrappedTest | undefined;
24+
let wrappedTestToUse: WrappedTest;
1925
if (CurrentRuntime == Runtime.Deno) {
20-
const { wrappedTest } = await import("./shims/deno.js");
26+
const { wrappedTest } = await import("./shims/deno.ts");
2127
// @ts-ignore js
2228
wrappedTestToUse = wrappedTest;
2329
} else if (CurrentRuntime == Runtime.Node) {
24-
const { wrappedTest } = await import("./shims/node.js");
30+
const { wrappedTest } = await import("./shims/node.ts");
31+
// @ts-ignore js
32+
wrappedTestToUse = wrappedTest;
33+
} else if (CurrentRuntime == Runtime.Bun) {
34+
const { wrappedTest } = await import("./shims/bun.ts");
2535
// @ts-ignore js
2636
wrappedTestToUse = wrappedTest;
2737
} else {
2838
throw new Error("Unsupported runtime");
2939
}
3040
/**
3141
* Defines and executes a single test.
32-
* @param {string} name - The name of the test.
33-
* @param {any} options - Options for the test (structure depends on your shim)
34-
* @param {() => Promise<void>} testFn - The function containing the test logic.
42+
* @param name - The name of the test.
43+
* @param options? - Options for the test (structure depends on your shim)
44+
* @param testFn - The function containing the test logic.
3545
*/
36-
export async function test(name: string, options: WrappedTestOptions, testFn: () => Promise<void>) {
37-
if (wrappedTestToUse) await wrappedTestToUse(name, options, testFn);
46+
export async function test(name: string, testFn: TestSubject, options: WrappedTestOptions = {}) {
47+
await wrappedTestToUse(name, testFn, options);
3848
}

shims/bun.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { test } from "bun:test";
2+
import { TestSubject, WrappedTestOptions } from "../mod.ts";
3+
4+
export async function wrappedTest(
5+
name: string,
6+
testFn: TestSubject,
7+
options: WrappedTestOptions
8+
) {
9+
return await test(name, async () => {
10+
// Adapt the context here
11+
let testFnPromise = undefined;
12+
const callbackPromise = new Promise((resolve, reject) => {
13+
testFnPromise = testFn(undefined, (e) => { if (e) { reject(e) } else { resolve(0) }});
14+
});
15+
let timeoutId: number = -1; // Store the timeout ID
16+
try {
17+
if (options.timeout) {
18+
const timeoutPromise = new Promise((_, reject) => {
19+
timeoutId = setTimeout(() => {
20+
reject(new Error("Test timed out"));
21+
}, options.timeout);
22+
});
23+
await Promise.race([options.waitForCallback ? callbackPromise : testFnPromise, timeoutPromise]);
24+
} else {
25+
// No timeout, just await testFn
26+
await options.waitForCallback ? callbackPromise : testFnPromise;
27+
}
28+
} catch (error) {
29+
throw error;
30+
} finally {
31+
if (timeoutId) clearTimeout(timeoutId);
32+
// Make sure testFnPromise has completed
33+
await testFnPromise;
34+
if (options.waitForCallback) await callbackPromise;
35+
}
36+
});
37+
}

shims/deno.js

Lines changed: 0 additions & 14 deletions
This file was deleted.

shims/deno.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import { TestSubject, WrappedTestOptions } from "../mod.ts"; // Assuming cross runtime types are here
2+
3+
export function wrappedTest(name: string, testFn: TestSubject, options: WrappedTestOptions) {
4+
Deno.test({
5+
name,
6+
ignore: options?.skip || false,
7+
async fn(context) {
8+
// Adapt the context here
9+
let testFnPromise = undefined;
10+
const callbackPromise = new Promise((resolve, reject) => {
11+
testFnPromise = testFn(context, (e) => { if (e) { reject(e) } else { resolve(0) }});
12+
});
13+
let timeoutId: number = -1; // Store the timeout ID
14+
try {
15+
if (options.timeout) {
16+
const timeoutPromise = new Promise((_, reject) => {
17+
timeoutId = setTimeout(() => {
18+
reject(new Error("Test timed out"));
19+
}, options.timeout);
20+
});
21+
await Promise.race([options.waitForCallback ? callbackPromise : testFnPromise, timeoutPromise]);
22+
} else {
23+
await options.waitForCallback ? callbackPromise : testFnPromise;
24+
}
25+
} catch (error) {
26+
throw error;
27+
} finally {
28+
if (timeoutId) clearTimeout(timeoutId);
29+
await testFnPromise;
30+
if (options.waitForCallback) await callbackPromise;
31+
}
32+
},
33+
});
34+
}

0 commit comments

Comments
 (0)