Files
qiming/qimingclaw/crates/agent-electron-client/src/shared/constants.test.ts

215 lines
7.1 KiB
TypeScript

/**
* 单元测试: constants
*
* 测试应用常量的完整性和一致性
*/
import { describe, it, expect } from "vitest";
import {
APP_DISPLAY_NAME,
APP_NAME_IDENTIFIER,
APP_DATA_DIR_NAME,
DEFAULT_MCP_PROXY_PORT,
DEFAULT_FILE_SERVER_PORT,
DEFAULT_AGENT_RUNNER_PORT,
DEFAULT_LANPROXY_PORT,
DEFAULT_DEV_SERVER_PORT,
LOCALHOST_IP,
LOCALHOST_HOSTNAME,
LOCAL_HOST_URL,
DEFAULT_ANTHROPIC_API_URL,
DEFAULT_SERVER_HOST,
DEFAULT_AI_ENGINE,
isAgentEngineType,
normalizeAgentEngine,
normalizeOptionalPort,
SUPPORTED_AGENT_ENGINES,
DEFAULT_AI_MODEL,
DEFAULT_MAX_TOKENS,
DEFAULT_TEMPERATURE,
MODEL_OPTIONS,
DEFAULT_API_TIMEOUT,
DEFAULT_SSE_RETRY_DELAY,
DEFAULT_SSE_MAX_RETRY_DELAY,
DEFAULT_SSE_HEARTBEAT_INTERVAL,
DEFAULT_STARTUP_DELAY,
CLEANUP_TIMEOUT,
PROCESS_KILL_ESCALATION_TIMEOUT,
ACP_ABORT_TIMEOUT,
ACP_PROMPT_TIMEOUT,
ENGINE_DESTROY_TIMEOUT,
DEPS_SYNC_TIMEOUT,
NPM_MIRRORS,
UV_MIRRORS,
DEFAULT_MIRROR_CONFIG,
STORAGE_KEYS,
AUTH_KEYS,
} from "./constants";
describe("Constants", () => {
describe("App Identity", () => {
it("should have consistent app name", () => {
expect(APP_DISPLAY_NAME).toBe("飞天数字员工");
expect(APP_NAME_IDENTIFIER).toBe("qimingclaw");
});
it("should have app data dir name with dot prefix", () => {
expect(APP_DATA_DIR_NAME).toBe(".qimingclaw");
});
});
describe("Port Configuration", () => {
it("should have valid port numbers", () => {
expect(DEFAULT_MCP_PROXY_PORT).toBeGreaterThan(0);
expect(DEFAULT_MCP_PROXY_PORT).toBeLessThan(65536);
expect(DEFAULT_FILE_SERVER_PORT).toBe(60005);
expect(DEFAULT_AGENT_RUNNER_PORT).toBe(60006);
expect(DEFAULT_LANPROXY_PORT).toBe(60002);
expect(DEFAULT_DEV_SERVER_PORT).toBe(60173);
});
it("should have non-overlapping ports", () => {
const ports = [
DEFAULT_MCP_PROXY_PORT,
DEFAULT_FILE_SERVER_PORT,
DEFAULT_AGENT_RUNNER_PORT,
DEFAULT_LANPROXY_PORT,
DEFAULT_DEV_SERVER_PORT,
];
const uniquePorts = new Set(ports);
expect(uniquePorts.size).toBe(ports.length);
});
});
describe("Host Configuration", () => {
it("should have localhost configuration", () => {
expect(LOCALHOST_IP).toBe("127.0.0.1");
expect(LOCALHOST_HOSTNAME).toBe("localhost");
expect(LOCAL_HOST_URL).toBe("http://127.0.0.1");
});
});
describe("API URLs", () => {
it("should have valid API URLs", () => {
expect(DEFAULT_ANTHROPIC_API_URL).toMatch(/^https?:\/\//);
expect(DEFAULT_SERVER_HOST).toMatch(/^https?:\/\//);
});
});
describe("AI Configuration", () => {
it("should have valid AI engine type", () => {
expect(["claude-code", "qimingcode"]).toContain(DEFAULT_AI_ENGINE);
expect(SUPPORTED_AGENT_ENGINES).toEqual(["claude-code", "qimingcode"]);
});
it("should normalize legacy or invalid AI engine values", () => {
expect(isAgentEngineType("claude-code")).toBe(true);
expect(isAgentEngineType("qimingcode")).toBe(true);
expect(isAgentEngineType("hermes-agent")).toBe(false);
expect(normalizeAgentEngine("qimingcode")).toBe("qimingcode");
expect(normalizeAgentEngine("hermes-agent")).toBe(DEFAULT_AI_ENGINE);
expect(normalizeAgentEngine(undefined)).toBe(DEFAULT_AI_ENGINE);
});
it("should normalize optional port values", () => {
expect(normalizeOptionalPort(60001)).toBe(60001);
expect(normalizeOptionalPort("60001")).toBe(60001);
expect(normalizeOptionalPort("")).toBeUndefined();
expect(normalizeOptionalPort("abc")).toBeUndefined();
expect(normalizeOptionalPort(0)).toBeUndefined();
expect(normalizeOptionalPort(65536)).toBeUndefined();
});
it("should have non-empty model name", () => {
expect(DEFAULT_AI_MODEL).toBeTruthy();
expect(DEFAULT_AI_MODEL.length).toBeGreaterThan(0);
});
it("should have valid token limits", () => {
expect(DEFAULT_MAX_TOKENS).toBeGreaterThan(0);
});
it("should have valid temperature range", () => {
expect(DEFAULT_TEMPERATURE).toBeGreaterThanOrEqual(0);
expect(DEFAULT_TEMPERATURE).toBeLessThanOrEqual(1);
});
it("should have model options with labels and values", () => {
MODEL_OPTIONS.forEach((option) => {
expect(option.label).toBeTruthy();
expect(option.value).toBeTruthy();
});
});
});
describe("Timeout Configuration", () => {
it("should have positive timeout values", () => {
expect(DEFAULT_API_TIMEOUT).toBeGreaterThan(0);
expect(DEFAULT_SSE_RETRY_DELAY).toBeGreaterThan(0);
expect(DEFAULT_SSE_MAX_RETRY_DELAY).toBeGreaterThan(0);
expect(DEFAULT_SSE_HEARTBEAT_INTERVAL).toBeGreaterThan(0);
expect(DEFAULT_STARTUP_DELAY).toBeGreaterThan(0);
expect(CLEANUP_TIMEOUT).toBeGreaterThan(0);
expect(PROCESS_KILL_ESCALATION_TIMEOUT).toBeGreaterThan(0);
expect(ACP_ABORT_TIMEOUT).toBeGreaterThan(0);
expect(ACP_PROMPT_TIMEOUT).toBeGreaterThan(0);
expect(ENGINE_DESTROY_TIMEOUT).toBeGreaterThan(0);
expect(DEPS_SYNC_TIMEOUT).toBeGreaterThan(0);
});
it("should have max retry delay greater than initial retry delay", () => {
expect(DEFAULT_SSE_MAX_RETRY_DELAY).toBeGreaterThanOrEqual(
DEFAULT_SSE_RETRY_DELAY,
);
});
it("should have process kill escalation shorter than cleanup timeout", () => {
expect(PROCESS_KILL_ESCALATION_TIMEOUT).toBeLessThan(CLEANUP_TIMEOUT);
});
it("should have ACP abort timeout shorter than engine destroy timeout", () => {
expect(ACP_ABORT_TIMEOUT).toBeLessThanOrEqual(ENGINE_DESTROY_TIMEOUT);
});
it("should have deps sync timeout as the largest timeout", () => {
expect(DEPS_SYNC_TIMEOUT).toBeGreaterThan(ENGINE_DESTROY_TIMEOUT);
expect(DEPS_SYNC_TIMEOUT).toBeGreaterThan(CLEANUP_TIMEOUT);
});
});
describe("Mirror Configuration", () => {
it("should have npm mirror presets", () => {
expect(NPM_MIRRORS.OFFICIAL).toContain("npmjs.org");
expect(NPM_MIRRORS.TAOBAO).toContain("npmmirror");
expect(NPM_MIRRORS.TENCENT).toContain("tencent");
});
it("should have uv mirror presets", () => {
expect(UV_MIRRORS.OFFICIAL).toContain("pypi.org");
expect(UV_MIRRORS.TUNA).toContain("tsinghua");
expect(UV_MIRRORS.ALIYUN).toContain("aliyun");
expect(UV_MIRRORS.TENCENT).toContain("tencent");
});
it("should have default mirror config", () => {
expect(DEFAULT_MIRROR_CONFIG.npmRegistry).toBeTruthy();
expect(DEFAULT_MIRROR_CONFIG.uvIndexUrl).toBeTruthy();
});
});
describe("Storage Keys", () => {
it("should have all required storage keys", () => {
expect(STORAGE_KEYS.SETUP_STATE).toBe("setup_state");
expect(STORAGE_KEYS.STEP1_CONFIG).toBe("step1_config");
expect(STORAGE_KEYS.AUTH_USER).toBe("auth_user");
expect(STORAGE_KEYS.API_KEY).toBe("anthropic_api_key");
});
it("should have auth keys", () => {
expect(AUTH_KEYS.USERNAME).toBe("auth.username");
expect(AUTH_KEYS.PASSWORD).toBe("auth.password");
expect(AUTH_KEYS.SAVED_KEY).toBe("auth.saved_key");
});
});
});