UNPKG

symref

Version:

Static code checker for AI code agents (Windsurf, Cline, etc.)

176 lines (164 loc) 5.92 kB
/** * テストプロンプトを生成するクラス */ export class TestPromptGenerator { /** * テストプロンプトを生成する * @param context 生成コンテキスト * @returns 生成されたプロンプト */ generate(context) { const { callGraph, fromRefs, toRefs, framework } = context; return `# テストコード生成支援情報 ## 1. 検証対象の呼び出し経路 ${this.formatCallPath(callGraph)} ## 2. シンボル情報 ### 開始シンボル: ${fromRefs.symbol} - 定義: ${fromRefs.definition.filePath}:${fromRefs.definition.line} - 種類: ${fromRefs.type} - 参照数: ${fromRefs.references.length} ### 終了シンボル: ${toRefs.symbol} - 定義: ${toRefs.definition.filePath}:${toRefs.definition.line} - 種類: ${toRefs.type} - 参照数: ${toRefs.references.length} ## 3. テスト要件 1. エントリーポイントからの呼び出しフローを検証 2. 各シンボルの呼び出しをspyで検証 3. 呼び出し順序の確認 4. エラーケースの検証 ## 4. 推奨テスト構造 \`\`\`typescript ${this.generateTestStructure(context)} \`\`\` ## 5. テストデータ ${this.generateTestData(context)} ## 6. 注意事項 - テストケースは実際のユースケースに合わせて調整してください - モックの設定は必要に応じて追加してください - 非同期処理の場合は適切な待機処理を追加してください `; } /** * 呼び出し経路をフォーマットする * @param callGraph 呼び出しグラフ * @returns フォーマットされた呼び出し経路 */ formatCallPath(callGraph) { if (!callGraph.paths || callGraph.paths.length === 0) { return '呼び出し経路が見つかりませんでした。'; } return callGraph.paths.map(path => { return path.nodes.map((node, index) => { const prefix = index === 0 ? '' : ' '.repeat(index - 1) + '└─ '; return `${prefix}${node.symbol}`; }).join('\n'); }).join('\n\n'); } /** * テスト構造を生成する * @param context 生成コンテキスト * @returns 生成されたテスト構造 */ generateTestStructure(context) { const { framework, fromRefs, toRefs } = context; const isJest = framework === 'jest'; return `describe('${fromRefs.symbol} to ${toRefs.symbol} の呼び出し経路', () => { // スパイとモックの設定 const spies = { ${this.generateSpySetup(context)} }; // テストケース it('正常系: 呼び出し経路が正しく実行されること', async () => { // テストの実装 ${this.generateTestImplementation(context)} }); it('異常系: エラーが発生した場合の処理', async () => { // エラーケースの実装 ${this.generateErrorCase(context)} }); });`; } /** * スパイの設定を生成する * @param context 生成コンテキスト * @returns 生成されたスパイ設定 */ generateSpySetup(context) { const { callGraph } = context; if (!callGraph.paths || callGraph.paths.length === 0) { return ''; } // 呼び出し経路から一意のシンボルを抽出 const uniqueSymbols = new Set(); callGraph.paths.forEach((path) => { path.nodes.forEach((node) => uniqueSymbols.add(node.symbol)); }); return Array.from(uniqueSymbols) .map(symbol => `${symbol}: ${context.framework === 'jest' ? 'jest.spyOn()' : 'sinon.spy()'}`) .join(',\n '); } /** * テスト実装を生成する * @param context 生成コンテキスト * @returns 生成されたテスト実装 */ generateTestImplementation(context) { const { fromRefs, toRefs } = context; return `// ${fromRefs.symbol}を呼び出し await ${fromRefs.symbol}(); // 呼び出し順序の検証 ${this.generateCallOrderVerification(context)}`; } /** * 呼び出し順序の検証を生成する * @param context 生成コンテキスト * @returns 生成された呼び出し順序検証 */ generateCallOrderVerification(context) { const { callGraph, framework } = context; if (!callGraph.paths || callGraph.paths.length === 0) { return ''; } const isJest = framework === 'jest'; const path = callGraph.paths[0]; // 最初の経路を使用 return path.nodes.map((node, index) => { const expectFunc = isJest ? 'expect' : 'assert'; return `${expectFunc}(spies.${node.symbol}).toHaveBeenCalled();`; }).join('\n'); } /** * エラーケースを生成する * @param context 生成コンテキスト * @returns 生成されたエラーケース */ generateErrorCase(context) { const { framework } = context; const isJest = framework === 'jest'; return `// エラーを発生させる ${isJest ? 'jest.spyOn()' : 'sinon.stub()'}.mockRejectedValue(new Error('テストエラー')); // エラーハンドリングの検証 ${isJest ? 'expect' : 'assert'}(async () => { await ${context.fromRefs.symbol}(); }).rejects.toThrow('テストエラー');`; } /** * テストデータを生成する * @param context 生成コンテキスト * @returns 生成されたテストデータ */ generateTestData(context) { return `## テストデータ例 \`\`\`typescript const testData = { // テストデータをここに定義 }; \`\`\` ## モックデータ例 \`\`\`typescript const mockData = { // モックデータをここに定義 }; \`\`\``; } } //# sourceMappingURL=TestPromptGenerator.js.map