Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 52 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: CI

on:
push:
branches: [master]
pull_request:
branches: [master]
workflow_dispatch:

jobs:
test:
runs-on: ubuntu-latest

strategy:
matrix:
node-version: [20]

steps:
- uses: actions/checkout@v4

- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
cache: 'npm'

- name: Install dependencies
run: npm install --legacy-peer-deps

- name: Lint
run: npm run lint

- name: Typecheck
run: npm run typecheck

- name: Test
run: npm test

bun-test:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2

- name: Install dependencies
run: bun install

- name: Run Bun tests
run: bun test source/bun.test.js
7 changes: 0 additions & 7 deletions .travis.yml

This file was deleted.

94 changes: 94 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -456,3 +456,97 @@ describe('sum()', () => {
});
});
```

## Bun

[Bun](https://bun.sh/) has a fast, built-in test runner that is Jest-compatible. Riteway provides a Bun adapter so you can use the familiar `assert` API with Bun's test runner.

### Installing

First, make sure you have Bun installed. Then install Riteway into your project:

```shell
bun add --dev riteway
```

### Setup

Before using `assert`, you need to call `setupRitewayBun()` once to register the custom matcher. We recommend doing this in a global setup file using Bun's `preload` option.

Create a setup file (e.g., `test/setup.ts`):

```ts
import { setupRitewayBun } from 'riteway/bun';

setupRitewayBun();
```

Then configure Bun to preload it. Add to your `bunfig.toml`:

```toml
[test]
preload = ["./test/setup.ts"]
```

Or specify it via CLI:

```shell
bun test --preload ./test/setup.ts
```

### Usage

In your test files, import `test`, `describe`, and `assert` from `riteway/bun`:

```ts
import { test, describe, assert } from 'riteway/bun';
```

Then run your tests with `bun test`:

```shell
bun test
```

### Example

```ts
import { test, describe, assert } from 'riteway/bun';

// a function to test
const sum = (...args) => {
if (args.some(v => Number.isNaN(v))) throw new TypeError('NaN');
return args.reduce((acc, n) => acc + n, 0);
};

describe('sum()', () => {
test('given: no arguments, should: return 0', () => {
assert({
given: 'no arguments',
should: 'return 0',
actual: sum(),
expected: 0
});
});

test('given: two numbers, should: return the correct sum', () => {
assert({
given: 'two numbers',
should: 'return the correct sum',
actual: sum(2, 3),
expected: 5
});
});
});
```

### Failure Output

When a test fails, the error message includes the `given` and `should` context:

```
error: Given two different numbers: should be equal

Expected: 43
Received: 42
```
File renamed without changes.
5 changes: 3 additions & 2 deletions bin/riteway.test.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
// @ts-nocheck
import { describe } from '../source/riteway.js';
import { execSync } from 'child_process';

Expand All @@ -8,7 +9,7 @@ import {
createIgnoreMatcher,
resolveTestFiles,
runTests
} from './riteway';
} from './riteway.js';

// Test utilities
const testSubprocessExit = (command, { cwd = process.cwd() } = {}) => {
Expand Down Expand Up @@ -96,7 +97,7 @@ describe('createIgnoreMatcher()', async assert => {
{
// Test in subprocess since createIgnoreMatcher calls process.exit()
const { exitCode, stderr } = testSubprocessExit(
'node -e "import(\'./bin/riteway\').then(m => m.createIgnoreMatcher({ ignore: \'nonexistent.ignore\', cwd: process.cwd() }))"'
'node -e "import(\'./bin/riteway.js\').then(m => m.createIgnoreMatcher({ ignore: \'nonexistent.ignore\', cwd: process.cwd() }))"'
);

assert({
Expand Down
19 changes: 19 additions & 0 deletions bun.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
declare module 'riteway/bun' {
interface Assertion<T> {
readonly given: string;
readonly should: string;
readonly actual: T;
readonly expected: T;
}

export function assert<T>(assertion: Assertion<T>): void;

/**
* Setup function to extend Bun's expect with a custom RITEway matcher.
* Call this once in your test setup file or at the top of test files.
*/
export function setupRitewayBun(): void;

// Re-export test and describe from bun:test
export { test, describe } from 'bun:test';
}
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@
"import": "./source/vitest.js",
"types": "./vitest.d.ts"
},
"./bun": {
"import": "./source/bun.js",
"types": "./bun.d.ts"
},
Comment on lines +18 to +21
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For consistency with the vitest adapter (which has exports at lines 54-66 including "./esm/vitest.js" and "./esm/vitest.test.jsx"), consider adding corresponding esm exports for the bun adapter. This would include:

  • "./esm/bun.js" pointing to "./source/bun.js" with types "./bun.d.ts"
  • "./esm/bun.test.js" pointing to "./source/bun.test.js"

These exports appear to support the package's esm build process (see the "esm" script at line 77).

Copilot uses AI. Check for mistakes.
"./match": {
"import": "./source/match.js",
"types": "./match.d.ts"
Expand Down Expand Up @@ -62,12 +66,12 @@
}
},
"bin": {
"riteway": "bin/riteway"
"riteway": "bin/riteway.js"
},
"scripts": {
"lint": "eslint source && echo 'Lint complete.'",
"lint-fix": "eslint --fix source && eslint --fix ./*.js",
"typecheck": "npx -p typescript tsc --esModuleInterop --rootDir . source/test.js --allowJs --checkJs --noEmit --lib es6 --jsx react && npx -p typescript tsc index.d.ts --noEmit && echo 'TypeScript check complete.'",
"typecheck": "npx -p typescript tsc --esModuleInterop --rootDir . source/test.js --allowJs --checkJs --noEmit --lib es6 --jsx react --skipLibCheck && npx -p typescript tsc index.d.ts --noEmit --skipLibCheck && echo 'TypeScript check complete.'",
"ts": "npm run -s typecheck",
"test": "node source/test.js && vitest run",
"esm": "cp source/*.js esm/ && cp source/*.jsx esm/ && cp esm/riteway.js esm/index.js && echo 'esm complete.'",
Expand Down
43 changes: 43 additions & 0 deletions source/bun.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { expect, test, describe } from 'bun:test';

export { test, describe };

const requiredKeys = ['given', 'should', 'actual', 'expected'];

/**
* Setup function to extend Bun's expect with a custom RITEway matcher.
* Call this once in your test setup file or at the top of test files.
*/
export const setupRitewayBun = () => {
expect.extend({
toRitewayEqual(received, expected, given, should) {
const pass = this.equals(received, expected);

if (pass) {
return { pass: true };
}

return {
pass: false,
message: () =>
`Given ${given}: should ${should}\n\nExpected: ${this.utils.printExpected(expected)}\nReceived: ${this.utils.printReceived(received)}`,
};
},
});
};

/**
* Assert function compatible with Bun's expect, using the custom matcher.
* @param {Object} args - Assertion object with given, should, actual, expected.
*/
export const assert = (args = {}) => {
const missing = requiredKeys.filter((k) => !Object.keys(args).includes(k));
if (missing.length) {
throw new Error(
`The following parameters are required by \`assert\`: ${missing.join(', ')}`
);
}

const { given, should, actual, expected } = args;
expect(actual).toRitewayEqual(expected, given, should);
};
50 changes: 50 additions & 0 deletions source/bun.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { test, describe, assert, setupRitewayBun } from './bun.js';

setupRitewayBun();

describe('riteway/bun', () => {
test('given: matching primitives, should: pass', () => {
assert({
given: 'two identical numbers',
should: 'be equal',
actual: 42,
expected: 42,
});
});

test('given: matching strings, should: pass', () => {
assert({
given: 'two identical strings',
should: 'be equal',
actual: 'hello',
expected: 'hello',
});
});

test('given: matching objects, should: pass', () => {
assert({
given: 'two identical objects',
should: 'be deeply equal',
actual: { name: 'Bun', version: 1.1 },
expected: { name: 'Bun', version: 1.1 },
});
});

test('given: matching arrays, should: pass', () => {
assert({
given: 'two identical arrays',
should: 'be deeply equal',
actual: [1, 2, 3],
expected: [1, 2, 3],
});
});

test('given: nested structures, should: pass', () => {
assert({
given: 'two identical nested structures',
should: 'be deeply equal',
actual: { users: [{ name: 'Alice' }, { name: 'Bob' }] },
expected: { users: [{ name: 'Alice' }, { name: 'Bob' }] },
});
});
});
Comment on lines +1 to +50
Copy link

Copilot AI Feb 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test file only covers happy path scenarios where all assertions pass. Based on the vitest test suite (source/vitest.test.jsx lines 72-107), the bun adapter tests should also include:

  1. Tests for assert() error handling when required parameters are missing (e.g., calling assert({}) or assert({ given: 'x', should: 'y' }) without actual/expected)
  2. Tests to verify the error message format matches: "The following parameters are required by assert: [missing keys]"
  3. Tests for undefined values to ensure they don't throw errors when all parameters are provided

These tests would verify that the parameter validation logic in source/bun.js works correctly.

Copilot uses AI. Check for mistakes.
4 changes: 3 additions & 1 deletion vitest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ export default defineConfig({
'**/.{idea,git,cache,output,temp}/**',
'**/{karma,rollup,webpack,vite,vitest,jest,ava,babel,nyc,cypress,tsup,build,eslint,prettier}.config.*',
// Exclude bin/riteway.test.js as it uses Tape instead of Vitest
'**/bin/riteway.test.js'
'**/bin/riteway.test.js',
// Exclude bun.test.js as it uses bun:test instead of Vitest
'**/bun.test.js'
]
}
});
Expand Down