From 838c3bbb8b2bf866d906b54fa5d5a3e3af8b939f Mon Sep 17 00:00:00 2001 From: Ashcon Partovi Date: Thu, 27 Feb 2025 14:09:25 -0800 Subject: [PATCH] Add cursor rules for writing tests --- .cursor/rules/building-bun.mdc | 27 ++++++++++ .cursor/rules/writing-tests.mdc | 91 +++++++++++++++++++++++++++++++++ 2 files changed, 118 insertions(+) create mode 100644 .cursor/rules/building-bun.mdc create mode 100644 .cursor/rules/writing-tests.mdc diff --git a/.cursor/rules/building-bun.mdc b/.cursor/rules/building-bun.mdc new file mode 100644 index 0000000000..28f86a9f17 --- /dev/null +++ b/.cursor/rules/building-bun.mdc @@ -0,0 +1,27 @@ +--- +description: How to build Bun +globs: +--- +# How to build Bun + +## CMake + +Bun is built using CMake, which you can find in `CMakeLists.txt` and in the `cmake/` directory. + +* `CMakeLists.txt` +* `cmake/` + * `Globals.cmake` - macros and functions used by all the other files + * `Options.cmake` - build options for configuring the build (e.g. debug/release mode) + * `CompilerFlags.cmake` - compiler and linker flags used by all the targets + * `tools/` - setup scripts for various build tools (e.g. llvm, zig, webkit, rust, etc.) + * `targets/` - targets for bun and its dependencies (e.g. brotli, boringssl, libuv, etc.) + +## How to + +There are `package.json` scripts that make it easy to build Bun without calling CMake directly, for example: + +```sh +bun run build # builds a debug build: `build/debug/bun-debug` +bun run build:release # builds a release build: `build/release/bun` +bun run build:assert # builds a release build with debug assertions: `build/assert/bun` +``` diff --git a/.cursor/rules/writing-tests.mdc b/.cursor/rules/writing-tests.mdc new file mode 100644 index 0000000000..4905019005 --- /dev/null +++ b/.cursor/rules/writing-tests.mdc @@ -0,0 +1,91 @@ +--- +description: Writing tests for Bun +globs: +--- +# Writing tests for Bun + +## Where tests are found + +You'll find all of Bun's tests in the `test/` directory. + +* `test/` + * `cli/` - CLI command tests, like `bun install` or `bun init` + * `js/` - JavaScript & TypeScript tests + * `bun/` - `Bun` APIs tests, seperated by category, for example: `glob/` for `Bun.Glob` tests + * `node/` - Node.js module tests, seperated by module, for example: `assert/` for `node:assert` tests + * `test/` - Vendored Node.js tests, taken from the Node.js repository (does not conform to Bun's test style) + * `web/` - Web API tests, seperated by category, for example: `fetch/` for `Request` and `Response` tests + * `third_party/` - npm package tests, to validate that basic usage works in Bun + * `napi/` - N-API tests + * `v8/` - V8 C++ API tests + * `bundler/` - Bundler, transpiler, CSS, and `bun build` tests + * `regression/issue/[number]` - Regression tests, always make one when fixing a particular issue + +## How tests are written + +Bun's tests are written as JavaScript and TypeScript files with the Jest-style APIs, like `test`, `describe`, and `expect`. They are tested using Bun's own test runner, `bun test`. + +```js +import { describe, test, expect } from "bun:test"; +import assert, { AssertionError } from "assert"; + +describe("assert(expr)", () => { + test.each([true, 1, "foo"])(`assert(%p) does not throw`, expr => { + expect(() => assert(expr)).not.toThrow(); + }); + + test.each([false, 0, "", null, undefined])(`assert(%p) throws`, expr => { + expect(() => assert(expr)).toThrow(AssertionError); + }); +}); +``` + +## Testing conventions + +* See `test/harness.ts` for common test utilities and helpers +* Be rigorous and test for edge-cases and unexpected inputs +* Use data-driven tests, e.g. `test.each`, to reduce boilerplate when possible +* When you need to test Bun as a CLI, use the following pattern: + +```js +import { test, expect } from "bun:test"; +import { spawn } from "bun"; +import { bunExe, bunEnv } from "harness"; + +test("bun --version", async () => { + const { exited, stdout: stdoutStream, stderr: stderrStream } = spawn({ + cmd: [bunExe(), "--version"], + env: bunEnv, + stdout: "pipe", + stderr: "pipe", + }); + const [ exitCode, stdout, stderr ] = await Promise.all([ + exited, + new Response(stdoutStream).text(), + new Response(stderrStream).text(), + ]); + expect({ exitCode, stdout, stderr }).toMatchObject({ + exitCode: 0, + stdout: expect.stringContaining(Bun.version), + stderr: "", + }); +}); +``` + +## Before writing a test + +* If you are fixing a bug, write the test first and make sure it fails (as expected) with the canary version of Bun +* If you are fixing a Node.js compatibility bug, create a throw-away snippet of code and test that it works as you expect in Node.js, then that it fails (as expected) with the canary version of Bun +* When the expected behaviour is ambigious, defer to matching what happens in Node.js +* Always attempt to find related tests in an existing test file before creating a new test file + + + + + + + + + + +