diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 00000000..7daf4a0d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,87 @@ +# 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); + * ``` + * + * @param value the value that number should be greater than + * @returns the assertion instance + */ +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 +// 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 + +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` (the fixed package must no longer appear in the report; exit 0 means no findings at all). + +## 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..ce8305cd 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. [AGENTS.md](../AGENTS.md) is the instruction file for coding agents. ## 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 ``` @@ -39,10 +40,12 @@ 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 | -| `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): 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 | +| `sinon` | `@assertive-ts/sinon` | fix(sinon): Spy assertion bug |