Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/release-please/manifest.json
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{".":"0.4.0"}
{".":"0.4.1"}
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Changelog

## [0.4.1](https://github.com/do-pa/itdoc/compare/v0.4.0...v0.4.1) (2025-08-21)


### 🩹 Fixes

* og_image is not working ([#231](https://github.com/do-pa/itdoc/issues/231)) ([d1070ec](https://github.com/do-pa/itdoc/commit/d1070ec1064cf914b576e2eb9153378903ccaf89)), closes [#230](https://github.com/do-pa/itdoc/issues/230)
* resolve issue causing LLM script to not run properly ([#235](https://github.com/do-pa/itdoc/issues/235)) ([1fa8d90](https://github.com/do-pa/itdoc/commit/1fa8d90fe14c37031baaa58f375550785f055275))

## [0.4.0](https://github.com/do-pa/itdoc/compare/v0.3.0...v0.4.0) (2025-08-08)


Expand Down
21 changes: 10 additions & 11 deletions bin/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,22 +55,19 @@ Example:
program
.command("generate")
.description("Generate ITDOC test code based on LLM.")
.option("-p, --path <testspecPath>", "Path to the markdown test spec file.")
.option("-a, --app <appPath>", "Path to the Express root app file.")
.option("-e, --env <envPath>", "Path to the .env file.")
.action((options: { path?: string; env?: string; app?: string }) => {
.action(async (options: { env?: string; app?: string }) => {
const envPath = options.env
? path.isAbsolute(options.env)
? options.env
: path.resolve(process.cwd(), options.env)
: path.resolve(process.cwd(), ".env")

if (!options.path && !options.app) {
if (!options.app) {
logger.error(
"Either a test spec path (-p) or an Express app path (-a) must be provided. By default, the OpenAI key (OPENAI_API_KEY in .env) is loaded from the root directory, but you can customize the path if needed",
"An Express app path (-a) must be provided. By default, the OpenAI key (OPENAI_API_KEY in .env) is loaded from the root directory, but you can customize the path with -e/--env if needed.",
)
logger.info("ex) itdoc generate -p ../md/testspec.md")
logger.info("ex) itdoc generate --path ../md/testspec.md")
logger.info("ex) itdoc generate -a ../app.js")
logger.info("ex) itdoc generate --app ../app.js")
logger.info("ex) itdoc generate -a ../app.js -e <custom path : env>")
Expand All @@ -80,12 +77,14 @@ program
logger.box("ITDOC LLM START")
if (options.app) {
const appPath = resolvePath(options.app)

logger.info(`Running analysis based on Express app path: ${appPath}`)
generateByLLM("", appPath, envPath)
} else if (options.path) {
const specPath = resolvePath(options.path)
logger.info(`Running analysis based on test spec (MD) path: ${specPath}`)
generateByLLM(specPath, "", envPath)
try {
await generateByLLM(appPath, envPath)
} catch (err) {
logger.error(`LLM generation failed: ${(err as Error).message}`)
process.exit(1)
}
}
})

Expand Down
108 changes: 55 additions & 53 deletions examples/express/__tests__/expressApp.test.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,60 @@
const app = require("../expressApp.js")
const { describeAPI, itDoc, HttpStatus, field, HttpMethod } = require("itdoc")

const targetApp = app
const targetApp = app
describeAPI(
HttpMethod.POST,
"signup",
{
summary: "회원 가입 API",
tag: "Auth",
description: "사용자로 부터 아이디와 패스워드를 받아 회원가입을 수행합니다.",
},
targetApp,
(apiDoc) => {
itDoc("회원가입 성공", async () => {
await apiDoc
.test()
.prettyPrint()
.req()
.body({
username: field("사용자 이름", "username"),
password: field("패스워드", "P@ssw0rd123!@#"),
})
.res()
.status(HttpStatus.CREATED)
})

itDoc("아이디를 입력하지 않으면 회원가입 실패한다.", async () => {
await apiDoc
.test()
.req()
.body({
password: field("패스워드", "P@ssw0rd123!@#"),
})
.res()
.status(HttpStatus.BAD_REQUEST)
.body({
error: field("에러 메시지", "username is required"),
})
})

itDoc("패스워드가 8자 미만이면 회원가입 실패한다.", async () => {
await apiDoc
.test()
.req()
.body({
username: field("아이디", "penekhun"),
password: field("패스워드", "1234567"),
})
.res()
.status(HttpStatus.BAD_REQUEST)
.body({
error: field("에러 메시지", "password must be at least 8 characters"),
})
})
},
)

describeAPI(
HttpMethod.GET,
Expand Down Expand Up @@ -419,7 +472,7 @@ describeAPI(
.test()
.req()
.header({
"If-None-Match": field("ETag 값", '"abc123"'),
"if-none-match": field("ETag 값", '"abc123"'),
Accept: "application/json",
"Accept-Language": "ko-KR,ko;q=0.9,en-US;q=0.8,en;q=0.7",
})
Expand All @@ -440,57 +493,6 @@ describeAPI(
})
},
)

describeAPI(
HttpMethod.POST,
"/validate",
{
summary: "데이터 유효성 검증 API",
tag: "Validation",
description: "다양한 형태의 데이터 유효성을 검증하고 상세한 오류 정보를 제공합니다.",
},
targetApp,
(apiDoc) => {
itDoc("다양한 필드 유효성 오류", async () => {
await apiDoc
.test()
.req()
.body({
username: field("잘못된 사용자명", "a"),
email: field("잘못된 이메일", "not-an-email"),
age: field("잘못된 나이", -5),
registrationDate: field("잘못된 날짜", "2023-13-45"),
})
.res()
.status(HttpStatus.BAD_REQUEST)
.body({
success: false,
errors: field("오류 목록", [
{
field: "username",
message: "Username must be at least 3 characters",
code: "MIN_LENGTH",
},
{
field: "email",
message: "Invalid email format",
code: "INVALID_FORMAT",
},
{
field: "age",
message: "Age must be a positive number",
code: "POSITIVE_NUMBER",
},
{
field: "registrationDate",
message: "Invalid date format",
code: "INVALID_DATE",
},
]),
})
})
},
)
describeAPI(
HttpMethod.GET,
"/failed-test",
Expand Down
58 changes: 0 additions & 58 deletions examples/express/__tests__/expressApp2.test.js

This file was deleted.

Loading
Loading