@codemieai/code 0.0.33 → 0.0.35
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 +78 -7
- package/bin/codemie-claude-acp.js +21 -0
- package/bin/codemie-opencode.js +11 -0
- package/bin/codemie.js +13 -0
- package/dist/agents/codemie-code/agent.d.ts +38 -4
- package/dist/agents/codemie-code/agent.d.ts.map +1 -1
- package/dist/agents/codemie-code/agent.js +333 -178
- package/dist/agents/codemie-code/agent.js.map +1 -1
- package/dist/agents/codemie-code/index.d.ts +2 -1
- package/dist/agents/codemie-code/index.d.ts.map +1 -1
- package/dist/agents/codemie-code/index.js +36 -7
- package/dist/agents/codemie-code/index.js.map +1 -1
- package/dist/agents/codemie-code/prompts.d.ts +12 -5
- package/dist/agents/codemie-code/prompts.d.ts.map +1 -1
- package/dist/agents/codemie-code/prompts.js +53 -6
- package/dist/agents/codemie-code/prompts.js.map +1 -1
- package/dist/agents/codemie-code/toolMetadata.d.ts.map +1 -1
- package/dist/agents/codemie-code/toolMetadata.js +9 -8
- package/dist/agents/codemie-code/toolMetadata.js.map +1 -1
- package/dist/agents/codemie-code/tools/assistant-invocation.d.ts +47 -0
- package/dist/agents/codemie-code/tools/assistant-invocation.d.ts.map +1 -0
- package/dist/agents/codemie-code/tools/assistant-invocation.js +129 -0
- package/dist/agents/codemie-code/tools/assistant-invocation.js.map +1 -0
- package/dist/agents/codemie-code/tools/index.d.ts +70 -4
- package/dist/agents/codemie-code/tools/index.d.ts.map +1 -1
- package/dist/agents/codemie-code/tools/index.js +57 -44
- package/dist/agents/codemie-code/tools/index.js.map +1 -1
- package/dist/agents/codemie-code/tools/planning.d.ts +6 -5
- package/dist/agents/codemie-code/tools/planning.d.ts.map +1 -1
- package/dist/agents/codemie-code/tools/planning.js +12 -10
- package/dist/agents/codemie-code/tools/planning.js.map +1 -1
- package/dist/agents/codemie-code/types.d.ts +27 -3
- package/dist/agents/codemie-code/types.d.ts.map +1 -1
- package/dist/agents/codemie-code/types.js +24 -0
- package/dist/agents/codemie-code/types.js.map +1 -1
- package/dist/agents/codemie-code/ui/autocomplete.d.ts +98 -0
- package/dist/agents/codemie-code/ui/autocomplete.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/autocomplete.js +145 -0
- package/dist/agents/codemie-code/ui/autocomplete.js.map +1 -0
- package/dist/agents/codemie-code/ui/keyHandlers.d.ts +112 -0
- package/dist/agents/codemie-code/ui/keyHandlers.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/keyHandlers.js +415 -0
- package/dist/agents/codemie-code/ui/keyHandlers.js.map +1 -0
- package/dist/agents/codemie-code/ui/mentions.d.ts +86 -0
- package/dist/agents/codemie-code/ui/mentions.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/mentions.js +122 -0
- package/dist/agents/codemie-code/ui/mentions.js.map +1 -0
- package/dist/agents/codemie-code/ui/terminalCodes.d.ts +38 -0
- package/dist/agents/codemie-code/ui/terminalCodes.d.ts.map +1 -0
- package/dist/agents/codemie-code/ui/terminalCodes.js +42 -0
- package/dist/agents/codemie-code/ui/terminalCodes.js.map +1 -0
- package/dist/agents/codemie-code/ui/todoPanel.d.ts.map +1 -1
- package/dist/agents/codemie-code/ui/todoPanel.js +3 -4
- package/dist/agents/codemie-code/ui/todoPanel.js.map +1 -1
- package/dist/agents/codemie-code/ui.d.ts +8 -7
- package/dist/agents/codemie-code/ui.d.ts.map +1 -1
- package/dist/agents/codemie-code/ui.js +87 -145
- package/dist/agents/codemie-code/ui.js.map +1 -1
- package/dist/agents/core/AgentCLI.d.ts +5 -0
- package/dist/agents/core/AgentCLI.d.ts.map +1 -1
- package/dist/agents/core/AgentCLI.js +25 -1
- package/dist/agents/core/AgentCLI.js.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.d.ts.map +1 -1
- package/dist/agents/core/BaseAgentAdapter.js +90 -27
- package/dist/agents/core/BaseAgentAdapter.js.map +1 -1
- package/dist/agents/core/extension/BaseExtensionInstaller.d.ts +7 -1
- package/dist/agents/core/extension/BaseExtensionInstaller.d.ts.map +1 -1
- package/dist/agents/core/extension/BaseExtensionInstaller.js +58 -15
- package/dist/agents/core/extension/BaseExtensionInstaller.js.map +1 -1
- package/dist/agents/core/session/BaseSessionAdapter.d.ts +25 -0
- package/dist/agents/core/session/BaseSessionAdapter.d.ts.map +1 -1
- package/dist/agents/core/session/discovery-types.d.ts +53 -0
- package/dist/agents/core/session/discovery-types.d.ts.map +1 -0
- package/dist/agents/core/session/discovery-types.js +8 -0
- package/dist/agents/core/session/discovery-types.js.map +1 -0
- package/dist/agents/core/types.d.ts +62 -0
- package/dist/agents/core/types.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude-acp.plugin.d.ts +27 -0
- package/dist/agents/plugins/claude/claude-acp.plugin.d.ts.map +1 -0
- package/dist/agents/plugins/claude/claude-acp.plugin.js +63 -0
- package/dist/agents/plugins/claude/claude-acp.plugin.js.map +1 -0
- package/dist/agents/plugins/claude/claude-message-types.d.ts +1 -0
- package/dist/agents/plugins/claude/claude-message-types.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.d.ts +44 -1
- package/dist/agents/plugins/claude/claude.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.plugin.js +263 -12
- package/dist/agents/plugins/claude/claude.plugin.js.map +1 -1
- package/dist/agents/plugins/claude/claude.session.d.ts.map +1 -1
- package/dist/agents/plugins/claude/claude.session.js +14 -7
- package/dist/agents/plugins/claude/claude.session.js.map +1 -1
- package/dist/agents/plugins/claude/plugin/.claude-plugin/plugin.json +1 -1
- package/dist/agents/plugins/claude/plugin/README.md +40 -2
- package/dist/agents/plugins/claude/plugin/claude-templates/README.md +5 -5
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/CLAUDE.md.template +177 -436
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/code-review-agent-template.md.template +49 -82
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/refactor-cleaner-agent.md.template +337 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/solution-architect-agent.md.template +129 -419
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/agents/unit-tester-agent.md.template +146 -693
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/api/api-patterns.md.template +110 -138
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/architecture.md.template +197 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/data/database-patterns.md.template +171 -91
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/development/development-practices.md.template +219 -131
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/security/security-practices.md.template +223 -98
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/standards/code-quality.md.template +131 -95
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/testing/testing-patterns.md.template +247 -75
- package/dist/agents/plugins/claude/plugin/commands/README.md +133 -0
- package/dist/agents/plugins/claude/plugin/commands/codemie-init.md +336 -544
- package/dist/agents/plugins/claude/plugin/commands/codemie-subagents.md +233 -504
- package/dist/agents/plugins/claude/plugin/commands/memory-add.md +311 -30
- package/dist/agents/plugins/claude/plugin/commands/memory-refresh.md +218 -39
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.d.ts.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js +43 -8
- package/dist/agents/plugins/claude/session/processors/claude.conversations-processor.js.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.d.ts.map +1 -1
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js +68 -40
- package/dist/agents/plugins/claude/session/processors/claude.metrics-processor.js.map +1 -1
- package/dist/agents/plugins/gemini/gemini.plugin.d.ts.map +1 -1
- package/dist/agents/plugins/gemini/gemini.plugin.js +0 -3
- package/dist/agents/plugins/gemini/gemini.plugin.js.map +1 -1
- package/dist/agents/plugins/opencode/index.d.ts +8 -0
- package/dist/agents/plugins/opencode/index.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/index.js +12 -0
- package/dist/agents/plugins/opencode/index.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode-message-types.d.ts +207 -0
- package/dist/agents/plugins/opencode/opencode-message-types.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode-message-types.js +59 -0
- package/dist/agents/plugins/opencode/opencode-message-types.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode-model-configs.d.ts +65 -0
- package/dist/agents/plugins/opencode/opencode-model-configs.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode-model-configs.js +184 -0
- package/dist/agents/plugins/opencode/opencode-model-configs.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.paths.d.ts +62 -0
- package/dist/agents/plugins/opencode/opencode.paths.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.paths.js +148 -0
- package/dist/agents/plugins/opencode/opencode.paths.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.plugin.d.ts +35 -0
- package/dist/agents/plugins/opencode/opencode.plugin.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.plugin.js +338 -0
- package/dist/agents/plugins/opencode/opencode.plugin.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.session.d.ts +77 -0
- package/dist/agents/plugins/opencode/opencode.session.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.session.js +424 -0
- package/dist/agents/plugins/opencode/opencode.session.js.map +1 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts +25 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.js +96 -0
- package/dist/agents/plugins/opencode/opencode.storage-utils.js.map +1 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts +30 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js +116 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.conversations-processor.js.map +1 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts +102 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.d.ts.map +1 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js +584 -0
- package/dist/agents/plugins/opencode/session/processors/opencode.metrics-processor.js.map +1 -0
- package/dist/agents/registry.d.ts +1 -1
- package/dist/agents/registry.d.ts.map +1 -1
- package/dist/agents/registry.js +5 -1
- package/dist/agents/registry.js.map +1 -1
- package/dist/cli/commands/assistants/chat.d.ts +11 -0
- package/dist/cli/commands/assistants/chat.d.ts.map +1 -0
- package/dist/cli/commands/assistants/chat.js +201 -0
- package/dist/cli/commands/assistants/chat.js.map +1 -0
- package/dist/cli/commands/assistants/constants.d.ts +81 -0
- package/dist/cli/commands/assistants/constants.d.ts.map +1 -0
- package/dist/cli/commands/assistants/constants.js +75 -0
- package/dist/cli/commands/assistants/constants.js.map +1 -0
- package/dist/cli/commands/assistants/generators/claude-agent-generator.d.ts +26 -0
- package/dist/cli/commands/assistants/generators/claude-agent-generator.d.ts.map +1 -0
- package/dist/cli/commands/assistants/generators/claude-agent-generator.js +115 -0
- package/dist/cli/commands/assistants/generators/claude-agent-generator.js.map +1 -0
- package/dist/cli/commands/assistants/index.d.ts +11 -0
- package/dist/cli/commands/assistants/index.d.ts.map +1 -0
- package/dist/cli/commands/assistants/index.js +28 -0
- package/dist/cli/commands/assistants/index.js.map +1 -0
- package/dist/cli/commands/assistants/list.d.ts +11 -0
- package/dist/cli/commands/assistants/list.d.ts.map +1 -0
- package/dist/cli/commands/assistants/list.js +323 -0
- package/dist/cli/commands/assistants/list.js.map +1 -0
- package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts +5 -0
- package/dist/cli/commands/doctor/checks/AgentsCheck.d.ts.map +1 -1
- package/dist/cli/commands/doctor/checks/AgentsCheck.js +29 -0
- package/dist/cli/commands/doctor/checks/AgentsCheck.js.map +1 -1
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +104 -13
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/opencode-metrics.d.ts +13 -0
- package/dist/cli/commands/opencode-metrics.d.ts.map +1 -0
- package/dist/cli/commands/opencode-metrics.js +200 -0
- package/dist/cli/commands/opencode-metrics.js.map +1 -0
- package/dist/cli/commands/self-update.d.ts +3 -0
- package/dist/cli/commands/self-update.d.ts.map +1 -0
- package/dist/cli/commands/self-update.js +55 -0
- package/dist/cli/commands/self-update.js.map +1 -0
- package/dist/cli/commands/setup.d.ts.map +1 -1
- package/dist/cli/commands/setup.js +113 -0
- package/dist/cli/commands/setup.js.map +1 -1
- package/dist/cli/commands/skill.d.ts +6 -0
- package/dist/cli/commands/skill.d.ts.map +1 -0
- package/dist/cli/commands/skill.js +196 -0
- package/dist/cli/commands/skill.js.map +1 -0
- package/dist/cli/commands/update.d.ts.map +1 -1
- package/dist/cli/commands/update.js +34 -6
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +12 -4
- package/dist/cli/index.js.map +1 -1
- package/dist/env/types.d.ts +13 -0
- package/dist/env/types.d.ts.map +1 -1
- package/dist/env/types.js +1 -1
- package/dist/env/types.js.map +1 -1
- package/dist/migrations/003-remove-hooks-node.migration.d.ts +22 -0
- package/dist/migrations/003-remove-hooks-node.migration.d.ts.map +1 -0
- package/dist/migrations/003-remove-hooks-node.migration.js +103 -0
- package/dist/migrations/003-remove-hooks-node.migration.js.map +1 -0
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +1 -1
- package/dist/migrations/index.js.map +1 -1
- package/dist/providers/plugins/sso/sso.http-client.js +2 -2
- package/dist/providers/plugins/sso/sso.http-client.js.map +1 -1
- package/dist/providers/plugins/sso/sso.setup-steps.d.ts.map +1 -1
- package/dist/providers/plugins/sso/sso.setup-steps.js +14 -10
- package/dist/providers/plugins/sso/sso.setup-steps.js.map +1 -1
- package/dist/skills/core/SkillDiscovery.d.ts +83 -0
- package/dist/skills/core/SkillDiscovery.d.ts.map +1 -0
- package/dist/skills/core/SkillDiscovery.js +237 -0
- package/dist/skills/core/SkillDiscovery.js.map +1 -0
- package/dist/skills/core/SkillManager.d.ts +86 -0
- package/dist/skills/core/SkillManager.d.ts.map +1 -0
- package/dist/skills/core/SkillManager.js +155 -0
- package/dist/skills/core/SkillManager.js.map +1 -0
- package/dist/skills/core/types.d.ts +120 -0
- package/dist/skills/core/types.d.ts.map +1 -0
- package/dist/skills/core/types.js +20 -0
- package/dist/skills/core/types.js.map +1 -0
- package/dist/skills/index.d.ts +12 -0
- package/dist/skills/index.d.ts.map +1 -0
- package/dist/skills/index.js +12 -0
- package/dist/skills/index.js.map +1 -0
- package/dist/skills/utils/content-loader.d.ts +25 -0
- package/dist/skills/utils/content-loader.d.ts.map +1 -0
- package/dist/skills/utils/content-loader.js +161 -0
- package/dist/skills/utils/content-loader.js.map +1 -0
- package/dist/skills/utils/frontmatter.d.ts +60 -0
- package/dist/skills/utils/frontmatter.d.ts.map +1 -0
- package/dist/skills/utils/frontmatter.js +114 -0
- package/dist/skills/utils/frontmatter.js.map +1 -0
- package/dist/skills/utils/pattern-matcher.d.ts +60 -0
- package/dist/skills/utils/pattern-matcher.d.ts.map +1 -0
- package/dist/skills/utils/pattern-matcher.js +97 -0
- package/dist/skills/utils/pattern-matcher.js.map +1 -0
- package/dist/utils/auth.d.ts +22 -0
- package/dist/utils/auth.d.ts.map +1 -0
- package/dist/utils/auth.js +50 -0
- package/dist/utils/auth.js.map +1 -0
- package/dist/utils/cli-updater.d.ts +70 -0
- package/dist/utils/cli-updater.d.ts.map +1 -0
- package/dist/utils/cli-updater.js +339 -0
- package/dist/utils/cli-updater.js.map +1 -0
- package/dist/utils/config.d.ts +6 -1
- package/dist/utils/config.d.ts.map +1 -1
- package/dist/utils/config.js +13 -0
- package/dist/utils/config.js.map +1 -1
- package/dist/utils/installation-detector.d.ts +22 -0
- package/dist/utils/installation-detector.d.ts.map +1 -0
- package/dist/utils/installation-detector.js +49 -0
- package/dist/utils/installation-detector.js.map +1 -0
- package/dist/utils/native-installer.d.ts +49 -0
- package/dist/utils/native-installer.d.ts.map +1 -0
- package/dist/utils/native-installer.js +225 -0
- package/dist/utils/native-installer.js.map +1 -0
- package/dist/utils/processes.js +1 -1
- package/dist/utils/profile.d.ts +2 -0
- package/dist/utils/profile.d.ts.map +1 -1
- package/dist/utils/profile.js +5 -0
- package/dist/utils/profile.js.map +1 -1
- package/dist/utils/sdk-client.d.ts +15 -0
- package/dist/utils/sdk-client.d.ts.map +1 -0
- package/dist/utils/sdk-client.js +92 -0
- package/dist/utils/sdk-client.js.map +1 -0
- package/dist/utils/version-utils.d.ts +50 -0
- package/dist/utils/version-utils.d.ts.map +1 -0
- package/dist/utils/version-utils.js +92 -0
- package/dist/utils/version-utils.js.map +1 -0
- package/package.json +11 -3
- package/scripts/copy-mr-skill-to-global.ts +252 -0
- package/scripts/demo-hooks.sh +125 -0
- package/scripts/test-hooks.sh +196 -0
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/INDEX.md +0 -205
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/TEMPLATE_SIZES.md +0 -74
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/layered-architecture.md.template +0 -143
- package/dist/agents/plugins/claude/plugin/claude-templates/templates/guides/architecture/project-structure.md.template +0 -127
- package/dist/agents/plugins/claude/plugin/commands/codemie-pr.md +0 -25
|
@@ -11,191 +11,78 @@ color: green
|
|
|
11
11
|
|
|
12
12
|
# Unit Tester Agent Template
|
|
13
13
|
|
|
14
|
-
**Purpose**: This template guides
|
|
14
|
+
**Purpose**: This template guides generation of project-specific unit testing agents. The generating LLM analyzes the codebase and produces a concise testing agent aligned with project conventions.
|
|
15
15
|
|
|
16
16
|
---
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
## Core Mission
|
|
19
19
|
|
|
20
|
-
|
|
20
|
+
Create comprehensive, production-ready unit tests that:
|
|
21
|
+
- Follow project's testing framework and conventions
|
|
22
|
+
- Test business logic, not trivial code
|
|
23
|
+
- Use correct mocking patterns
|
|
24
|
+
- Are fast, isolated, and maintainable
|
|
21
25
|
|
|
22
|
-
|
|
23
|
-
1. **Testing Framework**: Identify from package files and existing tests (pytest, Jest, JUnit, RSpec, Go testing, etc.)
|
|
24
|
-
2. **Test Structure**: Analyze how tests are organized (mirroring source, by feature, by type)
|
|
25
|
-
3. **Test Patterns**: Extract from existing test files (AAA, Given-When-Then, BDD)
|
|
26
|
-
4. **Mocking Libraries**: Identify what's used for mocking (unittest.mock, Jest mocks, Mockito, testify/mock)
|
|
27
|
-
5. **Test Documentation Location**: Find testing guides in docs
|
|
28
|
-
|
|
29
|
-
**FIRST STEP**: Read `[TEST_DOCS_LOCATION]` for project-specific testing patterns.
|
|
30
|
-
|
|
31
|
-
**[TEMPLATE]**:
|
|
32
|
-
**Framework**: [TEST_FRAMEWORK] [VERSION] ONLY with [PLUGINS/EXTENSIONS]
|
|
33
|
-
**Structure**: Tests [ORGANIZATION_PATTERN] in `[TEST_DIRECTORY]`
|
|
34
|
-
**Pattern**: [TEST_PATTERN] (e.g., Arrange-Act-Assert, Given-When-Then)
|
|
35
|
-
**Patching Rule**: [MOCKING_RULE] (e.g., Patch where object is USED, not where DEFINED)
|
|
36
|
-
|
|
37
|
-
**[EXAMPLES FOR DIFFERENT STACKS]**:
|
|
38
|
-
|
|
39
|
-
**Python/pytest**:
|
|
40
|
-
```
|
|
41
|
-
**Framework**: pytest 8.3.x ONLY with pytest-asyncio, pytest-cov, pytest-mock
|
|
42
|
-
**Structure**: Tests mirror source structure in `tests/`
|
|
43
|
-
**Pattern**: Arrange-Act-Assert (AAA)
|
|
44
|
-
**Patching Rule**: Patch where object is USED, not where DEFINED
|
|
45
|
-
```
|
|
26
|
+
---
|
|
46
27
|
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
**Framework**: Jest 29.x ONLY with @testing-library/react, ts-jest
|
|
50
|
-
**Structure**: Tests colocated with source in `__tests__/` or `*.test.ts` files
|
|
51
|
-
**Pattern**: Arrange-Act-Assert (AAA)
|
|
52
|
-
**Mocking Rule**: Mock modules at the top level, use jest.mock()
|
|
53
|
-
```
|
|
28
|
+
## Project Context
|
|
54
29
|
|
|
55
|
-
**
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
**Mocking Rule**: Use @Mock and @InjectMocks annotations
|
|
61
|
-
```
|
|
30
|
+
**[GENERATION INSTRUCTION]**: Analyze project to populate:
|
|
31
|
+
- `.codemie/guides/` folder (if exists) for testing guidelines
|
|
32
|
+
- Existing test files for patterns and conventions
|
|
33
|
+
- Package files for framework and dependencies
|
|
34
|
+
- Test config files for coverage requirements
|
|
62
35
|
|
|
63
|
-
**
|
|
36
|
+
**[TEMPLATE]**:
|
|
64
37
|
```
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
38
|
+
Framework: [TEST_FRAMEWORK] [VERSION] with [PLUGINS]
|
|
39
|
+
Structure: [TEST_DIRECTORY] ([ORGANIZATION_PATTERN])
|
|
40
|
+
Pattern: [TEST_PATTERN] (AAA, Given-When-Then, Table-driven)
|
|
41
|
+
Mocking: [MOCK_LIBRARY] - [MOCKING_RULE]
|
|
42
|
+
Async: [ASYNC_PATTERN]
|
|
69
43
|
```
|
|
70
44
|
|
|
71
45
|
---
|
|
72
46
|
|
|
73
|
-
##
|
|
47
|
+
## What to Test vs Skip
|
|
74
48
|
|
|
75
|
-
|
|
49
|
+
### ✅ TEST: Business Logic
|
|
76
50
|
|
|
77
|
-
|
|
51
|
+
- Calculations, transformations, conditional logic
|
|
52
|
+
- Validation and error handling
|
|
53
|
+
- Edge cases (null, empty, boundaries)
|
|
54
|
+
- State changes and workflows
|
|
55
|
+
- Integration points (with mocked dependencies)
|
|
78
56
|
|
|
79
|
-
|
|
80
|
-
- **Business logic**: Calculations, transformations, conditional logic
|
|
81
|
-
- **Error handling**: Exception/error handling, validation failures
|
|
82
|
-
- **Edge cases**: Boundary conditions (null/nil/None, empty, max/min values)
|
|
83
|
-
- **Integration points**: Component interactions (with mocked dependencies)
|
|
84
|
-
- **State changes**: Operations that modify state
|
|
85
|
-
- **Complex workflows**: Multi-step processes
|
|
86
|
-
- [PROJECT_SPECIFIC_CRITICAL_PATHS]
|
|
87
|
-
|
|
88
|
-
### ❌ DON'T TEST: Trivial Code
|
|
89
|
-
|
|
90
|
-
**[INSTRUCTIONS FOR GENERATION]**: Identify project-specific trivial patterns by analyzing existing code:
|
|
91
|
-
- ORM/Model frameworks that handle defaults (Pydantic, TypeORM, JPA)
|
|
92
|
-
- Framework behavior (FastAPI, Express, Spring Boot internals)
|
|
93
|
-
- Auto-generated code (database migrations, GraphQL resolvers)
|
|
94
|
-
- Simple pass-through methods
|
|
57
|
+
### ❌ SKIP: Trivial Code
|
|
95
58
|
|
|
96
|
-
|
|
97
|
-
- Model
|
|
98
|
-
-
|
|
99
|
-
-
|
|
100
|
-
- Auto-generated code ([MIGRATION_TOOL] migrations)
|
|
101
|
-
- Trivial assignments (`self.x = x` or `this.x = x`)
|
|
59
|
+
- Simple getters/setters
|
|
60
|
+
- Model defaults ([ORM_FRAMEWORK] handles this)
|
|
61
|
+
- Framework internals
|
|
62
|
+
- Auto-generated code
|
|
102
63
|
- Pass-through methods with no logic
|
|
103
64
|
|
|
104
|
-
**
|
|
105
|
-
```[language]
|
|
106
|
-
# ❌ BAD: Testing [FRAMEWORK] default values
|
|
107
|
-
[bad_test_example]
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
**[INSTRUCTIONS FOR GENERATION]**: Generate a concrete bad test example in the project's language showing what NOT to test (e.g., testing Pydantic defaults, TypeScript interface types, Java bean getters).
|
|
65
|
+
**Decision Rule**: If there's no conditional logic or business rule, don't test it.
|
|
111
66
|
|
|
112
67
|
---
|
|
113
68
|
|
|
114
69
|
## Essential Test Patterns
|
|
115
70
|
|
|
116
|
-
|
|
117
|
-
- Language syntax
|
|
118
|
-
- Testing framework
|
|
119
|
-
- Mocking library
|
|
120
|
-
- Async patterns (if applicable)
|
|
121
|
-
- Common domain objects
|
|
122
|
-
|
|
123
|
-
### 1. Basic Test ([TEST_PATTERN] Pattern)
|
|
71
|
+
### 1. Basic Test Structure
|
|
124
72
|
|
|
125
|
-
**[TEMPLATE
|
|
73
|
+
**[TEMPLATE]**:
|
|
126
74
|
```[language]
|
|
127
|
-
[
|
|
128
|
-
[async_keyword
|
|
129
|
-
// [ARRANGE_STEP_NAME]: Set up test data and mocks
|
|
130
|
-
[mock_setup_code]
|
|
131
|
-
[test_data_setup]
|
|
132
|
-
[system_under_test_creation]
|
|
133
|
-
|
|
134
|
-
// [ACT_STEP_NAME]: Execute the code under test
|
|
135
|
-
[result_variable] = [await if needed] [method_call]
|
|
136
|
-
|
|
137
|
-
// [ASSERT_STEP_NAME]: Verify expectations
|
|
138
|
-
[assertion_syntax]([expected_condition])
|
|
139
|
-
[verify_mock_calls]
|
|
140
|
-
}
|
|
141
|
-
```
|
|
142
|
-
|
|
143
|
-
**[EXAMPLES FOR DIFFERENT STACKS]**:
|
|
144
|
-
|
|
145
|
-
**Python/pytest**:
|
|
146
|
-
```python
|
|
147
|
-
@pytest.mark.asyncio
|
|
148
|
-
async def test_service_method_success():
|
|
149
|
-
"""Test service method succeeds with valid input"""
|
|
150
|
-
# Arrange
|
|
151
|
-
mock_repository = AsyncMock()
|
|
152
|
-
mock_repository.find_by_id.return_value = {"id": "123"}
|
|
153
|
-
service = MyService(repository=mock_repository)
|
|
154
|
-
|
|
155
|
-
# Act
|
|
156
|
-
result = await service.get_by_id("123")
|
|
157
|
-
|
|
158
|
-
# Assert
|
|
159
|
-
assert result["id"] == "123"
|
|
160
|
-
mock_repository.find_by_id.assert_called_once_with("123")
|
|
161
|
-
```
|
|
162
|
-
|
|
163
|
-
**JavaScript/Jest**:
|
|
164
|
-
```typescript
|
|
165
|
-
describe('MyService', () => {
|
|
166
|
-
test('should retrieve item by id successfully', async () => {
|
|
75
|
+
[test_decorator_or_annotation]
|
|
76
|
+
[async_keyword] [function_keyword] test_[method]_[scenario]_[expected]() {
|
|
167
77
|
// Arrange
|
|
168
|
-
|
|
169
|
-
findById: jest.fn().mockResolvedValue({ id: '123' })
|
|
170
|
-
};
|
|
171
|
-
const service = new MyService(mockRepository);
|
|
78
|
+
[setup_mocks_and_data]
|
|
172
79
|
|
|
173
80
|
// Act
|
|
174
|
-
|
|
81
|
+
[result] = [await] [method_call]
|
|
175
82
|
|
|
176
83
|
// Assert
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
expect(mockRepository.findById).toHaveBeenCalledTimes(1);
|
|
180
|
-
});
|
|
181
|
-
});
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
**Java/JUnit**:
|
|
185
|
-
```java
|
|
186
|
-
@Test
|
|
187
|
-
void testServiceMethodSuccess() {
|
|
188
|
-
// Given
|
|
189
|
-
when(mockRepository.findById("123"))
|
|
190
|
-
.thenReturn(Optional.of(new Entity("123")));
|
|
191
|
-
MyService service = new MyService(mockRepository);
|
|
192
|
-
|
|
193
|
-
// When
|
|
194
|
-
Entity result = service.getById("123");
|
|
195
|
-
|
|
196
|
-
// Then
|
|
197
|
-
assertThat(result.getId()).isEqualTo("123");
|
|
198
|
-
verify(mockRepository, times(1)).findById("123");
|
|
84
|
+
[assertions]
|
|
85
|
+
[verify_mock_calls]
|
|
199
86
|
}
|
|
200
87
|
```
|
|
201
88
|
|
|
@@ -203,603 +90,169 @@ void testServiceMethodSuccess() {
|
|
|
203
90
|
|
|
204
91
|
**[TEMPLATE]**:
|
|
205
92
|
```[language]
|
|
206
|
-
[
|
|
207
|
-
|
|
208
|
-
[
|
|
209
|
-
[
|
|
93
|
+
[test_decorator_or_annotation]
|
|
94
|
+
[function_keyword] test_[method]_raises_[exception]() {
|
|
95
|
+
[expect_exception_syntax] {
|
|
96
|
+
[method_call_that_fails]
|
|
210
97
|
}
|
|
211
|
-
[verify_exception_message]
|
|
212
|
-
}
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
**[EXAMPLES FOR DIFFERENT STACKS]**:
|
|
216
|
-
|
|
217
|
-
**Python/pytest**:
|
|
218
|
-
```python
|
|
219
|
-
def test_validation_raises_exception():
|
|
220
|
-
"""Test invalid input raises ValidationException"""
|
|
221
|
-
with pytest.raises(ValidationException) as exc_info:
|
|
222
|
-
service.validate_input(None)
|
|
223
|
-
assert "cannot be None" in str(exc_info.value)
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
**JavaScript/Jest**:
|
|
227
|
-
```typescript
|
|
228
|
-
test('should throw ValidationError for invalid input', async () => {
|
|
229
|
-
await expect(service.validateInput(null))
|
|
230
|
-
.rejects
|
|
231
|
-
.toThrow(ValidationError);
|
|
232
|
-
|
|
233
|
-
await expect(service.validateInput(null))
|
|
234
|
-
.rejects
|
|
235
|
-
.toThrow('cannot be null');
|
|
236
|
-
});
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
**Java/JUnit**:
|
|
240
|
-
```java
|
|
241
|
-
@Test
|
|
242
|
-
void testValidationThrowsException() {
|
|
243
|
-
ValidationException exception = assertThrows(
|
|
244
|
-
ValidationException.class,
|
|
245
|
-
() -> service.validateInput(null)
|
|
246
|
-
);
|
|
247
|
-
assertThat(exception.getMessage()).contains("cannot be null");
|
|
248
98
|
}
|
|
249
99
|
```
|
|
250
100
|
|
|
251
|
-
### 3. Parametrized
|
|
252
|
-
|
|
253
|
-
**[INSTRUCTIONS FOR GENERATION]**: Parametrized testing syntax varies significantly by framework. Extract the correct pattern from existing tests.
|
|
101
|
+
### 3. Parametrized Tests
|
|
254
102
|
|
|
255
103
|
**[TEMPLATE]**:
|
|
256
104
|
```[language]
|
|
257
|
-
[
|
|
258
|
-
[
|
|
259
|
-
|
|
105
|
+
[parametrize_decorator]([test_cases])
|
|
106
|
+
[test_decorator_or_annotation]
|
|
107
|
+
[function_keyword] test_[method]_multiple_cases([params]) {
|
|
260
108
|
[assertion]
|
|
261
109
|
}
|
|
262
110
|
```
|
|
263
111
|
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
**Python/pytest**:
|
|
267
|
-
```python
|
|
268
|
-
@pytest.mark.parametrize(
|
|
269
|
-
"input_value, expected_valid",
|
|
270
|
-
[
|
|
271
|
-
("valid", True),
|
|
272
|
-
("", False),
|
|
273
|
-
(None, False),
|
|
274
|
-
("a" * 256, False),
|
|
275
|
-
],
|
|
276
|
-
)
|
|
277
|
-
def test_validation_multiple_cases(input_value, expected_valid):
|
|
278
|
-
"""Test validation with multiple cases"""
|
|
279
|
-
assert validate_input(input_value) == expected_valid
|
|
280
|
-
```
|
|
281
|
-
|
|
282
|
-
**JavaScript/Jest**:
|
|
283
|
-
```typescript
|
|
284
|
-
describe.each([
|
|
285
|
-
['valid', true],
|
|
286
|
-
['', false],
|
|
287
|
-
[null, false],
|
|
288
|
-
['a'.repeat(256), false],
|
|
289
|
-
])('validateInput(%s)', (input, expectedValid) => {
|
|
290
|
-
test(`should return ${expectedValid}`, () => {
|
|
291
|
-
expect(validateInput(input)).toBe(expectedValid);
|
|
292
|
-
});
|
|
293
|
-
});
|
|
294
|
-
```
|
|
112
|
+
### 4. Mocking ([MOCKING_RULE])
|
|
295
113
|
|
|
296
|
-
**
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
@
|
|
300
|
-
|
|
301
|
-
assertThat(validateInput(input)).isEqualTo(expectedValid);
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
private static Stream<Arguments> validationCases() {
|
|
305
|
-
return Stream.of(
|
|
306
|
-
Arguments.of("valid", true),
|
|
307
|
-
Arguments.of("", false),
|
|
308
|
-
Arguments.of(null, false),
|
|
309
|
-
Arguments.of("a".repeat(256), false)
|
|
310
|
-
);
|
|
311
|
-
}
|
|
312
|
-
```
|
|
313
|
-
|
|
314
|
-
### 4. Mocking (CRITICAL: [MOCKING_RULE])
|
|
315
|
-
|
|
316
|
-
**[INSTRUCTIONS FOR GENERATION]**: Mocking rules are framework-specific. Extract the correct pattern:
|
|
317
|
-
- Python: "Patch where USED, not where DEFINED"
|
|
318
|
-
- JavaScript/Jest: "Mock modules at top level"
|
|
319
|
-
- Java/Mockito: "Use @Mock and @InjectMocks"
|
|
320
|
-
- Go: "Use interfaces and concrete mock implementations"
|
|
114
|
+
**[GENERATION INSTRUCTION]**: Document the correct mocking approach for the project's language:
|
|
115
|
+
- Python: Patch where object is USED, not where DEFINED
|
|
116
|
+
- JavaScript: Mock modules at top level with jest.mock()
|
|
117
|
+
- Java: Use @Mock and @InjectMocks annotations
|
|
118
|
+
- Go: Use interfaces with mock implementations
|
|
321
119
|
|
|
322
120
|
**[TEMPLATE]**:
|
|
323
121
|
```[language]
|
|
324
|
-
//
|
|
325
|
-
[
|
|
122
|
+
// ✅ CORRECT
|
|
123
|
+
[correct_mock_example]
|
|
326
124
|
|
|
327
|
-
|
|
328
|
-
function [method]([params]) {
|
|
329
|
-
return [DependencyName].[method_call]([args]) // Used HERE
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
// ✅ CORRECT: [CORRECT_MOCKING_PATTERN]
|
|
334
|
-
[mock_annotation or function]
|
|
335
|
-
[test_annotation]
|
|
336
|
-
function/method test_[scenario]([mock_parameters]) {
|
|
337
|
-
[mock_setup]
|
|
338
|
-
[execute_test]
|
|
339
|
-
[assertions]
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// ❌ WRONG: [WRONG_MOCKING_PATTERN]
|
|
125
|
+
// ❌ WRONG
|
|
343
126
|
[wrong_mock_example]
|
|
344
127
|
```
|
|
345
128
|
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
**Python/pytest**:
|
|
349
|
-
```python
|
|
350
|
-
# In src/service/user_service.py
|
|
351
|
-
from src.database.user_repository import UserRepository
|
|
352
|
-
|
|
353
|
-
class UserService:
|
|
354
|
-
def get_user(self, user_id):
|
|
355
|
-
return UserRepository.find_by_id(user_id) # Used HERE
|
|
356
|
-
|
|
357
|
-
# ✅ CORRECT: Patch where USED
|
|
358
|
-
@patch('src.service.user_service.UserRepository.find_by_id')
|
|
359
|
-
def test_get_user(mock_find):
|
|
360
|
-
mock_find.return_value = {"id": "123"}
|
|
361
|
-
result = UserService().get_user("123")
|
|
362
|
-
assert result["id"] == "123"
|
|
363
|
-
|
|
364
|
-
# ❌ WRONG: Patching where DEFINED
|
|
365
|
-
@patch('src.database.user_repository.UserRepository.find_by_id')
|
|
366
|
-
```
|
|
367
|
-
|
|
368
|
-
**JavaScript/Jest**:
|
|
369
|
-
```typescript
|
|
370
|
-
// In src/service/UserService.ts
|
|
371
|
-
import { UserRepository } from '../database/UserRepository';
|
|
372
|
-
|
|
373
|
-
class UserService {
|
|
374
|
-
getUser(userId: string) {
|
|
375
|
-
return UserRepository.findById(userId); // Used HERE
|
|
376
|
-
}
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// ✅ CORRECT: Mock module at top level
|
|
380
|
-
jest.mock('../database/UserRepository');
|
|
381
|
-
|
|
382
|
-
test('should get user', () => {
|
|
383
|
-
const mockFindById = UserRepository.findById as jest.Mock;
|
|
384
|
-
mockFindById.mockResolvedValue({ id: '123' });
|
|
385
|
-
|
|
386
|
-
const result = await new UserService().getUser('123');
|
|
387
|
-
expect(result.id).toBe('123');
|
|
388
|
-
});
|
|
389
|
-
|
|
390
|
-
// ❌ WRONG: Trying to mock after import
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
**Java/JUnit + Mockito**:
|
|
394
|
-
```java
|
|
395
|
-
// ✅ CORRECT: Use @Mock and @InjectMocks
|
|
396
|
-
@ExtendWith(MockitoExtension.class)
|
|
397
|
-
class UserServiceTest {
|
|
398
|
-
@Mock
|
|
399
|
-
private UserRepository userRepository;
|
|
400
|
-
|
|
401
|
-
@InjectMocks
|
|
402
|
-
private UserService userService;
|
|
403
|
-
|
|
404
|
-
@Test
|
|
405
|
-
void testGetUser() {
|
|
406
|
-
when(userRepository.findById("123"))
|
|
407
|
-
.thenReturn(Optional.of(new User("123")));
|
|
408
|
-
|
|
409
|
-
User result = userService.getUser("123");
|
|
410
|
-
assertThat(result.getId()).isEqualTo("123");
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
```
|
|
414
|
-
|
|
415
|
-
### 5. Testing [API_FRAMEWORK] Endpoints
|
|
416
|
-
|
|
417
|
-
**[INSTRUCTIONS FOR GENERATION]**: Identify the API framework used (FastAPI, Express, Spring Boot, etc.) and provide appropriate test patterns.
|
|
129
|
+
### 5. API/Endpoint Testing
|
|
418
130
|
|
|
419
131
|
**[TEMPLATE]**:
|
|
420
132
|
```[language]
|
|
421
|
-
[
|
|
422
|
-
|
|
423
|
-
[
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
[fixture_or_beforeEach]
|
|
429
|
-
function/method [auth_setup]() {
|
|
430
|
-
return [auth_headers_or_tokens]
|
|
431
|
-
}
|
|
432
|
-
|
|
433
|
-
[mock_annotation]
|
|
434
|
-
[test_annotation]
|
|
435
|
-
function/method test_[endpoint]_[scenario]([parameters]) {
|
|
436
|
-
[mock_service_setup]
|
|
437
|
-
[response_variable] = [client].[http_method]([path], [options])
|
|
438
|
-
[status_assertion]
|
|
439
|
-
[body_assertion]
|
|
133
|
+
[test_decorator_or_annotation]
|
|
134
|
+
[async_keyword] [function_keyword] test_[endpoint]_[scenario]() {
|
|
135
|
+
[mock_service_layer]
|
|
136
|
+
[response] = [test_client].[http_method]([path], [options])
|
|
137
|
+
[assert_status]
|
|
138
|
+
[assert_body]
|
|
440
139
|
}
|
|
441
140
|
```
|
|
442
141
|
|
|
443
|
-
**[EXAMPLES FOR DIFFERENT STACKS]**:
|
|
444
|
-
|
|
445
|
-
**Python/FastAPI**:
|
|
446
|
-
```python
|
|
447
|
-
from fastapi.testclient import TestClient
|
|
448
|
-
|
|
449
|
-
@pytest.fixture
|
|
450
|
-
def client():
|
|
451
|
-
return TestClient(app)
|
|
452
|
-
|
|
453
|
-
@pytest.fixture
|
|
454
|
-
def auth_headers():
|
|
455
|
-
return {"Authorization": "Bearer test-token"}
|
|
456
|
-
|
|
457
|
-
@patch('myapp.service.assistant_service.AssistantService.get_by_id')
|
|
458
|
-
def test_get_assistant_success(mock_get, client, auth_headers):
|
|
459
|
-
mock_get.return_value = {"id": "123", "name": "Test"}
|
|
460
|
-
response = client.get("/v1/assistants/123", headers=auth_headers)
|
|
461
|
-
assert response.status_code == 200
|
|
462
|
-
assert response.json()["id"] == "123"
|
|
463
|
-
```
|
|
464
|
-
|
|
465
|
-
**JavaScript/Express**:
|
|
466
|
-
```typescript
|
|
467
|
-
import request from 'supertest';
|
|
468
|
-
import app from '../app';
|
|
469
|
-
|
|
470
|
-
jest.mock('../service/AssistantService');
|
|
471
|
-
|
|
472
|
-
describe('GET /v1/assistants/:id', () => {
|
|
473
|
-
test('should return assistant successfully', async () => {
|
|
474
|
-
const mockGet = AssistantService.getById as jest.Mock;
|
|
475
|
-
mockGet.mockResolvedValue({ id: '123', name: 'Test' });
|
|
476
|
-
|
|
477
|
-
const response = await request(app)
|
|
478
|
-
.get('/v1/assistants/123')
|
|
479
|
-
.set('Authorization', 'Bearer test-token');
|
|
480
|
-
|
|
481
|
-
expect(response.status).toBe(200);
|
|
482
|
-
expect(response.body.id).toBe('123');
|
|
483
|
-
});
|
|
484
|
-
});
|
|
485
|
-
```
|
|
486
|
-
|
|
487
|
-
**Java/Spring Boot**:
|
|
488
|
-
```java
|
|
489
|
-
@WebMvcTest(AssistantController.class)
|
|
490
|
-
class AssistantControllerTest {
|
|
491
|
-
@Autowired
|
|
492
|
-
private MockMvc mockMvc;
|
|
493
|
-
|
|
494
|
-
@MockBean
|
|
495
|
-
private AssistantService assistantService;
|
|
496
|
-
|
|
497
|
-
@Test
|
|
498
|
-
void testGetAssistantSuccess() throws Exception {
|
|
499
|
-
when(assistantService.getById("123"))
|
|
500
|
-
.thenReturn(new Assistant("123", "Test"));
|
|
501
|
-
|
|
502
|
-
mockMvc.perform(get("/v1/assistants/123")
|
|
503
|
-
.header("Authorization", "Bearer test-token"))
|
|
504
|
-
.andExpect(status().isOk())
|
|
505
|
-
.andExpect(jsonPath("$.id").value("123"));
|
|
506
|
-
}
|
|
507
|
-
}
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
---
|
|
511
|
-
|
|
512
|
-
## Decision Framework
|
|
513
|
-
|
|
514
|
-
**When deciding what to test, ask:**
|
|
515
|
-
1. Is there business logic? → TEST IT
|
|
516
|
-
2. Can this fail unexpectedly? → TEST EDGE CASES
|
|
517
|
-
3. Does this handle errors? → TEST ERROR SCENARIOS
|
|
518
|
-
4. Does this integrate with external systems? → TEST WITH MOCKS
|
|
519
|
-
5. Is this auto-generated or framework code? → DON'T TEST
|
|
520
|
-
6. Is this a simple getter/setter? → DON'T TEST
|
|
521
|
-
|
|
522
|
-
**Priority:**
|
|
523
|
-
1. Critical business logic ([PROJECT_CRITICAL_PATHS])
|
|
524
|
-
2. Error handling
|
|
525
|
-
3. Complex algorithms
|
|
526
|
-
4. Integration points (mocked)
|
|
527
|
-
5. Edge cases
|
|
528
|
-
|
|
529
|
-
**[INSTRUCTIONS FOR GENERATION]**: Replace [PROJECT_CRITICAL_PATHS] with actual critical paths from the project (e.g., "auth, payments, validation" for e-commerce; "data ingestion, transformation, analytics" for data platform).
|
|
530
|
-
|
|
531
142
|
---
|
|
532
143
|
|
|
533
144
|
## Test Quality Checklist
|
|
534
145
|
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
**[TEMPLATE]**:
|
|
538
|
-
- [ ] [TEST_PATTERN] pattern used
|
|
539
|
-
- [ ] Clear test names (`test_<method>_<scenario>_<result>`)
|
|
540
|
-
- [ ] [DOCUMENTATION_REQUIREMENT] present (docstrings, comments, descriptions)
|
|
146
|
+
- [ ] Clear test name: `test_<method>_<scenario>_<expected>`
|
|
147
|
+
- [ ] [TEST_PATTERN] pattern followed
|
|
541
148
|
- [ ] External dependencies mocked
|
|
542
|
-
- [ ] Correct [MOCKING_PATTERN] (e.g., patching where USED)
|
|
543
|
-
- [ ] [ASYNC_TEST_ANNOTATION] for async tests (if applicable)
|
|
544
149
|
- [ ] Mock calls verified
|
|
545
|
-
- [ ] Specific assertions (
|
|
150
|
+
- [ ] Specific assertions (not just `assertTrue`)
|
|
546
151
|
- [ ] Fast execution (no real I/O)
|
|
547
152
|
- [ ] No hardcoded credentials
|
|
548
|
-
- [PROJECT_SPECIFIC_CHECKS]
|
|
549
|
-
|
|
550
|
-
---
|
|
551
|
-
|
|
552
|
-
## Key Reminders
|
|
553
|
-
|
|
554
|
-
**[TEMPLATE]**:
|
|
555
|
-
1. **[TEST_FRAMEWORK] [VERSION] ONLY** - No [ALTERNATIVE_FRAMEWORKS]
|
|
556
|
-
2. **[MOCKING_RULE]** - [MOCKING_EXPLANATION]
|
|
557
|
-
3. **Mock external deps** - [COMMON_EXTERNAL_DEPS]
|
|
558
|
-
4. **Test logic, not trivia** - Skip [TRIVIAL_EXAMPLES]
|
|
559
|
-
5. **Read [TEST_DOCS_LOCATION] FIRST** - Critical project patterns
|
|
560
153
|
|
|
561
154
|
---
|
|
562
155
|
|
|
563
156
|
## Running Tests
|
|
564
157
|
|
|
565
|
-
**[INSTRUCTIONS FOR GENERATION]**: Extract actual test commands from package.json, Makefile, pom.xml, or CI configs. Include commands for:
|
|
566
|
-
- Running all tests
|
|
567
|
-
- Running specific test files
|
|
568
|
-
- Running with coverage
|
|
569
|
-
- Running specific test cases
|
|
570
|
-
- Watching for changes (if applicable)
|
|
571
|
-
|
|
572
158
|
**[TEMPLATE]**:
|
|
573
159
|
```bash
|
|
574
|
-
#
|
|
575
|
-
[
|
|
160
|
+
# All tests
|
|
161
|
+
[run_all_command]
|
|
576
162
|
|
|
577
|
-
#
|
|
578
|
-
[
|
|
163
|
+
# Specific file
|
|
164
|
+
[run_file_command] [path]
|
|
579
165
|
|
|
580
|
-
#
|
|
581
|
-
[
|
|
166
|
+
# With coverage
|
|
167
|
+
[coverage_command]
|
|
582
168
|
|
|
583
|
-
#
|
|
584
|
-
[
|
|
585
|
-
|
|
586
|
-
# Watch mode (if applicable)
|
|
587
|
-
[watch_mode_command]
|
|
588
|
-
```
|
|
589
|
-
|
|
590
|
-
**[EXAMPLES FOR DIFFERENT STACKS]**:
|
|
591
|
-
|
|
592
|
-
**Python/pytest**:
|
|
593
|
-
```bash
|
|
594
|
-
# Run all tests
|
|
595
|
-
poetry run pytest tests/
|
|
596
|
-
|
|
597
|
-
# Run specific file
|
|
598
|
-
poetry run pytest tests/service/test_my_service.py
|
|
599
|
-
|
|
600
|
-
# Run with coverage
|
|
601
|
-
poetry run pytest tests/ --cov=src --cov-report=html
|
|
602
|
-
|
|
603
|
-
# Run specific test
|
|
604
|
-
poetry run pytest tests/service/test_my_service.py::test_create_success
|
|
605
|
-
```
|
|
606
|
-
|
|
607
|
-
**JavaScript/Jest**:
|
|
608
|
-
```bash
|
|
609
|
-
# Run all tests
|
|
610
|
-
npm test
|
|
611
|
-
|
|
612
|
-
# Run specific file
|
|
613
|
-
npm test -- src/service/__tests__/MyService.test.ts
|
|
614
|
-
|
|
615
|
-
# Run with coverage
|
|
616
|
-
npm test -- --coverage
|
|
617
|
-
|
|
618
|
-
# Run specific test
|
|
619
|
-
npm test -- -t "should create successfully"
|
|
620
|
-
|
|
621
|
-
# Watch mode
|
|
622
|
-
npm test -- --watch
|
|
623
|
-
```
|
|
624
|
-
|
|
625
|
-
**Java/Maven**:
|
|
626
|
-
```bash
|
|
627
|
-
# Run all tests
|
|
628
|
-
mvn test
|
|
629
|
-
|
|
630
|
-
# Run specific test class
|
|
631
|
-
mvn test -Dtest=MyServiceTest
|
|
632
|
-
|
|
633
|
-
# Run with coverage
|
|
634
|
-
mvn test jacoco:report
|
|
635
|
-
|
|
636
|
-
# Run specific test method
|
|
637
|
-
mvn test -Dtest=MyServiceTest#testCreateSuccess
|
|
638
|
-
```
|
|
639
|
-
|
|
640
|
-
**Go/testing**:
|
|
641
|
-
```bash
|
|
642
|
-
# Run all tests
|
|
643
|
-
go test ./...
|
|
644
|
-
|
|
645
|
-
# Run specific package
|
|
646
|
-
go test ./service
|
|
647
|
-
|
|
648
|
-
# Run with coverage
|
|
649
|
-
go test ./... -cover
|
|
650
|
-
|
|
651
|
-
# Run specific test
|
|
652
|
-
go test ./service -run TestMyService_CreateSuccess
|
|
653
|
-
|
|
654
|
-
# Verbose output
|
|
655
|
-
go test ./... -v
|
|
169
|
+
# Specific test
|
|
170
|
+
[run_single_command] [test_name]
|
|
656
171
|
```
|
|
657
172
|
|
|
658
173
|
---
|
|
659
174
|
|
|
660
|
-
##
|
|
661
|
-
|
|
662
|
-
**[TEMPLATE]**:
|
|
663
|
-
- ✅ Critical paths tested (success, errors, edge cases)
|
|
664
|
-
- ✅ External dependencies mocked
|
|
665
|
-
- ✅ [TEST_PATTERN] pattern with clear structure
|
|
666
|
-
- ✅ Mock calls verified
|
|
667
|
-
- ✅ Tests run fast ([PERFORMANCE_THRESHOLD])
|
|
668
|
-
- ✅ No hardcoded credentials
|
|
669
|
-
- ✅ Coverage [COVERAGE_REQUIREMENT] for new code
|
|
670
|
-
|
|
671
|
-
**[INSTRUCTIONS FOR GENERATION]**: Extract coverage requirements from project config (.coveragerc, jest.config.js, sonar-project.properties) and performance expectations from existing tests.
|
|
175
|
+
## Key Reminders
|
|
672
176
|
|
|
673
|
-
|
|
177
|
+
1. **[TEST_FRAMEWORK] only** - Don't mix frameworks
|
|
178
|
+
2. **[MOCKING_RULE]** - Critical for correct test isolation
|
|
179
|
+
3. **Test behavior, not implementation** - Focus on what, not how
|
|
180
|
+
4. **Mock external dependencies** - Database, APIs, file system
|
|
181
|
+
5. **Skip trivial code** - No value in testing getters/defaults
|
|
674
182
|
|
|
675
183
|
---
|
|
676
184
|
|
|
677
|
-
## Generation Instructions
|
|
185
|
+
## Generation Instructions
|
|
678
186
|
|
|
679
187
|
**For LLM generating project-specific agent from this template:**
|
|
680
188
|
|
|
681
|
-
### Step 1:
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
- Package files
|
|
685
|
-
-
|
|
686
|
-
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
-
|
|
701
|
-
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
- Test file naming (`test_*.py`, `*.test.ts`, `*Test.java`, `*_test.go`)
|
|
705
|
-
- Test function/method naming conventions
|
|
706
|
-
- Test suite organization (describe blocks, test classes)
|
|
707
|
-
|
|
708
|
-
### Step 3: Extract Test Patterns
|
|
709
|
-
|
|
710
|
-
**Analyze 10-20 existing test files** to identify:
|
|
711
|
-
- Test structure pattern (AAA, Given-When-Then, BDD)
|
|
712
|
-
- Async test handling (if applicable)
|
|
713
|
-
- Mock setup patterns
|
|
714
|
-
- Assertion styles
|
|
189
|
+
### Step 1: Discover Testing Stack
|
|
190
|
+
|
|
191
|
+
Analyze:
|
|
192
|
+
- Package files for test framework and dependencies
|
|
193
|
+
- Existing test files for patterns
|
|
194
|
+
- Test config files for settings
|
|
195
|
+
- `.codemie/guides/` folder if exists
|
|
196
|
+
|
|
197
|
+
Extract:
|
|
198
|
+
| Item | Source |
|
|
199
|
+
|------|--------|
|
|
200
|
+
| Framework + version | package.json, pyproject.toml, pom.xml |
|
|
201
|
+
| Plugins/extensions | Same + test configs |
|
|
202
|
+
| Mock library | Import statements in test files |
|
|
203
|
+
| Test directory | Project structure |
|
|
204
|
+
| Naming convention | Existing test file names |
|
|
205
|
+
|
|
206
|
+
### Step 2: Identify Patterns
|
|
207
|
+
|
|
208
|
+
From 5-10 existing test files, extract:
|
|
209
|
+
- Test structure (AAA, Given-When-Then, Table-driven)
|
|
210
|
+
- Async handling pattern
|
|
211
|
+
- Mock setup approach
|
|
715
212
|
- Fixture/setup patterns
|
|
716
|
-
-
|
|
717
|
-
|
|
718
|
-
### Step 4: Identify Project-Specific Rules
|
|
719
|
-
|
|
720
|
-
**Critical paths**: What's most important to test?
|
|
721
|
-
- Authentication/authorization
|
|
722
|
-
- Payment processing
|
|
723
|
-
- Data validation
|
|
724
|
-
- Critical business logic
|
|
725
|
-
- API endpoints
|
|
726
|
-
|
|
727
|
-
**Trivial code to avoid testing**:
|
|
728
|
-
- Framework-generated code
|
|
729
|
-
- Simple getters/setters
|
|
730
|
-
- Model defaults
|
|
731
|
-
- Pass-through methods
|
|
732
|
-
|
|
733
|
-
### Step 5: Extract Mocking Conventions
|
|
213
|
+
- Assertion style
|
|
734
214
|
|
|
735
|
-
|
|
736
|
-
**JavaScript-specific**: Module mocking with `jest.mock()`
|
|
737
|
-
**Java-specific**: Annotation-based mocking with Mockito
|
|
738
|
-
**Go-specific**: Interface-based mocking
|
|
215
|
+
### Step 3: Document Mocking Rule
|
|
739
216
|
|
|
740
|
-
|
|
217
|
+
**Critical** - Identify the correct mocking approach:
|
|
741
218
|
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
219
|
+
| Language | Rule |
|
|
220
|
+
|----------|------|
|
|
221
|
+
| Python | Patch where USED, not DEFINED |
|
|
222
|
+
| JavaScript | jest.mock() at module level |
|
|
223
|
+
| Java | @Mock + @InjectMocks |
|
|
224
|
+
| Go | Interface-based mocks |
|
|
747
225
|
|
|
748
|
-
### Step
|
|
226
|
+
### Step 4: Create Concrete Examples
|
|
749
227
|
|
|
750
|
-
|
|
751
|
-
- `.coveragerc`, `jest.config.js`, `sonar-project.properties`
|
|
752
|
-
- CI/CD quality gates
|
|
753
|
-
- Project documentation
|
|
754
|
-
|
|
755
|
-
**Performance standards**:
|
|
756
|
-
- Expected test execution time
|
|
757
|
-
- Timeout configurations
|
|
758
|
-
- Parallel execution settings
|
|
759
|
-
|
|
760
|
-
### Step 8: Populate Language-Specific Examples
|
|
761
|
-
|
|
762
|
-
**For each essential test pattern**, create examples using:
|
|
228
|
+
For each essential pattern, generate examples using:
|
|
763
229
|
- Project's actual language syntax
|
|
764
|
-
- Project's
|
|
765
|
-
- Project's
|
|
766
|
-
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
-
|
|
772
|
-
-
|
|
773
|
-
-
|
|
774
|
-
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
- [ ]
|
|
779
|
-
-
|
|
780
|
-
- [
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
| Go | testing package | testify/mock | goroutines/channels | Table-driven | *_test.go |
|
|
794
|
-
| C# | xUnit, NUnit, MSTest | Moq, NSubstitute | async/await | AAA | *Tests.cs |
|
|
795
|
-
| Ruby | RSpec, Minitest | RSpec mocks | async gems | BDD | *_spec.rb |
|
|
796
|
-
| Rust | cargo test | mockall | async-std/tokio | Result-based | tests/*.rs |
|
|
797
|
-
|
|
798
|
-
**Key Customization Points per Language**:
|
|
799
|
-
1. **Assertions**: `assert` vs `expect` vs `assertThat`
|
|
800
|
-
2. **Mocking**: Import patching vs interface mocking vs annotation-based
|
|
801
|
-
3. **Async**: Decorators vs keywords vs test runners
|
|
802
|
-
4. **Organization**: Mirror source vs colocate vs separate directory
|
|
803
|
-
5. **Setup/Teardown**: Fixtures vs beforeEach vs setUp vs test tables
|
|
804
|
-
|
|
805
|
-
The goal is to produce an agent that generates tests perfectly aligned with the project's testing framework, conventions, and quality standards.
|
|
230
|
+
- Project's test framework
|
|
231
|
+
- Project's mock library
|
|
232
|
+
- Realistic method/class names from codebase
|
|
233
|
+
|
|
234
|
+
### Step 5: Extract Test Commands
|
|
235
|
+
|
|
236
|
+
From package.json scripts, Makefile, or CI config:
|
|
237
|
+
- Run all tests
|
|
238
|
+
- Run single file
|
|
239
|
+
- Run with coverage
|
|
240
|
+
- Run specific test
|
|
241
|
+
|
|
242
|
+
### Step 6: Finalize Agent
|
|
243
|
+
|
|
244
|
+
- Remove all `[GENERATION INSTRUCTION]` blocks
|
|
245
|
+
- Remove this "Generation Instructions" section
|
|
246
|
+
- Replace all `[PLACEHOLDERS]` with project values
|
|
247
|
+
- Include 1-2 concrete examples per pattern
|
|
248
|
+
- **Target agent size: 100-150 lines**
|
|
249
|
+
|
|
250
|
+
### Validation
|
|
251
|
+
|
|
252
|
+
- [ ] Framework and version specified
|
|
253
|
+
- [ ] Mocking rule clearly stated with example
|
|
254
|
+
- [ ] All 5 patterns have project-specific examples
|
|
255
|
+
- [ ] Test commands are accurate
|
|
256
|
+
- [ ] No `[PLACEHOLDERS]` remain
|
|
257
|
+
- [ ] No generation instructions remain
|
|
258
|
+
- [ ] Agent under 150 lines
|