xtrm-tools 2.3.0 → 2.4.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/README.md +132 -111
- package/cli/dist/index.cjs +142 -53
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/config/pi/extensions/beads.ts +24 -0
- package/hooks/beads-gate-core.mjs +6 -4
- package/hooks/beads-memory-gate.mjs +12 -5
- package/hooks/hooks.json +126 -0
- package/package.json +3 -1
- package/skills/test-planning/SKILL.md +208 -0
- package/skills/test-planning/evals/evals.json +23 -0
- package/skills/using-xtrm/SKILL.md +5 -27
- package/project-skills/tdd-guard/.claude/hooks/tdd-guard-pretool-bridge.cjs +0 -103
- package/project-skills/tdd-guard/.claude/settings.json +0 -38
- package/project-skills/tdd-guard/.claude/skills/using-tdd-guard/SKILL.md +0 -79
- package/project-skills/tdd-guard/CLAUDE.md +0 -98
- package/project-skills/tdd-guard/CONTRIBUTING.md +0 -38
- package/project-skills/tdd-guard/DEVELOPMENT.md +0 -127
- package/project-skills/tdd-guard/LICENSE +0 -21
- package/project-skills/tdd-guard/README.md +0 -398
- package/project-skills/tdd-guard/docs/adr/001-claude-session-subdirectory.md +0 -52
- package/project-skills/tdd-guard/docs/adr/002-secure-claude-binary-path.md +0 -56
- package/project-skills/tdd-guard/docs/adr/003-remove-configurable-data-directory.md +0 -56
- package/project-skills/tdd-guard/docs/adr/004-monorepo-architecture.md +0 -64
- package/project-skills/tdd-guard/docs/adr/005-claude-project-dir-support.md +0 -55
- package/project-skills/tdd-guard/docs/adr/006-phpunit-separate-repository.md +0 -93
- package/project-skills/tdd-guard/docs/adr/007-golangci-lint-path-support.md +0 -83
- package/project-skills/tdd-guard/docs/adr/008-storybook-reporter-design.md +0 -182
- package/project-skills/tdd-guard/docs/assets/tdd-guard-demo-screenshot.gif +0 -0
- package/project-skills/tdd-guard/docs/config-migration.md +0 -143
- package/project-skills/tdd-guard/docs/configuration.md +0 -137
- package/project-skills/tdd-guard/docs/custom-instructions.md +0 -43
- package/project-skills/tdd-guard/docs/enforcement.md +0 -46
- package/project-skills/tdd-guard/docs/ignore-patterns.md +0 -81
- package/project-skills/tdd-guard/docs/linting.md +0 -109
- package/project-skills/tdd-guard/docs/quick-commands.md +0 -52
- package/project-skills/tdd-guard/docs/session-management.md +0 -75
- package/project-skills/tdd-guard/docs/storybook-vitest-addon.md +0 -120
- package/project-skills/tdd-guard/docs/validation-model.md +0 -63
- package/project-skills/tdd-guard/eslint.config.mjs +0 -140
- package/project-skills/tdd-guard/package-lock.json +0 -16937
- package/project-skills/tdd-guard/package.json +0 -102
- package/project-skills/tdd-guard/reporters/go/README.md +0 -67
- package/project-skills/tdd-guard/reporters/go/cmd/tdd-guard-go/main.go +0 -127
- package/project-skills/tdd-guard/reporters/go/cmd/tdd-guard-go/main_test.go +0 -280
- package/project-skills/tdd-guard/reporters/go/go.mod +0 -3
- package/project-skills/tdd-guard/reporters/go/go.sum +0 -0
- package/project-skills/tdd-guard/reporters/go/internal/formatter/formatter.go +0 -126
- package/project-skills/tdd-guard/reporters/go/internal/formatter/formatter_test.go +0 -264
- package/project-skills/tdd-guard/reporters/go/internal/io/tee_reader.go +0 -26
- package/project-skills/tdd-guard/reporters/go/internal/io/tee_reader_test.go +0 -37
- package/project-skills/tdd-guard/reporters/go/internal/parser/mixed_reader.go +0 -94
- package/project-skills/tdd-guard/reporters/go/internal/parser/mixed_reader_test.go +0 -198
- package/project-skills/tdd-guard/reporters/go/internal/parser/parser.go +0 -245
- package/project-skills/tdd-guard/reporters/go/internal/parser/parser_test.go +0 -547
- package/project-skills/tdd-guard/reporters/go/internal/storage/storage.go +0 -35
- package/project-skills/tdd-guard/reporters/go/internal/storage/storage_test.go +0 -113
- package/project-skills/tdd-guard/reporters/go/internal/transformer/transformer.go +0 -103
- package/project-skills/tdd-guard/reporters/go/internal/transformer/transformer_test.go +0 -303
- package/project-skills/tdd-guard/reporters/jest/README.md +0 -102
- package/project-skills/tdd-guard/reporters/jest/package.json +0 -38
- package/project-skills/tdd-guard/reporters/jest/src/JestReporter.test-data.ts +0 -199
- package/project-skills/tdd-guard/reporters/jest/src/JestReporter.test.ts +0 -302
- package/project-skills/tdd-guard/reporters/jest/src/JestReporter.ts +0 -201
- package/project-skills/tdd-guard/reporters/jest/src/index.ts +0 -4
- package/project-skills/tdd-guard/reporters/jest/src/types.ts +0 -42
- package/project-skills/tdd-guard/reporters/jest/tsconfig.json +0 -11
- package/project-skills/tdd-guard/reporters/phpunit/.php-cs-fixer.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/README.md +0 -97
- package/project-skills/tdd-guard/reporters/phpunit/SYNC_README.md +0 -29
- package/project-skills/tdd-guard/reporters/phpunit/composer.json +0 -55
- package/project-skills/tdd-guard/reporters/phpunit/phpunit.xml.dist +0 -19
- package/project-skills/tdd-guard/reporters/phpunit/psalm.xml +0 -44
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/ErroredTestSubscriber.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/FailedTestSubscriber.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/IncompleteTestSubscriber.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/PassedTestSubscriber.php +0 -27
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/SkippedTestSubscriber.php +0 -28
- package/project-skills/tdd-guard/reporters/phpunit/src/Event/TestRunnerFinishedSubscriber.php +0 -24
- package/project-skills/tdd-guard/reporters/phpunit/src/PathValidator.php +0 -88
- package/project-skills/tdd-guard/reporters/phpunit/src/Storage.php +0 -26
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardExtension.php +0 -33
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardListener.php +0 -158
- package/project-skills/tdd-guard/reporters/phpunit/src/TddGuardSubscriber.php +0 -35
- package/project-skills/tdd-guard/reporters/phpunit/src/TestResultCollector.php +0 -105
- package/project-skills/tdd-guard/reporters/phpunit/tests/PathValidatorTest.php +0 -74
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardExtensionFailedTest.php +0 -241
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardExtensionTest.php +0 -84
- package/project-skills/tdd-guard/reporters/phpunit/tests/TddGuardStorageLocationTest.php +0 -71
- package/project-skills/tdd-guard/reporters/pytest/README.md +0 -77
- package/project-skills/tdd-guard/reporters/pytest/pyproject.toml +0 -43
- package/project-skills/tdd-guard/reporters/pytest/pytest.ini.example +0 -7
- package/project-skills/tdd-guard/reporters/pytest/tdd_guard_pytest/__init__.py +0 -1
- package/project-skills/tdd-guard/reporters/pytest/tdd_guard_pytest/pytest_reporter.py +0 -134
- package/project-skills/tdd-guard/reporters/pytest/tests/__init__.py +0 -1
- package/project-skills/tdd-guard/reporters/pytest/tests/conftest.py +0 -3
- package/project-skills/tdd-guard/reporters/pytest/tests/helpers.py +0 -293
- package/project-skills/tdd-guard/reporters/pytest/tests/test_config_option.py +0 -38
- package/project-skills/tdd-guard/reporters/pytest/tests/test_path_validation.py +0 -59
- package/project-skills/tdd-guard/reporters/pytest/tests/test_plugin_config.py +0 -32
- package/project-skills/tdd-guard/reporters/pytest/tests/test_project_root.py +0 -296
- package/project-skills/tdd-guard/reporters/pytest/tests/test_pytest_reporter.py +0 -137
- package/project-skills/tdd-guard/reporters/rspec/Gemfile +0 -3
- package/project-skills/tdd-guard/reporters/rust/Cargo.lock +0 -458
- package/project-skills/tdd-guard/reporters/rust/Cargo.toml +0 -33
- package/project-skills/tdd-guard/reporters/rust/Makefile.example +0 -95
- package/project-skills/tdd-guard/reporters/rust/README.md +0 -88
- package/project-skills/tdd-guard/reporters/rust/src/error_parser.rs +0 -309
- package/project-skills/tdd-guard/reporters/rust/src/main.rs +0 -464
- package/project-skills/tdd-guard/reporters/rust/src/parser.rs +0 -225
- package/project-skills/tdd-guard/reporters/rust/src/transformer.rs +0 -409
- package/project-skills/tdd-guard/reporters/storybook/README.md +0 -108
- package/project-skills/tdd-guard/reporters/storybook/package-lock.json +0 -9482
- package/project-skills/tdd-guard/reporters/storybook/package.json +0 -43
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.test-data.ts +0 -22
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.test.ts +0 -190
- package/project-skills/tdd-guard/reporters/storybook/src/StorybookReporter.ts +0 -88
- package/project-skills/tdd-guard/reporters/storybook/src/index.ts +0 -12
- package/project-skills/tdd-guard/reporters/storybook/src/types.ts +0 -37
- package/project-skills/tdd-guard/reporters/storybook/tsconfig.json +0 -11
- package/project-skills/tdd-guard/reporters/test/artifacts/go/failing/go.mod +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/go/failing/single_failing_test.go +0 -13
- package/project-skills/tdd-guard/reporters/test/artifacts/go/import/go.mod +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/go/import/single_import_error_test.go +0 -17
- package/project-skills/tdd-guard/reporters/test/artifacts/go/passing/go.mod +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/go/passing/single_passing_test.go +0 -13
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-failing.test.js +0 -5
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-import-error.test.js +0 -8
- package/project-skills/tdd-guard/reporters/test/artifacts/jest/single-passing.test.js +0 -5
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SingleFailingTest.php +0 -11
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SingleImportErrorTest.php +0 -14
- package/project-skills/tdd-guard/reporters/test/artifacts/phpunit/SinglePassingTest.php +0 -11
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_failing.py +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_import_error.py +0 -6
- package/project-skills/tdd-guard/reporters/test/artifacts/pytest/test_single_passing.py +0 -3
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/Cargo.lock +0 -7
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/Cargo.toml +0 -4
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/failing/src/lib.rs +0 -14
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/Cargo.lock +0 -7
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/Cargo.toml +0 -4
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/import/src/lib.rs +0 -13
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/Cargo.lock +0 -7
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/Cargo.toml +0 -4
- package/project-skills/tdd-guard/reporters/test/artifacts/rust/passing/src/lib.rs +0 -14
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/Calculator.js +0 -4
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-failing.stories.js +0 -15
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-import-error.stories.js +0 -14
- package/project-skills/tdd-guard/reporters/test/artifacts/storybook/single-passing.stories.js +0 -15
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-failing.test.js +0 -7
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-import-error.test.js +0 -9
- package/project-skills/tdd-guard/reporters/test/artifacts/vitest/single-passing.test.js +0 -7
- package/project-skills/tdd-guard/reporters/test/factories/go.ts +0 -59
- package/project-skills/tdd-guard/reporters/test/factories/helpers.ts +0 -48
- package/project-skills/tdd-guard/reporters/test/factories/index.ts +0 -7
- package/project-skills/tdd-guard/reporters/test/factories/jest.ts +0 -51
- package/project-skills/tdd-guard/reporters/test/factories/phpunit.ts +0 -63
- package/project-skills/tdd-guard/reporters/test/factories/pytest.ts +0 -41
- package/project-skills/tdd-guard/reporters/test/factories/rust.ts +0 -158
- package/project-skills/tdd-guard/reporters/test/factories/storybook.ts +0 -198
- package/project-skills/tdd-guard/reporters/test/factories/vitest.ts +0 -51
- package/project-skills/tdd-guard/reporters/test/reporters.integration.test.ts +0 -735
- package/project-skills/tdd-guard/reporters/test/types.ts +0 -28
- package/project-skills/tdd-guard/reporters/vitest/README.md +0 -64
- package/project-skills/tdd-guard/reporters/vitest/package.json +0 -35
- package/project-skills/tdd-guard/reporters/vitest/src/VitestReporter.test-data.ts +0 -85
- package/project-skills/tdd-guard/reporters/vitest/src/VitestReporter.test.ts +0 -446
- package/project-skills/tdd-guard/reporters/vitest/src/VitestReporter.ts +0 -110
- package/project-skills/tdd-guard/reporters/vitest/src/index.ts +0 -4
- package/project-skills/tdd-guard/reporters/vitest/src/types.ts +0 -39
- package/project-skills/tdd-guard/reporters/vitest/tsconfig.json +0 -11
- package/project-skills/tdd-guard/src/cli/buildContext.test.ts +0 -200
- package/project-skills/tdd-guard/src/cli/buildContext.ts +0 -48
- package/project-skills/tdd-guard/src/cli/tdd-guard.test.ts +0 -159
- package/project-skills/tdd-guard/src/cli/tdd-guard.ts +0 -48
- package/project-skills/tdd-guard/src/config/Config.test.ts +0 -538
- package/project-skills/tdd-guard/src/config/Config.ts +0 -172
- package/project-skills/tdd-guard/src/contracts/schemas/guardSchemas.test.ts +0 -58
- package/project-skills/tdd-guard/src/contracts/schemas/guardSchemas.ts +0 -8
- package/project-skills/tdd-guard/src/contracts/schemas/lintSchemas.test.ts +0 -347
- package/project-skills/tdd-guard/src/contracts/schemas/lintSchemas.ts +0 -61
- package/project-skills/tdd-guard/src/contracts/schemas/pytestSchemas.test.ts +0 -24
- package/project-skills/tdd-guard/src/contracts/schemas/pytestSchemas.ts +0 -7
- package/project-skills/tdd-guard/src/contracts/schemas/reporterSchemas.test.ts +0 -377
- package/project-skills/tdd-guard/src/contracts/schemas/reporterSchemas.ts +0 -75
- package/project-skills/tdd-guard/src/contracts/schemas/toolSchemas.test.ts +0 -563
- package/project-skills/tdd-guard/src/contracts/schemas/toolSchemas.ts +0 -140
- package/project-skills/tdd-guard/src/contracts/types/ClientType.ts +0 -1
- package/project-skills/tdd-guard/src/contracts/types/ConfigOptions.ts +0 -12
- package/project-skills/tdd-guard/src/contracts/types/Context.ts +0 -16
- package/project-skills/tdd-guard/src/contracts/types/ModelClient.ts +0 -3
- package/project-skills/tdd-guard/src/contracts/types/ValidationResult.ts +0 -6
- package/project-skills/tdd-guard/src/guard/GuardManager.test.ts +0 -336
- package/project-skills/tdd-guard/src/guard/GuardManager.ts +0 -83
- package/project-skills/tdd-guard/src/hooks/HookEvents.test.ts +0 -107
- package/project-skills/tdd-guard/src/hooks/HookEvents.ts +0 -39
- package/project-skills/tdd-guard/src/hooks/fileTypeDetection.ts +0 -16
- package/project-skills/tdd-guard/src/hooks/postToolLint.test.ts +0 -327
- package/project-skills/tdd-guard/src/hooks/postToolLint.ts +0 -165
- package/project-skills/tdd-guard/src/hooks/processHookData.test.ts +0 -465
- package/project-skills/tdd-guard/src/hooks/processHookData.ts +0 -203
- package/project-skills/tdd-guard/src/hooks/sessionHandler.test.ts +0 -136
- package/project-skills/tdd-guard/src/hooks/sessionHandler.ts +0 -31
- package/project-skills/tdd-guard/src/hooks/userPromptHandler.test.ts +0 -131
- package/project-skills/tdd-guard/src/hooks/userPromptHandler.ts +0 -55
- package/project-skills/tdd-guard/src/index.ts +0 -19
- package/project-skills/tdd-guard/src/linters/Linter.ts +0 -5
- package/project-skills/tdd-guard/src/linters/eslint/ESLint.test.ts +0 -183
- package/project-skills/tdd-guard/src/linters/eslint/ESLint.ts +0 -82
- package/project-skills/tdd-guard/src/linters/golangci/GolangciLint.test.ts +0 -170
- package/project-skills/tdd-guard/src/linters/golangci/GolangciLint.ts +0 -148
- package/project-skills/tdd-guard/src/processors/index.ts +0 -1
- package/project-skills/tdd-guard/src/processors/lintProcessor.ts +0 -77
- package/project-skills/tdd-guard/src/processors/testResults/TestResultsProcessor.test.ts +0 -303
- package/project-skills/tdd-guard/src/processors/testResults/TestResultsProcessor.ts +0 -255
- package/project-skills/tdd-guard/src/providers/LinterProvider.test.ts +0 -43
- package/project-skills/tdd-guard/src/providers/LinterProvider.ts +0 -20
- package/project-skills/tdd-guard/src/providers/ModelClientProvider.test.ts +0 -68
- package/project-skills/tdd-guard/src/providers/ModelClientProvider.ts +0 -22
- package/project-skills/tdd-guard/src/storage/FileStorage.test.ts +0 -76
- package/project-skills/tdd-guard/src/storage/FileStorage.ts +0 -108
- package/project-skills/tdd-guard/src/storage/MemoryStorage.ts +0 -57
- package/project-skills/tdd-guard/src/storage/Storage.test.ts +0 -227
- package/project-skills/tdd-guard/src/storage/Storage.ts +0 -17
- package/project-skills/tdd-guard/src/validation/context/context.test.ts +0 -364
- package/project-skills/tdd-guard/src/validation/context/context.ts +0 -155
- package/project-skills/tdd-guard/src/validation/models/AnthropicApi.test.ts +0 -171
- package/project-skills/tdd-guard/src/validation/models/AnthropicApi.ts +0 -49
- package/project-skills/tdd-guard/src/validation/models/ClaudeAgentSdk.test.ts +0 -167
- package/project-skills/tdd-guard/src/validation/models/ClaudeAgentSdk.ts +0 -54
- package/project-skills/tdd-guard/src/validation/models/ClaudeCli.test.ts +0 -239
- package/project-skills/tdd-guard/src/validation/models/ClaudeCli.ts +0 -57
- package/project-skills/tdd-guard/src/validation/prompts/file-types.ts +0 -52
- package/project-skills/tdd-guard/src/validation/prompts/operations/edit.ts +0 -58
- package/project-skills/tdd-guard/src/validation/prompts/operations/multi-edit.ts +0 -54
- package/project-skills/tdd-guard/src/validation/prompts/operations/write.ts +0 -54
- package/project-skills/tdd-guard/src/validation/prompts/response.ts +0 -40
- package/project-skills/tdd-guard/src/validation/prompts/rules.ts +0 -51
- package/project-skills/tdd-guard/src/validation/prompts/system-prompt.ts +0 -10
- package/project-skills/tdd-guard/src/validation/prompts/tools/lint-results.ts +0 -15
- package/project-skills/tdd-guard/src/validation/prompts/tools/test-output.ts +0 -14
- package/project-skills/tdd-guard/src/validation/prompts/tools/todos.ts +0 -9
- package/project-skills/tdd-guard/src/validation/validator.test.ts +0 -268
- package/project-skills/tdd-guard/src/validation/validator.ts +0 -159
- package/project-skills/tdd-guard/test/artifacts/go/.golangci.yml +0 -6
- package/project-skills/tdd-guard/test/artifacts/go/with-issues/file-with-issues.go +0 -12
- package/project-skills/tdd-guard/test/artifacts/go/with-issues/go.mod +0 -3
- package/project-skills/tdd-guard/test/artifacts/go/without-issues/file-without-issues.go +0 -7
- package/project-skills/tdd-guard/test/artifacts/go/without-issues/go.mod +0 -3
- package/project-skills/tdd-guard/test/artifacts/javascript/eslint.config.js +0 -20
- package/project-skills/tdd-guard/test/artifacts/javascript/file-with-issues.js +0 -12
- package/project-skills/tdd-guard/test/artifacts/javascript/file-without-issues.js +0 -10
- package/project-skills/tdd-guard/test/hooks/fileTypeDetection.test.ts +0 -26
- package/project-skills/tdd-guard/test/hooks/processHookData.fileType.test.ts +0 -46
- package/project-skills/tdd-guard/test/hooks/processHookData.python.test.ts +0 -68
- package/project-skills/tdd-guard/test/integration/test-context.test.ts +0 -66
- package/project-skills/tdd-guard/test/integration/validator.core.test.ts +0 -96
- package/project-skills/tdd-guard/test/integration/validator.scenarios.test.ts +0 -497
- package/project-skills/tdd-guard/test/utils/assertions.ts +0 -29
- package/project-skills/tdd-guard/test/utils/factories/contextFactory.ts +0 -30
- package/project-skills/tdd-guard/test/utils/factories/editFactory.ts +0 -82
- package/project-skills/tdd-guard/test/utils/factories/helpers.test.ts +0 -46
- package/project-skills/tdd-guard/test/utils/factories/helpers.ts +0 -46
- package/project-skills/tdd-guard/test/utils/factories/lintFactory.ts +0 -352
- package/project-skills/tdd-guard/test/utils/factories/modelClientProviderFactory.ts +0 -21
- package/project-skills/tdd-guard/test/utils/factories/multiEditFactory.ts +0 -79
- package/project-skills/tdd-guard/test/utils/factories/operations.ts +0 -57
- package/project-skills/tdd-guard/test/utils/factories/reporterFactory.ts +0 -55
- package/project-skills/tdd-guard/test/utils/factories/scenarios/index.ts +0 -22
- package/project-skills/tdd-guard/test/utils/factories/scenarios/languages/python.ts +0 -745
- package/project-skills/tdd-guard/test/utils/factories/scenarios/languages/typescript.ts +0 -767
- package/project-skills/tdd-guard/test/utils/factories/scenarios/types.ts +0 -77
- package/project-skills/tdd-guard/test/utils/factories/scenarios/utils.ts +0 -15
- package/project-skills/tdd-guard/test/utils/factories/sessionStartFactory.ts +0 -36
- package/project-skills/tdd-guard/test/utils/factories/testDefaults.ts +0 -90
- package/project-skills/tdd-guard/test/utils/factories/testResultsFactory.ts +0 -234
- package/project-skills/tdd-guard/test/utils/factories/todoFactory.ts +0 -99
- package/project-skills/tdd-guard/test/utils/factories/userPromptSubmitFactory.ts +0 -39
- package/project-skills/tdd-guard/test/utils/factories/writeFactory.ts +0 -70
- package/project-skills/tdd-guard/test/utils/index.ts +0 -131
- package/project-skills/tdd-guard/tsconfig.build.json +0 -16
- package/project-skills/tdd-guard/tsconfig.eslint.json +0 -17
- package/project-skills/tdd-guard/tsconfig.json +0 -32
- package/project-skills/tdd-guard/tsconfig.node.json +0 -10
- package/project-skills/tdd-guard/vitest.config.ts +0 -85
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
import { describe, test, expect, beforeEach } from 'vitest'
|
|
2
|
-
import { VitestReporter } from 'tdd-guard-vitest'
|
|
3
|
-
import { TestResultsProcessor } from '../../src/processors'
|
|
4
|
-
import { MemoryStorage } from '../../src/storage/MemoryStorage'
|
|
5
|
-
import { testData } from '../utils'
|
|
6
|
-
|
|
7
|
-
describe('Test Context', () => {
|
|
8
|
-
describe('reporter and processor handle module import errors correctly', () => {
|
|
9
|
-
let storage: MemoryStorage
|
|
10
|
-
let reporter: VitestReporter
|
|
11
|
-
let processor: TestResultsProcessor
|
|
12
|
-
let result: string
|
|
13
|
-
|
|
14
|
-
beforeEach(async () => {
|
|
15
|
-
// Setup
|
|
16
|
-
storage = new MemoryStorage()
|
|
17
|
-
reporter = new VitestReporter(storage)
|
|
18
|
-
processor = new TestResultsProcessor()
|
|
19
|
-
|
|
20
|
-
// Given a module with import error
|
|
21
|
-
const moduleWithError = testData.testModule({
|
|
22
|
-
moduleId: '/src/utils/helpers.test.ts',
|
|
23
|
-
})
|
|
24
|
-
|
|
25
|
-
// And an import error
|
|
26
|
-
const importError = testData.createUnhandledError()
|
|
27
|
-
|
|
28
|
-
// When the reporter processes the module with error
|
|
29
|
-
reporter.onTestModuleCollected(moduleWithError)
|
|
30
|
-
await reporter.onTestRunEnd([], [importError])
|
|
31
|
-
|
|
32
|
-
// And the processor formats the stored data
|
|
33
|
-
const storedData = await storage.getTest()
|
|
34
|
-
expect(storedData).toBeTruthy()
|
|
35
|
-
result = processor.process(storedData!)
|
|
36
|
-
})
|
|
37
|
-
|
|
38
|
-
test('shows the module as passed with 0 tests', () => {
|
|
39
|
-
expect(result).toContain('✓ /src/utils/helpers.test.ts (0 tests)')
|
|
40
|
-
})
|
|
41
|
-
|
|
42
|
-
test('displays unhandled errors section', () => {
|
|
43
|
-
expect(result).toContain('Unhandled Errors:')
|
|
44
|
-
})
|
|
45
|
-
|
|
46
|
-
test('shows error name and message', () => {
|
|
47
|
-
expect(result).toContain('× Error: Cannot find module "./helpers"')
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
test('includes stack trace header', () => {
|
|
51
|
-
expect(result).toContain('Stack:')
|
|
52
|
-
})
|
|
53
|
-
|
|
54
|
-
test('shows import location in stack trace', () => {
|
|
55
|
-
expect(result).toContain('imported from')
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
test('summary shows 1 passed test file', () => {
|
|
59
|
-
expect(result).toContain('Test Files 1 passed (1)')
|
|
60
|
-
})
|
|
61
|
-
|
|
62
|
-
test('summary shows 0 tests', () => {
|
|
63
|
-
expect(result).toContain('Tests 0 passed (0)')
|
|
64
|
-
})
|
|
65
|
-
})
|
|
66
|
-
})
|
|
@@ -1,96 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'vitest'
|
|
2
|
-
import { validator } from '../../src/validation/validator'
|
|
3
|
-
import { Context } from '../../src/contracts/types/Context'
|
|
4
|
-
import { Config } from '../../src/config/Config'
|
|
5
|
-
import { ModelClientProvider } from '../../src/providers/ModelClientProvider'
|
|
6
|
-
import { testData } from '../utils'
|
|
7
|
-
import { expectDecision } from '../utils/factories/scenarios'
|
|
8
|
-
|
|
9
|
-
const { createEditOperation, languages } = testData
|
|
10
|
-
|
|
11
|
-
describe('Core Validator Scenarios', () => {
|
|
12
|
-
const config = new Config({ mode: 'test' })
|
|
13
|
-
const provider = new ModelClientProvider()
|
|
14
|
-
const model = provider.getModelClient(config)
|
|
15
|
-
|
|
16
|
-
languages.forEach((lang) => {
|
|
17
|
-
const { methodStubReturning0, methodImplementation, empty, completeClass } =
|
|
18
|
-
lang.implementationModifications
|
|
19
|
-
|
|
20
|
-
describe(`${lang.language} scenarios`, () => {
|
|
21
|
-
test('should allow making a failing test pass', async () => {
|
|
22
|
-
const oldContent = methodStubReturning0.content
|
|
23
|
-
const newContent = methodImplementation.content
|
|
24
|
-
const operation = createEditOperation(
|
|
25
|
-
lang.implementationFile,
|
|
26
|
-
oldContent,
|
|
27
|
-
newContent
|
|
28
|
-
)
|
|
29
|
-
const context: Context = {
|
|
30
|
-
modifications: operation,
|
|
31
|
-
todo: JSON.stringify(lang.todos.methodInProgress.content),
|
|
32
|
-
test: lang.testResults.assertionError.content,
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
const result = await validator(context, model)
|
|
36
|
-
expectDecision(result, undefined)
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
test('should block premature implementation', async () => {
|
|
40
|
-
const oldContent = empty.content
|
|
41
|
-
const newContent = completeClass.content
|
|
42
|
-
const operation = createEditOperation(
|
|
43
|
-
lang.implementationFile,
|
|
44
|
-
oldContent,
|
|
45
|
-
newContent
|
|
46
|
-
)
|
|
47
|
-
const context: Context = {
|
|
48
|
-
modifications: operation,
|
|
49
|
-
todo: JSON.stringify(lang.todos.methodInProgress.content),
|
|
50
|
-
test: lang.testResults.notDefined.content,
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const result = await validator(context, model)
|
|
54
|
-
expectDecision(result, 'block')
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
test('should block adding multiple tests at once', async () => {
|
|
58
|
-
const oldContent =
|
|
59
|
-
lang.testModifications.emptyTestContainerWithImports.content
|
|
60
|
-
const newContent =
|
|
61
|
-
lang.testModifications.multipleTestsWithImports.content
|
|
62
|
-
const operation = createEditOperation(
|
|
63
|
-
lang.testFile,
|
|
64
|
-
oldContent,
|
|
65
|
-
newContent
|
|
66
|
-
)
|
|
67
|
-
const context: Context = {
|
|
68
|
-
modifications: operation,
|
|
69
|
-
todo: JSON.stringify(lang.todos.empty.content),
|
|
70
|
-
test: lang.testResults.empty.content,
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
const result = await validator(context, model)
|
|
74
|
-
expectDecision(result, 'block')
|
|
75
|
-
})
|
|
76
|
-
|
|
77
|
-
test('should allow test refactoring when tests are passing', async () => {
|
|
78
|
-
const oldContent = lang.testModifications.multipleTests.content
|
|
79
|
-
const newContent = lang.testModifications.refactoredTests.content
|
|
80
|
-
const operation = createEditOperation(
|
|
81
|
-
lang.testFile,
|
|
82
|
-
oldContent,
|
|
83
|
-
newContent
|
|
84
|
-
)
|
|
85
|
-
const context: Context = {
|
|
86
|
-
modifications: operation,
|
|
87
|
-
todo: JSON.stringify(lang.todos.empty.content),
|
|
88
|
-
test: lang.testResults.passing.content,
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
const result = await validator(context, model)
|
|
92
|
-
expectDecision(result, undefined)
|
|
93
|
-
})
|
|
94
|
-
})
|
|
95
|
-
})
|
|
96
|
-
})
|
|
@@ -1,497 +0,0 @@
|
|
|
1
|
-
import { describe, test } from 'vitest'
|
|
2
|
-
import { validator } from '../../src/validation/validator'
|
|
3
|
-
import { Config } from '../../src/config/Config'
|
|
4
|
-
import { ModelClientProvider } from '../../src/providers/ModelClientProvider'
|
|
5
|
-
import { testData } from '@testUtils'
|
|
6
|
-
import { TestData } from '../utils/factories/scenarios/types'
|
|
7
|
-
import { Context } from '../../src/contracts/types/Context'
|
|
8
|
-
import {
|
|
9
|
-
Todo,
|
|
10
|
-
FileModificationSchema,
|
|
11
|
-
} from '../../src/contracts/schemas/toolSchemas'
|
|
12
|
-
import { expectDecision } from '../utils/factories/scenarios'
|
|
13
|
-
|
|
14
|
-
const {
|
|
15
|
-
createWriteOperation,
|
|
16
|
-
createEditOperation,
|
|
17
|
-
createMultiEditOperation,
|
|
18
|
-
languages,
|
|
19
|
-
} = testData
|
|
20
|
-
|
|
21
|
-
export interface Scenario {
|
|
22
|
-
filePath: string
|
|
23
|
-
oldContent?: TestData
|
|
24
|
-
newContent: TestData
|
|
25
|
-
todos: TestData<Todo[]>
|
|
26
|
-
testResult: TestData
|
|
27
|
-
violation: boolean
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
type OperationType = 'Write' | 'Edit' | 'MultiEdit'
|
|
31
|
-
|
|
32
|
-
describe('Validator', () => {
|
|
33
|
-
const config = new Config({ mode: 'test' })
|
|
34
|
-
const provider = new ModelClientProvider()
|
|
35
|
-
const model = provider.getModelClient(config)
|
|
36
|
-
const defaultOperations: OperationType[] = ['Edit', 'Write']
|
|
37
|
-
|
|
38
|
-
languages.forEach((lang) => {
|
|
39
|
-
describe(`${lang.language} scenarios`, () => {
|
|
40
|
-
const testFile = lang.testFile
|
|
41
|
-
const implementationFile = lang.implementationFile
|
|
42
|
-
const {
|
|
43
|
-
testModifications,
|
|
44
|
-
implementationModifications,
|
|
45
|
-
refactoringImplementation,
|
|
46
|
-
refactoringTestResults,
|
|
47
|
-
refactoringTests,
|
|
48
|
-
todos,
|
|
49
|
-
testResults,
|
|
50
|
-
} = lang
|
|
51
|
-
|
|
52
|
-
describe('Valid operations', () => {
|
|
53
|
-
const violation = false
|
|
54
|
-
|
|
55
|
-
describe('Creating new test', () => {
|
|
56
|
-
const oldContent = testModifications.emptyTestContainerWithImports
|
|
57
|
-
const newContent = testModifications.singleTestComplete
|
|
58
|
-
|
|
59
|
-
// Todo states that should not hinder the writing of a new test
|
|
60
|
-
const todoVariations = [
|
|
61
|
-
todos.empty,
|
|
62
|
-
todos.classInProgress,
|
|
63
|
-
todos.irrelevantInProgress,
|
|
64
|
-
]
|
|
65
|
-
|
|
66
|
-
// Test result outputs that should not hinder the writing of a new test
|
|
67
|
-
const resultVariations = [testResults.empty, testResults.irrelevant]
|
|
68
|
-
|
|
69
|
-
todoVariations.forEach((todoData) => {
|
|
70
|
-
describe(`with ${todoData.description}`, () => {
|
|
71
|
-
resultVariations.forEach((resultData) => {
|
|
72
|
-
describe(`and ${resultData.description}`, () => {
|
|
73
|
-
testOperations({
|
|
74
|
-
filePath: testFile,
|
|
75
|
-
oldContent,
|
|
76
|
-
newContent,
|
|
77
|
-
todos: todoData,
|
|
78
|
-
testResult: resultData,
|
|
79
|
-
violation,
|
|
80
|
-
})
|
|
81
|
-
})
|
|
82
|
-
})
|
|
83
|
-
})
|
|
84
|
-
})
|
|
85
|
-
})
|
|
86
|
-
|
|
87
|
-
describe('Creating implementation to pass failing test', () => {
|
|
88
|
-
const oldContent = implementationModifications.methodStubReturning0
|
|
89
|
-
const newContent = implementationModifications.methodImplementation
|
|
90
|
-
|
|
91
|
-
// Todo states - any todo state is fine as long as test is failing appropriately
|
|
92
|
-
const todoVariations = [
|
|
93
|
-
todos.empty,
|
|
94
|
-
todos.classInProgress,
|
|
95
|
-
todos.irrelevantInProgress,
|
|
96
|
-
]
|
|
97
|
-
|
|
98
|
-
// Test must be failing for the right reason to allow implementation
|
|
99
|
-
const validFailureResults = [testResults.assertionError]
|
|
100
|
-
|
|
101
|
-
todoVariations.forEach((todoData) => {
|
|
102
|
-
describe(`with ${todoData.description}`, () => {
|
|
103
|
-
validFailureResults.forEach((resultData) => {
|
|
104
|
-
describe(`and ${resultData.description}`, () => {
|
|
105
|
-
testOperations(
|
|
106
|
-
{
|
|
107
|
-
filePath: implementationFile,
|
|
108
|
-
oldContent,
|
|
109
|
-
newContent,
|
|
110
|
-
todos: todoData,
|
|
111
|
-
testResult: resultData,
|
|
112
|
-
violation,
|
|
113
|
-
},
|
|
114
|
-
['Edit']
|
|
115
|
-
)
|
|
116
|
-
})
|
|
117
|
-
})
|
|
118
|
-
})
|
|
119
|
-
})
|
|
120
|
-
})
|
|
121
|
-
|
|
122
|
-
describe('Refactoring existing tests regardless of todo as long as relevant tests are passing', () => {
|
|
123
|
-
const oldContent = testModifications.multipleTests
|
|
124
|
-
const newContent = testModifications.refactoredTests
|
|
125
|
-
|
|
126
|
-
// Test refactoring should be allowed with various todo states
|
|
127
|
-
const todoVariations = [
|
|
128
|
-
todos.empty,
|
|
129
|
-
todos.methodInProgress,
|
|
130
|
-
todos.irrelevantInProgress,
|
|
131
|
-
]
|
|
132
|
-
|
|
133
|
-
// Test refactoring should be allowed only when relevant tests are passing
|
|
134
|
-
const resultVariations = [testResults.passing]
|
|
135
|
-
|
|
136
|
-
todoVariations.forEach((todoData) => {
|
|
137
|
-
resultVariations.forEach((resultData) => {
|
|
138
|
-
describe(`with ${todoData.description} and ${resultData.description}`, () => {
|
|
139
|
-
testOperations(
|
|
140
|
-
{
|
|
141
|
-
filePath: testFile,
|
|
142
|
-
oldContent,
|
|
143
|
-
newContent,
|
|
144
|
-
todos: todoData,
|
|
145
|
-
testResult: resultData,
|
|
146
|
-
violation,
|
|
147
|
-
},
|
|
148
|
-
['Edit']
|
|
149
|
-
)
|
|
150
|
-
})
|
|
151
|
-
})
|
|
152
|
-
})
|
|
153
|
-
})
|
|
154
|
-
|
|
155
|
-
describe('Edit operation with one existing test and one new test', () => {
|
|
156
|
-
const oldContent = testModifications.singleTest
|
|
157
|
-
const newContent = testModifications.multipleTests // Contains both the existing test and a new one
|
|
158
|
-
|
|
159
|
-
// Various todo states - should be allowed regardless
|
|
160
|
-
const todoVariations = [todos.empty, todos.methodInProgress]
|
|
161
|
-
|
|
162
|
-
todoVariations.forEach((todoData) => {
|
|
163
|
-
describe(`with ${todoData.description}`, () => {
|
|
164
|
-
testOperations(
|
|
165
|
-
{
|
|
166
|
-
filePath: testFile,
|
|
167
|
-
oldContent,
|
|
168
|
-
newContent,
|
|
169
|
-
todos: todoData,
|
|
170
|
-
testResult: testResults.passing,
|
|
171
|
-
violation,
|
|
172
|
-
},
|
|
173
|
-
['Edit']
|
|
174
|
-
)
|
|
175
|
-
})
|
|
176
|
-
})
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
describe('Refactoring implementation code', () => {
|
|
180
|
-
describe('Allowed when tests have been run and are passing', () => {
|
|
181
|
-
const oldContent = refactoringImplementation.beforeRefactor
|
|
182
|
-
const newContent = refactoringImplementation.afterRefactor
|
|
183
|
-
|
|
184
|
-
const todoVariations = [
|
|
185
|
-
todos.empty,
|
|
186
|
-
todos.irrelevantInProgress,
|
|
187
|
-
todos.refactoring,
|
|
188
|
-
]
|
|
189
|
-
|
|
190
|
-
const resultVariations = [
|
|
191
|
-
refactoringTestResults.passing, // Tests must be passing
|
|
192
|
-
]
|
|
193
|
-
|
|
194
|
-
todoVariations.forEach((todoData) => {
|
|
195
|
-
resultVariations.forEach((resultData) => {
|
|
196
|
-
describe(`with ${todoData.description} and ${resultData.description}`, () => {
|
|
197
|
-
testOperations(
|
|
198
|
-
{
|
|
199
|
-
filePath: implementationFile,
|
|
200
|
-
oldContent,
|
|
201
|
-
newContent,
|
|
202
|
-
todos: todoData,
|
|
203
|
-
testResult: resultData,
|
|
204
|
-
violation: false,
|
|
205
|
-
},
|
|
206
|
-
['Edit']
|
|
207
|
-
)
|
|
208
|
-
})
|
|
209
|
-
})
|
|
210
|
-
})
|
|
211
|
-
})
|
|
212
|
-
|
|
213
|
-
describe('Not allowed when no relevant tests are passing', () => {
|
|
214
|
-
const oldContent = refactoringImplementation.beforeRefactor
|
|
215
|
-
const newContent = refactoringImplementation.afterRefactor
|
|
216
|
-
|
|
217
|
-
const todoVariations = [
|
|
218
|
-
todos.empty,
|
|
219
|
-
todos.methodInProgress,
|
|
220
|
-
todos.irrelevantInProgress,
|
|
221
|
-
todos.refactoring,
|
|
222
|
-
]
|
|
223
|
-
|
|
224
|
-
const resultVariations = [
|
|
225
|
-
testResults.irrelevant,
|
|
226
|
-
refactoringTestResults.failing,
|
|
227
|
-
testResults.empty,
|
|
228
|
-
]
|
|
229
|
-
|
|
230
|
-
todoVariations.forEach((todoData) => {
|
|
231
|
-
resultVariations.forEach((resultData) => {
|
|
232
|
-
describe(`with ${todoData.description} and ${resultData.description}`, () => {
|
|
233
|
-
testOperations(
|
|
234
|
-
{
|
|
235
|
-
filePath: implementationFile,
|
|
236
|
-
oldContent,
|
|
237
|
-
newContent,
|
|
238
|
-
todos: todoData,
|
|
239
|
-
testResult: resultData,
|
|
240
|
-
violation: true,
|
|
241
|
-
},
|
|
242
|
-
['Edit']
|
|
243
|
-
)
|
|
244
|
-
})
|
|
245
|
-
})
|
|
246
|
-
})
|
|
247
|
-
})
|
|
248
|
-
})
|
|
249
|
-
|
|
250
|
-
describe('Refactoring test code', () => {
|
|
251
|
-
describe('Allowed when relevant tests are passing', () => {
|
|
252
|
-
const oldContent = refactoringTests.beforeRefactor
|
|
253
|
-
const newContent = refactoringTests.afterRefactor
|
|
254
|
-
|
|
255
|
-
const todoVariations = [
|
|
256
|
-
todos.empty,
|
|
257
|
-
todos.irrelevantInProgress,
|
|
258
|
-
todos.refactoring,
|
|
259
|
-
]
|
|
260
|
-
|
|
261
|
-
const resultVariations = [refactoringTestResults.passing]
|
|
262
|
-
|
|
263
|
-
todoVariations.forEach((todoData) => {
|
|
264
|
-
resultVariations.forEach((resultData) => {
|
|
265
|
-
describe(`with ${todoData.description} and ${resultData.description}`, () => {
|
|
266
|
-
testOperations(
|
|
267
|
-
{
|
|
268
|
-
filePath: testFile,
|
|
269
|
-
oldContent,
|
|
270
|
-
newContent,
|
|
271
|
-
todos: todoData,
|
|
272
|
-
testResult: resultData,
|
|
273
|
-
violation: false,
|
|
274
|
-
},
|
|
275
|
-
['Edit']
|
|
276
|
-
)
|
|
277
|
-
})
|
|
278
|
-
})
|
|
279
|
-
})
|
|
280
|
-
})
|
|
281
|
-
|
|
282
|
-
describe('Not allowed when no passing tests', () => {
|
|
283
|
-
const oldContent = refactoringTests.beforeRefactor
|
|
284
|
-
const newContent = refactoringTests.afterRefactor
|
|
285
|
-
|
|
286
|
-
const todoVariations = [
|
|
287
|
-
todos.empty,
|
|
288
|
-
todos.methodInProgress,
|
|
289
|
-
todos.irrelevantInProgress,
|
|
290
|
-
]
|
|
291
|
-
|
|
292
|
-
const resultVariations = [
|
|
293
|
-
refactoringTestResults.failing,
|
|
294
|
-
testResults.irrelevant,
|
|
295
|
-
testResults.empty,
|
|
296
|
-
]
|
|
297
|
-
|
|
298
|
-
todoVariations.forEach((todoData) => {
|
|
299
|
-
resultVariations.forEach((resultData) => {
|
|
300
|
-
describe(`with ${todoData.description} and ${resultData.description}`, () => {
|
|
301
|
-
testOperations(
|
|
302
|
-
{
|
|
303
|
-
filePath: testFile,
|
|
304
|
-
oldContent,
|
|
305
|
-
newContent,
|
|
306
|
-
todos: todoData,
|
|
307
|
-
testResult: resultData,
|
|
308
|
-
violation: true,
|
|
309
|
-
},
|
|
310
|
-
['Edit']
|
|
311
|
-
)
|
|
312
|
-
})
|
|
313
|
-
})
|
|
314
|
-
})
|
|
315
|
-
})
|
|
316
|
-
})
|
|
317
|
-
})
|
|
318
|
-
|
|
319
|
-
describe('TDD Violations', () => {
|
|
320
|
-
const violation = true
|
|
321
|
-
|
|
322
|
-
describe('Adding multiple tests at once', () => {
|
|
323
|
-
const oldContent = testModifications.emptyTestContainerWithImports
|
|
324
|
-
const newContent = testModifications.multipleTestsWithImports
|
|
325
|
-
|
|
326
|
-
// Todo states - violation occurs regardless of todo state
|
|
327
|
-
const todoVariations = [
|
|
328
|
-
todos.empty,
|
|
329
|
-
todos.classInProgress,
|
|
330
|
-
todos.refactoring,
|
|
331
|
-
todos.irrelevantInProgress,
|
|
332
|
-
]
|
|
333
|
-
|
|
334
|
-
// Test results - violation occurs regardless of test output
|
|
335
|
-
const resultVariations = [
|
|
336
|
-
testResults.empty,
|
|
337
|
-
testResults.passing,
|
|
338
|
-
testResults.assertionError,
|
|
339
|
-
testResults.irrelevant,
|
|
340
|
-
]
|
|
341
|
-
|
|
342
|
-
todoVariations.forEach((todoData) => {
|
|
343
|
-
describe(`with ${todoData.description}`, () => {
|
|
344
|
-
resultVariations.forEach((resultData) => {
|
|
345
|
-
describe(`and ${resultData.description}`, () => {
|
|
346
|
-
testOperations({
|
|
347
|
-
filePath: testFile,
|
|
348
|
-
oldContent,
|
|
349
|
-
newContent,
|
|
350
|
-
todos: todoData,
|
|
351
|
-
testResult: resultData,
|
|
352
|
-
violation,
|
|
353
|
-
})
|
|
354
|
-
})
|
|
355
|
-
})
|
|
356
|
-
})
|
|
357
|
-
})
|
|
358
|
-
})
|
|
359
|
-
|
|
360
|
-
describe('Implementing without proper test failure', () => {
|
|
361
|
-
const oldContent = implementationModifications.empty
|
|
362
|
-
const newContent = implementationModifications.methodImplementation
|
|
363
|
-
|
|
364
|
-
// Todo states - violation occurs regardless of todo state
|
|
365
|
-
const todoVariations = [
|
|
366
|
-
todos.empty,
|
|
367
|
-
todos.classInProgress,
|
|
368
|
-
todos.irrelevantInProgress,
|
|
369
|
-
]
|
|
370
|
-
|
|
371
|
-
// Invalid test results that should block implementation
|
|
372
|
-
const invalidTestResults = [
|
|
373
|
-
testResults.empty, // No test has been run
|
|
374
|
-
testResults.irrelevant, // Test output is for something else
|
|
375
|
-
testResults.notAConstructor, // Failing for wrong reason
|
|
376
|
-
testResults.notDefined, // Failing for wrong reason
|
|
377
|
-
]
|
|
378
|
-
|
|
379
|
-
todoVariations.forEach((todoData) => {
|
|
380
|
-
describe(`with ${todoData.description}`, () => {
|
|
381
|
-
invalidTestResults.forEach((resultData) => {
|
|
382
|
-
describe(`and ${resultData.description}`, () => {
|
|
383
|
-
testOperations({
|
|
384
|
-
filePath: implementationFile,
|
|
385
|
-
oldContent,
|
|
386
|
-
newContent,
|
|
387
|
-
todos: todoData,
|
|
388
|
-
testResult: resultData,
|
|
389
|
-
violation,
|
|
390
|
-
})
|
|
391
|
-
})
|
|
392
|
-
})
|
|
393
|
-
})
|
|
394
|
-
})
|
|
395
|
-
})
|
|
396
|
-
|
|
397
|
-
describe('Implementing entire class when only one method test is failing', () => {
|
|
398
|
-
const oldContent = implementationModifications.empty
|
|
399
|
-
const newContent = implementationModifications.completeClass // Full class with multiple methods
|
|
400
|
-
|
|
401
|
-
// Test is only for add method, but implementation adds everything
|
|
402
|
-
testOperations({
|
|
403
|
-
filePath: implementationFile,
|
|
404
|
-
oldContent,
|
|
405
|
-
newContent,
|
|
406
|
-
todos: todos.methodInProgress,
|
|
407
|
-
testResult: testResults.notDefined, // Single method test failing
|
|
408
|
-
violation,
|
|
409
|
-
})
|
|
410
|
-
})
|
|
411
|
-
|
|
412
|
-
describe('Excessive implementation beyond test requirements', () => {
|
|
413
|
-
const filePath = implementationFile
|
|
414
|
-
const oldContent = implementationModifications.methodStub
|
|
415
|
-
const newContent = implementationModifications.overEngineered // Complex implementation with validation, etc.
|
|
416
|
-
|
|
417
|
-
// Test only checks basic addition, but implementation adds validation and error handling
|
|
418
|
-
testOperations({
|
|
419
|
-
filePath,
|
|
420
|
-
oldContent,
|
|
421
|
-
newContent,
|
|
422
|
-
todos: todos.methodInProgress,
|
|
423
|
-
testResult: testResults.assertionError, // Simple assertion failure
|
|
424
|
-
violation,
|
|
425
|
-
})
|
|
426
|
-
})
|
|
427
|
-
})
|
|
428
|
-
|
|
429
|
-
function testOperations(
|
|
430
|
-
scenario: Scenario,
|
|
431
|
-
operations: OperationType[] = defaultOperations
|
|
432
|
-
): void {
|
|
433
|
-
operations.forEach((operation) => {
|
|
434
|
-
test(`${operation} should ${scenario.violation ? 'block' : 'allow'}`, async () => {
|
|
435
|
-
const context = createContext(scenario, operation)
|
|
436
|
-
const result = await validator(context, model)
|
|
437
|
-
expectDecision(result, scenario.violation ? 'block' : undefined)
|
|
438
|
-
})
|
|
439
|
-
})
|
|
440
|
-
}
|
|
441
|
-
})
|
|
442
|
-
})
|
|
443
|
-
})
|
|
444
|
-
|
|
445
|
-
// Convert scenario to context for a specific operation type
|
|
446
|
-
function createContext(
|
|
447
|
-
scenario: Scenario,
|
|
448
|
-
operationType: OperationType
|
|
449
|
-
): Context {
|
|
450
|
-
const modificationString = createModificationString(scenario, operationType)
|
|
451
|
-
validateModification(modificationString)
|
|
452
|
-
|
|
453
|
-
return {
|
|
454
|
-
modifications: modificationString,
|
|
455
|
-
todo: formatTodos(scenario.todos.content),
|
|
456
|
-
test: scenario.testResult.content,
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
function createModificationString(
|
|
461
|
-
scenario: Scenario,
|
|
462
|
-
operationType: OperationType
|
|
463
|
-
): string {
|
|
464
|
-
const newString = scenario.newContent.content
|
|
465
|
-
const oldString = scenario.oldContent?.content ?? ''
|
|
466
|
-
|
|
467
|
-
const operationCreators: Record<OperationType, () => string> = {
|
|
468
|
-
Write: () => createWriteOperation(scenario.filePath, newString),
|
|
469
|
-
Edit: () => createEditOperation(scenario.filePath, oldString, newString),
|
|
470
|
-
MultiEdit: () =>
|
|
471
|
-
createMultiEditOperation(scenario.filePath, [
|
|
472
|
-
{
|
|
473
|
-
old_string: oldString,
|
|
474
|
-
new_string: newString,
|
|
475
|
-
replace_all: false,
|
|
476
|
-
},
|
|
477
|
-
]),
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
return operationCreators[operationType]()
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
function validateModification(modificationString: string): void {
|
|
484
|
-
const validationResult = FileModificationSchema.safeParse(
|
|
485
|
-
JSON.parse(modificationString)
|
|
486
|
-
)
|
|
487
|
-
|
|
488
|
-
if (!validationResult.success) {
|
|
489
|
-
throw new Error(
|
|
490
|
-
`Invalid file modification operation: ${validationResult.error.message}`
|
|
491
|
-
)
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
|
|
495
|
-
function formatTodos(todoList: unknown[]): string | undefined {
|
|
496
|
-
return todoList.length > 0 ? JSON.stringify(todoList) : undefined
|
|
497
|
-
}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Test assertion helpers for linter tests
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
import type { LintIssue } from '../../src/contracts/schemas/lintSchemas'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Check if issues contain a specific rule
|
|
9
|
-
*/
|
|
10
|
-
export const hasRule = (issues: LintIssue[], rule: string): boolean => {
|
|
11
|
-
return issues.some((issue) => issue.rule === rule)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* Check if issues contain all specified rules
|
|
16
|
-
*/
|
|
17
|
-
export const hasRules = (issues: LintIssue[], rules: string[]): boolean[] => {
|
|
18
|
-
return rules.map((rule) => hasRule(issues, rule))
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Filter issues from a specific file
|
|
23
|
-
*/
|
|
24
|
-
export const issuesFromFile = (
|
|
25
|
-
issues: LintIssue[],
|
|
26
|
-
filename: string
|
|
27
|
-
): LintIssue[] => {
|
|
28
|
-
return issues.filter((issue) => issue.file.includes(filename))
|
|
29
|
-
}
|