{"_id":"@crescware/eslint-plugin-crescware-no-inline-expected","_rev":"3-708800073da74188b6b192b273db0749","name":"@crescware/eslint-plugin-crescware-no-inline-expected","dist-tags":{"latest":"0.0.3"},"versions":{"0.0.1":{"name":"@crescware/eslint-plugin-crescware-no-inline-expected","version":"0.0.1","_id":"@crescware/eslint-plugin-crescware-no-inline-expected@0.0.1","maintainers":[{"name":"crescware","email":"okunokentaro+npm@crescware.com"}],"dist":{"shasum":"ccc95c4068b98ee786d01eac1779094ad1b94706","tarball":"https://registry.npmjs.org/@crescware/eslint-plugin-crescware-no-inline-expected/-/eslint-plugin-crescware-no-inline-expected-0.0.1.tgz","fileCount":4,"integrity":"sha512-UNQV5p26HQc0DFRi/MoqCqausSt3oAuB912zlT4/0BFfSOFqgKsAI3/Dd8m5bBIn6KCA/F48CT6DagP3BIdZLg==","signatures":[{"sig":"MEQCIBzJy80tCXkw/m2UsXWs/z7RTxBL0mE9NGgyfJkvgxRGAiAuWS9hxhjfAdMUrGhxK21z/Xu7Y07vEQNsKUmgcbFM/Q==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":18751},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"7599564c0cd13776b15537013449e44caabde83b","scripts":{"test":"vitest run","build":"rimraf dist && tsgo -p tsconfig.build.json","check":"pnpm run check:types && pnpm run check:lint && pnpm run check:knip && pnpm run test","format":"oxlint --fix && oxfmt","check:knip":"knip","check:lint":"oxlint && oxfmt --check","check:types":"tsgo -p tsconfig.json --noEmit","exec:fixtures":"oxlint -c fixtures/oxlintrc.default.json --no-ignore -f json fixtures/cases/","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"crescware","email":"okunokentaro+npm@crescware.com"},"_npmVersion":"11.12.1","description":"An [oxlint](https://oxc.rs/docs/guide/usage/linter) JS plugin that forbids passing an inline object or array literal as the expected value to an `expect(...)` matcher. Declare the expected value in a `const` variable first.","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.33.2","devDependencies":{"knip":"6.7.0","oxfmt":"0.47.0","oxlint":"1.62.0","rimraf":"6.1.3","vitest":"4.1.5","@types/node":"24.12.2","@typescript/native-preview":"7.0.0-dev.20260422.1"},"_npmOperationalInternal":{"tmp":"tmp/eslint-plugin-crescware-no-inline-expected_0.0.1_1781849710330_0.682633065716233","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@crescware/eslint-plugin-crescware-no-inline-expected","version":"0.0.2","_id":"@crescware/eslint-plugin-crescware-no-inline-expected@0.0.2","maintainers":[{"name":"crescware","email":"okunokentaro+npm@crescware.com"}],"dist":{"shasum":"241964fcdca92f5baba3d615f09ed3600154a27c","tarball":"https://registry.npmjs.org/@crescware/eslint-plugin-crescware-no-inline-expected/-/eslint-plugin-crescware-no-inline-expected-0.0.2.tgz","fileCount":4,"integrity":"sha512-P/0Ijrn4crWdZj+3WFhGDj029jMhLSGecTjTRf5dx9VxOVZTV4eqdoq6H2nd5ieOpm0AM97p8u6BMVzzJEJg9A==","signatures":[{"sig":"MEQCIAy9D5Pt8gw3/+gT7hUX/0h8caEyQ8HYcSuAGPr1uOg3AiAMD02/JmeUnP2Pw4d2pwMlmSDretdBQchGhLw5tuvoag==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24808},"main":"dist/index.js","type":"module","types":"./dist/index.d.ts","exports":{".":"./dist/index.js"},"gitHead":"9c0c92ba68fcb137fa5fc8aaea910bb4fdd08a36","scripts":{"test":"vitest run","build":"rimraf dist && tsgo -p tsconfig.build.json","check":"pnpm run check:types && pnpm run check:lint && pnpm run check:knip && pnpm run test","format":"oxlint --fix && oxfmt","check:knip":"knip","check:lint":"oxlint && oxfmt --check","check:types":"tsgo -p tsconfig.json --noEmit","exec:fixtures":"oxlint -c fixtures/oxlintrc.default.json --no-ignore -f json fixtures/cases/","prepublishOnly":"pnpm run build"},"_npmUser":{"name":"crescware","email":"okunokentaro+npm@crescware.com"},"_npmVersion":"11.12.1","description":"An [oxlint](https://oxc.rs/docs/guide/usage/linter) JS plugin that forbids passing an inline object or array literal as the expected value to an `expect(...)` matcher. Declare the expected value in a `const` variable first.","directories":{},"_nodeVersion":"24.15.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"packageManager":"pnpm@10.33.2","devDependencies":{"knip":"6.7.0","oxfmt":"0.47.0","oxlint":"1.62.0","rimraf":"6.1.3","vitest":"4.1.5","@types/node":"24.12.2","@typescript/native-preview":"7.0.0-dev.20260422.1"},"_npmOperationalInternal":{"tmp":"tmp/eslint-plugin-crescware-no-inline-expected_0.0.2_1781854887754_0.15928497726896107","host":"s3://npm-registry-packages-npm-production"}},"0.0.3":{"name":"@crescware/eslint-plugin-crescware-no-inline-expected","version":"0.0.3","type":"module","main":"dist/index.js","exports":{".":"./dist/index.js"},"publishConfig":{"access":"public"},"scripts":{"build":"rimraf dist && tsgo -p tsconfig.build.json","check":"pnpm run check:types && pnpm run check:lint && pnpm run check:knip && pnpm run test","check:knip":"knip","check:lint":"oxlint && oxfmt --check","check:types":"tsgo -p tsconfig.json --noEmit","exec:fixtures":"oxlint -c fixtures/oxlintrc.default.json --no-ignore -f json fixtures/cases/","format":"oxlint --fix && oxfmt","prepublishOnly":"pnpm run build","test":"vitest run"},"devDependencies":{"@types/node":"24.12.2","@typescript/native-preview":"7.0.0-dev.20260422.1","knip":"6.7.0","oxfmt":"0.47.0","oxlint":"1.62.0","rimraf":"6.1.3","vitest":"4.1.5"},"packageManager":"pnpm@10.33.2","gitHead":"e0fbb0741e3ed4b0df434f3cacb101e4c4787d56","types":"./dist/index.d.ts","_id":"@crescware/eslint-plugin-crescware-no-inline-expected@0.0.3","description":"An [oxlint](https://oxc.rs/docs/guide/usage/linter) JS plugin that forbids passing an inline object or array literal as the expected value to an `expect(...)` matcher. Declare the expected value in a `const` variable first.","_nodeVersion":"24.15.0","_npmVersion":"11.12.1","dist":{"integrity":"sha512-UT6UYDNqlunANRX/J55Xvn3JRmUJZPG9qZDUEmC2z9BWuxxx+W8Fxy7DdDZT9BJgUsa3aSDR/NGenzzWUUg+7w==","shasum":"5d90267fcdaaa6c6efad6d85e98441a55adf45cc","tarball":"https://registry.npmjs.org/@crescware/eslint-plugin-crescware-no-inline-expected/-/eslint-plugin-crescware-no-inline-expected-0.0.3.tgz","fileCount":4,"unpackedSize":25615,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEvgF/yBtqbVxAhxAhbI4es1kSMg5mTnKWu8BwLrxho0AiEAnT6shsh4o58hPMthBYw1x2m6t1DFuxB2HMR5idOfmzM="}]},"_npmUser":{"name":"crescware","email":"okunokentaro+npm@crescware.com"},"directories":{},"maintainers":[{"name":"crescware","email":"okunokentaro+npm@crescware.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/eslint-plugin-crescware-no-inline-expected_0.0.3_1781857197572_0.6230617071066167"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-19T06:15:10.144Z","modified":"2026-06-19T08:19:57.857Z","0.0.1":"2026-06-19T06:15:10.488Z","0.0.2":"2026-06-19T07:41:27.892Z","0.0.3":"2026-06-19T08:19:57.757Z"},"description":"An [oxlint](https://oxc.rs/docs/guide/usage/linter) JS plugin that forbids passing an inline object or array literal as the expected value to an `expect(...)` matcher. Declare the expected value in a `const` variable first.","maintainers":[{"name":"crescware","email":"okunokentaro+npm@crescware.com"}],"readme":"# @crescware/eslint-plugin-crescware-no-inline-expected\n\nAn [oxlint](https://oxc.rs/docs/guide/usage/linter) JS plugin that forbids passing an inline object or array literal as the expected value to an `expect(...)` matcher. Declare the expected value in a `const` variable first.\n\n## Rule: `no-inline-expected`\n\nWhen the expected value of an assertion is written inline as an object or array literal (`expect(actual).toEqual({ ... })` / `expect(actual).toStrictEqual([ ... ])`), extract it into a named variable. A named `expected` separates \"what is being compared\" from \"what the answer should be\", keeps the assertion line short, and gives the expected value a name to refer to.\n\n```ts\n// NG: an inline object literal as the expected value\nexpect(actual).toEqual({ id: 1, name: \"Alice\" });\n\n// NG: an inline array literal as the expected value\nexpect(actual).toEqual([1, 2, 3]);\n\n// NG: an empty literal is still an inline literal\nexpect(actual).toEqual({});\nexpect(actual).toEqual([]);\n\n// OK: the expected value is declared first\nconst expected = { id: 1, name: \"Alice\" };\nexpect(actual).toEqual(expected);\n\n// OK: a non-literal argument is out of scope\nexpect(actual).toEqual(buildExpected());\n```\n\nBy default the rule also enforces that, inside a `test` / `it` callback, the expected variable is declared **first** — at the top of the callback. Only declarations of variables that the expected value uses may precede it, and even those may not be part of the value passed to `expect(...)`.\n\n```ts\n// NG: an unrelated variable is declared above expected\ntest(\"...\", () => {\n  const something = {};\n  const expected = {};\n  expect(something).toEqual(expected);\n});\n\n// NG: expected is aliased from the value under test\ntest(\"...\", () => {\n  const actual = { a: 1 };\n  const expected = actual;\n  expect(actual).toStrictEqual(expected);\n});\n\n// OK: expected is declared first\ntest(\"...\", () => {\n  const expected = {};\n  const actual = {};\n  expect(actual).toEqual(expected);\n});\n\n// OK: a variable used to build expected may precede it, as long as it is not\n// the value under test\ntest(\"...\", () => {\n  const id = makeId();\n  const expected = { id, name: \"alice\" };\n  const actual = makeUser(id);\n  expect(actual).toEqual(expected);\n});\n```\n\n### Scope\n\nThe rule fires when **all** of the following hold for a call expression:\n\n- The callee is a member access whose property is one of the configured `matchers` (default: `toEqual`, `toStrictEqual`).\n- The receiver chain is anchored at an `expect(...)` call. Modifier chains are followed, so `expect(x).not.toEqual(...)`, `expect(x).resolves.toEqual(...)`, `expect(x).rejects.toEqual(...)`, and `expect.soft(x).toEqual(...)` are all in scope. An unrelated `foo.toEqual({ ... })` that is not anchored at `expect` is **not** reported.\n- An argument is a plain object literal (`ObjectExpression`) or array literal (`ArrayExpression`), optionally wrapped in `as` / `satisfies` clauses (`{ ... } as Foo`, `[ ... ] as const`, `{ ... } satisfies T`, including multi-step chains such as `{ ... } as unknown as T`). The wrappers are unwrapped to classify the underlying literal.\n\nNotes:\n\n- Object and array literals are treated the same, including empty `{}` / `[]`.\n- Every argument is inspected, so multi-argument matchers (e.g. a configured `toHaveBeenCalledWith`) report each inline literal.\n- The rule applies to JavaScript (`.js` / `.mjs` / `.cjs` / `.jsx`) as well as TypeScript: it targets a runtime assertion call, not any TypeScript-only syntax.\n- The expected-first check (on by default) only applies inside a `test` / `it` callback, and only when the expected value is a plain identifier declared directly in that callback. An expected value that is an inline literal, a call, or declared elsewhere (an outer scope, a parameter, an import) has no callback-top position to enforce and is left alone. Modifier and table forms (`it.only`, `test.each(table)(...)`) are recognized.\n- Type-only declarations (`type` / `interface`) introduce no runtime value, so they are always allowed above the expected declaration, whether or not the expected value uses them.\n- The rule does not autofix; it reports only.\n\n### Options\n\n```jsonc\n\"crescware-no-inline-expected/no-inline-expected\": [\n  \"error\",\n  {\n    // The matcher names to check. Replaces the default set, not extends it.\n    \"matchers\": [\"toEqual\", \"toStrictEqual\"],\n\n    // true (default): inside a `test` / `it` callback the expected variable\n    // must be declared first. Set to false to disable this check.\n    \"requireExpectedFirstInTest\": true\n  }\n]\n```\n\n| Option                       | Type       | Default                        | Effect                                                                                                                                                                                                                                                       |\n| ---------------------------- | ---------- | ------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |\n| `matchers`                   | `string[]` | `[\"toEqual\", \"toStrictEqual\"]` | The matcher names whose inline-literal arguments are reported. Setting this **replaces** the default set. Add names such as `toMatchObject`, `toContainEqual`, or `toHaveBeenCalledWith` to widen coverage.                                                  |\n| `requireExpectedFirstInTest` | `boolean`  | `true`                         | When `true`, additionally requires the expected variable to be declared first inside its `test` / `it` callback. Only declarations of variables the expected value uses may precede it (and not the value under test). Set to `false` to disable this check. |\n\n## Usage\n\nRegister the plugin in your `.oxlintrc.json` and enable the rule:\n\n```json\n{\n  \"jsPlugins\": [\"@crescware/eslint-plugin-crescware-no-inline-expected\"],\n  \"rules\": {\n    \"crescware-no-inline-expected/no-inline-expected\": \"error\"\n  }\n}\n```\n\n## Stack\n\n- **Runtime**: Node.js 24 (via [mise](https://mise.jdx.dev/))\n- **Package manager**: pnpm (via corepack)\n- **Language**: TypeScript ([native preview](https://github.com/microsoft/typescript-go))\n- **Test**: [Vitest](https://vitest.dev/)\n- **Lint**: [oxlint](https://oxc.rs/docs/guide/usage/linter)\n- **Format**: [oxfmt](https://github.com/oxc-project/oxc)\n- **Unused code**: [Knip](https://knip.dev/)\n\n## Setup\n\n```sh\nmise install\ncorepack enable\npnpm install\n```\n\n## Scripts\n\n| Command            | Description                              |\n| ------------------ | ---------------------------------------- |\n| `pnpm build`       | Compile `src` to `dist`                  |\n| `pnpm check`       | Run all checks (types, lint, knip, test) |\n| `pnpm check:types` | Type check                               |\n| `pnpm check:lint`  | Lint and format check                    |\n| `pnpm check:knip`  | Unused files/exports check               |\n| `pnpm test`        | Run fixture integration tests            |\n| `pnpm format`      | Fix lint and format                      |\n","readmeFilename":"README.md"}