Files
deeplx/tests/utils/testHelpers.ts
T
xixu-me 8afa94767e Initial repository setup and core files added
Add configuration, documentation, code of conduct, contributing guide, license, and README files. Set up .gitignore, coverage config, GitHub issue templates, pull request template, and initial source code, scripts, and tests for DeepLX optimized for Cloudflare Workers.
2025-07-27 02:09:25 +08:00

260 lines
5.6 KiB
TypeScript

/**
* Test utility functions and helpers
*/
/**
* Create a mock translation response
*/
export function createMockTranslationResponse(
text: string = "你好世界",
sourceLang: string = "EN",
targetLang: string = "ZH",
id: number = 12345
) {
return {
result: {
texts: [{ text }],
lang: sourceLang,
},
id,
};
}
/**
* Create a mock error response
*/
export function createMockErrorResponse(
code: number = 1156049,
message: string = "Invalid request format"
) {
return {
error: {
code,
message,
},
};
}
/**
* Create a mock fetch response
*/
export function createMockFetchResponse(
data: any,
options: { ok?: boolean; status?: number } = {}
) {
return {
ok: options.ok ?? true,
status: options.status ?? 200,
json: () => Promise.resolve(data),
text: () => Promise.resolve(JSON.stringify(data)),
};
}
/**
* Create a mock request object
*/
export function createMockRequest(
url: string,
options: RequestInit & { body?: any } = {}
) {
return {
url,
method: options.method || "GET",
headers: new Map(Object.entries(options.headers || {})),
json: () => Promise.resolve(options.body || {}),
text: () =>
Promise.resolve(
typeof options.body === "string"
? options.body
: JSON.stringify(options.body || {})
),
};
}
/**
* Create a mock Hono context
*/
export function createMockHonoContext(
request: any,
env: Env,
options: any = {}
) {
return {
req: {
raw: request,
json: () => request.json(),
text: () => request.text(),
},
env,
json: jest.fn().mockImplementation((data, status) => ({
data,
status: status || 200,
})),
text: jest.fn().mockImplementation((text, status, headers) => ({
text,
status: status || 200,
headers,
})),
redirect: jest.fn().mockImplementation((url) => ({
redirect: url,
status: 302,
})),
...options,
};
}
/**
* Wait for a specified amount of time
*/
export function delay(ms: number): Promise<void> {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* Generate random text for testing
*/
export function generateRandomText(length: number = 100): string {
const chars =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 ";
let result = "";
for (let i = 0; i < length; i++) {
result += chars.charAt(Math.floor(Math.random() * chars.length));
}
return result;
}
/**
* Mock KV namespace with common operations
*/
export function createMockKV() {
const storage = new Map<string, string>();
return {
get: jest.fn().mockImplementation((key: string) => {
return Promise.resolve(storage.get(key) || null);
}),
put: jest.fn().mockImplementation((key: string, value: string) => {
storage.set(key, value);
return Promise.resolve();
}),
delete: jest.fn().mockImplementation((key: string) => {
storage.delete(key);
return Promise.resolve();
}),
list: jest.fn().mockImplementation(() => {
return Promise.resolve({
keys: Array.from(storage.keys()).map((key) => ({ name: key })),
});
}),
// Internal storage for testing
_storage: storage,
};
}
/**
* Assert that a response matches the expected translation format
*/
export function expectValidTranslationResponse(response: any) {
expect(response).toHaveProperty("code");
expect(response).toHaveProperty("data");
expect(response).toHaveProperty("id");
expect(response).toHaveProperty("source_lang");
expect(response).toHaveProperty("target_lang");
expect(typeof response.code).toBe("number");
expect(typeof response.id).toBe("number");
expect(typeof response.source_lang).toBe("string");
expect(typeof response.target_lang).toBe("string");
}
/**
* Assert that a response matches the expected error format
*/
export function expectValidErrorResponse(response: any) {
expect(response).toHaveProperty("code");
expect(response).toHaveProperty("data");
expect(response.code).toBeGreaterThanOrEqual(400);
expect(response.data).toBeNull();
}
/**
* Create a comprehensive test environment
*/
export function createTestEnvironment() {
const cacheKV = createMockKV();
const rateLimitKV = createMockKV();
const env: Env = {
CACHE_KV: cacheKV as any,
RATE_LIMIT_KV: rateLimitKV as any,
{ status: 200 }
)
),
}),
} as any,
ANALYTICS: {
writeDataPoint: jest.fn(),
} as any,
PROXY_URLS:
"https://test1.example.com/jsonrpc,https://test2.example.com/jsonrpc",
PROXY_WEIGHTS: "1,1",
DEBUG_MODE: "true",
};
return {
env,
cacheKV,
rateLimitKV,
cleanup: () => {
cacheKV._storage.clear();
rateLimitKV._storage.clear();
jest.clearAllMocks();
},
};
}
/**
* Performance measurement utility
*/
export class PerformanceTimer {
private startTime: number = 0;
private endTime: number = 0;
start(): void {
this.startTime = Date.now();
}
stop(): number {
this.endTime = Date.now();
return this.endTime - this.startTime;
}
get duration(): number {
return this.endTime - this.startTime;
}
}
/**
* Retry utility for flaky tests
*/
export async function retryTest<T>(
testFn: () => Promise<T>,
maxRetries: number = 3,
delay: number = 100
): Promise<T> {
let lastError: Error;
for (let i = 0; i <= maxRetries; i++) {
try {
return await testFn();
} catch (error) {
lastError = error as Error;
if (i < maxRetries) {
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
}
throw lastError!;
}