agentic-qe 3.7.8 → 3.7.9
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/.claude/skills/debug-loop/SKILL.md +1 -1
- package/.claude/skills/enterprise-integration-testing/evals/enterprise-integration-testing.yaml +158 -0
- package/.claude/skills/enterprise-integration-testing/schemas/output.json +74 -0
- package/.claude/skills/enterprise-integration-testing/scripts/validate-config.json +25 -0
- package/.claude/skills/middleware-testing-patterns/evals/middleware-testing-patterns.yaml +153 -0
- package/.claude/skills/middleware-testing-patterns/schemas/output.json +58 -0
- package/.claude/skills/middleware-testing-patterns/scripts/validate-config.json +25 -0
- package/.claude/skills/observability-testing-patterns/evals/observability-testing-patterns.yaml +157 -0
- package/.claude/skills/observability-testing-patterns/schemas/output.json +58 -0
- package/.claude/skills/observability-testing-patterns/scripts/validate-config.json +25 -0
- package/.claude/skills/pr-review/SKILL.md +1 -1
- package/.claude/skills/qcsd-cicd-swarm/evals/qcsd-cicd-swarm.yaml +211 -0
- package/.claude/skills/qcsd-cicd-swarm/schemas/output.json +86 -0
- package/.claude/skills/qcsd-cicd-swarm/scripts/validate-config.json +30 -0
- package/.claude/skills/qcsd-development-swarm/evals/qcsd-development-swarm.yaml +162 -0
- package/.claude/skills/qcsd-development-swarm/schemas/output.json +72 -0
- package/.claude/skills/qcsd-development-swarm/scripts/validate-config.json +25 -0
- package/.claude/skills/skills-manifest.json +1 -1
- package/.claude/skills/trust-tier-manifest.json +78 -7
- package/CHANGELOG.md +20 -0
- package/assets/skills/a11y-ally/SKILL.md +1664 -1658
- package/assets/skills/a11y-ally/evals/a11y-ally.yaml +376 -0
- package/assets/skills/a11y-ally/schemas/output.json +549 -0
- package/assets/skills/a11y-ally/scripts/validate-config.json +42 -0
- package/assets/skills/brutal-honesty-review/SKILL.md +5 -0
- package/assets/skills/brutal-honesty-review/schemas/output.json +291 -0
- package/assets/skills/brutal-honesty-review/scripts/validate-config.json +34 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/README.md +1 -1
- package/assets/skills/cicd-pipeline-qe-orchestrator/SKILL.md +6 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/evals/cicd-pipeline-qe-orchestrator.yaml +157 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/schemas/output.json +542 -0
- package/assets/skills/cicd-pipeline-qe-orchestrator/scripts/validate-config.json +42 -0
- package/assets/skills/debug-loop/SKILL.md +1 -1
- package/assets/skills/enterprise-integration-testing/evals/enterprise-integration-testing.yaml +158 -0
- package/assets/skills/enterprise-integration-testing/schemas/output.json +74 -0
- package/assets/skills/enterprise-integration-testing/scripts/validate-config.json +25 -0
- package/assets/skills/middleware-testing-patterns/evals/middleware-testing-patterns.yaml +153 -0
- package/assets/skills/middleware-testing-patterns/schemas/output.json +58 -0
- package/assets/skills/middleware-testing-patterns/scripts/validate-config.json +25 -0
- package/assets/skills/n8n-expression-testing/SKILL.md +6 -0
- package/assets/skills/n8n-expression-testing/evals/n8n-expression-testing.yaml +450 -0
- package/assets/skills/n8n-expression-testing/schemas/output.json +369 -0
- package/assets/skills/n8n-expression-testing/scripts/validate-config.json +39 -0
- package/assets/skills/n8n-integration-testing-patterns/SKILL.md +6 -0
- package/assets/skills/n8n-integration-testing-patterns/evals/n8n-integration-testing-patterns.yaml +522 -0
- package/assets/skills/n8n-integration-testing-patterns/schemas/output.json +291 -0
- package/assets/skills/n8n-integration-testing-patterns/scripts/validate-config.json +34 -0
- package/assets/skills/n8n-security-testing/SKILL.md +6 -0
- package/assets/skills/n8n-security-testing/evals/n8n-security-testing.yaml +493 -0
- package/assets/skills/n8n-security-testing/schemas/output.json +293 -0
- package/assets/skills/n8n-security-testing/scripts/validate-config.json +34 -0
- package/assets/skills/n8n-trigger-testing-strategies/SKILL.md +6 -0
- package/assets/skills/n8n-trigger-testing-strategies/evals/n8n-trigger-testing-strategies.yaml +500 -0
- package/assets/skills/n8n-trigger-testing-strategies/schemas/output.json +295 -0
- package/assets/skills/n8n-trigger-testing-strategies/scripts/validate-config.json +34 -0
- package/assets/skills/n8n-workflow-testing-fundamentals/SKILL.md +6 -0
- package/assets/skills/n8n-workflow-testing-fundamentals/evals/n8n-workflow-testing-fundamentals.yaml +497 -0
- package/assets/skills/n8n-workflow-testing-fundamentals/schemas/output.json +254 -0
- package/assets/skills/n8n-workflow-testing-fundamentals/scripts/validate-config.json +35 -0
- package/assets/skills/observability-testing-patterns/evals/observability-testing-patterns.yaml +157 -0
- package/assets/skills/observability-testing-patterns/schemas/output.json +58 -0
- package/assets/skills/observability-testing-patterns/scripts/validate-config.json +25 -0
- package/assets/skills/pentest-validation/scripts/validate-config.json +12 -0
- package/assets/skills/pr-review/SKILL.md +1 -1
- package/assets/skills/qcsd-cicd-swarm/evals/qcsd-cicd-swarm.yaml +211 -0
- package/assets/skills/qcsd-cicd-swarm/schemas/output.json +86 -0
- package/assets/skills/qcsd-cicd-swarm/scripts/validate-config.json +30 -0
- package/assets/skills/qcsd-development-swarm/evals/qcsd-development-swarm.yaml +162 -0
- package/assets/skills/qcsd-development-swarm/schemas/output.json +72 -0
- package/assets/skills/qcsd-development-swarm/scripts/validate-config.json +25 -0
- package/assets/skills/qcsd-ideation-swarm/evals/qcsd-ideation-swarm.yaml +138 -0
- package/assets/skills/qcsd-ideation-swarm/schemas/output.json +568 -0
- package/assets/skills/qcsd-ideation-swarm/scripts/validate-config.json +25 -0
- package/assets/skills/qcsd-production-swarm/SKILL.md +2781 -0
- package/assets/skills/qcsd-production-swarm/evals/qcsd-production-swarm.yaml +246 -0
- package/assets/skills/qcsd-production-swarm/schemas/output.json +505 -0
- package/assets/skills/qcsd-production-swarm/scripts/validate-config.json +25 -0
- package/assets/skills/qcsd-refinement-swarm/evals/qcsd-refinement-swarm.yaml +139 -0
- package/assets/skills/qcsd-refinement-swarm/schemas/output.json +811 -0
- package/assets/skills/qcsd-refinement-swarm/scripts/validate-config.json +25 -0
- package/assets/skills/security-visual-testing/scripts/validate-config.json +45 -0
- package/assets/skills/sherlock-review/SKILL.md +5 -0
- package/assets/skills/sherlock-review/schemas/output.json +297 -0
- package/assets/skills/sherlock-review/scripts/validate-config.json +35 -0
- package/assets/skills/testability-scoring/SKILL.md +5 -0
- package/assets/skills/testability-scoring/evals/testability-scoring.yaml +814 -0
- package/assets/skills/testability-scoring/schemas/output.json +606 -0
- package/assets/skills/testability-scoring/scripts/validate-config.json +42 -0
- package/assets/skills/trust-tier-manifest.json +2404 -0
- package/assets/skills/wms-testing-patterns/evals/wms-testing-patterns.yaml +165 -0
- package/assets/skills/wms-testing-patterns/schemas/output.json +150 -0
- package/assets/skills/wms-testing-patterns/scripts/validate-config.json +51 -0
- package/dist/benchmarks/performance-benchmarks.js +1 -1
- package/dist/cli/bundle.js +9130 -2283
- package/dist/cli/commands/hooks.d.ts.map +1 -1
- package/dist/cli/commands/hooks.js +92 -0
- package/dist/cli/commands/hooks.js.map +1 -1
- package/dist/cli/commands/migrate.js +2 -2
- package/dist/coordination/constants.d.ts +1 -1
- package/dist/coordination/constants.js +1 -1
- package/dist/coordination/handlers/coverage-handlers.js +1 -1
- package/dist/coordination/handlers/coverage-handlers.js.map +1 -1
- package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts +1 -1
- package/dist/domains/code-intelligence/services/semantic-analyzer.d.ts.map +1 -1
- package/dist/domains/code-intelligence/services/semantic-analyzer.js +1 -1
- package/dist/domains/code-intelligence/services/semantic-analyzer.js.map +1 -1
- package/dist/domains/coverage-analysis/coordinator.js +1 -1
- package/dist/domains/coverage-analysis/services/coverage-analyzer.js +1 -1
- package/dist/domains/coverage-analysis/services/coverage-embedder.d.ts +1 -1
- package/dist/domains/coverage-analysis/services/coverage-embedder.js +1 -1
- package/dist/domains/coverage-analysis/services/gap-detector.js +1 -1
- package/dist/domains/coverage-analysis/services/ghost-coverage-analyzer.js +1 -1
- package/dist/domains/coverage-analysis/services/hnsw-index.d.ts +2 -2
- package/dist/domains/coverage-analysis/services/hnsw-index.js +3 -3
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.d.ts +1 -1
- package/dist/domains/coverage-analysis/services/sublinear-analyzer.js +1 -1
- package/dist/domains/test-execution/services/test-prioritizer.js +1 -1
- package/dist/domains/test-generation/context/rust-context-builder.d.ts +31 -0
- package/dist/domains/test-generation/context/rust-context-builder.d.ts.map +1 -0
- package/dist/domains/test-generation/context/rust-context-builder.js +27 -0
- package/dist/domains/test-generation/context/rust-context-builder.js.map +1 -0
- package/dist/domains/test-generation/coordinator.js +3 -3
- package/dist/domains/test-generation/coordinator.js.map +1 -1
- package/dist/domains/test-generation/detectors/mobile-detector.d.ts +41 -0
- package/dist/domains/test-generation/detectors/mobile-detector.d.ts.map +1 -0
- package/dist/domains/test-generation/detectors/mobile-detector.js +111 -0
- package/dist/domains/test-generation/detectors/mobile-detector.js.map +1 -0
- package/dist/domains/test-generation/detectors/spring-detector.d.ts +22 -0
- package/dist/domains/test-generation/detectors/spring-detector.d.ts.map +1 -0
- package/dist/domains/test-generation/detectors/spring-detector.js +37 -0
- package/dist/domains/test-generation/detectors/spring-detector.js.map +1 -0
- package/dist/domains/test-generation/factories/test-generator-factory.d.ts +2 -1
- package/dist/domains/test-generation/factories/test-generator-factory.d.ts.map +1 -1
- package/dist/domains/test-generation/factories/test-generator-factory.js +33 -13
- package/dist/domains/test-generation/factories/test-generator-factory.js.map +1 -1
- package/dist/domains/test-generation/generators/flutter-test-generator.d.ts +107 -0
- package/dist/domains/test-generation/generators/flutter-test-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/generators/flutter-test-generator.js +590 -0
- package/dist/domains/test-generation/generators/flutter-test-generator.js.map +1 -0
- package/dist/domains/test-generation/generators/go-test-generator.d.ts +139 -0
- package/dist/domains/test-generation/generators/go-test-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/generators/go-test-generator.js +654 -0
- package/dist/domains/test-generation/generators/go-test-generator.js.map +1 -0
- package/dist/domains/test-generation/generators/index.d.ts +8 -0
- package/dist/domains/test-generation/generators/index.d.ts.map +1 -1
- package/dist/domains/test-generation/generators/index.js +8 -0
- package/dist/domains/test-generation/generators/index.js.map +1 -1
- package/dist/domains/test-generation/generators/jest-rn-generator.d.ts +95 -0
- package/dist/domains/test-generation/generators/jest-rn-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/generators/jest-rn-generator.js +591 -0
- package/dist/domains/test-generation/generators/jest-rn-generator.js.map +1 -0
- package/dist/domains/test-generation/generators/junit5-generator.d.ts +107 -0
- package/dist/domains/test-generation/generators/junit5-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/generators/junit5-generator.js +588 -0
- package/dist/domains/test-generation/generators/junit5-generator.js.map +1 -0
- package/dist/domains/test-generation/generators/kotlin-junit-generator.d.ts +109 -0
- package/dist/domains/test-generation/generators/kotlin-junit-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/generators/kotlin-junit-generator.js +588 -0
- package/dist/domains/test-generation/generators/kotlin-junit-generator.js.map +1 -0
- package/dist/domains/test-generation/generators/pytest-generator.d.ts +8 -1
- package/dist/domains/test-generation/generators/pytest-generator.d.ts.map +1 -1
- package/dist/domains/test-generation/generators/pytest-generator.js +57 -0
- package/dist/domains/test-generation/generators/pytest-generator.js.map +1 -1
- package/dist/domains/test-generation/generators/rust-test-generator.d.ts +80 -0
- package/dist/domains/test-generation/generators/rust-test-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/generators/rust-test-generator.js +442 -0
- package/dist/domains/test-generation/generators/rust-test-generator.js.map +1 -0
- package/dist/domains/test-generation/generators/swift-testing-generator.d.ts +97 -0
- package/dist/domains/test-generation/generators/swift-testing-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/generators/swift-testing-generator.js +482 -0
- package/dist/domains/test-generation/generators/swift-testing-generator.js.map +1 -0
- package/dist/domains/test-generation/generators/xunit-generator.d.ts +110 -0
- package/dist/domains/test-generation/generators/xunit-generator.d.ts.map +1 -0
- package/dist/domains/test-generation/generators/xunit-generator.js +611 -0
- package/dist/domains/test-generation/generators/xunit-generator.js.map +1 -0
- package/dist/domains/test-generation/interfaces.d.ts +11 -2
- package/dist/domains/test-generation/interfaces.d.ts.map +1 -1
- package/dist/domains/test-generation/prompts/language-prompts.d.ts +29 -0
- package/dist/domains/test-generation/prompts/language-prompts.d.ts.map +1 -0
- package/dist/domains/test-generation/prompts/language-prompts.js +135 -0
- package/dist/domains/test-generation/prompts/language-prompts.js.map +1 -0
- package/dist/domains/test-generation/services/compilation-validator.d.ts +43 -0
- package/dist/domains/test-generation/services/compilation-validator.d.ts.map +1 -0
- package/dist/domains/test-generation/services/compilation-validator.js +134 -0
- package/dist/domains/test-generation/services/compilation-validator.js.map +1 -0
- package/dist/domains/test-generation/services/index.d.ts +2 -1
- package/dist/domains/test-generation/services/index.d.ts.map +1 -1
- package/dist/domains/test-generation/services/index.js +3 -1
- package/dist/domains/test-generation/services/index.js.map +1 -1
- package/dist/domains/test-generation/services/test-file-resolver.d.ts +32 -0
- package/dist/domains/test-generation/services/test-file-resolver.d.ts.map +1 -0
- package/dist/domains/test-generation/services/test-file-resolver.js +159 -0
- package/dist/domains/test-generation/services/test-file-resolver.js.map +1 -0
- package/dist/domains/test-generation/services/test-generator.d.ts +10 -0
- package/dist/domains/test-generation/services/test-generator.d.ts.map +1 -1
- package/dist/domains/test-generation/services/test-generator.js +87 -10
- package/dist/domains/test-generation/services/test-generator.js.map +1 -1
- package/dist/governance/feature-flags.js +2 -2
- package/dist/governance/feature-flags.js.map +1 -1
- package/dist/governance/shard-embeddings.js +1 -1
- package/dist/init/init-wizard-hooks.d.ts.map +1 -1
- package/dist/init/init-wizard-hooks.js +0 -1
- package/dist/init/init-wizard-hooks.js.map +1 -1
- package/dist/init/phases/07-hooks.d.ts.map +1 -1
- package/dist/init/phases/07-hooks.js +0 -2
- package/dist/init/phases/07-hooks.js.map +1 -1
- package/dist/init/phases/08-mcp.d.ts +8 -4
- package/dist/init/phases/08-mcp.d.ts.map +1 -1
- package/dist/init/phases/08-mcp.js +13 -31
- package/dist/init/phases/08-mcp.js.map +1 -1
- package/dist/init/phases/10-workers.js +2 -2
- package/dist/init/phases/10-workers.js.map +1 -1
- package/dist/init/settings-merge.d.ts.map +1 -1
- package/dist/init/settings-merge.js +0 -2
- package/dist/init/settings-merge.js.map +1 -1
- package/dist/init/token-bootstrap.js +1 -1
- package/dist/init/token-bootstrap.js.map +1 -1
- package/dist/integrations/rl-suite/algorithms/decision-transformer.js +1 -1
- package/dist/kernel/constants.d.ts +2 -2
- package/dist/kernel/constants.js +2 -2
- package/dist/kernel/hnsw-adapter.js +1 -1
- package/dist/kernel/progressive-hnsw-backend.d.ts +2 -2
- package/dist/kernel/progressive-hnsw-backend.js +2 -2
- package/dist/learning/dream/concept-graph.d.ts +1 -1
- package/dist/learning/dream/concept-graph.js +1 -1
- package/dist/learning/dream/dream-engine.d.ts +1 -1
- package/dist/learning/dream/dream-engine.js +1 -1
- package/dist/learning/dream/index.d.ts +1 -1
- package/dist/learning/dream/index.js +1 -1
- package/dist/learning/dream/types.d.ts +1 -1
- package/dist/learning/dream/types.d.ts.map +1 -1
- package/dist/learning/dream/types.js +1 -1
- package/dist/learning/dream/types.js.map +1 -1
- package/dist/learning/token-tracker.js +1 -1
- package/dist/learning/token-tracker.js.map +1 -1
- package/dist/mcp/bundle.js +7515 -893
- package/dist/routing/qe-agent-registry.js +4 -4
- package/dist/routing/qe-agent-registry.js.map +1 -1
- package/dist/routing/types.d.ts +5 -8
- package/dist/routing/types.d.ts.map +1 -1
- package/dist/routing/types.js.map +1 -1
- package/dist/shared/embeddings/embedding-cache.js +2 -2
- package/dist/shared/embeddings/index.d.ts +2 -2
- package/dist/shared/embeddings/index.js +2 -2
- package/dist/shared/embeddings/nomic-embedder.d.ts +4 -4
- package/dist/shared/embeddings/nomic-embedder.js +2 -2
- package/dist/shared/embeddings/ollama-client.d.ts +1 -1
- package/dist/shared/embeddings/ollama-client.js +2 -2
- package/dist/shared/embeddings/ollama-client.js.map +1 -1
- package/dist/shared/embeddings/types.d.ts +2 -2
- package/dist/shared/embeddings/types.js +2 -2
- package/dist/shared/language-detector.d.ts +46 -0
- package/dist/shared/language-detector.d.ts.map +1 -0
- package/dist/shared/language-detector.js +183 -0
- package/dist/shared/language-detector.js.map +1 -0
- package/dist/shared/llm/providers/ollama.js +1 -1
- package/dist/shared/metrics/code-metrics.d.ts.map +1 -1
- package/dist/shared/metrics/code-metrics.js +24 -1
- package/dist/shared/metrics/code-metrics.js.map +1 -1
- package/dist/shared/parsers/index.d.ts +2 -0
- package/dist/shared/parsers/index.d.ts.map +1 -1
- package/dist/shared/parsers/index.js +2 -0
- package/dist/shared/parsers/index.js.map +1 -1
- package/dist/shared/parsers/interfaces.d.ts +81 -0
- package/dist/shared/parsers/interfaces.d.ts.map +1 -0
- package/dist/shared/parsers/interfaces.js +6 -0
- package/dist/shared/parsers/interfaces.js.map +1 -0
- package/dist/shared/parsers/multi-language-parser.d.ts +144 -0
- package/dist/shared/parsers/multi-language-parser.d.ts.map +1 -0
- package/dist/shared/parsers/multi-language-parser.js +1232 -0
- package/dist/shared/parsers/multi-language-parser.js.map +1 -0
- package/dist/shared/parsers/rust-ownership-analyzer.d.ts +45 -0
- package/dist/shared/parsers/rust-ownership-analyzer.d.ts.map +1 -0
- package/dist/shared/parsers/rust-ownership-analyzer.js +52 -0
- package/dist/shared/parsers/rust-ownership-analyzer.js.map +1 -0
- package/dist/shared/parsers/typescript-parser.d.ts +16 -0
- package/dist/shared/parsers/typescript-parser.d.ts.map +1 -1
- package/dist/shared/parsers/typescript-parser.js +85 -0
- package/dist/shared/parsers/typescript-parser.js.map +1 -1
- package/dist/shared/types/test-frameworks.d.ts +25 -0
- package/dist/shared/types/test-frameworks.d.ts.map +1 -0
- package/dist/shared/types/test-frameworks.js +111 -0
- package/dist/shared/types/test-frameworks.js.map +1 -0
- package/package.json +1 -1
- package/scripts/prepare-assets.sh +8 -2
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agentic QE v3 - Go Test Generator
|
|
3
|
+
* Strategy implementation for Go's testing package
|
|
4
|
+
*
|
|
5
|
+
* Generates test code using:
|
|
6
|
+
* - Table-driven tests (idiomatic Go)
|
|
7
|
+
* - testing.T and testing.B
|
|
8
|
+
* - github.com/stretchr/testify/assert
|
|
9
|
+
* - Mock structs implementing interfaces
|
|
10
|
+
* - context.Context as first parameter
|
|
11
|
+
* - (value, error) return pattern
|
|
12
|
+
* - t.Helper() for test helpers
|
|
13
|
+
* - _test.go file naming convention
|
|
14
|
+
*
|
|
15
|
+
* @module test-generation/generators
|
|
16
|
+
*/
|
|
17
|
+
import { faker } from '@faker-js/faker';
|
|
18
|
+
import { BaseTestGenerator } from './base-test-generator';
|
|
19
|
+
/**
|
|
20
|
+
* GoTestGenerator - Test generator for Go's testing package
|
|
21
|
+
*
|
|
22
|
+
* Generates idiomatic Go test code with:
|
|
23
|
+
* - Table-driven tests using anonymous struct slices
|
|
24
|
+
* - testify/assert for assertions
|
|
25
|
+
* - Mock structs for interface dependencies
|
|
26
|
+
* - Proper (value, error) return handling
|
|
27
|
+
* - context.Context propagation
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* ```typescript
|
|
31
|
+
* const generator = new GoTestGenerator();
|
|
32
|
+
* const testCode = generator.generateTests({
|
|
33
|
+
* moduleName: 'user_service',
|
|
34
|
+
* importPath: 'github.com/myorg/myapp/services',
|
|
35
|
+
* testType: 'unit',
|
|
36
|
+
* patterns: [],
|
|
37
|
+
* analysis: { functions: [...], classes: [...] }
|
|
38
|
+
* });
|
|
39
|
+
* ```
|
|
40
|
+
*/
|
|
41
|
+
export class GoTestGenerator extends BaseTestGenerator {
|
|
42
|
+
framework = 'go-test';
|
|
43
|
+
/**
|
|
44
|
+
* Convert ParsedFile from multi-language parser to CodeAnalysis.
|
|
45
|
+
* Maps universal parser types to the legacy IFunctionInfo/IClassInfo shape
|
|
46
|
+
* used by generateTests().
|
|
47
|
+
*/
|
|
48
|
+
static convertParsedFile(parsed) {
|
|
49
|
+
return {
|
|
50
|
+
functions: parsed.functions.map(f => ({
|
|
51
|
+
name: f.name,
|
|
52
|
+
parameters: f.parameters.map(p => ({
|
|
53
|
+
name: p.name,
|
|
54
|
+
type: p.type,
|
|
55
|
+
optional: p.isOptional,
|
|
56
|
+
defaultValue: p.defaultValue,
|
|
57
|
+
})),
|
|
58
|
+
returnType: f.returnType,
|
|
59
|
+
isAsync: f.isAsync,
|
|
60
|
+
isExported: f.isPublic,
|
|
61
|
+
complexity: f.complexity,
|
|
62
|
+
startLine: f.startLine,
|
|
63
|
+
endLine: f.endLine,
|
|
64
|
+
body: f.body,
|
|
65
|
+
})),
|
|
66
|
+
classes: parsed.classes.map(c => ({
|
|
67
|
+
name: c.name,
|
|
68
|
+
methods: c.methods.map(m => ({
|
|
69
|
+
name: m.name,
|
|
70
|
+
parameters: m.parameters.map(p => ({
|
|
71
|
+
name: p.name,
|
|
72
|
+
type: p.type,
|
|
73
|
+
optional: p.isOptional,
|
|
74
|
+
defaultValue: p.defaultValue,
|
|
75
|
+
})),
|
|
76
|
+
returnType: m.returnType,
|
|
77
|
+
isAsync: m.isAsync,
|
|
78
|
+
isExported: m.isPublic,
|
|
79
|
+
complexity: m.complexity,
|
|
80
|
+
startLine: m.startLine,
|
|
81
|
+
endLine: m.endLine,
|
|
82
|
+
})),
|
|
83
|
+
properties: c.properties.map(p => ({
|
|
84
|
+
name: p.name,
|
|
85
|
+
type: p.type,
|
|
86
|
+
isPrivate: !p.isPublic,
|
|
87
|
+
isReadonly: p.isReadonly,
|
|
88
|
+
})),
|
|
89
|
+
isExported: c.isPublic,
|
|
90
|
+
hasConstructor: c.methods.some(m => m.name === 'New' || m.name === 'Init'),
|
|
91
|
+
constructorParams: c.methods.find(m => m.name === 'New' || m.name === 'Init')?.parameters.map(p => ({
|
|
92
|
+
name: p.name,
|
|
93
|
+
type: p.type,
|
|
94
|
+
optional: p.isOptional,
|
|
95
|
+
defaultValue: p.defaultValue,
|
|
96
|
+
})),
|
|
97
|
+
})),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Generate complete test file from analysis
|
|
102
|
+
*/
|
|
103
|
+
generateTests(context) {
|
|
104
|
+
const { moduleName, importPath, testType, patterns, analysis, dependencies } = context;
|
|
105
|
+
if (!analysis || (analysis.functions.length === 0 && analysis.classes.length === 0)) {
|
|
106
|
+
return this.generateStubTests(context);
|
|
107
|
+
}
|
|
108
|
+
const patternComment = this.generateGoPatternComment(patterns);
|
|
109
|
+
const packageName = this.extractPackageName(moduleName);
|
|
110
|
+
// Collect imports needed
|
|
111
|
+
const imports = ['"testing"'];
|
|
112
|
+
const needsAssert = analysis.functions.length > 0 || analysis.classes.some(c => c.methods.length > 0);
|
|
113
|
+
if (needsAssert) {
|
|
114
|
+
imports.push('"github.com/stretchr/testify/assert"');
|
|
115
|
+
}
|
|
116
|
+
// Check if any function uses context.Context
|
|
117
|
+
const needsContext = this.analysisNeedsContext(analysis);
|
|
118
|
+
if (needsContext) {
|
|
119
|
+
imports.push('"context"');
|
|
120
|
+
}
|
|
121
|
+
// Add the module import if importPath is provided and non-empty
|
|
122
|
+
if (importPath && importPath !== moduleName) {
|
|
123
|
+
imports.push(`"${importPath}"`);
|
|
124
|
+
}
|
|
125
|
+
// KG: Add mock imports for external dependencies
|
|
126
|
+
const externalDeps = dependencies?.imports.filter(dep => !dep.startsWith('.')) || [];
|
|
127
|
+
for (const dep of externalDeps.slice(0, 5)) {
|
|
128
|
+
imports.push(`"${dep}"`);
|
|
129
|
+
}
|
|
130
|
+
let code = `${patternComment}package ${packageName}_test
|
|
131
|
+
|
|
132
|
+
import (
|
|
133
|
+
${imports.map(i => `\t${i}`).join('\n')}
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
`;
|
|
137
|
+
// Generate tests for exported functions
|
|
138
|
+
const exportedFns = analysis.functions.filter(fn => fn.isExported);
|
|
139
|
+
for (const fn of exportedFns) {
|
|
140
|
+
code += this.generateFunctionTests(fn, testType);
|
|
141
|
+
code += '\n';
|
|
142
|
+
}
|
|
143
|
+
// Generate tests for exported structs/classes
|
|
144
|
+
const exportedClasses = analysis.classes.filter(cls => cls.isExported);
|
|
145
|
+
for (const cls of exportedClasses) {
|
|
146
|
+
code += this.generateClassTests(cls, testType);
|
|
147
|
+
code += '\n';
|
|
148
|
+
}
|
|
149
|
+
return code;
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Generate table-driven tests for a standalone function
|
|
153
|
+
*/
|
|
154
|
+
generateFunctionTests(fn, _testType) {
|
|
155
|
+
const hasError = this.returnIncludesError(fn.returnType);
|
|
156
|
+
const hasContext = this.paramHasContext(fn.parameters);
|
|
157
|
+
const testName = `Test${this.pascalCase(fn.name)}`;
|
|
158
|
+
// Build table-driven test struct fields
|
|
159
|
+
const structFields = this.buildStructFields(fn, hasError);
|
|
160
|
+
const testCases = this.buildTestCases(fn, hasError);
|
|
161
|
+
const functionCall = this.buildFunctionCall(fn, hasContext);
|
|
162
|
+
const assertions = this.buildAssertions(fn, hasError);
|
|
163
|
+
let code = `func ${testName}(t *testing.T) {\n`;
|
|
164
|
+
code += `\ttests := []struct {\n`;
|
|
165
|
+
code += `\t\tname string\n`;
|
|
166
|
+
code += structFields;
|
|
167
|
+
code += `\t}{\n`;
|
|
168
|
+
code += testCases;
|
|
169
|
+
code += `\t}\n`;
|
|
170
|
+
code += `\tfor _, tt := range tests {\n`;
|
|
171
|
+
code += `\t\tt.Run(tt.name, func(t *testing.T) {\n`;
|
|
172
|
+
code += functionCall;
|
|
173
|
+
code += assertions;
|
|
174
|
+
code += `\t\t})\n`;
|
|
175
|
+
code += `\t}\n`;
|
|
176
|
+
code += `}\n`;
|
|
177
|
+
return code;
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Generate tests for a struct (class) and its methods
|
|
181
|
+
*/
|
|
182
|
+
generateClassTests(cls, _testType) {
|
|
183
|
+
let code = '';
|
|
184
|
+
// Generate a constructor/instantiation test if applicable
|
|
185
|
+
const constructorArgs = cls.constructorParams?.map(p => this.generateGoTestValue(p)).join(', ') || '';
|
|
186
|
+
code += `func TestNew${cls.name}(t *testing.T) {\n`;
|
|
187
|
+
if (cls.hasConstructor) {
|
|
188
|
+
code += `\tsvc := New${cls.name}(${constructorArgs})\n`;
|
|
189
|
+
}
|
|
190
|
+
else {
|
|
191
|
+
code += `\tsvc := &${cls.name}{}\n`;
|
|
192
|
+
}
|
|
193
|
+
code += `\tassert.NotNil(t, svc)\n`;
|
|
194
|
+
code += `}\n\n`;
|
|
195
|
+
// Generate table-driven tests for each public method
|
|
196
|
+
for (const method of cls.methods) {
|
|
197
|
+
// In Go, exported methods start with uppercase
|
|
198
|
+
if (method.name.startsWith('_') || /^[a-z]/.test(method.name)) {
|
|
199
|
+
continue;
|
|
200
|
+
}
|
|
201
|
+
const hasError = this.returnIncludesError(method.returnType);
|
|
202
|
+
const hasContext = this.paramHasContext(method.parameters);
|
|
203
|
+
const testName = `Test${cls.name}_${method.name}`;
|
|
204
|
+
const structFields = this.buildStructFields(method, hasError);
|
|
205
|
+
const testCases = this.buildTestCases(method, hasError);
|
|
206
|
+
code += `func ${testName}(t *testing.T) {\n`;
|
|
207
|
+
// Setup the struct instance
|
|
208
|
+
if (cls.hasConstructor) {
|
|
209
|
+
code += `\tsvc := New${cls.name}(${constructorArgs})\n\n`;
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
code += `\tsvc := &${cls.name}{}\n\n`;
|
|
213
|
+
}
|
|
214
|
+
code += `\ttests := []struct {\n`;
|
|
215
|
+
code += `\t\tname string\n`;
|
|
216
|
+
code += structFields;
|
|
217
|
+
code += `\t}{\n`;
|
|
218
|
+
code += testCases;
|
|
219
|
+
code += `\t}\n`;
|
|
220
|
+
code += `\tfor _, tt := range tests {\n`;
|
|
221
|
+
code += `\t\tt.Run(tt.name, func(t *testing.T) {\n`;
|
|
222
|
+
// Build method call
|
|
223
|
+
const callArgs = this.buildCallArgs(method.parameters, hasContext);
|
|
224
|
+
if (hasError) {
|
|
225
|
+
code += `\t\t\tgot, err := svc.${method.name}(${callArgs})\n`;
|
|
226
|
+
code += `\t\t\tif tt.wantErr {\n`;
|
|
227
|
+
code += `\t\t\t\tassert.Error(t, err)\n`;
|
|
228
|
+
code += `\t\t\t\treturn\n`;
|
|
229
|
+
code += `\t\t\t}\n`;
|
|
230
|
+
code += `\t\t\tassert.NoError(t, err)\n`;
|
|
231
|
+
code += `\t\t\tassert.Equal(t, tt.want, got)\n`;
|
|
232
|
+
}
|
|
233
|
+
else {
|
|
234
|
+
code += `\t\t\tgot := svc.${method.name}(${callArgs})\n`;
|
|
235
|
+
code += `\t\t\tassert.Equal(t, tt.want, got)\n`;
|
|
236
|
+
}
|
|
237
|
+
code += `\t\t})\n`;
|
|
238
|
+
code += `\t}\n`;
|
|
239
|
+
code += `}\n\n`;
|
|
240
|
+
}
|
|
241
|
+
return code;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Generate stub tests when no AST analysis is available
|
|
245
|
+
*/
|
|
246
|
+
generateStubTests(context) {
|
|
247
|
+
const { moduleName, importPath, testType, patterns, dependencies, similarCode } = context;
|
|
248
|
+
const patternComment = this.generateGoPatternComment(patterns);
|
|
249
|
+
const packageName = this.extractPackageName(moduleName);
|
|
250
|
+
// KG: Generate similarity-informed test hints
|
|
251
|
+
let similarityComment = '';
|
|
252
|
+
if (similarCode && similarCode.snippets.length > 0) {
|
|
253
|
+
similarityComment = `// KG: Similar modules found - consider testing shared patterns:\n`;
|
|
254
|
+
for (const s of similarCode.snippets.slice(0, 3)) {
|
|
255
|
+
similarityComment += `// - ${s.file} (${(s.score * 100).toFixed(0)}% similar)\n`;
|
|
256
|
+
}
|
|
257
|
+
similarityComment += `\n`;
|
|
258
|
+
}
|
|
259
|
+
// KG: dependency test hints
|
|
260
|
+
let depComment = '';
|
|
261
|
+
if (dependencies && dependencies.imports.length > 0) {
|
|
262
|
+
depComment += `// KG: Module depends on: ${dependencies.imports.slice(0, 5).join(', ')}\n`;
|
|
263
|
+
}
|
|
264
|
+
if (dependencies && dependencies.importedBy.length > 0) {
|
|
265
|
+
depComment += `// KG: Used by ${dependencies.importedBy.length} consumers\n`;
|
|
266
|
+
}
|
|
267
|
+
return `${patternComment}package ${packageName}_test
|
|
268
|
+
|
|
269
|
+
import (
|
|
270
|
+
\t"testing"
|
|
271
|
+
|
|
272
|
+
\t"github.com/stretchr/testify/assert"
|
|
273
|
+
${importPath ? `\t"${importPath}"` : ''}
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
${similarityComment}${depComment}
|
|
277
|
+
func TestModule_IsDefined(t *testing.T) {
|
|
278
|
+
\t// ${testType} test: Verify the module is properly accessible
|
|
279
|
+
\tassert.NotNil(t, ${moduleName})
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
func TestModule_BasicOperations(t *testing.T) {
|
|
283
|
+
\t// ${testType} test: Verify core functionality
|
|
284
|
+
\t// TODO: Add specific test cases based on module API
|
|
285
|
+
\tassert.True(t, true, "placeholder - replace with real assertions")
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
func TestModule_ErrorHandling(t *testing.T) {
|
|
289
|
+
\t// ${testType} test: Verify error conditions are handled
|
|
290
|
+
\t// TODO: Add error case testing
|
|
291
|
+
\tassert.True(t, true, "placeholder - replace with real assertions")
|
|
292
|
+
}
|
|
293
|
+
`;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* Generate coverage-focused tests for specific lines
|
|
297
|
+
*/
|
|
298
|
+
generateCoverageTests(moduleName, importPath, lines) {
|
|
299
|
+
const funcName = this.pascalCase(moduleName);
|
|
300
|
+
const lineRange = this.formatLineRange(lines);
|
|
301
|
+
const packageName = this.extractPackageName(moduleName);
|
|
302
|
+
return `package ${packageName}_test
|
|
303
|
+
|
|
304
|
+
import (
|
|
305
|
+
\t"testing"
|
|
306
|
+
|
|
307
|
+
\t"github.com/stretchr/testify/assert"
|
|
308
|
+
${importPath ? `\t"${importPath}"` : ''}
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
// Coverage test for ${lineRange} in ${moduleName}
|
|
312
|
+
func Test${funcName}_Cover_${lines[0]}_${lines[lines.length - 1]}(t *testing.T) {
|
|
313
|
+
\t// Arrange: Set up test inputs to reach uncovered lines (${lineRange})
|
|
314
|
+
\t// TODO: Replace with appropriate input values
|
|
315
|
+
|
|
316
|
+
\t// Act: Execute the code path
|
|
317
|
+
\tresult, err := ${funcName}(/* TODO: add args */)
|
|
318
|
+
|
|
319
|
+
\t// Assert: Verify expected behavior
|
|
320
|
+
\tassert.NoError(t, err)
|
|
321
|
+
\tassert.NotNil(t, result)
|
|
322
|
+
}
|
|
323
|
+
`;
|
|
324
|
+
}
|
|
325
|
+
// ============================================================================
|
|
326
|
+
// Go-Specific Helpers
|
|
327
|
+
// ============================================================================
|
|
328
|
+
/**
|
|
329
|
+
* Generate Go pattern comment
|
|
330
|
+
*/
|
|
331
|
+
generateGoPatternComment(patterns) {
|
|
332
|
+
if (patterns.length === 0)
|
|
333
|
+
return '';
|
|
334
|
+
return `// Applied patterns: ${patterns.map(p => p.name).join(', ')}\n`;
|
|
335
|
+
}
|
|
336
|
+
/**
|
|
337
|
+
* Extract package name from module name (last segment, lowercase)
|
|
338
|
+
*/
|
|
339
|
+
extractPackageName(moduleName) {
|
|
340
|
+
const parts = moduleName.split('/');
|
|
341
|
+
const last = parts[parts.length - 1];
|
|
342
|
+
// Convert camelCase/PascalCase to snake_case-style lowercase
|
|
343
|
+
return last.replace(/([a-z])([A-Z])/g, '$1_$2').toLowerCase().replace(/[^a-z0-9_]/g, '');
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Check if any function/method in the analysis uses context.Context
|
|
347
|
+
*/
|
|
348
|
+
analysisNeedsContext(analysis) {
|
|
349
|
+
const allFns = [
|
|
350
|
+
...analysis.functions,
|
|
351
|
+
...analysis.classes.flatMap(c => c.methods),
|
|
352
|
+
];
|
|
353
|
+
return allFns.some(fn => this.paramHasContext(fn.parameters));
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Check if a parameter list includes context.Context
|
|
357
|
+
*/
|
|
358
|
+
paramHasContext(params) {
|
|
359
|
+
return params.some(p => p.type?.includes('context.Context') || p.type?.includes('Context') || p.name === 'ctx');
|
|
360
|
+
}
|
|
361
|
+
/**
|
|
362
|
+
* Check if return type includes error
|
|
363
|
+
*/
|
|
364
|
+
returnIncludesError(returnType) {
|
|
365
|
+
if (!returnType)
|
|
366
|
+
return false;
|
|
367
|
+
const rt = returnType.toLowerCase();
|
|
368
|
+
return rt.includes('error') || rt.includes(', error') || rt.includes(',error');
|
|
369
|
+
}
|
|
370
|
+
/**
|
|
371
|
+
* Build struct fields for table-driven test
|
|
372
|
+
*/
|
|
373
|
+
buildStructFields(fn, hasError) {
|
|
374
|
+
let fields = '';
|
|
375
|
+
// Add fields for each non-context parameter
|
|
376
|
+
for (const param of fn.parameters) {
|
|
377
|
+
if (this.isContextParam(param))
|
|
378
|
+
continue;
|
|
379
|
+
const goType = this.mapToGoType(param.type);
|
|
380
|
+
fields += `\t\t${param.name} ${goType}\n`;
|
|
381
|
+
}
|
|
382
|
+
// Add want and wantErr fields
|
|
383
|
+
if (fn.returnType && fn.returnType !== 'void') {
|
|
384
|
+
const returnGoType = this.mapReturnToGoType(fn.returnType, hasError);
|
|
385
|
+
fields += `\t\twant ${returnGoType}\n`;
|
|
386
|
+
}
|
|
387
|
+
if (hasError) {
|
|
388
|
+
fields += `\t\twantErr bool\n`;
|
|
389
|
+
}
|
|
390
|
+
return fields;
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Build test case entries for table-driven test
|
|
394
|
+
*/
|
|
395
|
+
buildTestCases(fn, hasError) {
|
|
396
|
+
const nonCtxParams = fn.parameters.filter(p => !this.isContextParam(p));
|
|
397
|
+
let cases = '';
|
|
398
|
+
// Happy path case
|
|
399
|
+
const happyArgs = nonCtxParams.map(p => `${p.name}: ${this.generateGoTestValue(p)}`).join(', ');
|
|
400
|
+
const happyWant = this.generateGoWantValue(fn.returnType, hasError);
|
|
401
|
+
cases += `\t\t{name: "valid input", ${happyArgs}${happyWant}},\n`;
|
|
402
|
+
// Edge case: zero/empty values
|
|
403
|
+
if (nonCtxParams.length > 0) {
|
|
404
|
+
const edgeArgs = nonCtxParams.map(p => `${p.name}: ${this.generateGoZeroValue(p)}`).join(', ');
|
|
405
|
+
if (hasError) {
|
|
406
|
+
cases += `\t\t{name: "zero values", ${edgeArgs}, wantErr: true},\n`;
|
|
407
|
+
}
|
|
408
|
+
else {
|
|
409
|
+
const zeroWant = this.generateGoWantValue(fn.returnType, false);
|
|
410
|
+
cases += `\t\t{name: "zero values", ${edgeArgs}${zeroWant}},\n`;
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
// Error case with invalid input
|
|
414
|
+
if (hasError && nonCtxParams.length > 0) {
|
|
415
|
+
const invalidArgs = nonCtxParams.map(p => `${p.name}: ${this.generateGoInvalidValue(p)}`).join(', ');
|
|
416
|
+
cases += `\t\t{name: "invalid input", ${invalidArgs}, wantErr: true},\n`;
|
|
417
|
+
}
|
|
418
|
+
return cases;
|
|
419
|
+
}
|
|
420
|
+
/**
|
|
421
|
+
* Build function call for table-driven test body
|
|
422
|
+
*/
|
|
423
|
+
buildFunctionCall(fn, hasContext) {
|
|
424
|
+
const hasError = this.returnIncludesError(fn.returnType);
|
|
425
|
+
const callArgs = this.buildCallArgs(fn.parameters, hasContext);
|
|
426
|
+
let code = '';
|
|
427
|
+
if (hasError) {
|
|
428
|
+
code += `\t\t\tgot, err := ${fn.name}(${callArgs})\n`;
|
|
429
|
+
code += `\t\t\tif tt.wantErr {\n`;
|
|
430
|
+
code += `\t\t\t\tassert.Error(t, err)\n`;
|
|
431
|
+
code += `\t\t\t\treturn\n`;
|
|
432
|
+
code += `\t\t\t}\n`;
|
|
433
|
+
code += `\t\t\tassert.NoError(t, err)\n`;
|
|
434
|
+
}
|
|
435
|
+
else if (fn.returnType && fn.returnType !== 'void') {
|
|
436
|
+
code += `\t\t\tgot := ${fn.name}(${callArgs})\n`;
|
|
437
|
+
}
|
|
438
|
+
else {
|
|
439
|
+
code += `\t\t\t${fn.name}(${callArgs})\n`;
|
|
440
|
+
}
|
|
441
|
+
return code;
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* Build assertions for table-driven test body
|
|
445
|
+
*/
|
|
446
|
+
buildAssertions(fn, hasError) {
|
|
447
|
+
if (!fn.returnType || fn.returnType === 'void') {
|
|
448
|
+
return `\t\t\t// void function - no return value to assert\n`;
|
|
449
|
+
}
|
|
450
|
+
let code = '';
|
|
451
|
+
if (!hasError) {
|
|
452
|
+
code += `\t\t\tassert.Equal(t, tt.want, got)\n`;
|
|
453
|
+
}
|
|
454
|
+
else {
|
|
455
|
+
// Error assertions are already in buildFunctionCall
|
|
456
|
+
code += `\t\t\tassert.Equal(t, tt.want, got)\n`;
|
|
457
|
+
}
|
|
458
|
+
return code;
|
|
459
|
+
}
|
|
460
|
+
/**
|
|
461
|
+
* Build the argument list for a function call inside a table-driven test
|
|
462
|
+
*/
|
|
463
|
+
buildCallArgs(params, hasContext) {
|
|
464
|
+
const args = [];
|
|
465
|
+
for (const param of params) {
|
|
466
|
+
if (this.isContextParam(param)) {
|
|
467
|
+
args.push('context.Background()');
|
|
468
|
+
}
|
|
469
|
+
else {
|
|
470
|
+
args.push(`tt.${param.name}`);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
// If the function expects context but it was not in the param list explicitly
|
|
474
|
+
if (hasContext && args.length === 0) {
|
|
475
|
+
args.unshift('context.Background()');
|
|
476
|
+
}
|
|
477
|
+
return args.join(', ');
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Check if a parameter is a context.Context parameter
|
|
481
|
+
*/
|
|
482
|
+
isContextParam(param) {
|
|
483
|
+
return param.name === 'ctx' ||
|
|
484
|
+
param.type?.includes('context.Context') === true ||
|
|
485
|
+
param.type?.includes('Context') === true;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Generate a Go test value for a parameter
|
|
489
|
+
*/
|
|
490
|
+
generateGoTestValue(param) {
|
|
491
|
+
if (param.defaultValue) {
|
|
492
|
+
return param.defaultValue;
|
|
493
|
+
}
|
|
494
|
+
const type = param.type?.toLowerCase() || 'unknown';
|
|
495
|
+
const name = param.name.toLowerCase();
|
|
496
|
+
// Infer from param name
|
|
497
|
+
if (name.includes('id') && !name.includes('valid')) {
|
|
498
|
+
if (type.includes('int'))
|
|
499
|
+
return String(faker.number.int({ min: 1, max: 1000 }));
|
|
500
|
+
return `"${faker.string.uuid()}"`;
|
|
501
|
+
}
|
|
502
|
+
if (name.includes('name'))
|
|
503
|
+
return `"${faker.person.fullName()}"`;
|
|
504
|
+
if (name.includes('email'))
|
|
505
|
+
return `"${faker.internet.email()}"`;
|
|
506
|
+
if (name.includes('url'))
|
|
507
|
+
return `"${faker.internet.url()}"`;
|
|
508
|
+
// Infer from type
|
|
509
|
+
if (type.includes('string') || type === 'str')
|
|
510
|
+
return `"${faker.lorem.word()}"`;
|
|
511
|
+
if (type.includes('int64'))
|
|
512
|
+
return `int64(${faker.number.int({ min: 1, max: 100 })})`;
|
|
513
|
+
if (type.includes('int32'))
|
|
514
|
+
return `int32(${faker.number.int({ min: 1, max: 100 })})`;
|
|
515
|
+
if (type.includes('int'))
|
|
516
|
+
return String(faker.number.int({ min: 1, max: 100 }));
|
|
517
|
+
if (type.includes('float64'))
|
|
518
|
+
return `${faker.number.float({ min: 1, max: 100, fractionDigits: 2 })}`;
|
|
519
|
+
if (type.includes('float32'))
|
|
520
|
+
return `float32(${faker.number.float({ min: 1, max: 100, fractionDigits: 2 })})`;
|
|
521
|
+
if (type.includes('bool'))
|
|
522
|
+
return 'true';
|
|
523
|
+
if (type.includes('[]byte'))
|
|
524
|
+
return '[]byte("test data")';
|
|
525
|
+
if (type.includes('[]'))
|
|
526
|
+
return 'nil';
|
|
527
|
+
if (type.includes('map'))
|
|
528
|
+
return 'nil';
|
|
529
|
+
if (type.includes('*'))
|
|
530
|
+
return 'nil';
|
|
531
|
+
if (type.includes('error'))
|
|
532
|
+
return 'nil';
|
|
533
|
+
return `nil /* TODO: provide ${param.name}: ${param.type || 'unknown'} */`;
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Generate a Go zero value for boundary testing
|
|
537
|
+
*/
|
|
538
|
+
generateGoZeroValue(param) {
|
|
539
|
+
const type = param.type?.toLowerCase() || 'unknown';
|
|
540
|
+
if (type.includes('string') || type === 'str')
|
|
541
|
+
return '""';
|
|
542
|
+
if (type.includes('int'))
|
|
543
|
+
return '0';
|
|
544
|
+
if (type.includes('float'))
|
|
545
|
+
return '0.0';
|
|
546
|
+
if (type.includes('bool'))
|
|
547
|
+
return 'false';
|
|
548
|
+
if (type.includes('[]') || type.includes('map') || type.includes('*'))
|
|
549
|
+
return 'nil';
|
|
550
|
+
return 'nil';
|
|
551
|
+
}
|
|
552
|
+
/**
|
|
553
|
+
* Generate a Go invalid value for error testing
|
|
554
|
+
*/
|
|
555
|
+
generateGoInvalidValue(param) {
|
|
556
|
+
const type = param.type?.toLowerCase() || 'unknown';
|
|
557
|
+
const name = param.name.toLowerCase();
|
|
558
|
+
if (name.includes('id') && type.includes('int'))
|
|
559
|
+
return '-1';
|
|
560
|
+
if (type.includes('string') || type === 'str')
|
|
561
|
+
return '""';
|
|
562
|
+
if (type.includes('int'))
|
|
563
|
+
return '-1';
|
|
564
|
+
if (type.includes('float'))
|
|
565
|
+
return '-1.0';
|
|
566
|
+
if (type.includes('*'))
|
|
567
|
+
return 'nil';
|
|
568
|
+
return 'nil';
|
|
569
|
+
}
|
|
570
|
+
/**
|
|
571
|
+
* Generate the want value for table-driven test cases
|
|
572
|
+
*/
|
|
573
|
+
generateGoWantValue(returnType, hasError) {
|
|
574
|
+
if (!returnType || returnType === 'void')
|
|
575
|
+
return '';
|
|
576
|
+
// Strip error from multi-return
|
|
577
|
+
let cleanType = returnType;
|
|
578
|
+
if (hasError) {
|
|
579
|
+
cleanType = returnType.replace(/,?\s*error/i, '').trim();
|
|
580
|
+
if (cleanType.startsWith('(') && cleanType.endsWith(')')) {
|
|
581
|
+
cleanType = cleanType.slice(1, -1).trim();
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
const rt = cleanType.toLowerCase();
|
|
585
|
+
let value;
|
|
586
|
+
if (rt.includes('string') || rt === 'str')
|
|
587
|
+
value = '"expected"';
|
|
588
|
+
else if (rt.includes('int'))
|
|
589
|
+
value = '0';
|
|
590
|
+
else if (rt.includes('float'))
|
|
591
|
+
value = '0.0';
|
|
592
|
+
else if (rt.includes('bool'))
|
|
593
|
+
value = 'true';
|
|
594
|
+
else if (rt.includes('*') || rt.includes('[]') || rt.includes('map'))
|
|
595
|
+
value = 'nil';
|
|
596
|
+
else
|
|
597
|
+
value = 'nil';
|
|
598
|
+
if (hasError) {
|
|
599
|
+
return `, want: ${value}, wantErr: false`;
|
|
600
|
+
}
|
|
601
|
+
return `, want: ${value}`;
|
|
602
|
+
}
|
|
603
|
+
/**
|
|
604
|
+
* Map a type string to an idiomatic Go type for struct fields
|
|
605
|
+
*/
|
|
606
|
+
mapToGoType(type) {
|
|
607
|
+
if (!type)
|
|
608
|
+
return 'interface{}';
|
|
609
|
+
const t = type.toLowerCase();
|
|
610
|
+
if (t.includes('context.context') || t.includes('context'))
|
|
611
|
+
return 'context.Context';
|
|
612
|
+
if (t === 'string' || t === 'str')
|
|
613
|
+
return 'string';
|
|
614
|
+
if (t === 'int64')
|
|
615
|
+
return 'int64';
|
|
616
|
+
if (t === 'int32')
|
|
617
|
+
return 'int32';
|
|
618
|
+
if (t.includes('int'))
|
|
619
|
+
return 'int';
|
|
620
|
+
if (t === 'float64')
|
|
621
|
+
return 'float64';
|
|
622
|
+
if (t === 'float32')
|
|
623
|
+
return 'float32';
|
|
624
|
+
if (t.includes('float'))
|
|
625
|
+
return 'float64';
|
|
626
|
+
if (t === 'bool' || t === 'boolean')
|
|
627
|
+
return 'bool';
|
|
628
|
+
if (t.includes('[]byte'))
|
|
629
|
+
return '[]byte';
|
|
630
|
+
if (t.includes('[]'))
|
|
631
|
+
return type; // preserve original slice type
|
|
632
|
+
if (t.includes('map'))
|
|
633
|
+
return type;
|
|
634
|
+
if (t.includes('error'))
|
|
635
|
+
return 'error';
|
|
636
|
+
if (t.includes('*'))
|
|
637
|
+
return type;
|
|
638
|
+
return type;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Map return type to Go type, stripping error component
|
|
642
|
+
*/
|
|
643
|
+
mapReturnToGoType(returnType, hasError) {
|
|
644
|
+
let cleanType = returnType;
|
|
645
|
+
if (hasError) {
|
|
646
|
+
cleanType = returnType.replace(/,?\s*error/i, '').trim();
|
|
647
|
+
if (cleanType.startsWith('(') && cleanType.endsWith(')')) {
|
|
648
|
+
cleanType = cleanType.slice(1, -1).trim();
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
return this.mapToGoType(cleanType) || 'interface{}';
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
//# sourceMappingURL=go-test-generator.js.map
|