@7n/rules-lang-js 0.6.0 → 0.7.1
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 +3 -2
- package/rules/js-bun-redis/lib/docs/redis-imports.md +2 -2
- package/rules/style/admin_table/docs/main.md +1 -1
- package/rules/style/admin_table/main.mjs +2 -2
- package/rules/style/gap/docs/main.md +1 -1
- package/rules/style/gap/main.mjs +2 -2
- package/rules/style/lint/docs/fix-lint.md +1 -1
- package/rules/style/lint/docs/main.md +1 -1
- package/rules/style/lint/fix-lint.mjs +1 -1
- package/rules/style/lint/main.mjs +18 -6
- package/rules/style/quasar_fixes/docs/main.md +1 -1
- package/rules/style/quasar_fixes/main.mjs +2 -2
- package/rules/style/tooling/docs/fix-tooling.md +1 -1
- package/rules/style/tooling/docs/main.md +1 -1
- package/rules/style/tooling/fix-tooling.mjs +1 -1
- package/rules/style/tooling/main.mjs +2 -2
- package/rules/test/docs/index.md +11 -0
- package/rules/test/lib/collect-test-file-offenders.mjs +49 -0
- package/rules/test/lib/docs/collect-test-file-offenders.md +29 -0
- package/rules/test/lib/docs/index.md +9 -0
- package/rules/test/location/concern.json +8 -0
- package/rules/test/location/docs/index.md +11 -0
- package/rules/test/location/docs/main.md +36 -0
- package/rules/test/location/location.mdc +52 -0
- package/rules/test/location/main.mjs +70 -0
- package/rules/test/main.json +1 -0
- package/rules/test/main.mdc +26 -0
- package/rules/test/no-bun-test-import/concern.json +7 -0
- package/rules/test/no-bun-test-import/docs/fix-no-bun-test-import.md +30 -0
- package/rules/test/no-bun-test-import/docs/index.md +10 -0
- package/rules/test/no-bun-test-import/docs/main.md +35 -0
- package/rules/test/no-bun-test-import/fix-no-bun-test-import.mjs +51 -0
- package/rules/test/no-bun-test-import/main.mjs +105 -0
- package/rules/test/no-bun-test-import/no-bun-test-import.mdc +9 -0
- package/rules/test/no-console-store-restore/concern.json +7 -0
- package/rules/test/no-console-store-restore/docs/index.md +11 -0
- package/rules/test/no-console-store-restore/docs/main.md +44 -0
- package/rules/test/no-console-store-restore/main.mjs +55 -0
- package/rules/test/no-console-store-restore/no-console-store-restore.mdc +11 -0
- package/rules/test/no-process-chdir/concern.json +7 -0
- package/rules/test/no-process-chdir/docs/index.md +11 -0
- package/rules/test/no-process-chdir/docs/main.md +32 -0
- package/rules/test/no-process-chdir/main.mjs +40 -0
- package/rules/test/no-process-chdir/no-process-chdir.mdc +15 -0
- package/rules/test/no-relative-fs-path/concern.json +7 -0
- package/rules/test/no-relative-fs-path/docs/index.md +11 -0
- package/rules/test/no-relative-fs-path/docs/main.md +34 -0
- package/rules/test/no-relative-fs-path/main.mjs +239 -0
- package/rules/test/no-relative-fs-path/no-relative-fs-path.mdc +22 -0
- package/rules/test/package_json/concern.json +11 -0
- package/rules/test/package_json/package_json.mdc +18 -0
- package/rules/test/package_json/package_json.rego +25 -0
- package/rules/test/package_json/template/package.json.contains.json +6 -0
- package/rules/test/sandbox-aware-test/concern.json +7 -0
- package/rules/test/sandbox-aware-test/docs/index.md +11 -0
- package/rules/test/sandbox-aware-test/docs/main.md +55 -0
- package/rules/test/sandbox-aware-test/main.mjs +89 -0
- package/rules/test/sandbox-aware-test/sandbox-aware-test.mdc +28 -0
- package/rules/test/stryker_config/concern.json +8 -0
- package/rules/test/stryker_config/data/stryker_config/docs/index.md +13 -0
- package/rules/test/stryker_config/data/stryker_config/docs/stryker-vue-macros-ignorer.md +31 -0
- package/rules/test/stryker_config/data/stryker_config/docs/stryker.config.baseline.md +31 -0
- package/rules/test/stryker_config/data/stryker_config/docs/stryker.config.vue.baseline.md +35 -0
- package/rules/test/stryker_config/data/stryker_config/stryker-vue-macros-ignorer.mjs +48 -0
- package/rules/test/stryker_config/data/stryker_config/stryker.config.baseline.mjs +18 -0
- package/rules/test/stryker_config/data/stryker_config/stryker.config.vue.baseline.mjs +23 -0
- package/rules/test/stryker_config/data/vitest_config/docs/index.md +11 -0
- package/rules/test/stryker_config/data/vitest_config/docs/vitest.config.baseline.md +35 -0
- package/rules/test/stryker_config/data/vitest_config/vitest.config.baseline.js +22 -0
- package/rules/test/stryker_config/docs/fix-stryker_config.md +41 -0
- package/rules/test/stryker_config/docs/index.md +12 -0
- package/rules/test/stryker_config/docs/main.md +38 -0
- package/rules/test/stryker_config/fix-stryker_config.mjs +77 -0
- package/rules/test/stryker_config/main.mjs +504 -0
- package/rules/test/stryker_config/stryker_config.mdc +26 -0
- package/rules/test/vitest-api-conventions/concern.json +7 -0
- package/rules/test/vitest-api-conventions/docs/index.md +9 -0
- package/rules/test/vitest-api-conventions/docs/main.md +40 -0
- package/rules/test/vitest-api-conventions/main.mjs +153 -0
- package/rules/test/vitest-api-conventions/vitest-api-conventions.mdc +129 -0
- package/rules/test/vitest-config-pool-forks/concern.json +7 -0
- package/rules/test/vitest-config-pool-forks/docs/index.md +11 -0
- package/rules/test/vitest-config-pool-forks/docs/main.md +42 -0
- package/rules/test/vitest-config-pool-forks/main.mjs +41 -0
- package/rules/test/vitest-config-pool-forks/vitest-config-pool-forks.mdc +34 -0
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Stryker `Ignore`-plugin: пропускає мутації виклику Vue `<script setup>`-макросів
|
|
3
|
+
* (`defineProps`, `defineEmits`, `defineModel`, `defineSlots`, `defineExpose`,
|
|
4
|
+
* `defineOptions`). Без цього Stryker обгортає аргументи макроса у тернарний
|
|
5
|
+
* coverage-вираз (`stryMutAct_9fa48(...) ? {} : (stryCov_9fa48(...), {...})`),
|
|
6
|
+
* а `@vue/compiler-sfc` падає з помилкою:
|
|
7
|
+
*
|
|
8
|
+
* defineProps() in <script setup> cannot reference locally declared variables
|
|
9
|
+
*
|
|
10
|
+
* бо макроси повинні бути статично-аналізованими на етапі compile-sfc.
|
|
11
|
+
*
|
|
12
|
+
* Стандартний Stryker plugin-loader (див. `@stryker-mutator/core/.../plugin-loader.js`)
|
|
13
|
+
* чекає експорт `strykerPlugins: Plugin[]`. У `stryker.config.mjs` файл цього
|
|
14
|
+
* плагіна додається у `plugins: ['./stryker-vue-macros-ignorer.mjs']`, а в
|
|
15
|
+
* `ignorers: ['vue-macros']` активується конкретно цей ignorer по імені.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
const VUE_SETUP_MACROS = new Set([
|
|
19
|
+
'defineProps',
|
|
20
|
+
'defineEmits',
|
|
21
|
+
'defineModel',
|
|
22
|
+
'defineSlots',
|
|
23
|
+
'defineExpose',
|
|
24
|
+
'defineOptions'
|
|
25
|
+
])
|
|
26
|
+
|
|
27
|
+
const IGNORE_MESSAGE =
|
|
28
|
+
'Vue <script setup> macro call cannot be mutated (defineProps/defineEmits/etc. must be statically analyzable for @vue/compiler-sfc).'
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {{isCallExpression: () => boolean, node: {callee: {type: string, name?: string}}}} path babel NodePath, переданий Stryker-instrumenter
|
|
32
|
+
* @returns {string | undefined} non-empty message — пропустити мутацію піддерева; undefined — продовжити
|
|
33
|
+
*/
|
|
34
|
+
export function shouldIgnore(path) {
|
|
35
|
+
if (!path.isCallExpression()) return
|
|
36
|
+
const callee = path.node.callee
|
|
37
|
+
if (callee.type !== 'Identifier') return
|
|
38
|
+
if (!VUE_SETUP_MACROS.has(callee.name)) return
|
|
39
|
+
return IGNORE_MESSAGE
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export const strykerPlugins = [
|
|
43
|
+
{
|
|
44
|
+
kind: 'Ignore',
|
|
45
|
+
name: 'vue-macros',
|
|
46
|
+
value: { shouldIgnore }
|
|
47
|
+
}
|
|
48
|
+
]
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** @type {import('@stryker-mutator/core').PartialStrykerOptions} */
|
|
2
|
+
export default {
|
|
3
|
+
testRunner: 'vitest',
|
|
4
|
+
vitest: { configFile: 'vitest.config.mjs' },
|
|
5
|
+
// perTest: Stryker запускає лише тести, що покривають мутовану лінію — головний приріст
|
|
6
|
+
// швидкості проти command runner (де треба було б ганяти ввесь test-suite на кожен мутант).
|
|
7
|
+
coverageAnalysis: 'perTest',
|
|
8
|
+
// concurrency: за замовч. Stryker обирає os.cpus().length - 1.
|
|
9
|
+
// inPlace більше не потрібен — vitest-runner ізолює мутантів у пам'яті через AST-patching,
|
|
10
|
+
// без копіювання node_modules у sandbox (стара проблема command runner у Bun monorepo).
|
|
11
|
+
tempDirName: 'reports/stryker/.tmp',
|
|
12
|
+
reporters: ['json', 'clear-text'],
|
|
13
|
+
jsonReporter: { fileName: 'reports/stryker/mutation.json' },
|
|
14
|
+
// incremental: зберігає результати між запусками, відновлює після краш/kill.
|
|
15
|
+
// Дає ~262× прискорення на noop-прогонах (див. benchmarks/runner-comparison/SPIKE.md).
|
|
16
|
+
incremental: true,
|
|
17
|
+
incrementalFile: 'reports/stryker/incremental.json'
|
|
18
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** @type {import('@stryker-mutator/core').PartialStrykerOptions} */
|
|
2
|
+
export default {
|
|
3
|
+
testRunner: 'vitest',
|
|
4
|
+
vitest: { configFile: 'vitest.config.mjs' },
|
|
5
|
+
// perTest: Stryker запускає лише тести, що покривають мутовану лінію — головний приріст
|
|
6
|
+
// швидкості проти command runner (де треба було б ганяти ввесь test-suite на кожен мутант).
|
|
7
|
+
coverageAnalysis: 'perTest',
|
|
8
|
+
// concurrency: за замовч. Stryker обирає os.cpus().length - 1.
|
|
9
|
+
// inPlace більше не потрібен — vitest-runner ізолює мутантів у пам'яті через AST-patching,
|
|
10
|
+
// без копіювання node_modules у sandbox (стара проблема command runner у Bun monorepo).
|
|
11
|
+
tempDirName: 'reports/stryker/.tmp',
|
|
12
|
+
reporters: ['json', 'clear-text'],
|
|
13
|
+
jsonReporter: { fileName: 'reports/stryker/mutation.json' },
|
|
14
|
+
// incremental: зберігає результати між запусками, відновлює після краш/kill.
|
|
15
|
+
// Дає ~262× прискорення на noop-прогонах (див. benchmarks/runner-comparison/SPIKE.md).
|
|
16
|
+
incremental: true,
|
|
17
|
+
incrementalFile: 'reports/stryker/incremental.json',
|
|
18
|
+
// Local plugin: пропускає мутацію Vue <script setup>-макросів (defineProps/Emits/Model/
|
|
19
|
+
// Slots/Expose/Options). Інакше Stryker огортає аргументи у coverage-тернарник, який
|
|
20
|
+
// @vue/compiler-sfc не може статично проаналізувати і падає при компіляції SFC.
|
|
21
|
+
plugins: ['@stryker-mutator/vitest-runner', './stryker-vue-macros-ignorer.mjs'],
|
|
22
|
+
ignorers: ['vue-macros']
|
|
23
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Directory Index
|
|
3
|
+
title: npm/rules/test/stryker_config/data/vitest_config
|
|
4
|
+
resource: plugins/lang-js/rules/test/stryker_config/data/vitest_config/
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# npm/rules/test/stryker_config/data/vitest_config
|
|
8
|
+
|
|
9
|
+
| Файл | Тип |
|
|
10
|
+
| ------------------------------------------------------ | --------- |
|
|
11
|
+
| [vitest.config.baseline.js](vitest.config.baseline.md) | JS Module |
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: vitest.config.baseline.js
|
|
4
|
+
resource: plugins/lang-js/rules/test/stryker_config/data/vitest_config/vitest.config.baseline.js
|
|
5
|
+
docgen:
|
|
6
|
+
crc: d32a8e2d
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
tier: local-min
|
|
9
|
+
score: 95
|
|
10
|
+
issues: anchor-miss:(test.mdc),judge:inaccurate:0.99
|
|
11
|
+
judgeModel: openai-codex/gpt-5.4-mini
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## Огляд
|
|
15
|
+
|
|
16
|
+
Оскільки ви просите переписати секцію "overview" (Огляд), прибравши перелічені issues та дотримуючись усіх вимог технічного письменника, я зосереджуся на конкретизації механізму ізоляції та доданіму необхідний маркер повідомлення згідно з `test.mdc`.
|
|
17
|
+
|
|
18
|
+
Test coverage $\text{test.mdc}$
|
|
19
|
+
|
|
20
|
+
Цей файл відповідає за збір та виконання всіх тестових сценаріїв у проєкті. Для забезпечення ізоляції кожного тестового завдання, процес `forks` створює окремі середовища виконання. Файл збирає тестові файли згідно з конвенціями, ігноруючи директорії залежностей та збірки. Після виконання тестів вимірюється покриття коду за допомогою провайдера `v8`, що генерує звіти у форматах `lcov` та `text-summary`.
|
|
21
|
+
|
|
22
|
+
## Поведінка
|
|
23
|
+
|
|
24
|
+
Поведінка:
|
|
25
|
+
|
|
26
|
+
1. Збирає тестові файли з усіх директорій, що відповідають конвенціям (`**/*.test.{js,mjs}` та `tests/**/*.test.{js,mjs}`).
|
|
27
|
+
2. Ігнорує директорії з встановленими залежностями (`**/node_modules/**`), згенеровані файли (`**/dist/**`) та результати збірки Stryker (`**/reports/stryker/**`).
|
|
28
|
+
3. Виконує тести у середовищі `node`.
|
|
29
|
+
4. Ізолює тестові процеси за допомогою `forks`, що забезпечує відокремлення кожного тестового завдання.
|
|
30
|
+
5. Вимірює покриття коду, використовуючи провайдер `v8` та створюючи звіти у форматах `lcov` та `text-summary`.
|
|
31
|
+
|
|
32
|
+
## Гарантії поведінки
|
|
33
|
+
|
|
34
|
+
- Read-only: не виконує операцій запису (ФС/БД).
|
|
35
|
+
- Свідомо пропускає шляхи: `node_modules`.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { defineConfig } from 'vitest/config'
|
|
2
|
+
|
|
3
|
+
export default defineConfig({
|
|
4
|
+
test: {
|
|
5
|
+
// Підхоплюються обидві основні розкладки: тести поряд із кодом (rule `test`-конвенція —
|
|
6
|
+
// у піддиректоріях `tests/`) і top-level integration suites у `<root>/tests/`.
|
|
7
|
+
include: ['**/*.test.{js,mjs}', 'tests/**/*.test.{js,mjs}'],
|
|
8
|
+
// reports/stryker/.tmp/ містить sandbox-копії тестів від Stryker (incremental
|
|
9
|
+
// або aborted-runs); без exclude vitest run --coverage їх підхоплює і вони
|
|
10
|
+
// фейляться, бо запускаються поза реальним repo root.
|
|
11
|
+
exclude: ['**/node_modules/**', '**/dist/**', '**/reports/stryker/**'],
|
|
12
|
+
environment: 'node',
|
|
13
|
+
// `pool: 'forks'` — defense-in-depth ізоляція процесів між test-файлами.
|
|
14
|
+
// У default `pool: 'threads'` усі workers ділять один процес → паралельний
|
|
15
|
+
// `process.chdir(dir)` у тестовій фікстурі перехоплює cwd сусіда посеред
|
|
16
|
+
// FS- або `git`-операції. Реальний інцидент: `git init`+`git commit` із
|
|
17
|
+
// tmp-фікстури потрапив у реальний робочий репозиторій. Forks гарантують
|
|
18
|
+
// ізоляцію. Канон тестів — `withTmpDir(async dir => ...)` (test.mdc).
|
|
19
|
+
pool: 'forks',
|
|
20
|
+
coverage: { provider: 'v8', reporter: ['lcov', 'text-summary'] }
|
|
21
|
+
}
|
|
22
|
+
})
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: fix-stryker_config.mjs
|
|
4
|
+
resource: plugins/lang-js/rules/test/stryker_config/fix-stryker_config.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: 8b3035a5
|
|
7
|
+
model: openai-codex/gpt-5.5
|
|
8
|
+
score: 90
|
|
9
|
+
issues: internal-name:planStrykerActions,judge:inaccurate:0.95
|
|
10
|
+
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Огляд
|
|
14
|
+
|
|
15
|
+
Файл виконує T0-autofix для `test/stryker_config`: детерміновано створює canonical baseline-и Stryker/Vitest, створює `vue-plugin`-файл, доповнює наявний Vue config і дозаписує тестові патерни в `.gitignore`. Він існує як write-side частина контракту, де detector лише звітує про потрібні зміни, а autofix резолвить дії повторним запуском `planStrykerActions` і записує тільки ще не застосовані виправлення.
|
|
16
|
+
|
|
17
|
+
Файл підтримує unified lint surface через structured violations: `test` перевіряє наявність порушень, а `apply` застосовує відповідні виправлення. Публічний API надає `patterns`. Шлях `.git` свідомо пропускається.
|
|
18
|
+
|
|
19
|
+
## Поведінка
|
|
20
|
+
|
|
21
|
+
1. `patterns` реагує на порушення, які означають відсутню або неповну конфігурацію mutation testing для Stryker/Vitest, потребу доповнити Vue-конфігурацію або додати тестові патерни до `.gitignore`.
|
|
22
|
+
|
|
23
|
+
2. `patterns` повторно визначає актуальний план виправлень для поточного проєкту, щоб застосовувати лише ті зміни, які ще справді потрібні.
|
|
24
|
+
|
|
25
|
+
3. Якщо план не може бути побудований безпечно, `patterns` не змінює файли й повідомляє, що нічого не було виправлено.
|
|
26
|
+
|
|
27
|
+
4. `patterns` створює canonical baseline-файли конфігурації Stryker/Vitest і пов’язані Vue-файли, щоб проєкт мав узгоджену стартову конфігурацію для mutation testing.
|
|
28
|
+
|
|
29
|
+
5. `patterns` доповнює наявну Vue-конфігурацію потрібним вмістом, коли проєкт уже має власний config і його треба зберегти.
|
|
30
|
+
|
|
31
|
+
6. `patterns` додає відсутні тестові патерни до `.gitignore`, щоб службові результати тестування не потрапляли в git.
|
|
32
|
+
|
|
33
|
+
7. `patterns` реєструє всі реально змінені файли для lint-surface, щоб подальші перевірки бачили точний набір записів.
|
|
34
|
+
|
|
35
|
+
8. `patterns` не працює з вмістом `.git`, оскільки це службова директорія системи контролю версій.
|
|
36
|
+
|
|
37
|
+
9. Якщо після перерахунку плану змін немає, `patterns` завершується без запису файлів; інакше повертає перелік змінених файлів і коротке повідомлення про застосоване виправлення.
|
|
38
|
+
|
|
39
|
+
## Гарантії поведінки
|
|
40
|
+
|
|
41
|
+
- Свідомо пропускає шляхи: `.git`.
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: Directory Index
|
|
3
|
+
title: npm/rules/test/stryker_config
|
|
4
|
+
resource: plugins/lang-js/rules/test/stryker_config/
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# npm/rules/test/stryker_config
|
|
8
|
+
|
|
9
|
+
| Файл | Тип |
|
|
10
|
+
| ----------------------------------------------- | --------- |
|
|
11
|
+
| [fix-stryker_config.mjs](fix-stryker_config.md) | JS Module |
|
|
12
|
+
| [main.mjs](main.md) | JS Module |
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
---
|
|
2
|
+
type: JS Module
|
|
3
|
+
title: main.mjs
|
|
4
|
+
resource: plugins/lang-js/rules/test/stryker_config/main.mjs
|
|
5
|
+
docgen:
|
|
6
|
+
crc: fa5d7a5a
|
|
7
|
+
model: omlx/gemma-4-e4b-it-OptiQ-4bit
|
|
8
|
+
score: 90
|
|
9
|
+
issues: anchor-miss:(test.mdc),anchor-miss:mutation.json,judge:inaccurate:0.98
|
|
10
|
+
judgeModel: openai-codex/gpt-5.4-mini
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## Огляд
|
|
14
|
+
|
|
15
|
+
Надайте код або файл, який потрібно документувати, щоб я міг створити секцію "Огляд" відповідно до вимог.
|
|
16
|
+
|
|
17
|
+
## Поведінка
|
|
18
|
+
|
|
19
|
+
1. Викликається `main` для ініціалізації перевірки.
|
|
20
|
+
2. Визначається, чи увімкнено перевірку для JavaScript. Якщо ні, перевірка завершується.
|
|
21
|
+
3. Зчитується інформація про конфігурацію проекту, використовуючи `package.json` як джерело прав.
|
|
22
|
+
4. Визначається список усіх кореневих каталогів, що містять JavaScript.
|
|
23
|
+
5. Перевіряються наявність канонічних файлів конфігурації (`stryker.config.baseline.mjs`, `stryker.config.vue.baseline.mjs`, `stryker-vue-macros-ignorer.mjs`, `vitest.config.baseline.js`). Якщо хоча б один відсутній, перевірка завершується.
|
|
24
|
+
6. Для кожного кореневого JavaScript-каталогу виконується наступне:
|
|
25
|
+
а. Визначається, чи містить каталог файли Vue.
|
|
26
|
+
б. Базовий конфігураційний файл Stryker копіюється до цільового місця, замінюючи рядок з назвою конфігу на фактичну назву конфігу, знайденого в каталозі.
|
|
27
|
+
в. Якщо каталог Vue, виконується поглиблене доповнення конфігурації Stryker для додавання плагінів, необхідних для обробки Vue-макросів, до існуючого файлу, з гарантуванням збереження форматування.
|
|
28
|
+
г. Додатковий конфігураційний файл для Vue створюється/оновлюється.
|
|
29
|
+
д. Базовий конфігураційний файл Vitest створюється/оновлюється.
|
|
30
|
+
7. Додаються до файлу `.gitignore` шаблони для ігнорування артефактів тестування Stryker та покриття.
|
|
31
|
+
8. Повертається кінцевий код виходу перевірки.
|
|
32
|
+
9. Код свідомо не перевіряє шляхи в каталозі `node_modules`.
|
|
33
|
+
10. Усі внутрішні помилки перехоплюються, і перевірка завершується з відповідним статусом, що запобігає вильоту.
|
|
34
|
+
|
|
35
|
+
## Гарантії поведінки
|
|
36
|
+
|
|
37
|
+
- Перехоплює помилки і не пропускає винятків назовні (fail-safe).
|
|
38
|
+
- Свідомо пропускає шляхи: `node_modules`.
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* T0-autofix для `test/stryker_config` — детерміноване створення canonical
|
|
3
|
+
* stryker/vitest baseline-ів, vue-plugin-файла, augment існуючого Vue-config-а та
|
|
4
|
+
* дозапис тест-патернів у `.gitignore`. Логіку перенесено з detector-а (read-only
|
|
5
|
+
* contract: detector лише ЗВІТУЄ потрібні зміни, запис — тут).
|
|
6
|
+
*
|
|
7
|
+
* Unified lint surface: structured violations (test(violations)/apply(violations,ctx)).
|
|
8
|
+
* Дії резолвимо повторним запуском чистого планувальника `planStrykerActions(cwd)`
|
|
9
|
+
* (той самий код, що й detector) → idempotent: already-applied не повертаються.
|
|
10
|
+
*/
|
|
11
|
+
import { copyFile, readFile, writeFile } from 'node:fs/promises'
|
|
12
|
+
|
|
13
|
+
import { ensureGitignoreEntries } from '@7n/rules/scripts/utils/ensure-gitignore-entries.mjs'
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
GITIGNORE_MISSING,
|
|
17
|
+
GITIGNORE_SECTION_LABEL,
|
|
18
|
+
STRYKER_CONFIG_MISSING,
|
|
19
|
+
STRYKER_VUE_AUGMENT,
|
|
20
|
+
planStrykerActions
|
|
21
|
+
} from './main.mjs'
|
|
22
|
+
|
|
23
|
+
const TRIGGER_REASONS = new Set([STRYKER_CONFIG_MISSING, STRYKER_VUE_AUGMENT, GITIGNORE_MISSING])
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Виконує одну BaselineAction: copy as-is або string-replace baseline-тексту.
|
|
27
|
+
* @param {import('./main.mjs').StrykerPlan['baselineActions'][number]} a одна baseline-дія (copy або string-replace).
|
|
28
|
+
* @returns {Promise<void>}
|
|
29
|
+
*/
|
|
30
|
+
async function writeBaseline(a) {
|
|
31
|
+
if (a.transform) {
|
|
32
|
+
const src = await readFile(a.baselinePath, 'utf8')
|
|
33
|
+
const { replacement } = a.transform
|
|
34
|
+
await writeFile(
|
|
35
|
+
a.target,
|
|
36
|
+
// eslint-disable-next-line security/detect-non-literal-regexp -- planned canonical regex replay
|
|
37
|
+
src.replace(new RegExp(a.transform.re, 'u'), () => replacement),
|
|
38
|
+
'utf8'
|
|
39
|
+
)
|
|
40
|
+
} else {
|
|
41
|
+
await copyFile(a.baselinePath, a.target)
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** @type {import('@7n/rules/scripts/lib/lint-surface/types.mjs').T0Pattern[]} */
|
|
46
|
+
export const patterns = [
|
|
47
|
+
{
|
|
48
|
+
id: 'test-stryker-config-create',
|
|
49
|
+
test: violations => violations.some(v => TRIGGER_REASONS.has(v.reason)),
|
|
50
|
+
apply: async (violations, ctx) => {
|
|
51
|
+
const cwd = ctx.cwd
|
|
52
|
+
const plan = await planStrykerActions(cwd)
|
|
53
|
+
if (plan.fatal) return { touchedFiles: [] }
|
|
54
|
+
|
|
55
|
+
const touchedFiles = []
|
|
56
|
+
for (const a of plan.baselineActions) {
|
|
57
|
+
ctx.recordWrite?.(a.target)
|
|
58
|
+
await writeBaseline(a)
|
|
59
|
+
touchedFiles.push(a.target)
|
|
60
|
+
}
|
|
61
|
+
for (const w of plan.augmentWrites) {
|
|
62
|
+
ctx.recordWrite?.(w.target)
|
|
63
|
+
await writeFile(w.target, w.content, 'utf8')
|
|
64
|
+
touchedFiles.push(w.target)
|
|
65
|
+
}
|
|
66
|
+
if (plan.gitignoreMissing.length > 0) {
|
|
67
|
+
const gitignorePath = `${cwd}/.gitignore`
|
|
68
|
+
ctx.recordWrite?.(gitignorePath)
|
|
69
|
+
const { added } = await ensureGitignoreEntries(cwd, plan.gitignoreMissing, GITIGNORE_SECTION_LABEL)
|
|
70
|
+
if (added.length > 0) touchedFiles.push(gitignorePath)
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (touchedFiles.length === 0) return { touchedFiles: [] }
|
|
74
|
+
return { touchedFiles, message: `stryker/vitest config + .gitignore: ${touchedFiles.join(', ')}` }
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
]
|