@shivaedev/quality 0.36.0 → 0.39.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -0
- package/README.md +6 -4
- package/dist/inventory/ignoreScope.d.ts +1 -0
- package/dist/inventory/ignoreScope.d.ts.map +1 -1
- package/dist/inventory/ignoreScope.js +11 -1
- package/dist/inventory/ignoreScope.js.map +1 -1
- package/dist/inventory/trackedPaths.d.ts +1 -0
- package/dist/inventory/trackedPaths.d.ts.map +1 -1
- package/dist/inventory/trackedPaths.js +10 -6
- package/dist/inventory/trackedPaths.js.map +1 -1
- package/dist/inventory/walk.d.ts +1 -1
- package/dist/inventory/walk.d.ts.map +1 -1
- package/dist/inventory/walk.js +16 -7
- package/dist/inventory/walk.js.map +1 -1
- package/dist/rule.d.ts +1 -1
- package/dist/rules/builtIn.d.ts +1 -1
- package/dist/rules/builtIn.d.ts.map +1 -1
- package/dist/rules/builtIn.js +2 -0
- package/dist/rules/builtIn.js.map +1 -1
- package/dist/rules/stories/engine.d.ts +2 -0
- package/dist/rules/stories/engine.d.ts.map +1 -0
- package/dist/rules/stories/engine.js +47 -0
- package/dist/rules/stories/engine.js.map +1 -0
- package/dist/rules/stories/importOrigin.d.ts +2 -0
- package/dist/rules/stories/importOrigin.d.ts.map +1 -0
- package/dist/rules/stories/importOrigin.js +20 -0
- package/dist/rules/stories/importOrigin.js.map +1 -0
- package/dist/rules/stories/namedValues.d.ts.map +1 -1
- package/dist/rules/stories/namedValues.js +28 -2
- package/dist/rules/stories/namedValues.js.map +1 -1
- package/dist/rules/stories/noExpect.d.ts.map +1 -1
- package/dist/rules/stories/noExpect.js +11 -1
- package/dist/rules/stories/noExpect.js.map +1 -1
- package/dist/rules/stories/origins.d.ts +1 -0
- package/dist/rules/stories/origins.d.ts.map +1 -1
- package/dist/rules/stories/origins.js +15 -22
- package/dist/rules/stories/origins.js.map +1 -1
- package/dist/rules/stories/registersTests.d.ts +3 -0
- package/dist/rules/stories/registersTests.d.ts.map +1 -0
- package/dist/rules/stories/registersTests.js +69 -0
- package/dist/rules/stories/registersTests.js.map +1 -0
- package/dist/rules/stories/returnValues.d.ts +3 -0
- package/dist/rules/stories/returnValues.d.ts.map +1 -0
- package/dist/rules/stories/returnValues.js +24 -0
- package/dist/rules/stories/returnValues.js.map +1 -0
- package/dist/rules/stories/specs.d.ts.map +1 -1
- package/dist/rules/stories/specs.js +3 -0
- package/dist/rules/stories/specs.js.map +1 -1
- package/dist/rules/stories/usesInputs.d.ts +3 -0
- package/dist/rules/stories/usesInputs.d.ts.map +1 -0
- package/dist/rules/stories/usesInputs.js +39 -0
- package/dist/rules/stories/usesInputs.js.map +1 -0
- package/dist/testProjects.d.ts.map +1 -1
- package/dist/testProjects.js +15 -2
- package/dist/testProjects.js.map +1 -1
- package/dist/unitIoGuard.config.d.ts +2 -0
- package/dist/unitIoGuard.config.d.ts.map +1 -0
- package/dist/unitIoGuard.config.js +69 -0
- package/dist/unitIoGuard.config.js.map +1 -0
- package/package.json +4 -3
- package/src/inventory/ignoreScope.ts +12 -1
- package/src/inventory/trackedPaths.ts +12 -7
- package/src/inventory/walk.ts +19 -7
- package/src/rule.ts +1 -1
- package/src/rules/builtIn.ts +2 -0
- package/src/rules/stories/engine.ts +56 -0
- package/src/rules/stories/importOrigin.ts +20 -0
- package/src/rules/stories/namedValues.ts +29 -2
- package/src/rules/stories/noExpect.ts +13 -1
- package/src/rules/stories/origins.ts +16 -24
- package/src/rules/stories/registersTests.ts +78 -0
- package/src/rules/stories/returnValues.ts +24 -0
- package/src/rules/stories/specs.ts +3 -0
- package/src/rules/stories/usesInputs.ts +38 -0
- package/src/testProjects.ts +15 -2
- package/src/unitIoGuard.config.ts +72 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,51 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.39.0 - 2026-10-25
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
|
|
7
|
+
- `tests/named-values` now accepts zero and status or exit codes.
|
|
8
|
+
- Generated apps' stories assert observed items instead of numeric aliases.
|
|
9
|
+
|
|
10
|
+
## 0.38.0 - 2026-10-25
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Run `.unit` test and spec files in a default `pure` Node project whose runtime guard rejects file-system, network, process, worker and `fetch` calls, including I/O hidden in dependencies. Errors name the unit file and call. Ordinary Node files remain in `unit`, and `--project slow` keeps selecting slow tests alone.
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Use sort-package-json 4.1.0 for package manifest sorting.
|
|
19
|
+
|
|
20
|
+
### Fixed
|
|
21
|
+
|
|
22
|
+
- Skip untracked files ignored through git's `info/exclude` or `core.excludesFile` during directory discovery, including in linked worktrees, while continuing to check tracked files.
|
|
23
|
+
- `tests/no-expect-in-support` no longer reports test files that a nested Vitest run executes: unimported test-support files that register tests at module top level.
|
|
24
|
+
|
|
25
|
+
## 0.37.0 - 2026-10-25
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- `tests/story-engine` reports kit stories without traits that never reference their verbs, story or test context. Drive the engine through a kit verb or trait, or move pure code to a `.unit.test.ts` file that reaches no engine and mocks nothing.
|
|
30
|
+
|
|
31
|
+
## 0.36.3 - 2026-10-25
|
|
32
|
+
|
|
33
|
+
### Fixed
|
|
34
|
+
|
|
35
|
+
- Recognize story kits returned by local or imported factory functions, including kits extended through object spreads, while still reporting plain test registrations beside them.
|
|
36
|
+
|
|
37
|
+
## 0.36.2 - 2026-10-25
|
|
38
|
+
|
|
39
|
+
### Fixed
|
|
40
|
+
|
|
41
|
+
- Stop `tests/story-specs` from reporting inline trait calls inside a story kit registration as plain tests. Plain `it` and `test` registrations still report.
|
|
42
|
+
|
|
43
|
+
## 0.36.1 - 2026-10-25
|
|
44
|
+
|
|
45
|
+
### Changed
|
|
46
|
+
|
|
47
|
+
- Release with updated workspace dependencies.
|
|
48
|
+
|
|
3
49
|
## 0.36.0 - 2026-10-25
|
|
4
50
|
|
|
5
51
|
### Breaking
|
package/README.md
CHANGED
|
@@ -78,7 +78,7 @@ import { defineConfig } from "@shivaedev/quality/config.ts";
|
|
|
78
78
|
export default defineConfig({ sources: ["src"] });
|
|
79
79
|
```
|
|
80
80
|
|
|
81
|
-
When a config exists, its folder is the root for paths and hook scripts. Without one, the current directory is the root. `sources` chooses the files the source rules read; a missing source stops the run. Directory discovery skips untracked files ignored by git and the `.git`, `.worktrees` and `node_modules` directories. Tracked files remain checked even when an ignore pattern matches them; a folder named `generated/` does not exempt authored code. Some repository rules, such as manifest sorting, inspect the whole repository even when `sources` names only `src`.
|
|
81
|
+
When a config exists, its folder is the root for paths and hook scripts. Without one, the current directory is the root. `sources` chooses the files the source rules read; a missing source stops the run. Directory discovery skips untracked files ignored by git through `.gitignore`, `info/exclude` or `core.excludesFile`, and the `.git`, `.worktrees` and `node_modules` directories. Tracked files remain checked even when an ignore pattern matches them; a folder named `generated/` does not exempt authored code. Some repository rules, such as manifest sorting, inspect the whole repository even when `sources` names only `src`.
|
|
82
82
|
|
|
83
83
|
Quality discovers each app’s `components.json` and resolves `aliases.ui` through its TypeScript paths or package imports. That folder belongs to the shadcn CLI: source rules and Biome lint, formatting and fixes skip it by default. Neighbouring authored folders stay checked. This leaves TypeScript’s inputs unchanged, so type checking still covers the stock components.
|
|
84
84
|
|
|
@@ -136,7 +136,9 @@ Keep story kits and fixtures in `src/test-support` and keep each spec specific t
|
|
|
136
136
|
|
|
137
137
|
Quality's `tests/story-specs` rule reports a test file that declares tests without a kit's `it`, including plain Vitest `it` and `test` declarations mixed with stories. Typecheck tests are exempt, as are test-story itself and its transitive workspace dependencies, including development, optional and peer dependencies: requiring those packages to depend on test-story would create a cycle.
|
|
138
138
|
|
|
139
|
-
|
|
139
|
+
Quality's `tests/story-engine` rule reports a kit story with no traits whose body never references its verbs, its story or its test context. Drive the engine through one of the kit's verbs or traits, or, if the code under test is pure, move it to `<stem>.unit.test.ts`, which reaches no engine and mocks nothing. The rule follows the same kit origins and prerequisite exemptions as `tests/story-specs`; unit and typecheck files are exempt.
|
|
140
|
+
|
|
141
|
+
There is one other honest form. A pure function with no engine behind it gets a plain test in a **unit test** file, declared by the `unit` modifier: `parse.unit.test.ts` beside `parse.ts`, or `<behaviour>.unit.spec.ts`. A unit test exercises one unit and reaches nothing bigger, so `tests/story-specs` rejects a `.unit` file that reaches an engine, directly or through what it imports, following runtime imports through the shared import graph; type-only imports do not count. The engines are Node's file, network, process and worker modules, database clients, HTTP and socket libraries, DOM libraries and the story runners. A test-support fixture the unit file imports must pass the same check. The rule also rejects mocking (`vi.mock`, `vi.spyOn`, `vi.fn`, env and global stubs, fake timers), providing services (`Effect.provide*`, `Layer`, `ManagedRuntime`, `it.layer`) and DOM use in the unit file and its test-support fixtures. Running an Effect that needs nothing, such as with `Effect.runSync` or `it.effect`, is fine. When the module under test reaches an engine, the finding names the import chain and asks you to split the module: move the pure code into a module that reaches no engine and test that one. The static check reads imports and syntax. The runtime guard in `testProjects` catches I/O hidden inside an external package or a global such as `fetch` when a unit test runs.
|
|
140
142
|
|
|
141
143
|
Every finding names both repairs: drive the engine through the package's story kit, or, when the code under test is pure, move the test to a `.unit` file. Never wrap a pure function in a story that ignores its kit.
|
|
142
144
|
|
|
@@ -144,7 +146,7 @@ Every package tests its real engine through its own story kit, so setup and acti
|
|
|
144
146
|
|
|
145
147
|
Quality's `tests/story-setup` rule reports top-level test functions named with the words `seed`, `make`, `build` or `setup`, and fixture-writing calls imported from Node's `fs` or `fs/promises`. It leaves source and `test-support/` files alone. This is a check for those syntax patterns; a passing test file still needs review of what it tests.
|
|
146
148
|
|
|
147
|
-
Specs keep expectations visible. `tests/spec-helpers` moves all module-level helper functions out of specs and into the kit; `tests/no-expect-in-support` moves `expect` calls into the spec. `tests/named-values` rejects numeric literals passed to `toBe` or `toHaveLength` in specs: assert the observed items or give the value a domain name. `tests/no-limit-imports` rejects importing `MAX_*` constants from a `limits` module into specs, so a story proves behavior instead of copying an implementation cap.
|
|
149
|
+
Specs keep expectations visible. `tests/spec-helpers` moves all module-level helper functions out of specs and into the kit; `tests/no-expect-in-support` moves `expect` calls into the spec, except in test-support files that register tests at module top level and are not imported by any module, so nested Vitest runs can execute them as test files with real assertions. `tests/named-values` rejects numeric literals passed to `toBe` or `toHaveLength` in specs, except zero and a status or exit code asserted on a `status`, `code` or `exitCode` subject: assert the observed items or give the value a domain name. `tests/no-limit-imports` rejects importing `MAX_*` constants from a `limits` module into specs, so a story proves behavior instead of copying an implementation cap.
|
|
148
150
|
|
|
149
151
|
`boundaries/queue-sql` rejects SQL mentioning the private `pgboss.` schema. Apps use their queue definitions and let workers process jobs; there is no queue-purge API by design. `boundaries/auth-sql` rejects SQL accessing Better Auth's `user`, `account`, `session` and `verification` tables. Apps use platform's auth API; `options.owners` names platform's own auth implementation and its migrations. These rules inspect SQL templates, literal query calls and query variables, and inventoried `.sql` files. They do not evaluate arbitrary runtime SQL construction.
|
|
150
152
|
|
|
@@ -336,7 +338,7 @@ import { defineConfig } from "vitest/config";
|
|
|
336
338
|
export default defineConfig({ test: testProjects() });
|
|
337
339
|
```
|
|
338
340
|
|
|
339
|
-
`testProjects` runs tests, `.unit`
|
|
341
|
+
`testProjects` selects three projects by default: `unit` runs ordinary Node tests and specs, `pure` runs `.unit.test` and `.unit.spec` files in Node, and `dom` runs `.dom` tests and specs in test-story's DOM environment. The `pure` project always installs an I/O guard: calls to Node's `fs` (including `fs/promises`), `net`, `http`, `https`, `child_process` and `worker_threads` modules and global `fetch` throw an error naming the unit file and call. The guard also patches ESM named imports while preserving Node and Vitest module loading. Keep unit tests pure; test I/O through the package's story kit. Use `--project pure` to run only unit files, or `--project unit` for ordinary Node files. The DOM environment keeps Node's host constructors separate from the happy-dom window, so DOM specs need no project remap. Each test gets 30 seconds instead of Vitest's 5, because tests that start servers, browsers or CLIs take seconds on a busy CI runner. `.slow` tests run only when `--project slow` asks for them. Type tests are excluded from Vitest and belong in the compiler's input. Every project excludes `**/.worktrees/**` so a checkout does not collect specs from its worktrees.
|
|
340
342
|
|
|
341
343
|
Worker concurrency comes from a configured PostgreSQL connection budget, independent of CPU count: `max(1, floor(connectionBudget / connectionsPerWorker))`. The defaults are 80 usable connections and 14 connections per worker, giving five workers. The budget leaves room on a typical 100-connection server for administration and other clients; the estimate allows for full-app tests with several pools. Set the budget from your server's `SHOW max_connections`, subtracting connections reserved for other clients and concurrent test processes. Quality does not query the server. If even one worker exceeds the budget, it still runs one worker; reduce that test's pool sizes or increase the server capacity.
|
|
342
344
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ignoreScope.d.ts","sourceRoot":"","sources":["../../src/inventory/ignoreScope.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,UAAU,aAAa;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED,eAAO,MAAM,UAAU,EAAE,WAAmD,CAAC;AAE7E,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAK9F;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAE7E;AAgBD,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"ignoreScope.d.ts","sourceRoot":"","sources":["../../src/inventory/ignoreScope.ts"],"names":[],"mappings":"AACA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,MAAM,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAAC;AAErD,UAAU,aAAa;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,WAAW;IAC3B,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,OAAO,CAAC,EAAE,WAAW,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CAC5C;AAED,eAAO,MAAM,UAAU,EAAE,WAAmD,CAAC;AAE7E,wBAAgB,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE1C;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,WAAW,CAK9F;AAGD,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,WAAW,CAE7E;AAgBD,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,CAexF"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { relative } from "node:path";
|
|
1
|
+
import { dirname, relative, resolve } from "node:path";
|
|
2
2
|
import ignore from "ignore";
|
|
3
3
|
export const emptyScope = { boundary: undefined, matchers: [] };
|
|
4
4
|
export function posix(path) {
|
|
@@ -28,6 +28,16 @@ function matcherVerdict(matcher, boundary, path, directory) {
|
|
|
28
28
|
return result.unignored ? "kept" : "unknown";
|
|
29
29
|
}
|
|
30
30
|
export function verdictFor(scope, path, directory) {
|
|
31
|
+
if (scope.ignored !== undefined) {
|
|
32
|
+
for (let ancestor = resolve(path);; ancestor = dirname(ancestor)) {
|
|
33
|
+
if (scope.ignored.has(ancestor)) {
|
|
34
|
+
return "ignored";
|
|
35
|
+
}
|
|
36
|
+
if (ancestor === dirname(ancestor)) {
|
|
37
|
+
return "unknown";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
31
41
|
return (scope.matchers.map((matcher) => matcherVerdict(matcher, scope.boundary, path, directory)).findLast((verdict) => verdict !== "unknown")
|
|
32
42
|
?? "unknown");
|
|
33
43
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ignoreScope.js","sourceRoot":"","sources":["../../src/inventory/ignoreScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"ignoreScope.js","sourceRoot":"","sources":["../../src/inventory/ignoreScope.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACvD,OAAO,MAAM,MAAM,QAAQ,CAAC;AAe5B,MAAM,CAAC,MAAM,UAAU,GAAgB,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAE7E,MAAM,UAAU,KAAK,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;AACnC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,KAAkB,EAAE,IAAY,EAAE,QAAgB;IAChF,OAAO;QACN,QAAQ,EAAE,KAAK,CAAC,QAAQ;QACxB,QAAQ,EAAE,CAAC,GAAG,KAAK,CAAC,QAAQ,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;KACtE,CAAC;AACH,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,UAAU,CAAC,KAAkB,EAAE,SAAiB;IAC/D,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;AAC1D,CAAC;AAED,SAAS,cAAc,CAAC,OAAsB,EAAE,QAA4B,EAAE,IAAY,EAAE,SAAkB;IAC7G,MAAM,MAAM,GAAG,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACzG,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;IAC1C,IAAI,GAAG,KAAK,EAAE,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,6DAA6D;IAC7D,MAAM,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAC/D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,KAAkB,EAAE,IAAY,EAAE,SAAkB;IAC9E,IAAI,KAAK,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACjC,KAAK,IAAI,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,GAAI,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YACnE,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACjC,OAAO,SAAS,CAAC;YAClB,CAAC;YACD,IAAI,QAAQ,KAAK,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;gBACpC,OAAO,SAAS,CAAC;YAClB,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,CACN,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,EAAE,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,KAAK,SAAS,CAAC;WACnI,SAAS,CACZ,CAAC;AACH,CAAC"}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
export declare function trackedPaths(directory: string): Promise<readonly string[]>;
|
|
2
2
|
export declare function ignoredTrackedPaths(directory: string): Promise<readonly string[]>;
|
|
3
|
+
export declare function ignoredPaths(directory: string): Promise<readonly string[] | undefined>;
|
|
3
4
|
//# sourceMappingURL=trackedPaths.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trackedPaths.d.ts","sourceRoot":"","sources":["../../src/inventory/trackedPaths.ts"],"names":[],"mappings":"AAqBA,
|
|
1
|
+
{"version":3,"file":"trackedPaths.d.ts","sourceRoot":"","sources":["../../src/inventory/trackedPaths.ts"],"names":[],"mappings":"AAqBA,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAEhF;AAED,wBAAsB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAEvF;AAED,wBAAsB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,GAAG,SAAS,CAAC,CAG5F"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { execFile } from "node:child_process";
|
|
2
|
-
import { join } from "node:path";
|
|
2
|
+
import { join, resolve } from "node:path";
|
|
3
3
|
import { promisify } from "node:util";
|
|
4
4
|
const run = promisify(execFile);
|
|
5
5
|
async function listedPaths(directory, options) {
|
|
@@ -12,15 +12,19 @@ async function listedPaths(directory, options) {
|
|
|
12
12
|
}
|
|
13
13
|
catch (error) {
|
|
14
14
|
if (error instanceof Error && "stderr" in error && String(error.stderr).includes("not a git repository")) {
|
|
15
|
-
return
|
|
15
|
+
return undefined;
|
|
16
16
|
}
|
|
17
17
|
throw error;
|
|
18
18
|
}
|
|
19
19
|
}
|
|
20
|
-
export function trackedPaths(directory) {
|
|
21
|
-
return listedPaths(directory, []);
|
|
20
|
+
export async function trackedPaths(directory) {
|
|
21
|
+
return (await listedPaths(directory, [])) ?? [];
|
|
22
22
|
}
|
|
23
|
-
export function ignoredTrackedPaths(directory) {
|
|
24
|
-
return listedPaths(directory, ["--cached", "--ignored", "--exclude-standard"]);
|
|
23
|
+
export async function ignoredTrackedPaths(directory) {
|
|
24
|
+
return (await listedPaths(directory, ["--cached", "--ignored", "--exclude-standard"])) ?? [];
|
|
25
|
+
}
|
|
26
|
+
export async function ignoredPaths(directory) {
|
|
27
|
+
const paths = await listedPaths(directory, ["--others", "--ignored", "--exclude-standard", "--directory"]);
|
|
28
|
+
return paths?.map((path) => resolve(path));
|
|
25
29
|
}
|
|
26
30
|
//# sourceMappingURL=trackedPaths.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"trackedPaths.js","sourceRoot":"","sources":["../../src/inventory/trackedPaths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"trackedPaths.js","sourceRoot":"","sources":["../../src/inventory/trackedPaths.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AAEtC,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;AAEhC,KAAK,UAAU,WAAW,CAAC,SAAiB,EAAE,OAA0B;IACvE,IAAI,CAAC;QACJ,MAAM,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,CAAC,KAAK,EAAE,CAAC,UAAU,EAAE,IAAI,EAAE,GAAG,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACvH,OAAO,MAAM;aACX,KAAK,CAAC,IAAI,CAAC;aACX,MAAM,CAAC,OAAO,CAAC;aACf,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,CAAC;IACxC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QAChB,IAAI,KAAK,YAAY,KAAK,IAAI,QAAQ,IAAI,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,CAAC;YAC1G,OAAO,SAAS,CAAC;QAClB,CAAC;QACD,MAAM,KAAK,CAAC;IACb,CAAC;AACF,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IACnD,OAAO,CAAC,MAAM,WAAW,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,SAAiB;IAC1D,OAAO,CAAC,MAAM,WAAW,CAAC,SAAS,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,oBAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;AAC9F,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,SAAiB;IACnD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,SAAS,EAAE,CAAC,UAAU,EAAE,WAAW,EAAE,oBAAoB,EAAE,aAAa,CAAC,CAAC,CAAC;IAC3G,OAAO,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAC5C,CAAC"}
|
package/dist/inventory/walk.d.ts
CHANGED
|
@@ -2,6 +2,6 @@ import { Effect, FileSystem } from "effect";
|
|
|
2
2
|
import { FilesystemFailure } from "./filesystem.ts";
|
|
3
3
|
import { type IgnoreScope } from "./ignoreScope.ts";
|
|
4
4
|
export declare function ignoreScopeAt(dir: string, inherited?: IgnoreScope): Effect.Effect<IgnoreScope, FilesystemFailure, FileSystem.FileSystem>;
|
|
5
|
-
export declare
|
|
5
|
+
export declare const scopeAbove: (root: string, dir: string) => Effect.Effect<IgnoreScope, FilesystemFailure, FileSystem.FileSystem>;
|
|
6
6
|
export declare const walk: (dir: string, inherited?: IgnoreScope | undefined) => Effect.Effect<readonly string[], FilesystemFailure, FileSystem.FileSystem>;
|
|
7
7
|
//# sourceMappingURL=walk.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../src/inventory/walk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAkC,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAc,KAAK,WAAW,EAA0C,MAAM,kBAAkB,CAAC;AAKxG,wBAAgB,aAAa,CAC5B,GAAG,EAAE,MAAM,EACX,SAAS,GAAE,WAAwB,GACjC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,iBAAiB,EAAE,UAAU,CAAC,UAAU,CAAC,
|
|
1
|
+
{"version":3,"file":"walk.d.ts","sourceRoot":"","sources":["../../src/inventory/walk.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAkC,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAc,KAAK,WAAW,EAA0C,MAAM,kBAAkB,CAAC;AAKxG,wBAAgB,aAAa,CAC5B,GAAG,EAAE,MAAM,EACX,SAAS,GAAE,WAAwB,GACjC,MAAM,CAAC,MAAM,CAAC,WAAW,EAAE,iBAAiB,EAAE,UAAU,CAAC,UAAU,CAAC,CAOtE;AAED,eAAO,MAAM,UAAU,qGAoBrB,CAAC;AAEH,eAAO,MAAM,IAAI,kIAmBf,CAAC"}
|
package/dist/inventory/walk.js
CHANGED
|
@@ -2,20 +2,29 @@ import { dirname, join, relative, sep } from "node:path";
|
|
|
2
2
|
import { Effect, FileSystem } from "effect";
|
|
3
3
|
import { FilesystemFailure, orWhenAbsent, readOptionalText } from "./filesystem.js";
|
|
4
4
|
import { emptyScope, insideKept, verdictFor, withIgnoreFile } from "./ignoreScope.js";
|
|
5
|
-
import { trackedPaths } from "./trackedPaths.js";
|
|
5
|
+
import { ignoredPaths, trackedPaths } from "./trackedPaths.js";
|
|
6
6
|
const SKIPPED = new Set([".git", ".worktrees", "node_modules"]);
|
|
7
7
|
export function ignoreScopeAt(dir, inherited = emptyScope) {
|
|
8
|
+
if (inherited.ignored !== undefined) {
|
|
9
|
+
return Effect.succeed(inherited);
|
|
10
|
+
}
|
|
8
11
|
return Effect.map(readOptionalText(join(dir, ".gitignore")), (contents) => contents === undefined || contents === "" ? inherited : withIgnoreFile(inherited, dir, contents));
|
|
9
12
|
}
|
|
10
|
-
|
|
11
|
-
|
|
13
|
+
export const scopeAbove = Effect.fnUntraced(function* (root, dir) {
|
|
14
|
+
const ignored = yield* Effect.tryPromise({
|
|
15
|
+
catch: (cause) => new FilesystemFailure({ message: `cannot list ignored files in ${dir}: ${String(cause)}`, path: dir }),
|
|
16
|
+
try: () => ignoredPaths(dir),
|
|
17
|
+
});
|
|
18
|
+
if (ignored !== undefined) {
|
|
19
|
+
return { ...emptyScope, ignored: new Set(ignored) };
|
|
20
|
+
}
|
|
12
21
|
const parts = relative(root, dir)
|
|
13
22
|
.split(sep)
|
|
14
23
|
.filter((part) => part !== "");
|
|
15
24
|
const ancestors = parts.length === 0 ? [] : [root, ...parts.slice(0, -1).map((_, index) => join(root, ...parts.slice(0, index + 1)))];
|
|
16
|
-
return Effect.reduce(ancestors, () => emptyScope, (scope, ancestor) => (verdictFor(scope, ancestor, true) === "ignored" ? Effect.succeed(scope) : ignoreScopeAt(ancestor, scope)));
|
|
17
|
-
}
|
|
18
|
-
export const walk = Effect.fnUntraced(function* (dir, inherited
|
|
25
|
+
return yield* Effect.reduce(ancestors, () => emptyScope, (scope, ancestor) => (verdictFor(scope, ancestor, true) === "ignored" ? Effect.succeed(scope) : ignoreScopeAt(ancestor, scope)));
|
|
26
|
+
});
|
|
27
|
+
export const walk = Effect.fnUntraced(function* (dir, inherited) {
|
|
19
28
|
const fs = yield* FileSystem.FileSystem;
|
|
20
29
|
if ((yield* orWhenAbsent(dir, fs.stat(dir), undefined)) === undefined) {
|
|
21
30
|
return [];
|
|
@@ -30,7 +39,7 @@ export const walk = Effect.fnUntraced(function* (dir, inherited = emptyScope) {
|
|
|
30
39
|
tracked.add(folder);
|
|
31
40
|
}
|
|
32
41
|
}
|
|
33
|
-
return yield* walkDirectory(dir, inherited, tracked);
|
|
42
|
+
return yield* walkDirectory(dir, inherited ?? (yield* scopeAbove(dir, dir)), tracked);
|
|
34
43
|
});
|
|
35
44
|
const walkDirectory = Effect.fnUntraced(function* (dir, inherited, tracked) {
|
|
36
45
|
const fs = yield* FileSystem.FileSystem;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/inventory/walk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,UAAU,EAAoB,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"walk.js","sourceRoot":"","sources":["../../src/inventory/walk.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AACpF,OAAO,EAAE,UAAU,EAAoB,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AACxG,OAAO,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAE/D,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,YAAY,EAAE,cAAc,CAAC,CAAC,CAAC;AAEhE,MAAM,UAAU,aAAa,CAC5B,GAAW,EACX,SAAS,GAAgB,UAAU;IAEnC,IAAI,SAAS,CAAC,OAAO,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,EAAE,CAAC,QAAQ,EAAE,EAAE,CACzE,QAAQ,KAAK,SAAS,IAAI,QAAQ,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,cAAc,CAAC,SAAS,EAAE,GAAG,EAAE,QAAQ,CAAC,CAChG,CAAC;AACH,CAAC;AAED,MAAM,CAAC,MAAM,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EACpD,IAAY,EACZ,GAAW;IAEX,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACxC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,OAAO,EAAE,gCAAgC,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QACxH,GAAG,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC;KAC5B,CAAC,CAAC;IACH,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC3B,OAAO,EAAE,GAAG,UAAU,EAAE,OAAO,EAAE,IAAI,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;IACrD,CAAC;IACD,MAAM,KAAK,GAAG,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC;SAC/B,KAAK,CAAC,GAAG,CAAC;SACV,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,KAAK,EAAE,CAAC,CAAC;IAChC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACtI,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAC1B,SAAS,EACT,GAAG,EAAE,CAAC,UAAU,EAChB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC,CAC/H,CAAC;AACH,CAAC,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAC9C,GAAW,EACX,SAAuB;IAEvB,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,IAAI,CAAC,KAAK,CAAC,CAAC,YAAY,CAAmC,GAAG,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,SAAS,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;QACzG,OAAO,EAAE,CAAC;IACX,CAAC;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;QACtC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,iBAAiB,CAAC,EAAE,OAAO,EAAE,gCAAgC,GAAG,KAAK,MAAM,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;QACxH,GAAG,EAAE,GAAG,EAAE,CAAC,YAAY,CAAC,GAAG,CAAC;KAC5B,CAAC,CAAC;IACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,CAAC;IAC/B,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QAC1B,KAAK,IAAI,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;YACzG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACrB,CAAC;IACF,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;AACvF,CAAC,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAChD,GAAW,EACX,SAAsB,EACtB,OAA4B;IAE5B,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,aAAa,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;IAChH,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,YAAY,CAAoB,GAAG,EAAE,EAAE,CAAC,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;IACvF,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CACnC,OAAO,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAC9C,CAAC,KAAK,EAAE,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EACtD,EAAE,WAAW,EAAE,CAAC,EAAE,CAClB,CAAC;IACF,OAAO,MAAM,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC,CAAC,CAAC;AAEH,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,EAC5C,IAAY,EACZ,KAAkB,EAClB,OAA4B;IAE5B,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,UAAU,CAAC;IACxC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,YAAY,CAAmC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAC;IACnG,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,EAAE,CAAC;IACX,CAAC;IACD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,WAAW,CAAC;IAC5C,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;IACnD,IAAI,OAAO,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACjD,OAAO,EAAE,CAAC;IACX,CAAC;IACD,IAAI,CAAC,SAAS,EAAE,CAAC;QAChB,OAAO,CAAC,IAAI,CAAC,CAAC;IACf,CAAC;IACD,OAAO,KAAK,CAAC,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,UAAU,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;AAClG,CAAC,CAAC,CAAC"}
|
package/dist/rule.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Bivariant } from "@shivaedev/types/
|
|
1
|
+
import type { Bivariant } from "@shivaedev/types/Bivariant.ts";
|
|
2
2
|
import type { ExceptionDeclaration } from "#exceptions/declaration.ts";
|
|
3
3
|
import { type StandardSchemaV1 } from "./standardSchema.ts";
|
|
4
4
|
export interface Finding {
|
package/dist/rules/builtIn.d.ts
CHANGED
|
@@ -28,7 +28,7 @@ export declare const builtInRules: readonly [import("../rule.ts").Rule<"structur
|
|
|
28
28
|
readonly suites?: readonly string[];
|
|
29
29
|
}>, import("../rule.ts").Rule<"tests/colocated", {
|
|
30
30
|
readonly suites?: readonly string[];
|
|
31
|
-
}>, import("../rule.ts").Rule<"tests/story-setup", undefined>, import("../rule.ts").Rule<"tests/story-specs", undefined>, import("../rule.ts").Rule<"boundaries/queue-sql", undefined>, import("../rule.ts").Rule<"boundaries/auth-sql", {
|
|
31
|
+
}>, import("../rule.ts").Rule<"tests/story-setup", undefined>, import("../rule.ts").Rule<"tests/story-specs", undefined>, import("../rule.ts").Rule<"tests/story-engine", undefined>, import("../rule.ts").Rule<"boundaries/queue-sql", undefined>, import("../rule.ts").Rule<"boundaries/auth-sql", {
|
|
32
32
|
readonly owners?: readonly string[];
|
|
33
33
|
}>, import("../rule.ts").Rule<"tests/no-expect-in-support", undefined>, import("../rule.ts").Rule<"tests/spec-helpers", undefined>, import("../rule.ts").Rule<"boundaries/http-status", {
|
|
34
34
|
readonly edge?: readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtIn.d.ts","sourceRoot":"","sources":["../../src/rules/builtIn.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"builtIn.d.ts","sourceRoot":"","sources":["../../src/rules/builtIn.ts"],"names":[],"mappings":"AA2CA,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+HA2Cf,CAAC"}
|
package/dist/rules/builtIn.js
CHANGED
|
@@ -17,6 +17,7 @@ import { noTestCode } from "#rules/imports/noTestCode.ts";
|
|
|
17
17
|
import { importsResolvable } from "#rules/imports/resolvable.ts";
|
|
18
18
|
import { importsRuntime } from "#rules/imports/runtime.ts";
|
|
19
19
|
import { authSql } from "#rules/stories/authSql.ts";
|
|
20
|
+
import { storyEngine } from "#rules/stories/engine.ts";
|
|
20
21
|
import { httpStatus } from "#rules/stories/httpStatus.ts";
|
|
21
22
|
import { namedValues } from "#rules/stories/namedValues.ts";
|
|
22
23
|
import { noExpect } from "#rules/stories/noExpect.ts";
|
|
@@ -74,6 +75,7 @@ export const builtInRules = [
|
|
|
74
75
|
testsColocated,
|
|
75
76
|
storySetup,
|
|
76
77
|
storySpecs,
|
|
78
|
+
storyEngine,
|
|
77
79
|
queueSql,
|
|
78
80
|
authSql,
|
|
79
81
|
noExpect,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builtIn.js","sourceRoot":"","sources":["../../src/rules/builtIn.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,MAAM,4BAA4B,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACjE,OAAO,EAAE,MAAM,EAAE,MAAM,2BAA2B,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAC5D,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,4BAA4B,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AAClE,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,cAAc,EAAE,MAAM,uCAAuC,CAAC;AACvE,OAAO,EAAE,gBAAgB,EAAE,MAAM,yCAAyC,CAAC;AAC3E,OAAO,EAAE,YAAY,EAAE,MAAM,qCAAqC,CAAC;AACnE,OAAO,EAAE,oBAAoB,EAAE,MAAM,6CAA6C,CAAC;AACnF,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,MAAM,CAAC,MAAM,YAAY,GAAG;IAC3B,QAAQ;IACR,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,eAAe;IACf,aAAa;IACb,QAAQ;IACR,MAAM;IACN,mBAAmB;IACnB,UAAU;IACV,QAAQ;IACR,YAAY;IACZ,oBAAoB;IACpB,cAAc;IACd,gBAAgB;IAChB,KAAK;IACL,YAAY;IACZ,YAAY;IACZ,cAAc;IACd,iBAAiB;IACjB,eAAe;IACf,cAAc;IACd,UAAU;IACV,eAAe;IACf,oBAAoB;IACpB,qBAAqB;IACrB,gBAAgB;IAChB,WAAW;IACX,YAAY;IACZ,UAAU;IACV,WAAW;IACX,cAAc;IACd,UAAU;IACV,UAAU;IACV,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,WAAW;IACX,UAAU;IACV,WAAW;IACX,cAAc;CACL,CAAC"}
|
|
1
|
+
{"version":3,"file":"builtIn.js","sourceRoot":"","sources":["../../src/rules/builtIn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../src/rules/stories/engine.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,WAAW,0DAiCtB,CAAC"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import ts from "typescript";
|
|
2
|
+
import { importGraph } from "#imports/graph.ts";
|
|
3
|
+
import { packageOf } from "#imports/workspace.ts";
|
|
4
|
+
import { testName } from "#naming/testName.ts";
|
|
5
|
+
import { defineRule } from "#rule.ts";
|
|
6
|
+
import { storyOrigins } from "./origins.js";
|
|
7
|
+
import { storyPrerequisites } from "./prerequisites.js";
|
|
8
|
+
import { nodesWhere, unwrapped } from "./syntax.js";
|
|
9
|
+
import { storyUsesInputs } from "./usesInputs.js";
|
|
10
|
+
function ignoresEngine(call, checker) {
|
|
11
|
+
const traits = call.arguments[1];
|
|
12
|
+
const given = traits === undefined ? undefined : unwrapped(traits);
|
|
13
|
+
const body = call.arguments[2];
|
|
14
|
+
return (given !== undefined
|
|
15
|
+
&& ts.isArrayLiteralExpression(given)
|
|
16
|
+
&& given.elements.length === 0
|
|
17
|
+
&& (body === undefined || storyUsesInputs(body, checker) === false));
|
|
18
|
+
}
|
|
19
|
+
export const storyEngine = defineRule({
|
|
20
|
+
check: async (inputs) => {
|
|
21
|
+
const graph = await importGraph(inputs);
|
|
22
|
+
const exempt = await storyPrerequisites(inputs, graph.packages);
|
|
23
|
+
const origins = storyOrigins(inputs, graph);
|
|
24
|
+
return inputs.sources.flatMap((file) => {
|
|
25
|
+
const name = testName(file.path);
|
|
26
|
+
const owner = packageOf(graph.packages, file.path);
|
|
27
|
+
if (name === undefined
|
|
28
|
+
|| name.modifiers.some((modifier) => modifier === "unit" || modifier === "typecheck")
|
|
29
|
+
|| exempt.has(owner?.directory ?? "")) {
|
|
30
|
+
return [];
|
|
31
|
+
}
|
|
32
|
+
const source = origins.source(file.path);
|
|
33
|
+
if (source === undefined) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
const stories = nodesWhere(source, (node) => ts.isCallExpression(node) && origins.origin(node.expression) === "story" && ignoresEngine(node, origins.checker));
|
|
37
|
+
return stories.map((story) => ({
|
|
38
|
+
file: file.path,
|
|
39
|
+
line: source.getLineAndCharacterOfPosition(story.getStart(source)).line + 1,
|
|
40
|
+
message: `Declares a story without traits whose body never references its verbs, its story or its test context. Drive the engine through one of the kit's verbs or traits. If the code under test is pure, move the test to ${name.stem}.unit.${name.kind}${name.extension}, which reaches no engine and mocks nothing. See https://github.com/ShivaeDev/platform/tree/main/packages/quality#story-tests.`,
|
|
41
|
+
}));
|
|
42
|
+
});
|
|
43
|
+
},
|
|
44
|
+
description: "A story without traits references its kit's verbs, its story or its test context; pure tests belong in .unit files that reach no engine and mock nothing.",
|
|
45
|
+
id: "tests/story-engine",
|
|
46
|
+
});
|
|
47
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../../../src/rules/stories/engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importOrigin.d.ts","sourceRoot":"","sources":["../../../src/rules/stories/importOrigin.ts"],"names":[],"mappings":"AAOA,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE,IAAI,CAAC,EAAE,MAAM,oEAYnE"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
function moduleOrigin(from) {
|
|
2
|
+
if (from === "vitest" || from === "@effect/vitest") {
|
|
3
|
+
return "vitest";
|
|
4
|
+
}
|
|
5
|
+
return from === "@shivaedev/test-story" || from === "@shivaedev/test-story/server/storyKit.ts" ? "stories" : undefined;
|
|
6
|
+
}
|
|
7
|
+
export function importOrigin(from, name) {
|
|
8
|
+
const namespace = moduleOrigin(from);
|
|
9
|
+
if (name === undefined) {
|
|
10
|
+
return namespace;
|
|
11
|
+
}
|
|
12
|
+
if (name === "storyKit" && namespace === "stories") {
|
|
13
|
+
return "factory";
|
|
14
|
+
}
|
|
15
|
+
if ((name === "describe" || name === "suite") && namespace === "vitest") {
|
|
16
|
+
return "suite";
|
|
17
|
+
}
|
|
18
|
+
return (name === "it" || name === "test") && namespace === "vitest" ? "plain" : undefined;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=importOrigin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"importOrigin.js","sourceRoot":"","sources":["../../../src/rules/stories/importOrigin.ts"],"names":[],"mappings":"AAAA,SAAS,YAAY,CAAC,IAAwB;IAC7C,IAAI,IAAI,KAAK,QAAQ,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACpD,OAAO,QAAQ,CAAC;IACjB,CAAC;IACD,OAAO,IAAI,KAAK,uBAAuB,IAAI,IAAI,KAAK,0CAA0C,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;AACxH,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,IAAwB,EAAE,IAAa;IACnE,MAAM,SAAS,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,IAAI,KAAK,UAAU,IAAI,SAAS,KAAK,SAAS,EAAE,CAAC;QACpD,OAAO,SAAS,CAAC;IAClB,CAAC;IACD,IAAI,CAAC,IAAI,KAAK,UAAU,IAAI,IAAI,KAAK,OAAO,CAAC,IAAI,SAAS,KAAK,QAAQ,EAAE,CAAC;QACzE,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,KAAK,MAAM,CAAC,IAAI,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;AAC3F,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namedValues.d.ts","sourceRoot":"","sources":["../../../src/rules/stories/namedValues.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"namedValues.d.ts","sourceRoot":"","sources":["../../../src/rules/stories/namedValues.ts"],"names":[],"mappings":"AA0CA,eAAO,MAAM,WAAW,0DAKtB,CAAC"}
|
|
@@ -1,11 +1,37 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import { defineRule } from "#rule.ts";
|
|
3
|
-
import { isSpec, memberName, nodesWhere, numericValue, syntaxFindings } from "./syntax.js";
|
|
3
|
+
import { isSpec, memberName, nodesWhere, numericValue, syntaxFindings, unwrapped } from "./syntax.js";
|
|
4
4
|
const MESSAGE = "Passes a numeric literal to toBe or toHaveLength. Assert the observed items, or give the expected value a domain name before asserting it.";
|
|
5
|
+
function codeSubject(expression) {
|
|
6
|
+
const value = unwrapped(expression);
|
|
7
|
+
if (!(ts.isPropertyAccessExpression(value) || ts.isElementAccessExpression(value))) {
|
|
8
|
+
return false;
|
|
9
|
+
}
|
|
10
|
+
let root = unwrapped(value.expression);
|
|
11
|
+
while ((ts.isPropertyAccessExpression(root) || ts.isElementAccessExpression(root)) && memberName(root) === "not") {
|
|
12
|
+
root = unwrapped(root.expression);
|
|
13
|
+
}
|
|
14
|
+
if (!ts.isCallExpression(root)) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
const callee = unwrapped(root.expression);
|
|
18
|
+
const receiver = ts.isPropertyAccessExpression(callee) ? unwrapped(callee.expression) : callee;
|
|
19
|
+
const expect = ts.isIdentifier(receiver) && receiver.text === "expect" && (receiver === callee || memberName(callee) === "soft");
|
|
20
|
+
const argument = root.arguments[0];
|
|
21
|
+
if (!expect || argument === undefined) {
|
|
22
|
+
return false;
|
|
23
|
+
}
|
|
24
|
+
const subject = unwrapped(argument);
|
|
25
|
+
return ["status", "code", "exitCode"].includes(ts.isIdentifier(subject) ? subject.text : (memberName(subject) ?? ""));
|
|
26
|
+
}
|
|
5
27
|
function numericAssertion(node) {
|
|
6
28
|
return (ts.isCallExpression(node)
|
|
7
29
|
&& ["toBe", "toHaveLength"].includes(memberName(node.expression) ?? "")
|
|
8
|
-
&& node.
|
|
30
|
+
&& !codeSubject(node.expression)
|
|
31
|
+
&& node.arguments.some((argument) => {
|
|
32
|
+
const value = numericValue(argument);
|
|
33
|
+
return value !== undefined && value !== 0;
|
|
34
|
+
}));
|
|
9
35
|
}
|
|
10
36
|
export const namedValues = defineRule({
|
|
11
37
|
check: ({ sources }) => sources.filter((file) => isSpec(file.path)).flatMap((file) => syntaxFindings(file, (source) => nodesWhere(source, numericAssertion), MESSAGE)),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"namedValues.js","sourceRoot":"","sources":["../../../src/rules/stories/namedValues.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"namedValues.js","sourceRoot":"","sources":["../../../src/rules/stories/namedValues.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"noExpect.d.ts","sourceRoot":"","sources":["../../../src/rules/stories/noExpect.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"noExpect.d.ts","sourceRoot":"","sources":["../../../src/rules/stories/noExpect.ts"],"names":[],"mappings":"AAoCA,eAAO,MAAM,QAAQ,kEAcnB,CAAC"}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
|
+
import { importGraph } from "#imports/graph.ts";
|
|
2
3
|
import { isTestSupport } from "#naming/testName.ts";
|
|
3
4
|
import { defineRule } from "#rule.ts";
|
|
5
|
+
import { registersTests } from "./registersTests.js";
|
|
4
6
|
import { memberName, nodesWhere, syntaxFindings, unwrapped } from "./syntax.js";
|
|
5
7
|
const MESSAGE = "Calls expect in test-support. Return the engine's observed state from the verb and put the expectation in the spec; throw if an action cannot run.";
|
|
6
8
|
function assertionReference(expression, names) {
|
|
@@ -26,7 +28,15 @@ function assertionsIn(source) {
|
|
|
26
28
|
return nodesWhere(source, (node) => ts.isCallExpression(node) && assertionReference(node.expression, names));
|
|
27
29
|
}
|
|
28
30
|
export const noExpect = defineRule({
|
|
29
|
-
check:
|
|
31
|
+
check: async (inputs) => {
|
|
32
|
+
const support = inputs.sources.filter((file) => isTestSupport(file.path));
|
|
33
|
+
if (support.length === 0) {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
const graph = await importGraph(inputs);
|
|
37
|
+
const imported = new Set(graph.edges.flatMap((edge) => (edge.kind === "import" && edge.to.kind === "file" ? [edge.to.path] : [])));
|
|
38
|
+
return support.flatMap((file) => syntaxFindings(file, (source) => (!imported.has(file.path) && registersTests(source) ? [] : assertionsIn(source)), MESSAGE));
|
|
39
|
+
},
|
|
30
40
|
description: "Test-support performs actions and exposes observations; specs own expectations.",
|
|
31
41
|
id: "tests/no-expect-in-support",
|
|
32
42
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"noExpect.js","sourceRoot":"","sources":["../../../src/rules/stories/noExpect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEhF,MAAM,OAAO,GACZ,oJAAoJ,CAAC;AAEtJ,SAAS,kBAAkB,CAAC,UAAyB,EAAE,KAA0B;IAChF,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CACN,UAAU,CAAC,IAAI,CAAC,KAAK,QAAQ;WAC1B,CAAC,CAAC,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAC9H,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,MAAqB;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClC,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;QACvG,IAAI,QAAQ,KAAK,SAAS,IAAI,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACzC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC9D,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9G,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IAClC,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"noExpect.js","sourceRoot":"","sources":["../../../src/rules/stories/noExpect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAEhF,MAAM,OAAO,GACZ,oJAAoJ,CAAC;AAEtJ,SAAS,kBAAkB,CAAC,UAAyB,EAAE,KAA0B;IAChF,MAAM,IAAI,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;IACnC,IAAI,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3B,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7B,CAAC;IACD,OAAO,CACN,UAAU,CAAC,IAAI,CAAC,KAAK,QAAQ;WAC1B,CAAC,CAAC,EAAE,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,yBAAyB,CAAC,IAAI,CAAC,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAC9H,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,MAAqB;IAC1C,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC;IAClC,KAAK,MAAM,SAAS,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;QAC3C,MAAM,QAAQ,GAAG,EAAE,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,YAAY,EAAE,aAAa,CAAC,CAAC,CAAC,SAAS,CAAC;QACvG,IAAI,QAAQ,KAAK,SAAS,IAAI,EAAE,CAAC,cAAc,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC3D,KAAK,MAAM,OAAO,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACzC,IAAI,CAAC,OAAO,CAAC,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;oBAC9D,KAAK,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC9B,CAAC;YACF,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,UAAU,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,CAAC,CAAC;AAC9G,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GAAG,UAAU,CAAC;IAClC,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE;QACvB,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC1E,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAC;QACX,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,MAAM,CAAC,CAAC;QACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QACnI,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAC/B,cAAc,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,YAAY,CAAC,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAC3H,CAAC;IACH,CAAC;IACD,WAAW,EAAE,iFAAiF;IAC9F,EAAE,EAAE,4BAA4B;CAChC,CAAC,CAAC"}
|
|
@@ -3,6 +3,7 @@ import type { ImportGraph } from "#imports/graph.ts";
|
|
|
3
3
|
import type { RuleInputs } from "#rule.ts";
|
|
4
4
|
type Origin = "factory" | "kit" | "story" | "plain" | "suite" | "vitest" | "stories" | "function" | undefined;
|
|
5
5
|
export declare function storyOrigins(inputs: RuleInputs, graph: ImportGraph): {
|
|
6
|
+
checker: ts.TypeChecker;
|
|
6
7
|
origin: (node: ts.Node) => Origin;
|
|
7
8
|
source: (path: string) => ts.SourceFile | undefined;
|
|
8
9
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"origins.d.ts","sourceRoot":"","sources":["../../../src/rules/stories/origins.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"origins.d.ts","sourceRoot":"","sources":["../../../src/rules/stories/origins.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAK3C,KAAK,MAAM,GAAG,SAAS,GAAG,KAAK,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;AAW9G,wBAAgB,YAAY,CAAC,MAAM,EAAE,UAAU,EAAE,KAAK,EAAE,WAAW;;mBA2G7C,EAAE,CAAC,IAAI,KAAG,MAAM;mBAWW,MAAM;EACtD"}
|