specforge-mcp 0.2.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/engine/skill-generator/sections-skills.d.ts +4 -0
  2. package/dist/engine/skill-generator/sections-skills.d.ts.map +1 -0
  3. package/dist/engine/skill-generator/sections-skills.js +51 -0
  4. package/dist/engine/skill-generator/sections-skills.js.map +1 -0
  5. package/dist/engine/skill-generator/sections.d.ts +1 -0
  6. package/dist/engine/skill-generator/sections.d.ts.map +1 -1
  7. package/dist/engine/skill-generator/sections.js +2 -1
  8. package/dist/engine/skill-generator/sections.js.map +1 -1
  9. package/dist/engine/skill-generator.d.ts +3 -1
  10. package/dist/engine/skill-generator.d.ts.map +1 -1
  11. package/dist/engine/skill-generator.js +11 -2
  12. package/dist/engine/skill-generator.js.map +1 -1
  13. package/dist/engine/test-plan-generator.d.ts +3 -0
  14. package/dist/engine/test-plan-generator.d.ts.map +1 -0
  15. package/dist/engine/test-plan-generator.js +166 -0
  16. package/dist/engine/test-plan-generator.js.map +1 -0
  17. package/dist/engine/test-spec-generator.d.ts +8 -0
  18. package/dist/engine/test-spec-generator.d.ts.map +1 -0
  19. package/dist/engine/test-spec-generator.js +348 -0
  20. package/dist/engine/test-spec-generator.js.map +1 -0
  21. package/dist/tools/generate-rules.d.ts.map +1 -1
  22. package/dist/tools/generate-rules.js +20 -0
  23. package/dist/tools/generate-rules.js.map +1 -1
  24. package/dist/tools/generate-tests/generators/database-test-generator.d.ts +11 -0
  25. package/dist/tools/generate-tests/generators/database-test-generator.d.ts.map +1 -0
  26. package/dist/tools/generate-tests/generators/database-test-generator.js +329 -0
  27. package/dist/tools/generate-tests/generators/database-test-generator.js.map +1 -0
  28. package/dist/tools/generate-tests/generators/graphql-test-generator.d.ts +17 -0
  29. package/dist/tools/generate-tests/generators/graphql-test-generator.d.ts.map +1 -0
  30. package/dist/tools/generate-tests/generators/graphql-test-generator.js +235 -0
  31. package/dist/tools/generate-tests/generators/graphql-test-generator.js.map +1 -0
  32. package/dist/tools/generate-tests/generators/grpc-test-generator.d.ts +17 -0
  33. package/dist/tools/generate-tests/generators/grpc-test-generator.d.ts.map +1 -0
  34. package/dist/tools/generate-tests/generators/grpc-test-generator.js +283 -0
  35. package/dist/tools/generate-tests/generators/grpc-test-generator.js.map +1 -0
  36. package/dist/tools/generate-tests/generators/microservices-test-generator.d.ts +10 -0
  37. package/dist/tools/generate-tests/generators/microservices-test-generator.d.ts.map +1 -0
  38. package/dist/tools/generate-tests/generators/microservices-test-generator.js +341 -0
  39. package/dist/tools/generate-tests/generators/microservices-test-generator.js.map +1 -0
  40. package/dist/tools/generate-tests/generators/security-test-generator.d.ts +11 -0
  41. package/dist/tools/generate-tests/generators/security-test-generator.d.ts.map +1 -0
  42. package/dist/tools/generate-tests/generators/security-test-generator.js +318 -0
  43. package/dist/tools/generate-tests/generators/security-test-generator.js.map +1 -0
  44. package/dist/tools/generate-tests/generators/visual-regression-generator.d.ts +19 -0
  45. package/dist/tools/generate-tests/generators/visual-regression-generator.d.ts.map +1 -0
  46. package/dist/tools/generate-tests/generators/visual-regression-generator.js +304 -0
  47. package/dist/tools/generate-tests/generators/visual-regression-generator.js.map +1 -0
  48. package/dist/tools/generate-tests/generators/websocket-test-generator.d.ts +17 -0
  49. package/dist/tools/generate-tests/generators/websocket-test-generator.d.ts.map +1 -0
  50. package/dist/tools/generate-tests/generators/websocket-test-generator.js +243 -0
  51. package/dist/tools/generate-tests/generators/websocket-test-generator.js.map +1 -0
  52. package/dist/tools/generate-tests/plan-mode-handler.d.ts +3 -0
  53. package/dist/tools/generate-tests/plan-mode-handler.d.ts.map +1 -0
  54. package/dist/tools/generate-tests/plan-mode-handler.js +54 -0
  55. package/dist/tools/generate-tests/plan-mode-handler.js.map +1 -0
  56. package/dist/tools/generate-tests/spec-dispatcher.d.ts.map +1 -1
  57. package/dist/tools/generate-tests/spec-dispatcher.js +46 -0
  58. package/dist/tools/generate-tests/spec-dispatcher.js.map +1 -1
  59. package/dist/tools/generate-tests/test-helpers.d.ts +8 -0
  60. package/dist/tools/generate-tests/test-helpers.d.ts.map +1 -0
  61. package/dist/tools/generate-tests/test-helpers.js +120 -0
  62. package/dist/tools/generate-tests/test-helpers.js.map +1 -0
  63. package/dist/tools/generate-tests.d.ts.map +1 -1
  64. package/dist/tools/generate-tests.js +6 -118
  65. package/dist/tools/generate-tests.js.map +1 -1
  66. package/dist/tools/init-project/handler.d.ts.map +1 -1
  67. package/dist/tools/init-project/handler.js +29 -0
  68. package/dist/tools/init-project/handler.js.map +1 -1
  69. package/dist/types/stack/recommend.d.ts +2 -0
  70. package/dist/types/stack/recommend.d.ts.map +1 -1
  71. package/dist/types/testing.d.ts +51 -0
  72. package/dist/types/testing.d.ts.map +1 -1
  73. package/package.json +3 -2
  74. package/src/i18n/messages/en.json +333 -0
  75. package/src/i18n/messages/es.json +333 -0
  76. package/src/i18n/messages/pt.json +333 -0
@@ -0,0 +1,283 @@
1
+ // tools/generate-tests/generators/grpc-test-generator.ts — SPEC-058a Section D
2
+ // Generates gRPC test scaffolds: proto contracts, unary, streaming, deadlines.
3
+ const GRPC_SIGNALS = ['grpc', '@grpc/grpc-js', 'protobuf', 'buf', 'proto-loader', 'grpc-web'];
4
+ /**
5
+ * Returns true when the project uses gRPC / Protocol Buffers.
6
+ */
7
+ export function isGrpcProject(knowledge) {
8
+ const stackLower = knowledge.stack.map((s) => s.toLowerCase());
9
+ const hasStackSignal = GRPC_SIGNALS.some((sig) => stackLower.some((s) => s.includes(sig)));
10
+ const toolingValues = Object.values(knowledge.tooling).map((v) => v.toLowerCase());
11
+ const hasProtoFile = toolingValues.some((v) => v.includes('.proto') || v.includes('protobuf'));
12
+ return hasStackSignal || hasProtoFile;
13
+ }
14
+ /**
15
+ * Generate gRPC test definitions: proto contracts, unary, streaming, deadlines.
16
+ */
17
+ export function generateGrpcTestDefs(title, testDir, _testExt) {
18
+ return [
19
+ {
20
+ name: `${title} — gRPC: proto contract validation`,
21
+ type: 'integration',
22
+ file: `${testDir}/grpc/`,
23
+ description: 'Verify the .proto definition compiles and all service methods are reachable',
24
+ priority: 'critical',
25
+ automatable: true,
26
+ },
27
+ {
28
+ name: `${title} — gRPC: unary call returns correct response`,
29
+ type: 'integration',
30
+ file: `${testDir}/grpc/`,
31
+ description: 'Execute a unary RPC and assert the response message matches the proto schema',
32
+ priority: 'high',
33
+ automatable: true,
34
+ },
35
+ {
36
+ name: `${title} — gRPC: server streaming yields all expected messages`,
37
+ type: 'integration',
38
+ file: `${testDir}/grpc/`,
39
+ description: 'Consume a server-streaming RPC and verify each streamed message',
40
+ priority: 'high',
41
+ automatable: true,
42
+ },
43
+ {
44
+ name: `${title} — gRPC: client streaming aggregates messages correctly`,
45
+ type: 'integration',
46
+ file: `${testDir}/grpc/`,
47
+ description: 'Send multiple messages via client-streaming RPC and verify aggregated response',
48
+ priority: 'medium',
49
+ automatable: true,
50
+ },
51
+ {
52
+ name: `${title} — gRPC: bidirectional streaming echoes messages in order`,
53
+ type: 'integration',
54
+ file: `${testDir}/grpc/`,
55
+ description: 'Open a bidirectional stream and verify messages are echoed in FIFO order',
56
+ priority: 'medium',
57
+ automatable: true,
58
+ },
59
+ {
60
+ name: `${title} — gRPC: deadline propagation cancels slow calls`,
61
+ type: 'integration',
62
+ file: `${testDir}/grpc/`,
63
+ description: 'Set a short deadline on a slow call and assert DEADLINE_EXCEEDED status code',
64
+ priority: 'high',
65
+ automatable: true,
66
+ },
67
+ ];
68
+ }
69
+ // ---------------------------------------------------------------------------
70
+ // Content generators
71
+ // ---------------------------------------------------------------------------
72
+ function buildTsGrpcTest(title) {
73
+ return `// gRPC tests for: ${title}
74
+ // Generated by SpecForge SDD MCP Server (SPEC-058a)
75
+ import { describe, it, expect, beforeAll, afterAll } from 'vitest';
76
+ // import * as grpc from '@grpc/grpc-js';
77
+ // import * as protoLoader from '@grpc/proto-loader';
78
+
79
+ // const PROTO_PATH = './proto/service.proto';
80
+ // const packageDefinition = protoLoader.loadSync(PROTO_PATH);
81
+ // const proto = grpc.loadPackageDefinition(packageDefinition) as grpc.GrpcObject;
82
+
83
+ describe('${title} — gRPC Tests', () => {
84
+ // let client: grpc.ServiceClient;
85
+
86
+ beforeAll(() => {
87
+ // const ServiceClient = proto['YourService'] as grpc.ServiceClientConstructor;
88
+ // client = new ServiceClient(
89
+ // 'localhost:50051',
90
+ // grpc.credentials.createInsecure(),
91
+ // );
92
+ });
93
+
94
+ afterAll(() => {
95
+ // client.close();
96
+ });
97
+
98
+ describe('Proto contract', () => {
99
+ it('service definition loads without errors', () => {
100
+ // const packageDef = protoLoader.loadSync(PROTO_PATH);
101
+ // expect(packageDef).toBeDefined();
102
+ expect(true).toBe(true); // Replace with real proto load assertion
103
+ });
104
+ });
105
+
106
+ describe('Unary call', () => {
107
+ it('returns correct response message', async () => {
108
+ // const response = await new Promise((resolve, reject) =>
109
+ // client.unaryMethod({ id: '1' }, (err, res) =>
110
+ // err ? reject(err) : resolve(res),
111
+ // ),
112
+ // );
113
+ // expect(response).toMatchObject({ id: '1' });
114
+ expect(true).toBe(true); // Replace with real unary assertion
115
+ });
116
+ });
117
+
118
+ describe('Server streaming', () => {
119
+ it('yields all expected messages', async () => {
120
+ // const messages: unknown[] = [];
121
+ // await new Promise<void>((resolve, reject) => {
122
+ // const stream = client.serverStreamMethod({ count: 3 });
123
+ // stream.on('data', (msg) => messages.push(msg));
124
+ // stream.on('error', reject);
125
+ // stream.on('end', resolve);
126
+ // });
127
+ // expect(messages).toHaveLength(3);
128
+ expect(true).toBe(true); // Replace with real server-stream assertion
129
+ });
130
+ });
131
+
132
+ describe('Deadline propagation', () => {
133
+ it('returns DEADLINE_EXCEEDED for slow calls', async () => {
134
+ // const deadline = new Date(Date.now() + 1); // 1ms deadline
135
+ // await expect(
136
+ // new Promise((resolve, reject) =>
137
+ // client.slowMethod({}, { deadline }, (err, res) =>
138
+ // err ? reject(err) : resolve(res),
139
+ // ),
140
+ // ),
141
+ // ).rejects.toMatchObject({ code: grpc.status.DEADLINE_EXCEEDED });
142
+ expect(true).toBe(true); // Replace with real deadline assertion
143
+ });
144
+ });
145
+ });
146
+ `;
147
+ }
148
+ function buildGoGrpcTest(title) {
149
+ const pkg = title.toLowerCase().replace(/\s+/g, '_');
150
+ return `// gRPC tests for: ${title}
151
+ // Generated by SpecForge SDD MCP Server (SPEC-058a)
152
+ package ${pkg}_test
153
+
154
+ import (
155
+ \t"context"
156
+ \t"testing"
157
+ \t"time"
158
+
159
+ \t"google.golang.org/grpc"
160
+ \t"google.golang.org/grpc/codes"
161
+ \t"google.golang.org/grpc/credentials/insecure"
162
+ \t"google.golang.org/grpc/status"
163
+ \t// pb "your/module/proto/gen"
164
+ )
165
+
166
+ func setupClient(t *testing.T) (*grpc.ClientConn, func()) {
167
+ \tt.Helper()
168
+ \tconn, err := grpc.NewClient(
169
+ \t\t"localhost:50051",
170
+ \t\tgrpc.WithTransportCredentials(insecure.NewCredentials()),
171
+ \t)
172
+ \tif err != nil {
173
+ \t\tt.Fatalf("failed to connect: %v", err)
174
+ \t}
175
+ \treturn conn, func() { conn.Close() } //nolint:errcheck
176
+ }
177
+
178
+ func TestUnaryCall(t *testing.T) {
179
+ \t// conn, teardown := setupClient(t)
180
+ \t// defer teardown()
181
+ \t// client := pb.NewYourServiceClient(conn)
182
+ \t//
183
+ \t// ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
184
+ \t// defer cancel()
185
+ \t//
186
+ \t// resp, err := client.UnaryMethod(ctx, &pb.Request{Id: "1"})
187
+ \t// if err != nil { t.Fatalf("unary call failed: %v", err) }
188
+ \t// if resp.Id != "1" { t.Errorf("expected id=1, got %s", resp.Id) }
189
+ \tt.Skip("TODO: implement unary call test")
190
+ }
191
+
192
+ func TestDeadlinePropagation(t *testing.T) {
193
+ \t// conn, teardown := setupClient(t)
194
+ \t// defer teardown()
195
+ \t// client := pb.NewYourServiceClient(conn)
196
+ \t//
197
+ \tctx, cancel := context.WithTimeout(context.Background(), 1*time.Millisecond)
198
+ \tdefer cancel()
199
+ \t_ = ctx
200
+ \t//
201
+ \t// _, err := client.SlowMethod(ctx, &pb.Request{})
202
+ \t// if status.Code(err) != codes.DeadlineExceeded {
203
+ \t// t.Errorf("expected DeadlineExceeded, got %v", status.Code(err))
204
+ \t// }
205
+ \t_ = codes.DeadlineExceeded
206
+ \t_ = status.Code
207
+ \tt.Skip("TODO: implement deadline propagation test")
208
+ }
209
+ `;
210
+ }
211
+ function buildPythonGrpcTest(title) {
212
+ const cls = title.replace(/\s+/g, '');
213
+ return `"""gRPC tests for: ${title}
214
+ Generated by SpecForge SDD MCP Server (SPEC-058a).
215
+ Uses grpcio + grpcio-testing patterns.
216
+ """
217
+ import pytest
218
+ # import grpc
219
+ # from your.proto import service_pb2, service_pb2_grpc
220
+
221
+
222
+ class Test${cls}Grpc:
223
+ """gRPC test suite for ${title}."""
224
+
225
+ def test_proto_contract_loads(self) -> None:
226
+ """Proto definition loads without import errors."""
227
+ # TODO: from your.proto import service_pb2_grpc
228
+ pass
229
+
230
+ def test_unary_call_returns_correct_response(self) -> None:
231
+ """Unary RPC returns the expected response message."""
232
+ # TODO: channel = grpc.insecure_channel("localhost:50051")
233
+ # stub = service_pb2_grpc.YourServiceStub(channel)
234
+ # response = stub.UnaryMethod(service_pb2.Request(id="1"))
235
+ # assert response.id == "1"
236
+ pass
237
+
238
+ def test_server_streaming_yields_all_messages(self) -> None:
239
+ """Server-streaming RPC yields all expected messages."""
240
+ # TODO: messages = list(stub.ServerStreamMethod(service_pb2.Request(count=3)))
241
+ # assert len(messages) == 3
242
+ pass
243
+
244
+ def test_deadline_exceeded_for_slow_call(self) -> None:
245
+ """Call with a short deadline raises StatusCode.DEADLINE_EXCEEDED."""
246
+ # TODO: with pytest.raises(grpc.RpcError) as exc_info:
247
+ # stub.SlowMethod(request, timeout=0.001)
248
+ # assert exc_info.value.code() == grpc.StatusCode.DEADLINE_EXCEEDED
249
+ pass
250
+ `;
251
+ }
252
+ /**
253
+ * Generate gRPC test file scaffolds for the target language.
254
+ */
255
+ export function generateGrpcTestFiles(spec, testDir, framework, language, testExt, autoGenerate) {
256
+ let content;
257
+ let resolvedExt;
258
+ let resolvedFramework;
259
+ if (language === 'go') {
260
+ content = buildGoGrpcTest(spec.title);
261
+ resolvedExt = 'go';
262
+ resolvedFramework = 'go-test';
263
+ }
264
+ else if (language === 'python') {
265
+ content = buildPythonGrpcTest(spec.title);
266
+ resolvedExt = 'py';
267
+ resolvedFramework = 'pytest';
268
+ }
269
+ else {
270
+ content = buildTsGrpcTest(spec.title);
271
+ resolvedExt = testExt;
272
+ resolvedFramework = framework;
273
+ }
274
+ return [
275
+ {
276
+ path: `${testDir}/grpc/${spec.slug}.grpc.test.${resolvedExt}`,
277
+ framework: resolvedFramework,
278
+ content,
279
+ ready: autoGenerate,
280
+ },
281
+ ];
282
+ }
283
+ //# sourceMappingURL=grpc-test-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grpc-test-generator.js","sourceRoot":"","sources":["../../../../src/tools/generate-tests/generators/grpc-test-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { TestDefinition, TestFile, ProjectKnowledge } from '../../../types/index.js';
2
+ export declare function detectBroker(knowledge: ProjectKnowledge): string | null;
3
+ export declare function detectServiceMesh(knowledge: ProjectKnowledge): string | null;
4
+ export declare function isMicroservicesTestProject(knowledge: ProjectKnowledge): boolean;
5
+ export declare function generateMicroservicesTestDefs(title: string, testDir: string, _testExt: string, knowledge: ProjectKnowledge): TestDefinition[];
6
+ export declare function generateMicroservicesTestFiles(spec: {
7
+ title: string;
8
+ slug: string;
9
+ }, testDir: string, framework: string, language: string, testExt: string, autoGenerate: boolean, knowledge: ProjectKnowledge): TestFile[];
10
+ //# sourceMappingURL=microservices-test-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microservices-test-generator.d.ts","sourceRoot":"","sources":["../../../../src/tools/generate-tests/generators/microservices-test-generator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAa1F,wBAAgB,YAAY,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAQvE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAQ5E;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAe/E;AAED,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,gBAAgB,GAC1B,cAAc,EAAE,CA+DlB;AA2OD,wBAAgB,8BAA8B,CAC5C,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACrC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,EACrB,SAAS,EAAE,gBAAgB,GAC1B,QAAQ,EAAE,CAkBZ"}
@@ -0,0 +1,341 @@
1
+ // tools/generate-tests/generators/microservices-test-generator.ts — SPEC-058b Section E
2
+ // Generates microservices & distributed systems test scaffolds:
3
+ // contract testing, circuit breaker, retry, health checks, broker, service mesh.
4
+ const BROKER_SIGNALS = ['kafka', 'rabbitmq', 'sqs', 'nats', 'redis-streams', 'pulsar', 'amqp'];
5
+ const MESH_SIGNALS = [
6
+ 'istio',
7
+ 'envoy',
8
+ 'linkerd',
9
+ 'kong',
10
+ 'traefik',
11
+ 'nginx-ingress',
12
+ 'api-gateway',
13
+ ];
14
+ export function detectBroker(knowledge) {
15
+ const stackLower = knowledge.stack.map((s) => s.toLowerCase());
16
+ for (const sig of BROKER_SIGNALS) {
17
+ if (stackLower.some((s) => s.includes(sig))) {
18
+ return sig;
19
+ }
20
+ }
21
+ return null;
22
+ }
23
+ export function detectServiceMesh(knowledge) {
24
+ const stackLower = knowledge.stack.map((s) => s.toLowerCase());
25
+ for (const sig of MESH_SIGNALS) {
26
+ if (stackLower.some((s) => s.includes(sig))) {
27
+ return sig;
28
+ }
29
+ }
30
+ return null;
31
+ }
32
+ export function isMicroservicesTestProject(knowledge) {
33
+ if (knowledge.architecture.primary === 'microservices') {
34
+ return true;
35
+ }
36
+ if (knowledge.architecture.secondary.some((s) => s === 'microservices')) {
37
+ return true;
38
+ }
39
+ if (detectBroker(knowledge) !== null) {
40
+ return true;
41
+ }
42
+ if (detectServiceMesh(knowledge) !== null) {
43
+ return true;
44
+ }
45
+ const backends = knowledge.apps.filter((a) => a.type === 'backend' || a.type === 'worker');
46
+ return backends.length > 1;
47
+ }
48
+ export function generateMicroservicesTestDefs(title, testDir, _testExt, knowledge) {
49
+ const defs = [
50
+ {
51
+ name: `${title} — contract testing: inter-service Pact verification`,
52
+ type: 'integration',
53
+ file: `${testDir}/microservices/`,
54
+ description: 'Consumer-driven contract tests verify API compatibility between services',
55
+ priority: 'critical',
56
+ automatable: true,
57
+ },
58
+ {
59
+ name: `${title} — circuit breaker: open/half-open/closed state transitions`,
60
+ type: 'integration',
61
+ file: `${testDir}/microservices/`,
62
+ description: 'Verify circuit breaker opens on failures, transitions to half-open, and closes on recovery',
63
+ priority: 'high',
64
+ automatable: true,
65
+ },
66
+ {
67
+ name: `${title} — retry with backoff: exponential backoff and idempotency`,
68
+ type: 'integration',
69
+ file: `${testDir}/microservices/`,
70
+ description: 'Verify retry logic uses exponential backoff with jitter and respects idempotency keys',
71
+ priority: 'high',
72
+ automatable: true,
73
+ },
74
+ {
75
+ name: `${title} — health checks: liveness and readiness probes`,
76
+ type: 'integration',
77
+ file: `${testDir}/microservices/`,
78
+ description: 'Verify /healthz, /readyz, and startup probes return correct status codes',
79
+ priority: 'critical',
80
+ automatable: true,
81
+ },
82
+ ];
83
+ if (detectBroker(knowledge) !== null) {
84
+ defs.push({
85
+ name: `${title} — message broker: delivery guarantee and DLQ handling`,
86
+ type: 'integration',
87
+ file: `${testDir}/microservices/`,
88
+ description: 'Verify message delivery, ordering, dead letter queue handling, and consumer group rebalancing',
89
+ priority: 'high',
90
+ automatable: true,
91
+ });
92
+ }
93
+ if (detectServiceMesh(knowledge) !== null) {
94
+ defs.push({
95
+ name: `${title} — service mesh: routing rules and mTLS verification`,
96
+ type: 'integration',
97
+ file: `${testDir}/microservices/`,
98
+ description: 'Verify routing rules, mTLS certificate verification, and traffic splitting configuration',
99
+ priority: 'medium',
100
+ automatable: true,
101
+ });
102
+ }
103
+ return defs;
104
+ }
105
+ // ---------------------------------------------------------------------------
106
+ // Scaffold builders
107
+ // ---------------------------------------------------------------------------
108
+ function buildTsMicroservicesTest(title, broker, mesh) {
109
+ const brokerSection = broker
110
+ ? `
111
+ describe('Message broker (${broker})', () => {
112
+ it('guarantees message delivery to consumer', async () => {
113
+ // const producer = createProducer({ broker: '${broker}' });
114
+ // await producer.send({ topic: 'orders', value: { id: 1 } });
115
+ // const received = await consumer.waitForMessage('orders', 5000);
116
+ // expect(received.value).toMatchObject({ id: 1 });
117
+ expect(true).toBe(true); // Replace with real broker assertion
118
+ });
119
+
120
+ it('routes failed messages to dead letter queue', async () => {
121
+ // Simulate processing failure → verify message lands in DLQ
122
+ expect(true).toBe(true);
123
+ });
124
+
125
+ it('preserves message ordering within partition', async () => {
126
+ expect(true).toBe(true);
127
+ });
128
+
129
+ it('handles consumer group rebalancing gracefully', async () => {
130
+ expect(true).toBe(true);
131
+ });
132
+ });
133
+ `
134
+ : '';
135
+ const meshSection = mesh
136
+ ? `
137
+ describe('Service mesh (${mesh})', () => {
138
+ it('routes traffic according to configured rules', async () => {
139
+ expect(true).toBe(true);
140
+ });
141
+
142
+ it('verifies mTLS certificates between services', async () => {
143
+ expect(true).toBe(true);
144
+ });
145
+
146
+ it('splits traffic correctly between versions', async () => {
147
+ expect(true).toBe(true);
148
+ });
149
+ });
150
+ `
151
+ : '';
152
+ return `// Microservices & Distributed Systems tests for: ${title}
153
+ // Generated by SpecForge SDD MCP Server (SPEC-058b)
154
+ import { describe, it, expect } from 'vitest';
155
+
156
+ describe('${title} — Microservices Tests', () => {
157
+ describe('Contract testing (Pact)', () => {
158
+ it('consumer contract matches provider API', async () => {
159
+ // const interaction = new PactInteraction()
160
+ // .uponReceiving('a request for user')
161
+ // .withRequest({ method: 'GET', path: '/api/users/1' })
162
+ // .willRespondWith({ status: 200, body: { id: 1, name: 'Test' } });
163
+ // await provider.verify(interaction);
164
+ expect(true).toBe(true); // Replace with real Pact assertion
165
+ });
166
+ });
167
+
168
+ describe('Circuit breaker', () => {
169
+ it('opens after consecutive failures', async () => {
170
+ // Simulate 5 failures → verify circuit is open
171
+ expect(true).toBe(true);
172
+ });
173
+
174
+ it('transitions from open to half-open after timeout', async () => {
175
+ expect(true).toBe(true);
176
+ });
177
+
178
+ it('closes after successful request in half-open state', async () => {
179
+ expect(true).toBe(true);
180
+ });
181
+
182
+ it('returns fallback response when circuit is open', async () => {
183
+ expect(true).toBe(true);
184
+ });
185
+ });
186
+
187
+ describe('Retry with backoff', () => {
188
+ it('retries with exponential backoff on transient failure', async () => {
189
+ // Verify delays: 100ms, 200ms, 400ms (exponential)
190
+ expect(true).toBe(true);
191
+ });
192
+
193
+ it('respects max retry limit', async () => {
194
+ expect(true).toBe(true);
195
+ });
196
+
197
+ it('applies jitter to avoid thundering herd', async () => {
198
+ expect(true).toBe(true);
199
+ });
200
+
201
+ it('uses idempotency key to prevent duplicate processing', async () => {
202
+ expect(true).toBe(true);
203
+ });
204
+ });
205
+
206
+ describe('Health check endpoints', () => {
207
+ it('GET /healthz returns 200 when service is alive', async () => {
208
+ // const res = await request(app).get('/healthz');
209
+ // expect(res.status).toBe(200);
210
+ expect(true).toBe(true);
211
+ });
212
+
213
+ it('GET /readyz returns 200 when dependencies are ready', async () => {
214
+ expect(true).toBe(true);
215
+ });
216
+
217
+ it('GET /readyz returns 503 when a dependency is down', async () => {
218
+ expect(true).toBe(true);
219
+ });
220
+
221
+ it('startup probe succeeds within timeout', async () => {
222
+ expect(true).toBe(true);
223
+ });
224
+ });
225
+ ${brokerSection}${meshSection}});
226
+ `;
227
+ }
228
+ function buildPythonMicroservicesTest(title, broker, mesh) {
229
+ const cls = title.replace(/[^a-zA-Z0-9]/g, '');
230
+ const brokerSection = broker
231
+ ? `
232
+ def test_message_delivery_guarantee(self) -> None:
233
+ """Messages are delivered to consumers with at-least-once guarantee."""
234
+ # TODO: producer.send('orders', {'id': 1})
235
+ # msg = consumer.poll(timeout=5.0)
236
+ # assert msg.value == {'id': 1}
237
+ pass
238
+
239
+ def test_dead_letter_queue_routing(self) -> None:
240
+ """Failed messages are routed to the dead letter queue."""
241
+ pass
242
+
243
+ def test_message_ordering_within_partition(self) -> None:
244
+ """Messages within same partition maintain ordering."""
245
+ pass
246
+
247
+ def test_consumer_group_rebalancing(self) -> None:
248
+ """Consumer group rebalancing does not lose messages."""
249
+ pass
250
+ `
251
+ : '';
252
+ const meshSection = mesh
253
+ ? `
254
+ def test_routing_rules(self) -> None:
255
+ """Traffic is routed according to configured rules."""
256
+ pass
257
+
258
+ def test_mtls_verification(self) -> None:
259
+ """mTLS certificates are verified between services."""
260
+ pass
261
+
262
+ def test_traffic_splitting(self) -> None:
263
+ """Traffic is split correctly between service versions."""
264
+ pass
265
+ `
266
+ : '';
267
+ return `"""Microservices & Distributed Systems tests for: ${title}
268
+ Generated by SpecForge SDD MCP Server (SPEC-058b).
269
+ """
270
+ import pytest
271
+
272
+
273
+ class Test${cls}Microservices:
274
+ """Microservices test suite for ${title}."""
275
+
276
+ def test_consumer_contract_matches_provider(self) -> None:
277
+ """Consumer-driven contract matches the provider API."""
278
+ # TODO: pact = Pact('consumer', 'provider')
279
+ # pact.given('user exists').upon_receiving('get user')
280
+ # .with_request('GET', '/api/users/1')
281
+ # .will_respond_with(200, body={'id': 1})
282
+ pass
283
+
284
+ def test_circuit_breaker_opens_on_failures(self) -> None:
285
+ """Circuit breaker opens after consecutive failures."""
286
+ pass
287
+
288
+ def test_circuit_breaker_half_open_transition(self) -> None:
289
+ """Circuit transitions from open to half-open after timeout."""
290
+ pass
291
+
292
+ def test_circuit_breaker_closes_on_recovery(self) -> None:
293
+ """Circuit closes after successful request in half-open state."""
294
+ pass
295
+
296
+ def test_retry_exponential_backoff(self) -> None:
297
+ """Retries use exponential backoff with jitter."""
298
+ pass
299
+
300
+ def test_retry_respects_max_limit(self) -> None:
301
+ """Retry stops after max attempts."""
302
+ pass
303
+
304
+ def test_idempotency_key_prevents_duplicates(self) -> None:
305
+ """Idempotency key prevents duplicate processing on retry."""
306
+ pass
307
+
308
+ def test_healthz_returns_200(self) -> None:
309
+ """GET /healthz returns 200 when service is alive."""
310
+ # TODO: response = client.get('/healthz')
311
+ # assert response.status_code == 200
312
+ pass
313
+
314
+ def test_readyz_returns_200_when_ready(self) -> None:
315
+ """GET /readyz returns 200 when all dependencies are ready."""
316
+ pass
317
+
318
+ def test_readyz_returns_503_when_dependency_down(self) -> None:
319
+ """GET /readyz returns 503 when a dependency is unavailable."""
320
+ pass
321
+ ${brokerSection}${meshSection}`;
322
+ }
323
+ export function generateMicroservicesTestFiles(spec, testDir, framework, language, testExt, autoGenerate, knowledge) {
324
+ const broker = detectBroker(knowledge);
325
+ const mesh = detectServiceMesh(knowledge);
326
+ const isPython = language === 'python';
327
+ const ext = isPython ? 'py' : testExt;
328
+ const fw = isPython ? 'pytest' : framework;
329
+ const content = isPython
330
+ ? buildPythonMicroservicesTest(spec.title, broker, mesh)
331
+ : buildTsMicroservicesTest(spec.title, broker, mesh);
332
+ return [
333
+ {
334
+ path: `${testDir}/microservices/${spec.slug}.microservices.test.${ext}`,
335
+ framework: fw,
336
+ content,
337
+ ready: autoGenerate,
338
+ },
339
+ ];
340
+ }
341
+ //# sourceMappingURL=microservices-test-generator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"microservices-test-generator.js","sourceRoot":"","sources":["../../../../src/tools/generate-tests/generators/microservices-test-generator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import type { TestDefinition, TestFile, ProjectKnowledge } from '../../../types/index.js';
2
+ export declare function detectAuth(knowledge: ProjectKnowledge): string | null;
3
+ export declare function detectFileUpload(knowledge: ProjectKnowledge): string | null;
4
+ export declare function hasPublicApi(knowledge: ProjectKnowledge): boolean;
5
+ export declare function isSecurityTestProject(knowledge: ProjectKnowledge): boolean;
6
+ export declare function generateSecurityTestDefs(title: string, testDir: string, _testExt: string, knowledge: ProjectKnowledge): TestDefinition[];
7
+ export declare function generateSecurityTestFiles(spec: {
8
+ title: string;
9
+ slug: string;
10
+ }, testDir: string, framework: string, language: string, testExt: string, autoGenerate: boolean, knowledge: ProjectKnowledge): TestFile[];
11
+ //# sourceMappingURL=security-test-generator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"security-test-generator.d.ts","sourceRoot":"","sources":["../../../../src/tools/generate-tests/generators/security-test-generator.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AA4B1F,wBAAgB,UAAU,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAQrE;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,GAAG,IAAI,CAQ3E;AAED,wBAAgB,YAAY,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAKjE;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,gBAAgB,GAAG,OAAO,CAQ1E;AAED,wBAAgB,wBAAwB,CACtC,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,gBAAgB,GAC1B,cAAc,EAAE,CAiDlB;AAwND,wBAAgB,yBAAyB,CACvC,IAAI,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EACrC,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,OAAO,EACrB,SAAS,EAAE,gBAAgB,GAC1B,QAAQ,EAAE,CAmBZ"}