chore: 强化代码质量与风格检查体系
ESLint 升级到 recommended-type-checked + stylistic-type-checked, 引入 perfectionist 导入排序和 import 插件导入验证。 Prettier 显式声明全部格式化参数,消除跨环境差异。 TypeScript 启用 noUnusedLocals 和 noPropertyAccessFromIndexSignature。 完善 ignore 列表,排除 .agents/、bun.lock、data/ 等。 引入 husky + lint-staged(pre-commit)+ commitlint(commit-msg)。 更新 DEVELOPMENT.md 代码质量章节。 修复所有新增规则检测到的类型和风格违规。
This commit is contained in:
@@ -1,12 +1,13 @@
|
||||
import { beforeAll, afterAll, describe, expect, test } from "bun:test";
|
||||
import { loadConfig, parseDuration } from "../../../src/server/checker/config-loader";
|
||||
import { readRuntimeConfig } from "../../../src/server/config";
|
||||
import { afterAll, beforeAll, describe, expect, test } from "bun:test";
|
||||
import { mkdir, rm, writeFile } from "node:fs/promises";
|
||||
import { join } from "node:path";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
import { loadConfig, parseDuration } from "../../../src/server/checker/config-loader";
|
||||
import { checkerRegistry } from "../../../src/server/checker/runner";
|
||||
import { HttpChecker } from "../../../src/server/checker/runner/http/runner";
|
||||
import { CommandChecker } from "../../../src/server/checker/runner/command/runner";
|
||||
import { HttpChecker } from "../../../src/server/checker/runner/http/runner";
|
||||
import { readRuntimeConfig } from "../../../src/server/config";
|
||||
|
||||
function ensureRegistered() {
|
||||
if (!checkerRegistry.supportedTypes.includes("http")) {
|
||||
@@ -66,7 +67,7 @@ describe("loadConfig", () => {
|
||||
});
|
||||
|
||||
afterAll(async () => {
|
||||
await rm(tempDir, { recursive: true, force: true });
|
||||
await rm(tempDir, { force: true, recursive: true });
|
||||
});
|
||||
|
||||
test("解析最简 HTTP 配置", async () => {
|
||||
@@ -125,7 +126,7 @@ describe("loadConfig", () => {
|
||||
expect(t.command.args).toEqual(["nginx"]);
|
||||
expect(t.command.cwd).toBe(subdir);
|
||||
expect(t.command.maxOutputBytes).toBe(104857600);
|
||||
expect(t.command.env.PATH).toBeDefined();
|
||||
expect(t.command.env["PATH"]).toBeDefined();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -230,6 +231,7 @@ targets:
|
||||
});
|
||||
|
||||
test("配置文件不存在抛出错误", async () => {
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig("/nonexistent/file.yaml")).rejects.toThrow("配置文件不存在");
|
||||
});
|
||||
|
||||
@@ -243,6 +245,7 @@ targets:
|
||||
url: "http://example.com"
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("缺少 name 字段");
|
||||
});
|
||||
|
||||
@@ -256,6 +259,7 @@ targets:
|
||||
url: "http://example.com"
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("缺少 type 字段");
|
||||
});
|
||||
|
||||
@@ -269,6 +273,7 @@ targets:
|
||||
http: {}
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("缺少 http.url 字段");
|
||||
});
|
||||
|
||||
@@ -282,6 +287,7 @@ targets:
|
||||
command: {}
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("缺少 command.exec 字段");
|
||||
});
|
||||
|
||||
@@ -294,6 +300,7 @@ targets:
|
||||
type: dns
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("不支持的 type");
|
||||
});
|
||||
|
||||
@@ -312,12 +319,14 @@ targets:
|
||||
url: "http://b.com"
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("target name 重复");
|
||||
});
|
||||
|
||||
test("targets 为空数组抛出错误", async () => {
|
||||
const configPath = join(tempDir, "empty-targets.yaml");
|
||||
await writeFile(configPath, `targets: []`);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("至少一个 target");
|
||||
});
|
||||
|
||||
@@ -334,6 +343,7 @@ targets:
|
||||
url: "http://a.com"
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("无效端口号");
|
||||
});
|
||||
|
||||
@@ -350,6 +360,7 @@ targets:
|
||||
url: "http://a.com"
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("maxConcurrentChecks 必须为正整数");
|
||||
});
|
||||
|
||||
@@ -367,6 +378,7 @@ targets:
|
||||
url: "http://a.com"
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("无效的 size 格式");
|
||||
});
|
||||
|
||||
@@ -382,6 +394,7 @@ targets:
|
||||
url: "http://a.com"
|
||||
`,
|
||||
);
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("无效的时长格式");
|
||||
});
|
||||
|
||||
@@ -409,9 +422,9 @@ targets:
|
||||
const t = config.targets[0]!;
|
||||
if (t.type === "http") {
|
||||
expect(t.expect).toEqual({
|
||||
status: [200, 201],
|
||||
body: [{ contains: "ok" }, { json: { path: "$.status", equals: "ok" } }],
|
||||
body: [{ contains: "ok" }, { json: { equals: "ok", path: "$.status" } }],
|
||||
maxDurationMs: 3000,
|
||||
status: [200, 201],
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -441,9 +454,9 @@ targets:
|
||||
if (t.type === "command") {
|
||||
expect(t.expect).toEqual({
|
||||
exitCode: [0, 2],
|
||||
stdout: [{ contains: "ok" }, { match: "done" }],
|
||||
stderr: [{ empty: true }],
|
||||
maxDurationMs: 5000,
|
||||
stderr: [{ empty: true }],
|
||||
stdout: [{ contains: "ok" }, { match: "done" }],
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -488,9 +501,9 @@ targets:
|
||||
const config = await loadConfig(configPath);
|
||||
const t = config.targets[0]!;
|
||||
if (t.type === "command") {
|
||||
expect(t.command.env.LANG).toBe("C");
|
||||
expect(t.command.env.CUSTOM_VAR).toBe("test");
|
||||
expect(t.command.env.PATH).toBeDefined();
|
||||
expect(t.command.env["LANG"]).toBe("C");
|
||||
expect(t.command.env["CUSTOM_VAR"]).toBe("test");
|
||||
expect(t.command.env["PATH"]).toBeDefined();
|
||||
}
|
||||
});
|
||||
|
||||
@@ -540,6 +553,7 @@ targets:
|
||||
`,
|
||||
);
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/await-thenable
|
||||
await expect(loadConfig(configPath)).rejects.toThrow("group 字段必须为字符串");
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user