Skip to content

Commit

Permalink
Merge pull request #32 from jsr-core/cross-test
Browse files Browse the repository at this point in the history
test: Test codes with Node/Bun
  • Loading branch information
lambdalisue authored Aug 16, 2024
2 parents 6eaad95 + 385cf52 commit 7db916b
Show file tree
Hide file tree
Showing 20 changed files with 837 additions and 702 deletions.
33 changes: 32 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
- name: Type check
run: deno task check

test:
test-deno:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand All @@ -45,6 +45,37 @@ jobs:
files: ./coverage.lcov
token: ${{ secrets.CODECOV_TOKEN }}

test-node:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v1
with:
version: 22.x
- name: Install deps
run: |
npx jsr install
- name: Test
run: |
npx --yes tsx --test *_test.ts
timeout-minutes: 5

test-bun:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: antongolub/action-setup-bun@v1
with:
bun-version: v1.x # Uses latest bun 1
- name: Install deps
run: |
bun install
- name: Test
run: |
# https://github.com/cross-org/test/issues/1
ls -v1 *_test.ts | xargs -n1 bun test '{}'
timeout-minutes: 5

jsr-publish:
runs-on: ubuntu-latest
steps:
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
/node_modules
/.tools
/.deno
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
@jsr:registry=https://npm.jsr.io
17 changes: 17 additions & 0 deletions _testutil.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Using `deadline` in `@std/[email protected]` cause the following error:
// 'Promise resolution is still pending but the event loop has already resolved'
// So we need to implement `deadline` by ourselves.
export async function deadline<T>(
promise: Promise<T>,
timeout: number,
): Promise<T> {
const waiter = Promise.withResolvers<never>();
const timer = setTimeout(
() => waiter.reject(new DOMException("Signal timed out.")),
timeout,
);
return await Promise.race([
waiter.promise,
promise.finally(() => clearTimeout(timer)),
]);
}
21 changes: 10 additions & 11 deletions async_value_test.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { test } from "@cross/test";
import { assertEquals } from "@std/assert";
import { AsyncValue } from "./async_value.ts";

Deno.test("AsyncValue", async (t) => {
await t.step(
"'get' returns a promise that resolves to the value set by 'set'",
async () => {
const v = new AsyncValue(0);
assertEquals(await v.get(), 0);
await v.set(1);
assertEquals(await v.get(), 1);
},
);
});
test(
"AsyncValue 'get' returns a promise that resolves to the value set by 'set'",
async () => {
const v = new AsyncValue(0);
assertEquals(await v.get(), 0);
await v.set(1);
assertEquals(await v.get(), 1);
},
);
164 changes: 82 additions & 82 deletions barrier_test.ts
Original file line number Diff line number Diff line change
@@ -1,94 +1,94 @@
import { test } from "@cross/test";
import { assertEquals, assertRejects, assertThrows } from "@std/assert";
import { deadline, delay } from "@std/async";
import { delay } from "@std/async";
import { Barrier } from "./barrier.ts";
import { deadline } from "./_testutil.ts";

Deno.test("Barrier", async (t) => {
await t.step(
"'wait' waits until the number of waiters reached the size specified to the barrier",
async () => {
const barrier = new Barrier(5);
const workers = [];
const results: string[] = [];
for (let i = 0; i < 5; i++) {
workers.push((async () => {
results.push(`before wait ${i}`);
await barrier.wait();
results.push(`after wait ${i}`);
})());
}
await Promise.all(workers);
assertEquals(results, [
"before wait 0",
"before wait 1",
"before wait 2",
"before wait 3",
"before wait 4",
"after wait 0",
"after wait 1",
"after wait 2",
"after wait 3",
"after wait 4",
]);
},
);
test(
"Barrier 'wait' waits until the number of waiters reached the size specified to the barrier",
async () => {
const barrier = new Barrier(5);
const workers = [];
const results: string[] = [];
for (let i = 0; i < 5; i++) {
workers.push((async () => {
results.push(`before wait ${i}`);
await barrier.wait();
results.push(`after wait ${i}`);
})());
}
await Promise.all(workers);
assertEquals(results, [
"before wait 0",
"before wait 1",
"before wait 2",
"before wait 3",
"before wait 4",
"after wait 0",
"after wait 1",
"after wait 2",
"after wait 3",
"after wait 4",
]);
},
);

await t.step(
"'wait' with non-aborted signal",
async () => {
const controller = new AbortController();
const barrier = new Barrier(2);
test(
"Barrier 'wait' with non-aborted signal",
async () => {
const controller = new AbortController();
const barrier = new Barrier(2);

await assertRejects(
() => deadline(barrier.wait({ signal: controller.signal }), 100),
DOMException,
"Signal timed out.",
);
},
);
await assertRejects(
() => deadline(barrier.wait({ signal: controller.signal }), 100),
DOMException,
"Signal timed out.",
);
},
);

await t.step(
"'wait' with signal aborted after delay",
async () => {
const controller = new AbortController();
const barrier = new Barrier(2);
const reason = new Error("Aborted");
test(
"Barrier 'wait' with signal aborted after delay",
async () => {
const controller = new AbortController();
const barrier = new Barrier(2);
const reason = new Error("Aborted");

delay(50).then(() => controller.abort(reason));
delay(50).then(() => controller.abort(reason));

await assertRejects(
() => deadline(barrier.wait({ signal: controller.signal }), 100),
Error,
"Aborted",
);
},
);
await assertRejects(
() => deadline(barrier.wait({ signal: controller.signal }), 100),
Error,
"Aborted",
);
},
);

await t.step(
"'wait' with already aborted signal",
async () => {
const controller = new AbortController();
const barrier = new Barrier(2);
const reason = new Error("Aborted");
test(
"Barrier 'wait' with already aborted signal",
async () => {
const controller = new AbortController();
const barrier = new Barrier(2);
const reason = new Error("Aborted");

controller.abort(reason);
controller.abort(reason);

await assertRejects(
() => deadline(barrier.wait({ signal: controller.signal }), 100),
Error,
"Aborted",
);
},
);
await assertRejects(
() => deadline(barrier.wait({ signal: controller.signal }), 100),
Error,
"Aborted",
);
},
);

await t.step(
"throws RangeError if size is not a positive safe integer",
() => {
assertThrows(() => new Barrier(NaN), RangeError);
assertThrows(() => new Barrier(Infinity), RangeError);
assertThrows(() => new Barrier(-Infinity), RangeError);
assertThrows(() => new Barrier(-1), RangeError);
assertThrows(() => new Barrier(1.1), RangeError);
assertThrows(() => new Barrier(0), RangeError);
},
);
});
test(
"Barrier throws RangeError if size is not a positive safe integer",
() => {
assertThrows(() => new Barrier(NaN), RangeError);
assertThrows(() => new Barrier(Infinity), RangeError);
assertThrows(() => new Barrier(-Infinity), RangeError);
assertThrows(() => new Barrier(-1), RangeError);
assertThrows(() => new Barrier(1.1), RangeError);
assertThrows(() => new Barrier(0), RangeError);
},
);
Binary file added bun.lockb
Binary file not shown.
1 change: 1 addition & 0 deletions deno.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
"@core/asyncutil/stack": "./stack.ts",
"@core/asyncutil/wait-group": "./wait_group.ts",
"@core/iterutil": "jsr:@core/iterutil@^0.6.0",
"@cross/test": "jsr:@cross/test@^0.0.9",
"@std/assert": "jsr:@std/assert@^1.0.2",
"@std/async": "jsr:@std/async@^1.0.2"
},
Expand Down
31 changes: 29 additions & 2 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 7db916b

Please sign in to comment.