From ca363e563068518d87f835868886da21a236a9d1 Mon Sep 17 00:00:00 2001 From: Stefani Castellanos Date: Fri, 16 Oct 2026 09:06:09 -0500 Subject: [PATCH 1/2] docs(all): add AGENTS.md and update development guide Co-Authored-By: Claude Sonnet 5.5 --- AGENTS.md | 72 +++++++++++++++++++++++++++++++++++++++++++++ docs/development.md | 19 +++++++----- 2 files changed, 83 insertions(+), 8 deletions(-) create mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..79253087 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,72 @@ +# AGENTS.md + +Instructions for coding agents. Setup, workflow, commit scopes and releases are in [docs/development.md](docs/development.md). + +## Done condition + +Set up per [Requirements](docs/development.md#requirements). A change is done when this exits 0 (~30 s from a cold cache): + +```console +yarn compile && yarn lint && yarn test +``` + +For one package, run `yarn test` from `packages/` (core takes ~1 s). `yarn lint` prints react-native parse warnings; the exit code is the signal. + +## Where things live + +- `expect()` dispatch: `packages/core/src/lib/expect.ts`. +- Plugins: `usePlugin()` in `packages/core/src/main.ts` registers them into `packages/core/src/lib/config/Config.ts`, which `expect()` consults. +- One `*Assertion.ts` per type, in `packages//src/lib/`. Tests live in each package's `test/`. + +## Matcher pattern + +Build both errors, then pass them to `this.execute`, which handles `.not`. Copy `toBeGreaterThan` in `packages/core/src/lib/NumberAssertion.ts`: + +```ts +/** + * Check if the number value is greater than the defined value. + * + * @example + * ``` + * expect(5).toBeGreaterThan(3); + * ``` + */ +public toBeGreaterThan(value: number): this { + const error = new AssertionError({ + actual: this.actual, + message: `Expected <${this.actual}> to be greater than <${value}>`, + }); + const invertedError = new AssertionError({ + actual: this.actual, + message: `Expected <${this.actual}> NOT to be greater than <${value}>`, + }); + + return this.execute({ assertWhen: this.actual > value, error, invertedError }); +} +``` + +Each test case asserts the direct and the `.not` path with exact messages (`packages/core/test/lib/NumberAssertion.test.ts`): + +```ts +assert.deepStrictEqual(test.toBeGreaterThan(2), test); +assert.throws(() => test.not.toBeGreaterThan(2), { + message: "Expected <3> NOT to be greater than <2>", + name: AssertionError.name, +}); +``` + +## Test rule + +Give every comparison matcher an equal-value/boundary case and a negative-number case. JS `%` keeps the sign of the left operand, and the suite once let a `>` → `>=` mutation pass. + +## Pull requests + +The repo is squash-merge only: the PR title becomes the commit message and drives semantic-release. Write it as a Conventional Commit with a scope from [Scopes](docs/development.md#scopes). + +## Dependency fixes + +Add a `resolutions` entry in the root `package.json`, run `yarn dedupe`, then verify with `yarn why ` and `yarn npm audit --all --recursive --severity high` (exit 0 means clean). + +## Release boundary + +Only maintainers release, through `.github/workflows/release.yml`. Leave that workflow, `.yarn/releases/`, `yarn release` and `npm publish` alone. diff --git a/docs/development.md b/docs/development.md index 0121856b..35419109 100644 --- a/docs/development.md +++ b/docs/development.md @@ -1,17 +1,18 @@ # Development -To setup your local environment follow the next steps. +To setup your local environment follow the next steps. Coding agents should also read [AGENTS.md](../AGENTS.md), the instruction file for them. ## Requirements -* Latest [Yarn Classic](https://classic.yarnpkg.com) -* NodeJS (Use version set on [.nvmrc](https://github.com/stackbuilders/assertive-ts/blob/master/.nvmrc)) +* NodeJS (Use version set on [.nvmrc](https://github.com/stackbuilders/assertive-ts/blob/main/.nvmrc)) +* [Corepack](https://yarnpkg.com/corepack), which provides the Yarn 4 version pinned in `package.json`. Run `corepack enable` once. NodeJS 25 and later no longer bundle it, so run `npm install -g corepack` first. ## Useful commands ### Install dependencies ```console +corepack enable yarn install ``` @@ -41,8 +42,10 @@ The release process is automated by [semantic-release](https://semantic-release. Scopes are optional on Conventional Commits, but we take advantange of them to specify the package a change is aimed for. The table below describes the available scopes and what package they affect: -| Scope | Package | Commit example | -| :-----: | :-------------------: | -------------------------------- | -| `all` | All packages | feat(all): Upadate TypeScript | -| `core` | `@assertive-ts/core` | fix(core): Boolean assertion bug | -| `sinon` | `@assertive-ts/sinon` | fix(sinon): Spy assertion bug | +| Scope | Package | Commit example | +| :------: | :--------------------: | ---------------------------------- | +| `all` | All packages | feat(all): Upadate TypeScript | +| `core` | `@assertive-ts/core` | fix(core): Boolean assertion bug | +| `dom` | `@assertive-ts/dom` | fix(dom): Element assertion bug | +| `native` | `@assertive-ts/native` | fix(native): Element assertion bug | +| `sinon` | `@assertive-ts/sinon` | fix(sinon): Spy assertion bug | From 7def470bef248aaf81d2a3617d0d8548171a8472 Mon Sep 17 00:00:00 2001 From: Stefani Castellanos Date: Fri, 16 Oct 2026 09:16:42 -0500 Subject: [PATCH 2/2] docs(all): address review feedback on AGENTS.md Co-Authored-By: Claude Sonnet 5.5 --- AGENTS.md | 19 +++++++++++++++++-- docs/development.md | 6 +++--- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 79253087..7daf4a0d 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,6 +30,9 @@ Build both errors, then pass them to `this.execute`, which handles `.not`. Copy * ``` * expect(5).toBeGreaterThan(3); * ``` + * + * @param value the value that number should be greater than + * @returns the assertion instance */ public toBeGreaterThan(value: number): this { const error = new AssertionError({ @@ -41,18 +44,30 @@ public toBeGreaterThan(value: number): this { message: `Expected <${this.actual}> NOT to be greater than <${value}>`, }); - return this.execute({ assertWhen: this.actual > value, error, invertedError }); + return this.execute({ + assertWhen: this.actual > value, + error, + invertedError, + }); } ``` Each test case asserts the direct and the `.not` path with exact messages (`packages/core/test/lib/NumberAssertion.test.ts`): ```ts +// actual 3: passes directly, throws under .not assert.deepStrictEqual(test.toBeGreaterThan(2), test); assert.throws(() => test.not.toBeGreaterThan(2), { message: "Expected <3> NOT to be greater than <2>", name: AssertionError.name, }); + +// actual 1: throws directly, passes under .not +assert.throws(() => test.toBeGreaterThan(2), { + message: "Expected <1> to be greater than <2>", + name: AssertionError.name, +}); +assert.deepStrictEqual(test.not.toBeGreaterThan(2), test); ``` ## Test rule @@ -65,7 +80,7 @@ The repo is squash-merge only: the PR title becomes the commit message and drive ## Dependency fixes -Add a `resolutions` entry in the root `package.json`, run `yarn dedupe`, then verify with `yarn why ` and `yarn npm audit --all --recursive --severity high` (exit 0 means clean). +Add a `resolutions` entry in the root `package.json`, run `yarn dedupe`, then verify with `yarn why ` and `yarn npm audit --all --recursive --severity high` (the fixed package must no longer appear in the report; exit 0 means no findings at all). ## Release boundary diff --git a/docs/development.md b/docs/development.md index 35419109..ce8305cd 100644 --- a/docs/development.md +++ b/docs/development.md @@ -1,6 +1,6 @@ # Development -To setup your local environment follow the next steps. Coding agents should also read [AGENTS.md](../AGENTS.md), the instruction file for them. +To setup your local environment follow the next steps. [AGENTS.md](../AGENTS.md) is the instruction file for coding agents. ## Requirements @@ -40,11 +40,11 @@ The release process is automated by [semantic-release](https://semantic-release. ### Scopes -Scopes are optional on Conventional Commits, but we take advantange of them to specify the package a change is aimed for. The table below describes the available scopes and what package they affect: +Scopes are optional on Conventional Commits, but we take advantage of them to specify the package a change is aimed for. The table below describes the available scopes and what package they affect: | Scope | Package | Commit example | | :------: | :--------------------: | ---------------------------------- | -| `all` | All packages | feat(all): Upadate TypeScript | +| `all` | All packages | feat(all): Update TypeScript | | `core` | `@assertive-ts/core` | fix(core): Boolean assertion bug | | `dom` | `@assertive-ts/dom` | fix(dom): Element assertion bug | | `native` | `@assertive-ts/native` | fix(native): Element assertion bug |