xtrm-tools 2.2.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +127 -104
- package/cli/dist/index.cjs +1078 -970
- package/cli/dist/index.cjs.map +1 -1
- package/cli/package.json +1 -1
- package/config/pi/extensions/beads.ts +33 -5
- package/config/pi/extensions/service-skills.ts +17 -9
- package/config/pi/install-schema.json +2 -1
- 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,199 +0,0 @@
|
|
|
1
|
-
import type { Test, TestResult, AggregatedResult } from '@jest/reporters'
|
|
2
|
-
import type { Config } from '@jest/types'
|
|
3
|
-
|
|
4
|
-
// Create a minimal snapshot object that satisfies the type requirements
|
|
5
|
-
const createSnapshot = (): TestResult['snapshot'] =>
|
|
6
|
-
({
|
|
7
|
-
added: 0,
|
|
8
|
-
didUpdate: false,
|
|
9
|
-
failure: false,
|
|
10
|
-
filesAdded: 0,
|
|
11
|
-
filesRemoved: 0,
|
|
12
|
-
filesRemovedList: [],
|
|
13
|
-
filesUnmatched: 0,
|
|
14
|
-
filesUpdated: 0,
|
|
15
|
-
matched: 0,
|
|
16
|
-
total: 0,
|
|
17
|
-
unchecked: 0,
|
|
18
|
-
uncheckedKeysByFile: [],
|
|
19
|
-
unmatched: 0,
|
|
20
|
-
updated: 0,
|
|
21
|
-
// Additional properties that might be required by different versions
|
|
22
|
-
fileDeleted: false,
|
|
23
|
-
uncheckedKeys: [],
|
|
24
|
-
}) as TestResult['snapshot']
|
|
25
|
-
|
|
26
|
-
// Create a minimal snapshot summary for AggregatedResult
|
|
27
|
-
const createSnapshotSummary = (): AggregatedResult['snapshot'] =>
|
|
28
|
-
({
|
|
29
|
-
added: 0,
|
|
30
|
-
didUpdate: false,
|
|
31
|
-
failure: false,
|
|
32
|
-
filesAdded: 0,
|
|
33
|
-
filesRemoved: 0,
|
|
34
|
-
filesRemovedList: [],
|
|
35
|
-
filesUnmatched: 0,
|
|
36
|
-
filesUpdated: 0,
|
|
37
|
-
matched: 0,
|
|
38
|
-
total: 0,
|
|
39
|
-
unchecked: 0,
|
|
40
|
-
uncheckedKeysByFile: [],
|
|
41
|
-
unmatched: 0,
|
|
42
|
-
updated: 0,
|
|
43
|
-
}) as AggregatedResult['snapshot']
|
|
44
|
-
|
|
45
|
-
// Create a minimal Test object
|
|
46
|
-
export function createTest(overrides?: Partial<Test>): Test {
|
|
47
|
-
// For test purposes, we create minimal mock implementations
|
|
48
|
-
const mockContext = {
|
|
49
|
-
config: {} as Config.ProjectConfig,
|
|
50
|
-
hasteFS: {} as never, // Using never since we don't access these properties
|
|
51
|
-
moduleMap: {} as never, // Using never since we don't access these properties
|
|
52
|
-
resolver: {} as never, // Using never since we don't access these properties
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return {
|
|
56
|
-
context: mockContext,
|
|
57
|
-
duration: 100,
|
|
58
|
-
path: '/test/example.test.ts',
|
|
59
|
-
...overrides,
|
|
60
|
-
} as Test
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
// Create a minimal TestResult object
|
|
64
|
-
export function createTestResult(overrides?: Partial<TestResult>): TestResult {
|
|
65
|
-
const base: TestResult = {
|
|
66
|
-
leaks: false,
|
|
67
|
-
numFailingTests: 0,
|
|
68
|
-
numPassingTests: 1,
|
|
69
|
-
numPendingTests: 0,
|
|
70
|
-
numTodoTests: 0,
|
|
71
|
-
openHandles: [],
|
|
72
|
-
perfStats: {
|
|
73
|
-
end: 1000,
|
|
74
|
-
runtime: 100,
|
|
75
|
-
slow: false,
|
|
76
|
-
start: 900,
|
|
77
|
-
loadTestEnvironmentEnd: 950,
|
|
78
|
-
loadTestEnvironmentStart: 920,
|
|
79
|
-
setupAfterEnvEnd: 980,
|
|
80
|
-
setupAfterEnvStart: 960,
|
|
81
|
-
setupFilesEnd: 940,
|
|
82
|
-
setupFilesStart: 930,
|
|
83
|
-
},
|
|
84
|
-
skipped: false,
|
|
85
|
-
snapshot: createSnapshot(),
|
|
86
|
-
testExecError: undefined,
|
|
87
|
-
testFilePath: '/test/example.test.ts',
|
|
88
|
-
testResults: [
|
|
89
|
-
{
|
|
90
|
-
ancestorTitles: ['Example Suite'],
|
|
91
|
-
duration: 5,
|
|
92
|
-
failureDetails: [],
|
|
93
|
-
failureMessages: [],
|
|
94
|
-
fullName: 'Example Suite should pass',
|
|
95
|
-
invocations: 1,
|
|
96
|
-
location: undefined,
|
|
97
|
-
numPassingAsserts: 0,
|
|
98
|
-
retryReasons: [],
|
|
99
|
-
status: 'passed',
|
|
100
|
-
title: 'should pass',
|
|
101
|
-
},
|
|
102
|
-
],
|
|
103
|
-
...overrides,
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
// If test is failing, update the test results
|
|
107
|
-
if (overrides?.numFailingTests && overrides.numFailingTests > 0) {
|
|
108
|
-
base.testResults = [
|
|
109
|
-
{
|
|
110
|
-
ancestorTitles: ['Example Suite'],
|
|
111
|
-
duration: 5,
|
|
112
|
-
failureDetails: [{}],
|
|
113
|
-
failureMessages: ['expected 2 to be 3'],
|
|
114
|
-
fullName: 'Example Suite should fail',
|
|
115
|
-
invocations: 1,
|
|
116
|
-
location: undefined,
|
|
117
|
-
numPassingAsserts: 0,
|
|
118
|
-
retryReasons: [],
|
|
119
|
-
status: 'failed',
|
|
120
|
-
title: 'should fail',
|
|
121
|
-
},
|
|
122
|
-
]
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return base
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// Create a minimal AggregatedResult object
|
|
129
|
-
export function createAggregatedResult(
|
|
130
|
-
overrides?: Partial<AggregatedResult>
|
|
131
|
-
): AggregatedResult {
|
|
132
|
-
return {
|
|
133
|
-
numFailedTestSuites: 0,
|
|
134
|
-
numFailedTests: 0,
|
|
135
|
-
numPassedTestSuites: 1,
|
|
136
|
-
numPassedTests: 1,
|
|
137
|
-
numPendingTestSuites: 0,
|
|
138
|
-
numPendingTests: 0,
|
|
139
|
-
numRuntimeErrorTestSuites: 0,
|
|
140
|
-
numTodoTests: 0,
|
|
141
|
-
numTotalTestSuites: 1,
|
|
142
|
-
numTotalTests: 1,
|
|
143
|
-
openHandles: [],
|
|
144
|
-
runExecError: undefined,
|
|
145
|
-
snapshot: createSnapshotSummary(),
|
|
146
|
-
startTime: Date.now(),
|
|
147
|
-
success: true,
|
|
148
|
-
testResults: [],
|
|
149
|
-
wasInterrupted: false,
|
|
150
|
-
...overrides,
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export function createUnhandledError(
|
|
155
|
-
overrides: Partial<{ name: string; message: string; stack: string }> = {}
|
|
156
|
-
): AggregatedResult['runExecError'] {
|
|
157
|
-
return {
|
|
158
|
-
message: overrides.message ?? 'Cannot find module "./helpers"',
|
|
159
|
-
stack:
|
|
160
|
-
overrides.stack ??
|
|
161
|
-
"Error: Cannot find module './helpers' imported from '/src/example.test.ts'",
|
|
162
|
-
...(overrides.name && { name: overrides.name }),
|
|
163
|
-
// SerializableError might have additional properties but these are the required ones
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Create a module error (testExecError) for import failures
|
|
168
|
-
export function createModuleError(
|
|
169
|
-
overrides: Partial<{
|
|
170
|
-
name: string
|
|
171
|
-
message: string
|
|
172
|
-
stack: string
|
|
173
|
-
type: string
|
|
174
|
-
code: string
|
|
175
|
-
}> = {}
|
|
176
|
-
): TestResult['testExecError'] {
|
|
177
|
-
return {
|
|
178
|
-
message: overrides.message ?? "Cannot find module './non-existent-module'",
|
|
179
|
-
stack:
|
|
180
|
-
overrides.stack ??
|
|
181
|
-
"Error: Cannot find module './non-existent-module'\n at Resolver.resolveModule",
|
|
182
|
-
...(overrides.name && { name: overrides.name }),
|
|
183
|
-
...(overrides.type && { type: overrides.type }),
|
|
184
|
-
...(overrides.code && { code: overrides.code }),
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
// Create a TestResult with module import error
|
|
189
|
-
export function createTestResultWithModuleError(
|
|
190
|
-
overrides?: Partial<TestResult>
|
|
191
|
-
): TestResult {
|
|
192
|
-
return createTestResult({
|
|
193
|
-
testExecError: createModuleError(),
|
|
194
|
-
testResults: [], // No test results when module fails to load
|
|
195
|
-
numFailingTests: 0,
|
|
196
|
-
numPassingTests: 0,
|
|
197
|
-
...overrides,
|
|
198
|
-
})
|
|
199
|
-
}
|
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from 'vitest'
|
|
2
|
-
import { JestReporter } from './JestReporter'
|
|
3
|
-
import {
|
|
4
|
-
FileStorage,
|
|
5
|
-
MemoryStorage,
|
|
6
|
-
Config as TDDConfig,
|
|
7
|
-
DEFAULT_DATA_DIR,
|
|
8
|
-
} from 'tdd-guard'
|
|
9
|
-
import path from 'node:path'
|
|
10
|
-
import {
|
|
11
|
-
createTest,
|
|
12
|
-
createTestResult,
|
|
13
|
-
createAggregatedResult,
|
|
14
|
-
createUnhandledError,
|
|
15
|
-
createModuleError,
|
|
16
|
-
createTestResultWithModuleError,
|
|
17
|
-
} from './JestReporter.test-data'
|
|
18
|
-
|
|
19
|
-
describe('JestReporter', () => {
|
|
20
|
-
let sut: ReturnType<typeof setupJestReporter>
|
|
21
|
-
|
|
22
|
-
beforeEach(() => {
|
|
23
|
-
sut = setupJestReporter()
|
|
24
|
-
})
|
|
25
|
-
|
|
26
|
-
describe('constructor', () => {
|
|
27
|
-
it('uses FileStorage by default', () => {
|
|
28
|
-
const reporter = new JestReporter()
|
|
29
|
-
expect(reporter['storage']).toBeInstanceOf(FileStorage)
|
|
30
|
-
})
|
|
31
|
-
|
|
32
|
-
it('accepts Storage instance in reporterOptions', () => {
|
|
33
|
-
const storage = new MemoryStorage()
|
|
34
|
-
const globalConfig = undefined
|
|
35
|
-
const reporterOptions = { storage }
|
|
36
|
-
const reporter = new JestReporter(globalConfig, reporterOptions)
|
|
37
|
-
expect(reporter['storage']).toBe(storage)
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
it('accepts projectRoot string in reporterOptions', () => {
|
|
41
|
-
const rootPath = '/some/project/root'
|
|
42
|
-
const globalConfig = undefined
|
|
43
|
-
const reporterOptions = { projectRoot: rootPath }
|
|
44
|
-
const reporter = new JestReporter(globalConfig, reporterOptions)
|
|
45
|
-
|
|
46
|
-
// Verify the storage is configured with the correct path
|
|
47
|
-
const fileStorage = reporter['storage'] as FileStorage
|
|
48
|
-
const config = fileStorage['config'] as TDDConfig
|
|
49
|
-
const expectedDataDir = path.join(
|
|
50
|
-
rootPath,
|
|
51
|
-
...DEFAULT_DATA_DIR.split('/')
|
|
52
|
-
)
|
|
53
|
-
expect(config.dataDir).toBe(expectedDataDir)
|
|
54
|
-
})
|
|
55
|
-
})
|
|
56
|
-
|
|
57
|
-
describe('onTestResult', () => {
|
|
58
|
-
it('collects test results', () => {
|
|
59
|
-
const test = createTest()
|
|
60
|
-
const testResult = createTestResult()
|
|
61
|
-
|
|
62
|
-
sut.reporter.onTestResult(test, testResult)
|
|
63
|
-
|
|
64
|
-
expect(sut.reporter['testModules'].size).toBe(1)
|
|
65
|
-
})
|
|
66
|
-
})
|
|
67
|
-
|
|
68
|
-
describe('onRunComplete', () => {
|
|
69
|
-
it('saves test results to storage', async () => {
|
|
70
|
-
const test = createTest()
|
|
71
|
-
const testResult = createTestResult()
|
|
72
|
-
const aggregatedResult = createAggregatedResult()
|
|
73
|
-
|
|
74
|
-
// Collect test results first
|
|
75
|
-
sut.reporter.onTestResult(test, testResult)
|
|
76
|
-
|
|
77
|
-
// Run complete
|
|
78
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
79
|
-
|
|
80
|
-
// Verify results were saved
|
|
81
|
-
const parsed = await sut.getParsedData()
|
|
82
|
-
expect(parsed).toBeTruthy()
|
|
83
|
-
expect(parsed.testModules).toHaveLength(1)
|
|
84
|
-
})
|
|
85
|
-
|
|
86
|
-
it('includes test case details in output', async () => {
|
|
87
|
-
const test = createTest()
|
|
88
|
-
const testResult = createTestResult()
|
|
89
|
-
const aggregatedResult = createAggregatedResult()
|
|
90
|
-
|
|
91
|
-
// Collect test results
|
|
92
|
-
sut.reporter.onTestResult(test, testResult)
|
|
93
|
-
|
|
94
|
-
// Run complete
|
|
95
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
96
|
-
|
|
97
|
-
// Verify test details are included
|
|
98
|
-
const parsed = await sut.getParsedData()
|
|
99
|
-
const module = parsed.testModules[0]
|
|
100
|
-
expect(module.tests).toHaveLength(1)
|
|
101
|
-
expect(module.tests[0].name).toBe('should pass')
|
|
102
|
-
expect(module.tests[0].fullName).toBe('Example Suite should pass')
|
|
103
|
-
expect(module.tests[0].state).toBe('passed')
|
|
104
|
-
})
|
|
105
|
-
|
|
106
|
-
it('includes error details for failed tests', async () => {
|
|
107
|
-
const test = createTest()
|
|
108
|
-
const failedTestResult = createTestResult({ numFailingTests: 1 })
|
|
109
|
-
const aggregatedResult = createAggregatedResult()
|
|
110
|
-
|
|
111
|
-
// Collect test results
|
|
112
|
-
sut.reporter.onTestResult(test, failedTestResult)
|
|
113
|
-
|
|
114
|
-
// Run complete
|
|
115
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
116
|
-
|
|
117
|
-
// Verify error details are included
|
|
118
|
-
const parsed = await sut.getParsedData()
|
|
119
|
-
const module = parsed.testModules[0]
|
|
120
|
-
const failedTest = module.tests[0]
|
|
121
|
-
expect(failedTest.state).toBe('failed')
|
|
122
|
-
expect(failedTest.errors).toBeDefined()
|
|
123
|
-
expect(failedTest.errors).toHaveLength(1)
|
|
124
|
-
expect(failedTest.errors[0].message).toBe('expected 2 to be 3')
|
|
125
|
-
})
|
|
126
|
-
|
|
127
|
-
it('handles empty test runs', async () => {
|
|
128
|
-
// Run complete without any tests
|
|
129
|
-
await sut.reporter.onRunComplete(new Set(), createAggregatedResult())
|
|
130
|
-
|
|
131
|
-
// Verify empty output
|
|
132
|
-
const parsed = await sut.getParsedData()
|
|
133
|
-
expect(parsed.testModules).toEqual([])
|
|
134
|
-
})
|
|
135
|
-
|
|
136
|
-
it('includes unhandled errors in output', async () => {
|
|
137
|
-
const error = createUnhandledError()
|
|
138
|
-
const aggregatedResult = createAggregatedResult({
|
|
139
|
-
runExecError: error,
|
|
140
|
-
})
|
|
141
|
-
|
|
142
|
-
// Run complete with unhandled error
|
|
143
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
144
|
-
|
|
145
|
-
// Verify unhandled errors are included
|
|
146
|
-
const parsed = await sut.getParsedData()
|
|
147
|
-
expect(parsed.unhandledErrors).toBeDefined()
|
|
148
|
-
expect(parsed.unhandledErrors).toHaveLength(1)
|
|
149
|
-
expect(parsed.unhandledErrors[0].message).toBe(
|
|
150
|
-
'Cannot find module "./helpers"'
|
|
151
|
-
)
|
|
152
|
-
expect(parsed.unhandledErrors[0].name).toBe('Error')
|
|
153
|
-
expect(parsed.unhandledErrors[0].stack).toContain('imported from')
|
|
154
|
-
})
|
|
155
|
-
|
|
156
|
-
it('includes test run reason when tests pass', async () => {
|
|
157
|
-
const test = createTest()
|
|
158
|
-
const testResult = createTestResult()
|
|
159
|
-
const aggregatedResult = createAggregatedResult({
|
|
160
|
-
success: true,
|
|
161
|
-
numFailedTests: 0,
|
|
162
|
-
})
|
|
163
|
-
|
|
164
|
-
sut.reporter.onTestResult(test, testResult)
|
|
165
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
166
|
-
|
|
167
|
-
const parsed = await sut.getParsedData()
|
|
168
|
-
expect(parsed.reason).toBe('passed')
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
it('handles SerializableError without name property', async () => {
|
|
172
|
-
const aggregatedResult = createAggregatedResult({
|
|
173
|
-
runExecError: {
|
|
174
|
-
message: 'Module not found',
|
|
175
|
-
stack: 'at test.js:1:1',
|
|
176
|
-
},
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
180
|
-
|
|
181
|
-
const parsed = await sut.getParsedData()
|
|
182
|
-
expect(parsed.unhandledErrors[0].message).toBe('Module not found')
|
|
183
|
-
expect(parsed.unhandledErrors[0].name).toBe('Error')
|
|
184
|
-
expect(parsed.unhandledErrors[0].stack).toBe('at test.js:1:1')
|
|
185
|
-
})
|
|
186
|
-
|
|
187
|
-
it('includes module import errors as failed tests', async () => {
|
|
188
|
-
const test = createTest()
|
|
189
|
-
const testResult = createTestResultWithModuleError()
|
|
190
|
-
const aggregatedResult = createAggregatedResult()
|
|
191
|
-
|
|
192
|
-
sut.reporter.onTestResult(test, testResult)
|
|
193
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
194
|
-
|
|
195
|
-
const parsed = await sut.getParsedData()
|
|
196
|
-
const module = parsed.testModules[0]
|
|
197
|
-
expect(module.tests).toHaveLength(1)
|
|
198
|
-
|
|
199
|
-
const importErrorTest = module.tests[0]
|
|
200
|
-
expect(importErrorTest.name).toBe('Module failed to load (Error)')
|
|
201
|
-
expect(importErrorTest.fullName).toBe('Module failed to load (Error)')
|
|
202
|
-
expect(importErrorTest.state).toBe('failed')
|
|
203
|
-
expect(importErrorTest.errors).toHaveLength(1)
|
|
204
|
-
expect(importErrorTest.errors[0].message).toBe(
|
|
205
|
-
"Cannot find module './non-existent-module'"
|
|
206
|
-
)
|
|
207
|
-
})
|
|
208
|
-
|
|
209
|
-
it('preserves error stack trace from module import errors', async () => {
|
|
210
|
-
const test = createTest()
|
|
211
|
-
const moduleError = createModuleError({
|
|
212
|
-
message: "Cannot find module './helpers'",
|
|
213
|
-
stack:
|
|
214
|
-
"Error: Cannot find module './helpers'\n at Function.Module._resolveFilename",
|
|
215
|
-
name: 'Error',
|
|
216
|
-
})
|
|
217
|
-
const testResult = createTestResultWithModuleError({
|
|
218
|
-
testExecError: moduleError,
|
|
219
|
-
})
|
|
220
|
-
const aggregatedResult = createAggregatedResult()
|
|
221
|
-
|
|
222
|
-
sut.reporter.onTestResult(test, testResult)
|
|
223
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
224
|
-
|
|
225
|
-
const parsed = await sut.getParsedData()
|
|
226
|
-
const importErrorTest = parsed.testModules[0].tests[0]
|
|
227
|
-
|
|
228
|
-
expect(importErrorTest.errors[0].stack).toBe(
|
|
229
|
-
"Error: Cannot find module './helpers'\n at Function.Module._resolveFilename"
|
|
230
|
-
)
|
|
231
|
-
expect(importErrorTest.errors[0].name).toBe('Error')
|
|
232
|
-
})
|
|
233
|
-
|
|
234
|
-
it('uses error type in test name for module import errors', async () => {
|
|
235
|
-
const test = createTest()
|
|
236
|
-
const testResult = createTestResultWithModuleError({
|
|
237
|
-
testExecError: createModuleError({
|
|
238
|
-
message: 'Module parse failed',
|
|
239
|
-
stack: 'SyntaxError: Unexpected token',
|
|
240
|
-
name: 'SyntaxError',
|
|
241
|
-
}),
|
|
242
|
-
})
|
|
243
|
-
const aggregatedResult = createAggregatedResult()
|
|
244
|
-
|
|
245
|
-
sut.reporter.onTestResult(test, testResult)
|
|
246
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
247
|
-
|
|
248
|
-
const parsed = await sut.getParsedData()
|
|
249
|
-
const importErrorTest = parsed.testModules[0].tests[0]
|
|
250
|
-
|
|
251
|
-
expect(importErrorTest.name).toBe('Module failed to load (SyntaxError)')
|
|
252
|
-
expect(importErrorTest.fullName).toBe(
|
|
253
|
-
'Module failed to load (SyntaxError)'
|
|
254
|
-
)
|
|
255
|
-
})
|
|
256
|
-
|
|
257
|
-
it('handles SerializableError with type field for module import errors', async () => {
|
|
258
|
-
const test = createTest()
|
|
259
|
-
const testResult = createTestResultWithModuleError({
|
|
260
|
-
testExecError: createModuleError({
|
|
261
|
-
message: 'Module error',
|
|
262
|
-
stack: 'at test.js:1',
|
|
263
|
-
type: 'ReferenceError',
|
|
264
|
-
code: 'ERR_MODULE_NOT_FOUND',
|
|
265
|
-
}),
|
|
266
|
-
})
|
|
267
|
-
const aggregatedResult = createAggregatedResult()
|
|
268
|
-
|
|
269
|
-
sut.reporter.onTestResult(test, testResult)
|
|
270
|
-
await sut.reporter.onRunComplete(new Set(), aggregatedResult)
|
|
271
|
-
|
|
272
|
-
const parsed = await sut.getParsedData()
|
|
273
|
-
const importErrorTest = parsed.testModules[0].tests[0]
|
|
274
|
-
|
|
275
|
-
expect(importErrorTest.name).toBe(
|
|
276
|
-
'Module failed to load (ReferenceError)'
|
|
277
|
-
)
|
|
278
|
-
expect(importErrorTest.errors[0].name).toBe('ReferenceError')
|
|
279
|
-
expect(importErrorTest.errors[0].operator).toBe('ERR_MODULE_NOT_FOUND')
|
|
280
|
-
})
|
|
281
|
-
})
|
|
282
|
-
})
|
|
283
|
-
|
|
284
|
-
// Test setup helper function
|
|
285
|
-
function setupJestReporter() {
|
|
286
|
-
const storage = new MemoryStorage()
|
|
287
|
-
const globalConfig = undefined
|
|
288
|
-
const reporterOptions = { storage }
|
|
289
|
-
const reporter = new JestReporter(globalConfig, reporterOptions)
|
|
290
|
-
|
|
291
|
-
// Helper to get parsed test data
|
|
292
|
-
const getParsedData = async () => {
|
|
293
|
-
const savedData = await storage.getTest()
|
|
294
|
-
return savedData ? JSON.parse(savedData) : null
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
return {
|
|
298
|
-
reporter,
|
|
299
|
-
storage,
|
|
300
|
-
getParsedData,
|
|
301
|
-
}
|
|
302
|
-
}
|
|
@@ -1,201 +0,0 @@
|
|
|
1
|
-
import { BaseReporter, Config } from '@jest/reporters'
|
|
2
|
-
import type { Test, TestResult, AggregatedResult } from '@jest/reporters'
|
|
3
|
-
import type { AssertionResult } from '@jest/test-result'
|
|
4
|
-
import type { TestContext } from '@jest/test-result'
|
|
5
|
-
import { Storage, FileStorage, Config as TDDConfig } from 'tdd-guard'
|
|
6
|
-
import type {
|
|
7
|
-
TDDGuardReporterOptions,
|
|
8
|
-
CapturedError,
|
|
9
|
-
CapturedTest,
|
|
10
|
-
CapturedTestRun,
|
|
11
|
-
CapturedUnhandledError,
|
|
12
|
-
CapturedModule,
|
|
13
|
-
} from './types'
|
|
14
|
-
|
|
15
|
-
export class JestReporter extends BaseReporter {
|
|
16
|
-
private readonly storage: Storage
|
|
17
|
-
private readonly testModules: Map<
|
|
18
|
-
string,
|
|
19
|
-
{ test: Test; testResult: TestResult }
|
|
20
|
-
> = new Map()
|
|
21
|
-
|
|
22
|
-
constructor(
|
|
23
|
-
_globalConfig?: Config.GlobalConfig,
|
|
24
|
-
reporterOptions?: TDDGuardReporterOptions
|
|
25
|
-
) {
|
|
26
|
-
super()
|
|
27
|
-
this.storage = this.initializeStorage(reporterOptions)
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
private initializeStorage(options?: TDDGuardReporterOptions): Storage {
|
|
31
|
-
if (options?.storage) {
|
|
32
|
-
return options.storage
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
if (options?.projectRoot) {
|
|
36
|
-
const config = new TDDConfig({ projectRoot: options.projectRoot })
|
|
37
|
-
return new FileStorage(config)
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
return new FileStorage()
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
override onTestResult(test: Test, testResult: TestResult): void {
|
|
44
|
-
this.testModules.set(test.path, { test, testResult })
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
override async onRunComplete(
|
|
48
|
-
_contexts: Set<TestContext>,
|
|
49
|
-
results: AggregatedResult
|
|
50
|
-
): Promise<void> {
|
|
51
|
-
const output: CapturedTestRun = {
|
|
52
|
-
testModules: this.buildTestModules(),
|
|
53
|
-
unhandledErrors: this.buildUnhandledErrors(results),
|
|
54
|
-
reason: this.determineTestRunReason(results),
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
await this.storage.saveTest(JSON.stringify(output, null, 2))
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
private determineTestRunReason(
|
|
61
|
-
results: AggregatedResult
|
|
62
|
-
): 'passed' | 'failed' | 'interrupted' {
|
|
63
|
-
if (results.wasInterrupted) {
|
|
64
|
-
return 'interrupted'
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
if (results.numFailedTestSuites === 0 && results.numTotalTestSuites > 0) {
|
|
68
|
-
return 'passed'
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
return 'failed'
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
private mapTestResult(test: AssertionResult): CapturedTest {
|
|
75
|
-
const result: CapturedTest = {
|
|
76
|
-
name: test.title,
|
|
77
|
-
fullName: test.fullName,
|
|
78
|
-
state: test.status,
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Process failure details if present
|
|
82
|
-
if (test.failureMessages.length > 0) {
|
|
83
|
-
result.errors = this.processTestErrors(test)
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return result
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
private processTestErrors(test: AssertionResult): CapturedError[] {
|
|
90
|
-
if (test.failureDetails.length === 0) {
|
|
91
|
-
return test.failureMessages.map((message) => ({ message }))
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
return test.failureDetails.map((detail: unknown, index: number) => {
|
|
95
|
-
const message = test.failureMessages[index] || ''
|
|
96
|
-
const error: CapturedError = { message }
|
|
97
|
-
|
|
98
|
-
if (detail && typeof detail === 'object') {
|
|
99
|
-
this.extractErrorDetails(error, detail as Record<string, unknown>)
|
|
100
|
-
this.parseExpectedActualFromMessage(error, message)
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
return error
|
|
104
|
-
})
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private extractErrorDetails(
|
|
108
|
-
error: CapturedError,
|
|
109
|
-
obj: Record<string, unknown>
|
|
110
|
-
): void {
|
|
111
|
-
if ('actual' in obj) error.actual = String(obj.actual)
|
|
112
|
-
if ('expected' in obj) error.expected = String(obj.expected)
|
|
113
|
-
if ('showDiff' in obj) error.showDiff = Boolean(obj.showDiff)
|
|
114
|
-
if ('operator' in obj) error.operator = String(obj.operator)
|
|
115
|
-
if ('diff' in obj) error.diff = String(obj.diff)
|
|
116
|
-
if ('name' in obj) error.name = String(obj.name)
|
|
117
|
-
if ('ok' in obj) error.ok = Boolean(obj.ok)
|
|
118
|
-
if ('stack' in obj) error.stack = String(obj.stack)
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
private parseExpectedActualFromMessage(
|
|
122
|
-
error: CapturedError,
|
|
123
|
-
message: string
|
|
124
|
-
): void {
|
|
125
|
-
if (!error.expected || !error.actual) {
|
|
126
|
-
const expectedMatch = /Expected:\s*(\d+)/.exec(message)
|
|
127
|
-
const receivedMatch = /Received:\s*(\d+)/.exec(message)
|
|
128
|
-
if (expectedMatch && !error.expected) error.expected = expectedMatch[1]
|
|
129
|
-
if (receivedMatch && !error.actual) error.actual = receivedMatch[1]
|
|
130
|
-
}
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
private createTestFromExecError(execError: unknown): CapturedTest {
|
|
134
|
-
const errorObj = execError as Record<string, unknown>
|
|
135
|
-
const message = String(errorObj.message ?? 'Unknown error')
|
|
136
|
-
|
|
137
|
-
const error: CapturedError = {
|
|
138
|
-
message,
|
|
139
|
-
name: typeof errorObj.name === 'string' ? errorObj.name : 'Error',
|
|
140
|
-
stack: typeof errorObj.stack === 'string' ? errorObj.stack : undefined,
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Extract additional fields from Jest's SerializableError
|
|
144
|
-
if ('code' in errorObj && errorObj.code !== undefined) {
|
|
145
|
-
error.operator = String(errorObj.code)
|
|
146
|
-
}
|
|
147
|
-
if ('type' in errorObj && typeof errorObj.type === 'string') {
|
|
148
|
-
error.name = errorObj.type
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
const errorType = error.name ?? 'Error'
|
|
152
|
-
const testName = `Module failed to load (${errorType})`
|
|
153
|
-
|
|
154
|
-
return {
|
|
155
|
-
name: testName,
|
|
156
|
-
fullName: testName,
|
|
157
|
-
state: 'failed',
|
|
158
|
-
errors: [error],
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
private buildTestModules(): CapturedModule[] {
|
|
163
|
-
return Array.from(this.testModules.entries()).map(([path, data]) => {
|
|
164
|
-
const { testResult } = data
|
|
165
|
-
|
|
166
|
-
// Handle module/import errors
|
|
167
|
-
if (testResult.testExecError && testResult.testResults.length === 0) {
|
|
168
|
-
return {
|
|
169
|
-
moduleId: path,
|
|
170
|
-
tests: [this.createTestFromExecError(testResult.testExecError)],
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
return {
|
|
175
|
-
moduleId: path,
|
|
176
|
-
tests: testResult.testResults.map((test: AssertionResult) =>
|
|
177
|
-
this.mapTestResult(test)
|
|
178
|
-
),
|
|
179
|
-
}
|
|
180
|
-
})
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
private buildUnhandledErrors(
|
|
184
|
-
results: AggregatedResult
|
|
185
|
-
): CapturedUnhandledError[] {
|
|
186
|
-
if (!results.runExecError) {
|
|
187
|
-
return []
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
const error = results.runExecError
|
|
191
|
-
const errorObj = error as Record<string, unknown>
|
|
192
|
-
|
|
193
|
-
return [
|
|
194
|
-
{
|
|
195
|
-
message: String(errorObj.message ?? 'Unknown error'),
|
|
196
|
-
name: typeof errorObj.name === 'string' ? errorObj.name : 'Error',
|
|
197
|
-
stack: typeof errorObj.stack === 'string' ? errorObj.stack : undefined,
|
|
198
|
-
},
|
|
199
|
-
]
|
|
200
|
-
}
|
|
201
|
-
}
|