import type { RunResult, RunnerStrategy } from "../types"; /** * JavaScript/TypeScript 运行策略 */ async function runJavaScript( code: string, testCases?: import("../types").TestCase[], ): Promise { const startTime = performance.now(); try { // 1. 如果没有测试用例,保持原有逻辑 (Console 模式) if (!testCases || testCases.length === 0) { // 创建一个安全的执行环境 const logs: string[] = []; // 重写 console.log const customConsole = { log: (...args: any[]) => { logs.push( args .map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg), ) .join(" "), ); }, error: (...args: any[]) => { logs.push("ERROR: " + args.join(" ")); }, warn: (...args: any[]) => { logs.push("WARN: " + args.join(" ")); }, }; // 使用 Function 构造器创建沙箱 const fn = new Function("console", code); fn(customConsole); const executionTime = performance.now() - startTime; return { output: logs.join("\n") || "(无输出)", executionTime, status: "success", }; } // 2. 如果有测试用例 (Test Mode) const logs: string[] = []; const testResults: import("../types").TestCaseResult[] = []; // 构造 wrapper 代码来获取用户函数 const wrapperCode = ` ${code} // 尝试找到入口函数 let mainFn = null; // 优先级 1: solution 函数 if (typeof solution === 'function') mainFn = solution; // 优先级 2: twoSum (针对示例) else if (typeof twoSum === 'function') mainFn = twoSum; // 优先级 3: 寻找最后一个定义的函数 (简单启发式,可能不准确) if (!mainFn) { // 如果没找到具名函数,尝试返回一个错误 throw new Error("未找到入口函数 (请定义 solution 或 twoSum 函数)"); } return mainFn; `; // 定义日志处理代理 let logHandler = (type: "log" | "error" | "warn", args: any[]) => { const msg = args .map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg), ) .join(" "); logs.push(msg); // 默认写入全局日志 }; // 重写 console,使用代理 const customConsole = { log: (...args: any[]) => logHandler("log", args), error: (...args: any[]) => logHandler("error", args), warn: (...args: any[]) => logHandler("warn", args), }; // 获取用户函数 const getUserFn = new Function("console", wrapperCode); const userFn = getUserFn(customConsole); // 执行测试用例 for (const testCase of testCases) { const caseLog: string[] = []; const startTimeCase = performance.now(); let status: "passed" | "failed" | "error" = "error"; let output: any = undefined; let errorMsg: string | undefined = undefined; // 切换日志处理器到当前 case logHandler = (type, args) => { const msg = args .map((arg) => typeof arg === "object" ? JSON.stringify(arg, null, 2) : String(arg), ) .join(" "); caseLog.push(msg); // 也保留到全局日志,带上前缀方便调试 // logs.push(`[Case ${testCase.id}] ${msg}`); }; try { // 尝试安全调用 let result: any; if (Array.isArray(testCase.input)) { result = userFn(...testCase.input); } else { result = userFn(testCase.input); } output = result; // 验证结果 let passed = false; if (testCase.expected !== undefined) { // 简单比较 try { passed = JSON.stringify(result) === JSON.stringify(testCase.expected); } catch (e) { passed = result === testCase.expected; } } else { // 如果没有预期结果,只要不报错就算过?或者无法判断 passed = true; } status = passed ? "passed" : "failed"; } catch (e: any) { status = "error"; errorMsg = e.message; output = undefined; } const endTimeCase = performance.now(); testResults.push({ id: testCase.id, status, input: testCase.input, output, expected: testCase.expected, log: caseLog.join("\n"), error: errorMsg, executionTime: endTimeCase - startTimeCase, }); } const executionTime = performance.now() - startTime; // 统计状态 const hasError = testResults.some((r) => r.status === "error"); const hasFailure = testResults.some((r) => r.status === "failed"); return { output: logs.join("\n"), executionTime, status: hasError || hasFailure ? "error" : "success", // 这里只代表是否全部通过 testResults, }; } catch (error: any) { const executionTime = performance.now() - startTime; return { output: "", error: error.message || String(error), executionTime, status: "error", }; } } /** * Python 运行策略(使用 Pyodide) */ async function runPython(code: string): Promise { const startTime = performance.now(); try { // 提示:实际使用需要加载 Pyodide // const pyodide = await loadPyodide(); // 临时返回,实际实现需要集成 Pyodide return { output: "Python 运行功能需要加载 Pyodide (暂未实现)", executionTime: performance.now() - startTime, status: "error", error: "Pyodide 未加载", }; } catch (error: any) { return { output: "", error: error.message, executionTime: performance.now() - startTime, status: "error", }; } } /** * 远程运行策略(Java/C++/Go 等) */ async function runRemote(code: string, language: string): Promise { const startTime = performance.now(); try { // 提示:需要配置远程编译服务 API // 例如:Judge0 API, Piston API 等 return { output: `${language} 远程运行功能需要配置编译服务 (暂未实现)`, executionTime: performance.now() - startTime, status: "error", error: "远程编译服务未配置", }; } catch (error: any) { return { output: "", error: error.message, executionTime: performance.now() - startTime, status: "error", }; } } /** * 运行策略映射 * ⭐ 新增自定义运行逻辑只需在这里添加 */ export const RUNNER_STRATEGIES: Record = { javascript: runJavaScript, typescript: runJavaScript, // TypeScript 可以直接当 JS 运行(简化版) python: runPython, java: (code) => runRemote(code, "Java"), cpp: (code) => runRemote(code, "C++"), go: (code) => runRemote(code, "Go"), }; /** * 获取运行策略 */ export function getRunnerStrategy( language: string, ): RunnerStrategy | undefined { return RUNNER_STRATEGIES[language]; }