@nitra/cursor 12.8.6 → 12.8.8
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 +12 -0
- package/package.json +1 -1
- package/rules/abie/main.mdc +9 -5
- package/rules/abie/policy/base_deployment_preem/base_deployment_preem.mdc +22 -0
- package/rules/abie/policy/clean_merged_ignore_branches/clean_merged_ignore_branches.mdc +19 -0
- package/rules/abie/policy/health_check_policy/health_check_policy.mdc +17 -0
- package/rules/abie/policy/http_route_base/http_route_base.mdc +9 -0
- package/rules/abie/policy/package_json_shared/package_json_shared.mdc +17 -0
- package/rules/adr/js/hooks.mdc +32 -0
- package/rules/adr/js/madr_format.mdc +96 -0
- package/rules/adr/js/settings_policy.mdc +34 -0
- package/rules/adr/main.mdc +17 -95
- package/rules/adr/policy/settings_json/settings_json.mdc +7 -0
- package/rules/adr/policy/settings_local_json/settings_local_json.mdc +7 -0
- package/rules/bun/js/bunfig.mdc +12 -0
- package/rules/bun/js/layout.mdc +60 -0
- package/rules/bun/js/lint.mdc +9 -0
- package/rules/bun/js/package_json.mdc +19 -0
- package/rules/bun/main.mdc +7 -60
- package/rules/bun/policy/bunfig/bunfig.mdc +12 -0
- package/rules/bun/policy/package_json/package_json.mdc +14 -0
- package/rules/capacitor/js/ios_spm.mdc +69 -0
- package/rules/capacitor/js/version.mdc +29 -0
- package/rules/capacitor/main.mdc +6 -22
- package/rules/capacitor/policy/package_json/package_json.mdc +9 -0
- package/rules/changelog/js/agent-workflow.mdc +15 -0
- package/rules/changelog/js/changelog-format.mdc +33 -0
- package/rules/changelog/js/comparison-models.mdc +40 -0
- package/rules/changelog/main.mdc +4 -98
- package/rules/ci4/js/marksman_config.mdc +31 -0
- package/rules/ci4/js/vscode_extensions.mdc +33 -0
- package/rules/ci4/main.mdc +16 -14
- package/rules/ci4/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/docker/js/compile.mdc +44 -0
- package/rules/docker/js/hadolint.mdc +50 -0
- package/rules/docker/js/mirror.mdc +13 -0
- package/rules/docker/js/multistage.mdc +13 -0
- package/rules/docker/js/native-addon.mdc +43 -0
- package/rules/docker/js/nginx-tag.mdc +7 -0
- package/rules/docker/js/nginx-user.mdc +37 -0
- package/rules/docker/js/non-root.mdc +39 -0
- package/rules/docker/main.mdc +13 -196
- package/rules/docker/policy/lint_docker_yml/lint_docker_yml.mdc +14 -0
- package/rules/efes/main.mdc +1 -1
- package/rules/efes/policy/package_json_shared/package_json_shared.mdc +30 -0
- package/rules/ga/js/lint_toolchain.mdc +15 -0
- package/rules/ga/js/required_workflows.mdc +35 -0
- package/rules/ga/js/vscode.mdc +17 -0
- package/rules/ga/js/workflow_common.mdc +108 -0
- package/rules/ga/js/workflows.mdc +32 -0
- package/rules/ga/js/zizmor.mdc +7 -0
- package/rules/ga/main.mdc +16 -119
- package/rules/ga/policy/clean_ga_workflows/clean_ga_workflows.mdc +18 -0
- package/rules/ga/policy/clean_merged_branch/clean_merged_branch.mdc +22 -0
- package/rules/ga/policy/git_ai/git_ai.mdc +19 -0
- package/rules/ga/policy/lint_ga/lint_ga.mdc +21 -0
- package/rules/ga/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/ga/policy/vscode_settings/vscode_settings.mdc +9 -0
- package/rules/ga/policy/workflow_common/workflow_common.mdc +18 -0
- package/rules/ga/policy/zizmor_yml/zizmor_yml.mdc +9 -0
- package/rules/graphql/js/tooling.mdc +13 -0
- package/rules/graphql/js/vscode_extensions.mdc +13 -0
- package/rules/graphql/main.mdc +4 -21
- package/rules/graphql/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/hasura/js/internal_urls.mdc +27 -0
- package/rules/hasura/js/migrations.mdc +13 -0
- package/rules/hasura/js/svc_hl.mdc +17 -0
- package/rules/hasura/main.mdc +6 -30
- package/rules/hasura/policy/svc_hl/svc_hl.mdc +15 -0
- package/rules/image-avif/js/avif_generation.mdc +26 -0
- package/rules/image-avif/js/package_json_optout.mdc +21 -0
- package/rules/image-avif/main.mdc +5 -34
- package/rules/image-avif/policy/package_json/package_json.mdc +18 -0
- package/rules/image-compress/js/package_json.mdc +7 -0
- package/rules/image-compress/js/package_setup.mdc +13 -0
- package/rules/image-compress/main.mdc +4 -12
- package/rules/image-compress/policy/package_json/package_json.mdc +13 -0
- package/rules/js/docs/index.md +3 -3
- package/rules/js/js/dep-policy.mdc +17 -0
- package/rules/js/js/eslint-config.mdc +28 -0
- package/rules/js/js/extensions.mdc +8 -0
- package/rules/js/js/file-extensions.mdc +12 -0
- package/rules/js/js/for-in.mdc +26 -0
- package/rules/js/js/jscpd.mdc +42 -0
- package/rules/js/js/knip.mdc +15 -0
- package/rules/js/js/lint-js-workflow.mdc +58 -0
- package/rules/js/js/oxlintrc.mdc +20 -0
- package/rules/js/js/package-json.mdc +31 -0
- package/rules/js/js/tests.mdc +9 -0
- package/rules/js/js/utils-lib-structure.mdc +15 -0
- package/rules/js/main.mdc +19 -211
- package/rules/js/policy/jscpd/jscpd.mdc +14 -0
- package/rules/js/policy/lint_js_yml/lint_js_yml.mdc +14 -0
- package/rules/js/policy/package_json/package_json.mdc +15 -0
- package/rules/js/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/js-bun-db/js/bun-sql-migration.mdc +15 -0
- package/rules/js-bun-db/js/connection.mdc +42 -0
- package/rules/js-bun-db/js/pg-format-identifiers.mdc +102 -0
- package/rules/js-bun-db/js/pg-format-shim.mdc +99 -0
- package/rules/js-bun-db/js/pg-leftover.mdc +27 -0
- package/rules/js-bun-db/js/pg-listen-notify.mdc +51 -0
- package/rules/js-bun-db/js/query-safety.mdc +117 -0
- package/rules/js-bun-db/js/sql-array.mdc +88 -0
- package/rules/js-bun-db/js/unsafe.mdc +65 -0
- package/rules/js-bun-db/main.mdc +12 -607
- package/rules/js-bun-db/policy/package_json/package_json.mdc +17 -0
- package/rules/js-bun-redis/js/imports.mdc +47 -0
- package/rules/js-bun-redis/js/package_json.mdc +44 -0
- package/rules/js-bun-redis/main.mdc +4 -10
- package/rules/js-bun-redis/policy/package_json/package_json.mdc +11 -0
- package/rules/js-mssql/js/mssql-in-list.mdc +38 -0
- package/rules/js-mssql/js/mssql-pool.mdc +56 -0
- package/rules/js-mssql/js/mssql-query-template.mdc +33 -0
- package/rules/js-mssql/js/mssql-tvp.mdc +75 -0
- package/rules/js-mssql/js/mssql-version.mdc +7 -0
- package/rules/js-mssql/main.mdc +10 -198
- package/rules/js-mssql/policy/package_json/package_json.mdc +9 -0
- package/rules/js-run/js/check-env.mdc +35 -0
- package/rules/js-run/js/conn-aliases.mdc +109 -0
- package/rules/js-run/js/jsconfig.mdc +20 -0
- package/rules/js-run/js/otel-configmap.mdc +6 -0
- package/rules/js-run/js/pino.mdc +6 -0
- package/rules/js-run/js/project-structure.mdc +11 -0
- package/rules/js-run/js/runtime.mdc +14 -0
- package/rules/js-run/js/scope.mdc +11 -0
- package/rules/js-run/js/settimeout.mdc +11 -0
- package/rules/js-run/js/temporal.mdc +5 -0
- package/rules/js-run/main.mdc +16 -216
- package/rules/js-run/policy/configmap/configmap.mdc +31 -0
- package/rules/js-run/policy/jsconfig/jsconfig.mdc +25 -0
- package/rules/js-run/policy/package_json/package_json.mdc +38 -0
- package/rules/k8s/js/configmap.mdc +41 -0
- package/rules/k8s/js/deployment_resources.mdc +49 -0
- package/rules/k8s/js/hasura_httproute.mdc +91 -0
- package/rules/k8s/js/hpa_apiversion.mdc +27 -0
- package/rules/k8s/js/ingress_gateway.mdc +16 -0
- package/rules/k8s/js/kustomize_structure.mdc +144 -0
- package/rules/k8s/js/lint_k8s.mdc +72 -0
- package/rules/k8s/js/multidoc_yaml.mdc +5 -0
- package/rules/k8s/js/network_policy.mdc +136 -0
- package/rules/k8s/js/schema_modeline.mdc +57 -0
- package/rules/k8s/js/service.mdc +44 -0
- package/rules/k8s/js/topology_hpa_pdb.mdc +181 -0
- package/rules/k8s/main.mdc +29 -834
- package/rules/k8s/policy/base_kustomization/base_kustomization.mdc +12 -0
- package/rules/k8s/policy/base_manifest/base_manifest.mdc +14 -0
- package/rules/k8s/policy/gateway/gateway.mdc +17 -0
- package/rules/k8s/policy/hasura_configmap/hasura_configmap.mdc +20 -0
- package/rules/k8s/policy/hasura_httproute/hasura_httproute.mdc +16 -0
- package/rules/k8s/policy/hpa_pdb/hpa_pdb.mdc +23 -0
- package/rules/k8s/policy/kustomization/kustomization.mdc +20 -0
- package/rules/k8s/policy/manifest/manifest.mdc +17 -0
- package/rules/k8s/policy/network_policy/network_policy.mdc +22 -0
- package/rules/k8s/policy/svc_hl_yaml/svc_hl_yaml.mdc +13 -0
- package/rules/k8s/policy/svc_yaml/svc_yaml.mdc +12 -0
- package/rules/nginx-default-tpl/js/dockerfile.mdc +36 -0
- package/rules/nginx-default-tpl/js/http-route.mdc +41 -0
- package/rules/nginx-default-tpl/js/ini-keys.mdc +21 -0
- package/rules/nginx-default-tpl/js/template-structure.mdc +86 -0
- package/rules/nginx-default-tpl/js/vscode.mdc +37 -0
- package/rules/nginx-default-tpl/main.mdc +8 -110
- package/rules/nginx-default-tpl/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/nginx-default-tpl/policy/vscode_settings/vscode_settings.mdc +15 -0
- package/rules/npm-module/js/docs/index.md +5 -5
- package/rules/npm-module/js/docs/rule_meta.md +6 -6
- package/rules/npm-module/js/docs/skill_meta.md +8 -8
- package/rules/npm-module/js/header_doc_pointer.mdc +18 -0
- package/rules/npm-module/js/package_structure.mdc +62 -0
- package/rules/npm-module/js/rule_meta.mdc +11 -0
- package/rules/npm-module/js/skill_meta.mdc +11 -0
- package/rules/npm-module/main.mdc +10 -52
- package/rules/npm-module/policy/emit_types_config/emit_types_config.mdc +40 -0
- package/rules/npm-module/policy/npm_package_json/npm_package_json.mdc +50 -0
- package/rules/npm-module/policy/root_package_json/root_package_json.mdc +37 -0
- package/rules/php/js/lint_php_yml.mdc +12 -0
- package/rules/php/js/tooling.mdc +66 -0
- package/rules/php/main.mdc +5 -66
- package/rules/php/policy/lint_php_yml/lint_php_yml.mdc +21 -0
- package/rules/python/js/lint_python_yml.mdc +23 -0
- package/rules/python/js/pyproject_toml.mdc +32 -0
- package/rules/python/js/tooling.mdc +23 -0
- package/rules/python/main.mdc +7 -32
- package/rules/python/policy/lint_python_yml/lint_python_yml.mdc +12 -0
- package/rules/python/policy/pyproject_toml/pyproject_toml.mdc +13 -0
- package/rules/rego/js/rego-lint.mdc +31 -0
- package/rules/rego/js/vscode_extensions.mdc +11 -0
- package/rules/rego/js/vscode_settings.mdc +13 -0
- package/rules/rego/main.mdc +10 -22
- package/rules/rego/policy/vscode_extensions/vscode_extensions.mdc +11 -0
- package/rules/rego/policy/vscode_settings/vscode_settings.mdc +19 -0
- package/rules/rust/js/coverage.mdc +28 -0
- package/rules/rust/js/lint.mdc +22 -0
- package/rules/rust/js/tauri_composition.mdc +8 -0
- package/rules/rust/js/vscode_extensions.mdc +12 -0
- package/rules/rust/main.mdc +8 -38
- package/rules/rust/policy/lint_rust_yml/lint_rust_yml.mdc +12 -0
- package/rules/rust/policy/vscode_extensions/vscode_extensions.mdc +9 -0
- package/rules/security/js/rego_policies.mdc +15 -0
- package/rules/security/js/sample_secret.mdc +19 -0
- package/rules/security/js/trufflehog.mdc +21 -0
- package/rules/security/main.mdc +7 -34
- package/rules/security/policy/lint_security_yml/lint_security_yml.mdc +7 -0
- package/rules/security/policy/package_json/package_json.mdc +7 -0
- package/rules/style/js/admin-table.mdc +88 -0
- package/rules/style/js/colors.mdc +21 -0
- package/rules/style/js/gap.mdc +22 -0
- package/rules/style/js/quasar-fixes.mdc +32 -0
- package/rules/style/js/quasar.mdc +7 -0
- package/rules/style/js/tooling.mdc +85 -0
- package/rules/style/main.mdc +12 -251
- package/rules/style/policy/lint_style_yml/lint_style_yml.mdc +13 -0
- package/rules/style/policy/package_json/package_json.mdc +18 -0
- package/rules/style/policy/vscode_extensions/vscode_extensions.mdc +13 -0
- package/rules/style/policy/vscode_settings/vscode_settings.mdc +19 -0
- package/rules/tauri/js/cargo_mutants_config.mdc +39 -0
- package/rules/tauri/js/tool_surface.mdc +21 -0
- package/rules/tauri/js/tooling.mdc +25 -0
- package/rules/tauri/main.mdc +6 -78
- package/rules/tauri/policy/vscode_extensions/vscode_extensions.mdc +21 -0
- package/rules/test/js/cargo_mutants_config.mdc +18 -0
- package/rules/test/js/docs/index.md +7 -7
- package/rules/test/js/location.mdc +52 -0
- package/rules/test/js/no-console-store-restore.mdc +11 -0
- package/rules/test/js/no-process-chdir.mdc +15 -0
- package/rules/test/js/no-relative-fs-path.mdc +22 -0
- package/rules/test/js/sandbox-aware-test.mdc +28 -0
- package/rules/test/js/stryker_config.mdc +26 -0
- package/rules/test/js/vitest-config-pool-forks.mdc +33 -0
- package/rules/test/main.mdc +16 -184
- package/rules/test/policy/package_json/package_json.mdc +16 -0
- package/rules/text/js/ci-lint-text.mdc +15 -0
- package/rules/text/js/cspell.mdc +81 -0
- package/rules/text/js/dotenv-linter.mdc +16 -0
- package/rules/text/js/forbidden-prettier.mdc +13 -0
- package/rules/text/js/markdownlint.mdc +25 -0
- package/rules/text/js/oxfmt.mdc +35 -0
- package/rules/text/js/package-json.mdc +26 -0
- package/rules/text/js/shellcheck.mdc +18 -0
- package/rules/text/js/v8r.mdc +23 -0
- package/rules/text/js/vscode.mdc +86 -0
- package/rules/text/main.mdc +20 -231
- package/rules/text/policy/cspell/cspell.mdc +34 -0
- package/rules/text/policy/lint_text/lint_text.mdc +19 -0
- package/rules/text/policy/markdownlint/markdownlint.mdc +38 -0
- package/rules/text/policy/oxfmtrc/oxfmtrc.mdc +11 -0
- package/rules/text/policy/package_json/package_json.mdc +33 -0
- package/rules/text/policy/vscode_extensions/vscode_extensions.mdc +13 -0
- package/rules/text/policy/vscode_settings/vscode_settings.mdc +13 -0
- package/rules/vue/js/composition-api.mdc +82 -0
- package/rules/vue/js/nheader-layout.mdc +171 -0
- package/rules/vue/js/node-imports.mdc +25 -0
- package/rules/vue/js/quasar-ui.mdc +32 -0
- package/rules/vue/js/structure.mdc +101 -0
- package/rules/vue/js/testing.mdc +32 -0
- package/rules/vue/js/tfm-translations.mdc +26 -0
- package/rules/vue/js/vite-config.mdc +126 -0
- package/rules/vue/js/vite-env.mdc +55 -0
- package/rules/vue/js/vue-imports.mdc +25 -0
- package/rules/vue/main.mdc +15 -641
- package/rules/vue/policy/package_json/package_json.mdc +30 -0
- package/scripts/docs/index.md +16 -16
- package/scripts/lib/docs/index.md +36 -36
- package/scripts/utils/docs/index.md +14 -14
package/rules/tauri/main.mdc
CHANGED
|
@@ -5,86 +5,14 @@ alwaysApply: false
|
|
|
5
5
|
version: '1.5'
|
|
6
6
|
---
|
|
7
7
|
|
|
8
|
-
|
|
8
|
+
Правило встановлює канонічні вимоги для Tauri-проєктів: виявлення маркерів у монорепо, VS Code-розширення, налаштування mutation-testing для platform bridge та реалізацію Tool Surface поверх Tauri+Rust.
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
{
|
|
12
|
-
"recommendations": ["tauri-apps.tauri-vscode"]
|
|
13
|
-
}
|
|
14
|
-
```
|
|
10
|
+
## Швидкий gate через conftest
|
|
15
11
|
|
|
16
|
-
|
|
12
|
+
[tauri-vscode_extensions](./policy/vscode_extensions/vscode_extensions.mdc)
|
|
17
13
|
|
|
18
|
-
|
|
14
|
+
[tauri-tooling](./js/tooling.mdc)
|
|
19
15
|
|
|
20
|
-
|
|
16
|
+
[tauri-cargo_mutants_config](./js/cargo_mutants_config.mdc)
|
|
21
17
|
|
|
22
|
-
-
|
|
23
|
-
- існує `<ws>/src-tauri/Cargo.toml`;
|
|
24
|
-
- існує `<ws>/src-tauri/tauri.conf.json`;
|
|
25
|
-
- існує `<ws>/tauri.conf.json` (legacy flat-layout);
|
|
26
|
-
- `<ws>/package.json#dependencies` чи `devDependencies` містить ключ з префіксом `@tauri-apps/`.
|
|
27
|
-
|
|
28
|
-
Виявлення виконує `js/tooling.mjs` через `getMonorepoPackageRootDirs()`. Це дозволяє Tauri-rule працювати у монорепо, де Tauri живе в одному з пакетів (а не в корені), не вимагаючи кореневих маркерів.
|
|
29
|
-
|
|
30
|
-
## Mutation-testing: семантика app shell та platform bridge
|
|
31
|
-
|
|
32
|
-
`tauri` rule володіє Tauri-specific семантикою mutation-testing для каталога `src-tauri/`. Концерн `js/cargo_mutants_config.mjs` без дублювання додає у `<ws>/src-tauri/.cargo/mutants.toml` такі канонічні ключі:
|
|
33
|
-
|
|
34
|
-
```toml title="<ws>/src-tauri/.cargo/mutants.toml"
|
|
35
|
-
additional_cargo_test_args = ["--lib", "--tests"]
|
|
36
|
-
|
|
37
|
-
exclude_globs = [
|
|
38
|
-
"src/main.rs",
|
|
39
|
-
"src/lib.rs",
|
|
40
|
-
"src/**/android.rs",
|
|
41
|
-
"src/**/ios.rs",
|
|
42
|
-
"src/**/mobile.rs",
|
|
43
|
-
"src/**/desktop.rs",
|
|
44
|
-
"src/**/macos.rs",
|
|
45
|
-
"src/**/windows.rs",
|
|
46
|
-
"src/**/linux.rs"
|
|
47
|
-
]
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
Семантика (фіксована між Tauri-проєктами):
|
|
51
|
-
|
|
52
|
-
- **`src/main.rs`** — binary shell entrypoint: запускає Tauri runtime, реєструє plugins/handlers і повертає управління циклу подій. Тестується smoke/e2e (запуск бінарника), не mutation unit;
|
|
53
|
-
- **`src/lib.rs`** — Tauri runtime entrypoint (`pub fn run`): піднімає весь app shell. Один мутант там тримає весь Tauri runtime, тому ділить sandbox-фейл з `src/main.rs` і тестується smoke/e2e, а не mutation unit;
|
|
54
|
-
- **`*android.rs`, `*ios.rs`, `*mobile.rs`** — mobile plugin bridge / platform glue: тонка обгортка над JNI/Objective-C виклики, mapping platform errors, виклики Tauri AppHandle і native API;
|
|
55
|
-
- **`*macos.rs`, `*windows.rs`, `*linux.rs`, `*desktop.rs`** — desktop platform bridge / OS integration glue: opener/window APIs, OS-specific I/O, mapping platform errors.
|
|
56
|
-
|
|
57
|
-
Ці файли мають містити **тільки platform boundary**: виклик plugin/native API, Tauri AppHandle, opener/window APIs, OS-specific I/O, mapping platform errors. Якщо у bridge-файлі з'являється pure/business logic — її потрібно винести у platform-neutral модуль (`src/auth/oauth.rs`, `src/gmail/message.rs`, …) і тестувати mutation-testing там.
|
|
58
|
-
|
|
59
|
-
Це створює фіксовану семантику: `*android.rs`/`*macos.rs` — boundary-файли, а не місце для бізнес-логіки.
|
|
60
|
-
|
|
61
|
-
### Ідемпотентність і взаємодія з `test`-rule
|
|
62
|
-
|
|
63
|
-
- `test` rule створює універсальний нейтральний `.cargo/mutants.toml` (порожній з коментарем) для кожного Cargo.toml-manifest-файла — без framework-specific exclude'ів. Це наш baseline.
|
|
64
|
-
- `tauri` rule додає Tauri-канонічні ключі **поверх** того, що вже є у `<ws>/src-tauri/.cargo/mutants.toml`:
|
|
65
|
-
- якщо файла немає — створює з повного Tauri-baseline;
|
|
66
|
-
- якщо обидва канонічні ключі (`additional_cargo_test_args`, `exclude_globs`) вже присутні — `manual cargo-mutants config preserved`, нічого не зміниться;
|
|
67
|
-
- якщо якийсь канонічний ключ відсутній — додається окремим блоком у кінці файла, без зміни існуючих значень.
|
|
68
|
-
- Послідовний `fix test` → `fix tauri` створює Tauri-config; повторний `fix tauri` не дублює секцій; повторний `fix test` не перетирає Tauri-tuning.
|
|
69
|
-
|
|
70
|
-
## Tool Surface у Tauri (реалізація ядра `tool-surface`)
|
|
71
|
-
|
|
72
|
-
Це per-stack реалізація правила **`tool-surface`** (`n-tool-surface`) для Tauri+Rust. Контракт (каталог → `dispatch` → UI/оркестратор/LLM, інваріант паритету, конверт) — у тому правилі; тут — як він лягає на Tauri.
|
|
73
|
-
|
|
74
|
-
**Реальна робота живе в Rust, JS-каталог — тонкий call surface.** Handler тула не містить логіки сам — він **делегує** в native. Одна реалізація в Rust-крейті backs два споживачі:
|
|
75
|
-
|
|
76
|
-
- **Бінарник** (`src-tauri` як CLI, або окремий crate-bin) — headless-вхід для оркестратора;
|
|
77
|
-
- **Tauri-команда** (`#[tauri::command]`) — той самий крейт-fn, обгорнутий для UI.
|
|
78
|
-
|
|
79
|
-
**Два транспорти одного каталогу** (`src/tool/transports`):
|
|
80
|
-
|
|
81
|
-
- **UI (in-app):** `invoke(tool.tauri, input)` → Tauri-команда → крейт. Ключі `input` мапляться 1:1 на аргументи команди (camelCase, напр. `tasksDir`); поля вкладених struct лишаються snake_case (Tauri конвертить лише імена top-level аргументів).
|
|
82
|
-
- **Оркестратор (headless):** `bin/<app>.mjs` спавнить зібраний бінарник (`<bin> <verb> …` per-verb, або уніфікований `<bin> exec '<json>'`), парсить JSON stdout.
|
|
83
|
-
|
|
84
|
-
**Конверт:** Tauri-команда повертає `Result<T, String>`; адаптер мапить у `{ ok, output }` / `{ ok:false, error }`. Бінарник друкує конверт у stdout, exit ≠ 0 на `ok:false`.
|
|
85
|
-
|
|
86
|
-
**Єдине джерело схем:** надавай перевагу `schemars`-derive на Rust-param-структурах → бінарник віддає маніфест (`<bin> schema`); або тримай схему в JS-каталозі й валідуй до `invoke`. **Не дублюй** контракт між Rust і JS — лише деривація + спільні тест-вектори.
|
|
87
|
-
|
|
88
|
-
**Дозволи:** будь-який плагін, який смикають тули (`tauri-plugin-dialog`, `tauri-plugin-http` для локальної LLM тощо), має бути в `src-tauri/capabilities/*.json` і зареєстрований у `lib.rs` — інакше виклик тихо падає.
|
|
89
|
-
|
|
90
|
-
**LLM-раннер in-app:** chat-loop ходить до OpenAI-сумісного ендпоінта через `tauri-plugin-http` fetch (бо webview-fetch обмежений CSP/capability), а тули виконує через спільний `dispatch` (той самий, що й UI).
|
|
18
|
+
[tauri-tool_surface](./js/tool_surface.mdc)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
## VS Code розширення для Tauri-проєктів
|
|
2
|
+
|
|
3
|
+
Rego-пакет: `tauri.vscode_extensions`
|
|
4
|
+
|
|
5
|
+
Цільовий файл: `.vscode/extensions.json`
|
|
6
|
+
|
|
7
|
+
Перевіряє, що поле `recommendations` містить розширення `tauri-apps.tauri-vscode`.
|
|
8
|
+
|
|
9
|
+
Запускається умовно — лише якщо JS-перевірка (`tooling.mjs`) виявила маркер Tauri-проєкту (`src-tauri/`, `tauri.conf.json` або залежність `@tauri-apps/*`). Розширення `rust-lang.rust-analyzer` і `tamasfe.even-better-toml` вимагаються окремо правилом `rust` (rust.mdc).
|
|
10
|
+
|
|
11
|
+
**✓ Правильно:**
|
|
12
|
+
```json
|
|
13
|
+
{ "recommendations": ["tauri-apps.tauri-vscode"] }
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
**✗ Неправильно:**
|
|
17
|
+
```json
|
|
18
|
+
{ "recommendations": ["rust-lang.rust-analyzer"] }
|
|
19
|
+
{ "recommendations": [] }
|
|
20
|
+
{}
|
|
21
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
## Налаштування mutation-testing для Rust: `.cargo/mutants.toml`
|
|
2
|
+
|
|
3
|
+
Якщо у `.n-cursor.json#rules` присутнє правило `rust` — правило `test` створює `.cargo/mutants.toml` у каталозі **кожного** Cargo.toml-маніфесту: кореневий `Cargo.toml`, `<workspace>/src-tauri/Cargo.toml` (Tauri-патерн) і `<workspace>/Cargo.toml` (flat workspace).
|
|
4
|
+
|
|
5
|
+
Канон cargo-mutants config: [mutants.toml.baseline](./data/cargo_mutants_config/mutants.toml.baseline)
|
|
6
|
+
|
|
7
|
+
**Customization** (mutate patterns, exclude rules, timeout) — відповідальність проєкту-споживача; концерн лише забезпечує наявність файлу як стартового baseline в кожному з виявлених workspace-каталогів.
|
|
8
|
+
|
|
9
|
+
### Універсальний baseline і framework-specific tuning
|
|
10
|
+
|
|
11
|
+
Правило `test` відповідає лише за **універсальний baseline** mutation-testing:
|
|
12
|
+
|
|
13
|
+
- створює `.cargo/mutants.toml` для Rust crates (порожній, з коментарем);
|
|
14
|
+
- не робить припущень про framework/app shell;
|
|
15
|
+
- не виключає platform glue, generated wrappers або binary entrypoints;
|
|
16
|
+
- framework-specific tuning (`--lib`/`--tests`, `exclude_globs` для app-shell і platform bridge файлів) належить відповідним правилам (`tauri`, `capacitor` тощо).
|
|
17
|
+
|
|
18
|
+
Якщо інше правило спеціалізує mutation-behavior — воно зобов'язане **доповнювати** існуючий `.cargo/mutants.toml` без дублювання (додавати лише відсутні ключі) і **не перетирати** ручні налаштування. Послідовний запуск `npx @nitra/cursor fix test` після `fix tauri` не має скидати tauri-tuning, і навпаки — повторний `fix tauri` не дублює секції.
|
|
@@ -6,11 +6,11 @@ resource: npm/rules/test/js/
|
|
|
6
6
|
|
|
7
7
|
# npm/rules/test/js
|
|
8
8
|
|
|
9
|
-
| Файл
|
|
10
|
-
|
|
11
|
-
| [cargo_mutants_config.mjs](cargo_mutants_config.md)
|
|
12
|
-
| [location.mjs](location.md)
|
|
13
|
-
| [no-process-chdir.mjs](no-process-chdir.md)
|
|
14
|
-
| [no-relative-fs-path.mjs](no-relative-fs-path.md)
|
|
15
|
-
| [stryker_config.mjs](stryker_config.md)
|
|
9
|
+
| Файл | Тип |
|
|
10
|
+
| ----------------------------------------------------------- | --------- |
|
|
11
|
+
| [cargo_mutants_config.mjs](cargo_mutants_config.md) | JS Module |
|
|
12
|
+
| [location.mjs](location.md) | JS Module |
|
|
13
|
+
| [no-process-chdir.mjs](no-process-chdir.md) | JS Module |
|
|
14
|
+
| [no-relative-fs-path.mjs](no-relative-fs-path.md) | JS Module |
|
|
15
|
+
| [stryker_config.mjs](stryker_config.md) | JS Module |
|
|
16
16
|
| [vitest-config-pool-forks.mjs](vitest-config-pool-forks.md) | JS Module |
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
## Розміщення тестових файлів у каталозі `tests/`
|
|
2
|
+
|
|
3
|
+
JS-тести у пакеті лежать у **піддиректорії `tests/`** поряд із кодом, який тестується, а **не безпосередньо біля джерельного файлу**.
|
|
4
|
+
|
|
5
|
+
```
|
|
6
|
+
rules/foo/js/bar/
|
|
7
|
+
├── check.mjs ← JS-джерело
|
|
8
|
+
└── tests/
|
|
9
|
+
└── check.test.mjs ← тест check.mjs
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
**Чому так:**
|
|
13
|
+
|
|
14
|
+
- Каталог-з-кодом залишається чистим: продакшен-модулі, политики, темплейти не миготять серед тестових файлів.
|
|
15
|
+
- Один погляд на дерево показує, що піде у npm tarball (все, крім `tests/` і `__fixtures__/` — їх ловить `package.json#files` через негативні globs).
|
|
16
|
+
- Якщо тест переростає у мульти-файловий — він уже у власному каталозі, без хаотичного розкидання.
|
|
17
|
+
|
|
18
|
+
**Виняток — Rego unit-тести (`*_test.rego`):** лишаються **поряд із полісі-файлом** відповідно до загальноприйнятого OPA/Conftest community-патерну. `conftest verify -p <dir>` рекурсивно підхоплює їх незалежно від місця в каталозі.
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
rules/foo/policy/package_json/
|
|
22
|
+
├── package_json.rego ← Rego-правило
|
|
23
|
+
├── package_json_test.rego ← Rego unit-тести (поряд, не у tests/)
|
|
24
|
+
└── target.json
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
**Спеціальні випадки:**
|
|
28
|
+
|
|
29
|
+
- **Integration-тести на рівні пакета** — у `<root>/tests/` (наприклад `npm/tests/`). Це не «біля файлу», а виокремлений каталог для тестів, що покривають весь пакет.
|
|
30
|
+
- **Fixtures**: `__fixtures__/` (для shared) і `fixtures/` (для rule-specific) також живуть **усередині `tests/`**: `tests/__fixtures__/...` і `tests/fixtures/...`.
|
|
31
|
+
- **Test helpers** (`test-helpers.mjs`) можуть лишатися у `scripts/utils/` як shared infra — конвенція стосується файлів `*.test.mjs`.
|
|
32
|
+
|
|
33
|
+
**Гарантії tarball-чистоти** через `package.json#files`:
|
|
34
|
+
|
|
35
|
+
```json
|
|
36
|
+
"files": [
|
|
37
|
+
"...",
|
|
38
|
+
"!**/*.test.mjs",
|
|
39
|
+
"!**/*_test.rego",
|
|
40
|
+
"!**/__fixtures__/**",
|
|
41
|
+
"!**/fixtures/**",
|
|
42
|
+
"!**/test-helpers.mjs"
|
|
43
|
+
]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Recursive globs ловлять файли всередині `tests/` так само, як ловили б їх біля джерела.
|
|
47
|
+
|
|
48
|
+
`npx @nitra/cursor fix test` (concern `location`) проходить деревом пакета й перевіряє: **кожен `*.test.mjs` файл лежить усередині каталогу з ім'ям `tests`** (точне співпадіння басенейму батьківської директорії). Файли поза цим каталогом репортуються з порадою куди їх перенести.
|
|
49
|
+
|
|
50
|
+
`*_test.rego` перевіркою **не охоплюються** — вони не переміщуються.
|
|
51
|
+
|
|
52
|
+
Пропускаються: `node_modules`, `.git`, `dist`, `build`, `.venv`, `venv`, шляхи з `.n-cursor.json:ignore`.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
## Заборона ручного store/restore `console` у тестах
|
|
2
|
+
|
|
3
|
+
`console.log` / `console.error` / `console.warn` — **process-wide** мутації, рівно як `process.cwd()`. Якщо тест перехоплює їх через `const orig = console.log; console.log = (...) => …; try { … } finally { console.log = orig }`, паралельний test файл у `pool: 'forks'` (різний процес) ізольований, але в межах **одного** процесу всі тести у файлі ділять єдиний `console`-об'єкт. Якщо try/finally не виконається (наприклад, асинхронна помилка повз `await`), restore не спрацює і наступні тести втрачають вивід.
|
|
4
|
+
|
|
5
|
+
Тому:
|
|
6
|
+
|
|
7
|
+
- **Канон**: `vi.spyOn(console, 'log').mockReturnValue()` (та аналоги для `error`/`warn`/`info`) + `afterEach(() => vi.restoreAllMocks())`. Vitest сам слідкує за scope mock-у і гарантовано відновлює оригінал між тестами, навіть якщо тест кинув виняток.
|
|
8
|
+
- **Заборонено**: ручний store/restore (`const orig = console.log; console.log = stub`). Виняток — коли тест **необхідно** перехопити вивід **до** того, як завантажиться модуль із top-level-логуванням; у цьому випадку фіксуй pattern explicit-коментарем.
|
|
9
|
+
- Якщо потрібен лог зі stub-ом — `const logs = []; vi.spyOn(console, 'log').mockImplementation((...args) => logs.push(args.join(' ')))`.
|
|
10
|
+
|
|
11
|
+
**Перевірка** — концерн `no-console-store-restore` (`rules/test/js/no-console-store-restore.mjs`): AST-сканер, який ловить присвоєння `console.<method> = …` у `*.test.{js,mjs}`.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
## Заборона `process.chdir` у тестах
|
|
2
|
+
|
|
3
|
+
`process.chdir(dir)` — **process-wide** мутація. Vitest за замовчуванням ставить `pool: 'threads'`, і всі workers ділять один процес: паралельний test file може перехопити cwd сусіда посеред FS- або `git`-операції. У реальному інциденті це призвело до того, що `git init`+`git commit` із tmp-фікстури потрапив у реальний робочий репозиторій і створив rogue commit з автором `test <test@test>`, знищивши `npm/package.json` / `CHANGELOG.md`.
|
|
4
|
+
|
|
5
|
+
Тому:
|
|
6
|
+
|
|
7
|
+
- **У тестах заборонено** `process.chdir(...)` напряму та будь-які хелпери, що його викликають (історичний `withTmpCwd` видалений у `1.28.0`).
|
|
8
|
+
- Канон: `withTmpDir(async dir => { ... })` зі `scripts/utils/test-helpers.mjs` — створює tmpdir і передає **абсолютний** `dir` у callback **без** `process.chdir`.
|
|
9
|
+
- Усі FS-операції у тесті — через `join(dir, …)` і `writeJson(join(dir, …), …)` / `ensureDir(join(dir, …))` (хелпери валідують `isAbsolute`).
|
|
10
|
+
- Усі child-процеси — `execFile(bin, args, { cwd: dir })`, `spawnSync(bin, args, { cwd: dir })`.
|
|
11
|
+
- Concern-функції правил — `await check(dir)`, `await applies(dir)`, `await fix(dir)`; усі production функції приймають перший параметр `cwd = process.cwd()` (default зберігає CLI-сумісність).
|
|
12
|
+
|
|
13
|
+
**Перевірка** (`rules/test/js/no-process-chdir.mjs`): сканує `**/*.test.{js,mjs}` і падає з ❌ на будь-яке вживання `process.chdir(`.
|
|
14
|
+
|
|
15
|
+
**Кожен виклик `execFile`/`execFileSync`/`spawn`/`spawnSync`** у `*.test.{js,mjs}` приймає або **явний `{ cwd: dir }`** (де `dir` — змінна, не `process.cwd()`), або працює з **абсолютними шляхами** до бінарників/fixture-файлів. Це гарантує, що мутаційний test-flow у `pool: 'forks'` не страждає від implicit-`process.cwd()`-stride між тестами в одному воркері.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
## Заборона відносних шляхів у FS-функціях тестів
|
|
2
|
+
|
|
3
|
+
**`no-relative-fs-path`** (`rules/test/js/no-relative-fs-path.mjs`) — AST-сканер (`oxc-parser`): знаходить виклики FS-функцій із `node:fs`/`node:fs/promises` (`writeFile`, `copyFile`, `mkdir`, `readFile`, `existsSync`, `rename`, `symlink`, `cp`, … включно з `*Sync`-варіантами та `writeJson`/`ensureDir`-хелперами), де path-аргумент — це **string literal** без префікса `/`, `\`, `file:`, `http(s):`, `data:`, чи Windows-disk-letter `C:\`.
|
|
4
|
+
|
|
5
|
+
Виклики `copyFile`/`rename`/`symlink`/`link`/`cp` перевіряють **обидва** path-аргументи.
|
|
6
|
+
|
|
7
|
+
Виклики з обчисленим path (`join(dir, …)`, змінна, template-literal з виразом) пропускаються — припускається, що обчислений шлях абсолютний.
|
|
8
|
+
|
|
9
|
+
**Чому важливо:** відносний path у FS-виклику означає запис/читання відносно `process.cwd()` на момент виклику. У `pool: 'threads'` (дефолт Vitest) паралельні файли ділять процес — cwd може змінитися між тестами. Інцидент `v1.28.0`: `copyFile(src, 'default.conf.template')` у `tests/check-rule-fixtures.test.mjs` записав файл у production tree замість sandbox.
|
|
10
|
+
|
|
11
|
+
**Канон:** замінювати відносні шляхи на `join(dir, 'filename')`, де `dir` — абсолютний tmpdir із `withTmpDir`.
|
|
12
|
+
|
|
13
|
+
**Список FS-функцій, що перевіряються:**
|
|
14
|
+
|
|
15
|
+
| Функція | Перевірювані аргументи |
|
|
16
|
+
|---|---|
|
|
17
|
+
| `writeFile`, `readFile`, `appendFile`, `mkdir`, `rmdir`, `rm`, `unlink` | 1-й |
|
|
18
|
+
| `access`, `stat`, `lstat`, `chmod`, `chown`, `truncate`, `existsSync`, `readdir` | 1-й |
|
|
19
|
+
| `copyFile`, `rename`, `symlink`, `link`, `cp` | 1-й і 2-й |
|
|
20
|
+
| `writeJson`, `ensureDir` (test-helpers) | 1-й |
|
|
21
|
+
|
|
22
|
+
Усі `*Sync`-варіанти охоплені аналогічно.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
## Sandbox-aware тести (Stryker)
|
|
2
|
+
|
|
3
|
+
Stryker за замовчуванням копіює репо у sandbox-каталог (`reports/stryker/.tmp/sandbox-XXX/`), щоб AST-патчити мутантів без зачеплення робочого дерева. У sandbox **немає `.git/`**, і будь-який тест, що звертається до **реального** git-дерева через `import.meta.url + N≥3 рівнів вгору** (типу `const REPO_ROOT = join(import.meta.dirname, '..', '..', '..', '..', '..')`) фактично адресує sandbox-корінь, а не справжній репо. Це ламає `git rev-parse`/`git ls-files`/перевірки `.n-cursor.json`/CHANGELOG-співставлення — Stryker dry-run падає, мутаційний прогон не стартує, `mutation.json` лишається stale.
|
|
4
|
+
|
|
5
|
+
**Канон**: тест не повинен залежати від реального git-дерева через `import.meta.url + N≥3 рівнів вгору`. Якщо тест перевіряє git-логіку — ізолюй **повністю**:
|
|
6
|
+
|
|
7
|
+
```js
|
|
8
|
+
await withTmpDir(async dir => {
|
|
9
|
+
execFileSync('git', ['init', '-q', '--initial-branch=main'], { cwd: dir })
|
|
10
|
+
await writeFile(join(dir, 'a.sh'), '#!/bin/sh\n', 'utf8')
|
|
11
|
+
execFileSync('git', ['add', '-A'], { cwd: dir })
|
|
12
|
+
expect(listShellScriptPaths(dir)).toEqual(['a.sh'])
|
|
13
|
+
})
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Приклад у репо: `rules/text/lint/tests/run-shellcheck.test.mjs` — тест `listShellScriptPaths всередині git-репо`.
|
|
17
|
+
|
|
18
|
+
**Виняток** — top-level smoke-аудит тести, що **за визначенням** перевіряють інваріанти **живого** репо (структура файлів, узгодженість CHANGELOG з `package.json`, кожне правило має fixture). Приклади: `tests/integration-repo-checks.test.mjs`, `tests/check-rule-fixtures.test.mjs`. Такі тести **не дають додаткового coverage у unit-сенсі** — концерни, які вони перевіряють, уже покриті per-rule unit-тестами (`rules/<rule>/js/tests/`). Захищаємо їх `test.skipIf(env.STRYKER_MUTATOR_WORKER)` від запуску всередині Stryker-sandbox:
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { env } from 'node:process'
|
|
22
|
+
|
|
23
|
+
test.skipIf(env.STRYKER_MUTATOR_WORKER)('узгоджені з поточним деревом', async () => {
|
|
24
|
+
// …перевірки на REPO_ROOT
|
|
25
|
+
})
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
**Перевірка** — концерн `sandbox-aware-test` (`rules/test/js/sandbox-aware-test.mjs`): сканер `*.test.{js,mjs}`, який знаходить тести з `import.meta.url`-deep-relative навігацією (4+ `..`-рівнів) і вимагає або `withTmpDir` у їхніх `test`-блоках, або `test.skipIf(env.STRYKER_MUTATOR_WORKER)`.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
## Налаштування mutation-testing: Stryker + Vitest baseline
|
|
2
|
+
|
|
3
|
+
Якщо у `.n-cursor.json#rules` присутнє правило `js` — правило `test` створює canonical baseline `stryker.config.mjs` + `vitest.config.mjs` у **кожному** JS-root проєкту: у кожному workspace з власним `package.json` (або в корені для single-package). У monorepo з `workspaces: ['app', 'scripts']` отримаєте `app/stryker.config.mjs` + `app/vitest.config.mjs` і `scripts/stryker.config.mjs` + `scripts/vitest.config.mjs`.
|
|
4
|
+
|
|
5
|
+
Якщо у JS-root уже лежить legacy `vitest.config.js` — він лишається валідним, новий `.mjs` поряд не створюється, а `vitest.configFile` у скопійованому `stryker.config.mjs` приводиться до фактичного імені.
|
|
6
|
+
|
|
7
|
+
Канон Stryker config (Vitest runner + perTest): [stryker.config.baseline.mjs](./data/stryker_config/stryker.config.baseline.mjs)
|
|
8
|
+
|
|
9
|
+
### Vue SFC (`<script setup>` macros)
|
|
10
|
+
|
|
11
|
+
Якщо у JS-root знайдено бодай один `.vue` під `src/` (skip `node_modules`/`dist`/`reports`) — концерн ставить **vue-варіант** baseline ([`stryker.config.vue.baseline.mjs`](./data/stryker_config/stryker.config.vue.baseline.mjs)) замість звичайного і додатково копіює локальний Stryker `Ignore`-плагін [`stryker-vue-macros-ignorer.mjs`](./data/stryker_config/stryker-vue-macros-ignorer.mjs) поряд із конфігом.
|
|
12
|
+
|
|
13
|
+
Плагін реєструється як `plugins: ['@stryker-mutator/vitest-runner', './stryker-vue-macros-ignorer.mjs']` + `ignorers: ['vue-macros']` і виключає з мутацій виклики `<script setup>`-макросів: **`defineProps`**, **`defineEmits`**, **`defineModel`**, **`defineSlots`**, **`defineExpose`**, **`defineOptions`**. Без плагіна Stryker огортає аргументи макроса у coverage-тернарник (`stryMutAct_9fa48(...) ? {} : (stryCov_9fa48(...), {...})`), а `@vue/compiler-sfc` падає з `defineProps() in <script setup> cannot reference locally declared variables` — макроси мають бути статично-аналізованими на етапі compile-sfc.
|
|
14
|
+
|
|
15
|
+
JS-root без `.vue` отримує дефолтний baseline без `plugins`/`ignorers` (backward-compatible). Обидва файли копіюються idempotent — наявний `stryker.config.mjs` / `stryker-vue-macros-ignorer.mjs` не перетирається.
|
|
16
|
+
|
|
17
|
+
**Augment існуючого config.** Якщо у Vue JS-root `stryker.config.mjs` **уже лежить** (наприклад, після апгрейду з версії без Vue-підтримки), концерн `stryker_config` точково вставляє у наявний файл `plugins: [..., './stryker-vue-macros-ignorer.mjs']` і `ignorers: ['vue-macros']`, зберігши решту полів і коментарів. Редагування — string-splice за AST-аналізом (oxc-parser — лише для пошуку offsets, не для re-serialize), тож форматування й коментарі не переписуються; idempotent — повторний `fix test` не дублює entries. Якщо `export default` — **не** object-literal (factory/функція/змінна) або масиви динамічні (spread/computed), augment пропускається з вимогою додати плагін вручну згідно [`stryker.config.vue.baseline.mjs`](./data/stryker_config/stryker.config.vue.baseline.mjs).
|
|
18
|
+
|
|
19
|
+
### `.gitignore` тест-артефактів
|
|
20
|
+
|
|
21
|
+
Концерн `stryker_config` без дублювання додає у кореневий `.gitignore` тест-патерни:
|
|
22
|
+
|
|
23
|
+
- `**/reports/stryker/` — увесь каталог Stryker-output-у (backup'и `tempDirName`, `mutation.json`, HTML/dashboard-репорти якщо додасте інші reporter-и).
|
|
24
|
+
- `**/coverage/` — весь output vitest v8 coverage (`lcov.info` + HTML `lcov-report/`). Ефемерний: регенерується кожним прогоном, фінальні метрики живуть у `COVERAGE.md`.
|
|
25
|
+
|
|
26
|
+
Це запобігає випадковому коміту build-артефактів.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## Vitest: `pool: 'forks'` як захист від race у `process.cwd()`
|
|
2
|
+
|
|
3
|
+
**`vitest-config-pool-forks`** (`rules/test/js/vitest-config-pool-forks.mjs`) — substring-перевірка `pool: 'forks'` у `vitest.config.mjs` (або legacy `vitest.config.js`; `.mjs` пріоритетніший).
|
|
4
|
+
|
|
5
|
+
**Чому:** Defense-in-depth проти race у `process.cwd()` між паралельними test файлами. Навіть якщо хтось пропустить заборону `process.chdir`, fork-ізоляція не дасть race у production tree — кожен test-файл отримує власний процес зі своїм `cwd`.
|
|
6
|
+
|
|
7
|
+
Якщо `vitest.config.mjs` / `vitest.config.js` відсутній — перевірка пропускається (pass без помилки).
|
|
8
|
+
|
|
9
|
+
**Canonical `vitest.config.mjs`** (для довідки — `pool: 'forks'` + `include` + `coverage`) — у `rules/test/js/data/vitest_config/vitest.config.baseline.js`:
|
|
10
|
+
- `environment: 'node'`
|
|
11
|
+
- `coverage.provider: 'v8'` з lcov+text-summary репортами
|
|
12
|
+
- `include: ['**/*.test.{js,mjs}', 'tests/**/*.test.{js,mjs}']` — підхоплює тести у `tests/`-піддиректоріях і top-level integration suites у `<root>/tests/`
|
|
13
|
+
|
|
14
|
+
У `package.json#scripts` має бути `"test": "vitest run"` (substring `vitest`; допустимо `vitest run` та інші локальні розширення) та опційно `"test:watch": "vitest"`.
|
|
15
|
+
|
|
16
|
+
**Frontend-варіант (Vue/Vite + happy-dom):**
|
|
17
|
+
|
|
18
|
+
Для проєктів зі своїм `vite.config.js` `vitest.config.mjs` має повторно використовувати vite-плагіни та aliases і перемкнути `environment` на `'happy-dom'` (або `'jsdom'`):
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
import { defineConfig, mergeConfig } from 'vitest/config'
|
|
22
|
+
import viteConfig from './vite.config.js'
|
|
23
|
+
|
|
24
|
+
export default mergeConfig(viteConfig, defineConfig({
|
|
25
|
+
test: {
|
|
26
|
+
include: ['**/*.test.{js,mjs}', 'tests/**/*.test.{js,mjs}'],
|
|
27
|
+
environment: 'happy-dom',
|
|
28
|
+
coverage: { provider: 'v8', reporter: ['lcov', 'text-summary'] }
|
|
29
|
+
}
|
|
30
|
+
}))
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Концерн ставить node-варіант baseline; перехід на frontend — ручна модифікація, після якої концерн уже не перетирає (idempotent).
|