diff --git a/.vscode/settings.json b/.vscode/settings.json index 19f996ff..ca71d1a4 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,7 +1,6 @@ { // 파일 저장 시 자동 포맷팅 "editor.formatOnSave": true, - // TypeScript/JavaScript 파일에 대한 기본 포맷터로 Prettier 사용 "[typescript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" @@ -9,7 +8,6 @@ "[javascript]": { "editor.defaultFormatter": "esbenp.prettier-vscode" }, - // Markdown 및 MDX 파일에 대한 ESLint 및 Prettier 비활성화 "[markdown]": { "editor.formatOnSave": false, @@ -23,21 +21,17 @@ "source.fixAll.eslint": "never" } }, - // ESLint 설정 "eslint.enable": true, "eslint.validate": ["javascript", "typescript"], - // 파일 저장 시 ESLint 자동 수정 (Markdown/MDX 제외) "editor.codeActionsOnSave": { "source.fixAll.eslint": "explicit" }, - // Prettier 설정 "prettier.requireConfig": true, "prettier.configPath": ".prettierrc", "prettier.disableLanguages": ["markdown", "mdx"], - // TypeScript 설정 "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/bin/index.ts b/bin/index.ts index 92407061..e76e662d 100644 --- a/bin/index.ts +++ b/bin/index.ts @@ -57,7 +57,11 @@ program .description("Generate ITDOC test code based on LLM.") .option("-a, --app ", "Path to the Express root app file.") .option("-e, --env ", "Path to the .env file.") - .action(async (options: { env?: string; app?: string }) => { + .option( + "-l, --lang ", + "Output language for test generation: 'en' for English, 'ko' for Korean (default: 'ko')", + ) + .action(async (options: { env?: string; app?: string; lang?: string }) => { const envPath = options.env ? path.isAbsolute(options.env) ? options.env @@ -74,13 +78,22 @@ program process.exit(1) } + const lang = options.lang?.toLowerCase() + const isEn = lang === "en" + + if (lang && lang !== "en" && lang !== "ko") { + logger.error(`Invalid language option: ${lang}. Must be 'en' or 'ko'.`) + process.exit(1) + } + logger.box("ITDOC LLM START") if (options.app) { const appPath = resolvePath(options.app) logger.info(`Running analysis based on Express app path: ${appPath}`) + logger.info(`Output language: ${isEn ? "English" : "Korean"}`) try { - await generateByLLM(appPath, envPath) + await generateByLLM(appPath, envPath, isEn) } catch (err) { logger.error(`LLM generation failed: ${(err as Error).message}`) process.exit(1) diff --git a/itdoc-doc/docs/experiments/LLM.mdx b/itdoc-doc/docs/experiments/LLM.mdx index 6101ea10..02b37623 100644 --- a/itdoc-doc/docs/experiments/LLM.mdx +++ b/itdoc-doc/docs/experiments/LLM.mdx @@ -188,10 +188,29 @@ Currently, source code-based automatic test generation is only supported for the ```bash itdoc generate -a {YOUR_APP_FILE_PATH} itdoc generate --app {YOUR_APP_FILE_PATH} + +# Generate tests in English(default : korean) +itdoc generate -a {YOUR_APP_FILE_PATH} -l en +itdoc generate --app {YOUR_APP_FILE_PATH} --lang en ``` | Option | Description | |------------------------------------------------------------------------|--------------------------------| | --app (-a) | Root app source code file path | +| --lang (-l) | Output language: `en` for English, `ko` for Korean (default: `ko`) | + +When you run this command, it analyzes the Express application defined in `{YOUR_APP_FILE_PATH}` and automatically generates tests for the API endpoints in that application. + +:::tip[Language Selection] +- By default, test descriptions and comments are generated in **Korean** (`ko`). +- Use the `--lang en` (or `-l en`) option to generate all test content in **English**. +::: + +**Example:** +```bash +# Korean output (default) +itdoc generate -a ./app.js -When you run this command, it analyzes the Express application defined in `{YOUR_APP_FILE_PATH}` and automatically generates tests for the API endpoints in that application. \ No newline at end of file +# English output +itdoc generate -a ./app.js --lang en +``` \ No newline at end of file diff --git a/itdoc-doc/i18n/ko/docusaurus-plugin-content-docs/current/experiments/LLM.mdx b/itdoc-doc/i18n/ko/docusaurus-plugin-content-docs/current/experiments/LLM.mdx index 318b224b..b234478a 100644 --- a/itdoc-doc/i18n/ko/docusaurus-plugin-content-docs/current/experiments/LLM.mdx +++ b/itdoc-doc/i18n/ko/docusaurus-plugin-content-docs/current/experiments/LLM.mdx @@ -190,16 +190,35 @@ LLM 기능을 사용하기 전과 후를 비교해보겠습니다. ```bash itdoc generate -a {YOUR_APP_FILE_PATH} itdoc generate --app {YOUR_APP_FILE_PATH} + +# 영어로 테스트 생성 (기본값: 한국어) +itdoc generate -a {YOUR_APP_FILE_PATH} -l en +itdoc generate --app {YOUR_APP_FILE_PATH} --lang en ``` | 옵션 | 설명 | |------------------------------------------------------------------------|---------------------| | --app (-a) | root app 소스코드 파일 경로 | +| --lang (-l) | 출력 언어: `en`은 영어, `ko`는 한국어 (기본값: `ko`) | 명령어를 실행하면 `{YOUR_APP_FILE_PATH}`에 정의된 Express 애플리케이션을 분석하여, 해당 애플리케이션의 API 엔드포인트에 대한 테스트를 자동으로 생성합니다. +:::tip[언어 선택] +- 기본적으로 테스트 설명과 주석은 **한국어**(`ko`)로 생성됩니다. +- `--lang en` (또는 `-l en`) 옵션을 사용하면 모든 테스트 내용이 **영어**로 생성됩니다. +::: + +**예시:** +```bash +# 한국어 출력 (기본값) +itdoc generate -a ./app.js + +# 영어 출력 +itdoc generate -a ./app.js --lang en +``` + :::info[itdoc은 소스코드를 외부 서버에 전송하지 않습니다] 자체적인 AST 분석을 통해 `API Spec Markdown`을 만들고, 이를 ChatGPT에 전달하여 테스트 케이스를 생성합니다. 따라서, 여러분의 소스코드를 외부 서버에 전송하지 않으니 안심하고 사용하세요. diff --git a/script/llm/index.ts b/script/llm/index.ts index 248380c0..de69dd8d 100644 --- a/script/llm/index.ts +++ b/script/llm/index.ts @@ -46,8 +46,12 @@ function groupAndChunkSpecRoutes(routes: RouteResult[], chunkSize: number = 10): const by: Record = {} for (const r of routes) { const prefix = getPathPrefix(r.path || "/unknown") - ;(by[prefix] ||= []).push(r) + if (!by[prefix]) { + by[prefix] = [] + } + by[prefix].push(r) } + const out: RouteResult[][] = [] for (const group of Object.values(by)) { for (const c of _.chunk(group, chunkSize)) out.push(c) @@ -126,9 +130,14 @@ export async function makeitdoc( * - Writes the resulting test file with prelude (imports/helpers). * @param {string} [appPath] - Path to Express app entry. * @param {string} [envPath] - Path to .env file containing OPENAI_API_KEY. + * @param {boolean} [isEn] - Output in English (true) or Korean (false). Defaults to false (Korean). * @returns {Promise} Exits the process on unrecoverable errors. */ -export default async function generateByLLM(appPath?: string, envPath?: string): Promise { +export default async function generateByLLM( + appPath?: string, + envPath?: string, + isEn: boolean = false, +): Promise { const actualEnv = loadFile("env", envPath, false) dotenv.config({ path: actualEnv }) if (!process.env.OPENAI_API_KEY) { @@ -163,7 +172,7 @@ export default async function generateByLLM(appPath?: string, envPath?: string): process.exit(1) } - const doc = await makeitdoc(openai, analyzedRoutes, false, isTypeScript) + const doc = await makeitdoc(openai, analyzedRoutes, isEn, isTypeScript) if (!doc) { logger.error("Failed to generate itdoc from markdown spec.") process.exit(1) diff --git a/script/llm/prompt/index.ts b/script/llm/prompt/index.ts index fe6fc913..a465fb74 100644 --- a/script/llm/prompt/index.ts +++ b/script/llm/prompt/index.ts @@ -116,7 +116,32 @@ export function getItdocPrompt( const codeMessage = `${codeType} ${lang.codeLabel}` const partGuide = part > 1 ? lang.chunksGuideNext : lang.chunksGuideFirst - return ` + const promptTemplate = isEn + ? ` +Generate an itdoc test script in ${codeMessage} based on the following test description. + +Required Rules: +- ${lang.noComments} +- ${lang.codeOnly} +- ${lang.orderGuide} +- ${lang.branchGuide} +- ${lang.branchGuide2} +- ${lang.fieldGuide} +- ${lang.fieldGuide2} +- ${lang.headerGuide} +- ${lang.noPathImport} +- ${lang.initGiven} +- ${lang.etc} +- ${partGuide} +- ${lang.outputInstruction} + +[Route Analysis Results to Test] +${JSON.stringify(routesChunk, null, 2)} + +[Function Example] +${itdocExample} +`.trim() + : ` 다음 테스트 설명을 기반으로 itdoc 테스트 스크립트를 ${codeMessage}로 생성하세요. 필수 규칙: @@ -140,4 +165,6 @@ ${JSON.stringify(routesChunk, null, 2)} [함수 예시] ${itdocExample} `.trim() + + return promptTemplate }