// tools/generate-tests/generators/mcp-tests-generator.ts
// SPEC-016b: Generates test scaffolds for MCP servers.
// Criterion 6: tool registration, valid call, invalid call, resource read, e2e smoke test.
import { isMcpServerProject } from '../../../engine/detectors/mcp-server-detector.js';
// === Detection ===
export function isMcpProject(knowledge) {
    return isMcpServerProject(knowledge);
}
// === Test definitions ===
export function generateMcpTestDefs(title, testDir) {
    return [
        {
            name: `${title} — tool registration`,
            type: 'unit',
            file: `${testDir}/unit/`,
            description: 'Verify all tools are registered and appear in tools/list response',
            priority: 'critical',
            automatable: true,
        },
        {
            name: `${title} — valid tool call`,
            type: 'unit',
            file: `${testDir}/unit/`,
            description: 'Verify tool call with valid input returns expected output format',
            priority: 'critical',
            automatable: true,
        },
        {
            name: `${title} — invalid tool call (InvalidParams)`,
            type: 'unit',
            file: `${testDir}/unit/`,
            description: 'Verify tool call with invalid input returns McpError InvalidParams',
            priority: 'high',
            automatable: true,
        },
        {
            name: `${title} — resource read`,
            type: 'integration',
            file: `${testDir}/integration/`,
            description: 'Verify resource URIs are readable and return correct MIME type',
            priority: 'high',
            automatable: true,
        },
        {
            name: `${title} — e2e initialize handshake`,
            type: 'integration',
            file: `${testDir}/integration/`,
            description: 'E2E smoke test: launch server and verify initialize handshake succeeds',
            priority: 'critical',
            automatable: true,
        },
        {
            name: `${title} — tool call with extra fields rejected`,
            type: 'unit',
            file: `${testDir}/unit/`,
            description: 'Verify additionalProperties: false causes extra fields to be rejected (InvalidParams)',
            priority: 'high',
            automatable: true,
        },
        {
            name: `${title} — concurrent tool calls`,
            type: 'integration',
            file: `${testDir}/integration/`,
            description: 'Verify server handles concurrent tool calls without race conditions',
            priority: 'medium',
            automatable: true,
        },
    ];
}
// === Test file content generators ===
function buildImportLine(testFramework, language) {
    const isVitest = testFramework === 'vitest';
    const source = isVitest ? 'vitest' : 'jest';
    if (language === 'typescript') {
        return `import { describe, it, expect, beforeAll, afterAll } from '${source}';`;
    }
    return `const { describe, it, expect, beforeAll, afterAll } = require('${source}');`;
}
function buildMcpUnitTestContent(title, testFramework, language) {
    const importLine = buildImportLine(testFramework, language);
    const lines = [
        `// Unit tests for MCP server: ${title}`,
        '// SPEC-016b: Tool registration, valid/invalid calls, additionalProperties rejection',
        importLine,
        '',
        '// Replace with your actual server module path',
        "// import { createServer } from '../src/index.js';",
        "// import { Client } from '@modelcontextprotocol/sdk/client/index.js';",
        "// import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';",
        '',
        `describe('${title} — MCP Tool Registration', () => {`,
        '  // let client: Client;',
        '',
        '  beforeAll(async () => {',
        '    // const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();',
        '    // const server = createServer();',
        '    // await server.connect(serverTransport);',
        "    // client = new Client({ name: 'test-client', version: '1.0.0' }, { capabilities: {} });",
        '    // await client.connect(clientTransport);',
        '  });',
        '',
        "  it('should expose all expected tools in tools/list', async () => {",
        '    // const { tools } = await client.listTools();',
        '    // const toolNames = tools.map(t => t.name);',
        "    // expect(toolNames).toContain('your_tool_name');",
        '    expect(true).toBe(true); // replace with actual assertion',
        '  });',
        '',
        "  it('should have non-empty description for each tool', async () => {",
        '    // const { tools } = await client.listTools();',
        '    // for (const tool of tools) {',
        '    //   expect(tool.description).toBeTruthy();',
        '    //   expect(tool.description.length).toBeLessThanOrEqual(1024);',
        '    // }',
        '    expect(true).toBe(true);',
        '  });',
        '',
        '  it(\'should have valid inputSchema (type: "object") for each tool\', async () => {',
        '    // const { tools } = await client.listTools();',
        '    // for (const tool of tools) {',
        "    //   expect(tool.inputSchema.type).toBe('object');",
        '    // }',
        '    expect(true).toBe(true);',
        '  });',
        '});',
        '',
        `describe('${title} — Valid Tool Calls', () => {`,
        "  it('should return text content for valid input', async () => {",
        "    // const result = await client.callTool({ name: 'your_tool_name', arguments: { input: 'test' } });",
        '    // expect(result.isError).toBeFalsy();',
        "    // expect(result.content[0]?.type).toBe('text');",
        '    expect(true).toBe(true);',
        '  });',
        '});',
        '',
        `describe('${title} — Invalid Tool Calls (InvalidParams)', () => {`,
        "  it('should return InvalidParams error for missing required field', async () => {",
        "    // await expect(client.callTool({ name: 'your_tool_name', arguments: {} }))",
        '    //   .rejects.toThrow(/InvalidParams/);',
        '    expect(true).toBe(true);',
        '  });',
        '',
        "  it('should reject extra fields when additionalProperties is false', async () => {",
        '    // await expect(client.callTool({',
        "    //   name: 'your_tool_name',",
        "    //   arguments: { input: 'test', unknownField: 'extra' }",
        '    // })).rejects.toThrow(/InvalidParams/);',
        '    expect(true).toBe(true);',
        '  });',
        '});',
    ];
    return lines.join('\n');
}
function buildMcpIntegrationTestContent(title, testFramework) {
    const isVitest = testFramework === 'vitest';
    const source = isVitest ? 'vitest' : 'jest';
    const lines = [
        `// Integration tests for MCP server: ${title}`,
        '// SPEC-016b: E2E initialize handshake, resource reads, concurrent calls',
        `import { describe, it, expect, beforeAll, afterAll } from '${source}';`,
        '',
        "// import { Client } from '@modelcontextprotocol/sdk/client/index.js';",
        "// import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';",
        '',
        `describe('${title} — E2E Initialize Handshake', () => {`,
        '  // let client: Client;',
        '',
        '  beforeAll(async () => {',
        "    // const transport = new StdioClientTransport({ command: 'node', args: ['dist/index.js'] });",
        "    // client = new Client({ name: 'smoke-test', version: '1.0.0' }, { capabilities: {} });",
        '    // await client.connect(transport);',
        '  });',
        '',
        '  afterAll(async () => {',
        '    // await client.close();',
        '  });',
        '',
        "  it('should complete initialize handshake successfully', async () => {",
        '    // const serverInfo = client.getServerVersion();',
        '    // expect(serverInfo).toBeDefined();',
        '    expect(true).toBe(true);',
        '  });',
        '',
        "  it('should respond to tools/list after initialize', async () => {",
        '    // const { tools } = await client.listTools();',
        '    // expect(tools.length).toBeGreaterThan(0);',
        '    expect(true).toBe(true);',
        '  });',
        '});',
        '',
        `describe('${title} — Resource Reads', () => {`,
        "  it('should return resource content with correct MIME type', async () => {",
        "    // const { contents } = await client.readResource({ uri: 'config://server/settings' });",
        "    // expect(contents[0]?.mimeType).toBe('application/json');",
        '    expect(true).toBe(true);',
        '  });',
        '',
        "  it('should return error for unknown resource URI', async () => {",
        "    // await expect(client.readResource({ uri: 'unknown://not-found' }))",
        '    //   .rejects.toThrow();',
        '    expect(true).toBe(true);',
        '  });',
        '});',
        '',
        `describe('${title} — Concurrent Tool Calls', () => {`,
        "  it('should handle 10 concurrent calls without errors', async () => {",
        '    // const calls = Array.from({ length: 10 }, () =>',
        "    //   client.callTool({ name: 'your_tool_name', arguments: { input: 'concurrent-test' } })",
        '    // );',
        '    // const results = await Promise.all(calls);',
        '    // expect(results.every(r => !r.isError)).toBe(true);',
        '    expect(true).toBe(true);',
        '  });',
        '});',
    ];
    return lines.join('\n');
}
// === TestFile builders ===
export function generateMcpTestFiles(spec, testDir, testFramework, language) {
    const slug = spec.id.toLowerCase().replace(/[^a-z0-9]/g, '-');
    const ext = language === 'typescript' ? 'ts' : 'js';
    return [
        {
            path: `${testDir}/unit/${slug}.mcp.test.${ext}`,
            framework: testFramework,
            content: buildMcpUnitTestContent(spec.title, testFramework, language),
            ready: false,
        },
        {
            path: `${testDir}/integration/${slug}.mcp.integration.test.${ext}`,
            framework: testFramework,
            content: buildMcpIntegrationTestContent(spec.title, testFramework),
            ready: false,
        },
    ];
}
//# sourceMappingURL=mcp-tests-generator.js.map