Primeiro Commit v0.beta1
This commit is contained in:
168
tests/helpers/cli.mjs
Normal file
168
tests/helpers/cli.mjs
Normal file
@@ -0,0 +1,168 @@
|
||||
import { spawn } from "node:child_process";
|
||||
import fs from "node:fs/promises";
|
||||
import os from "node:os";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const helperDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
|
||||
export const testsDir = path.resolve(helperDir, "..");
|
||||
export const skillHome = path.resolve(testsDir, "..");
|
||||
export const fetchScriptPath = path.join(skillHome, "scripts", "fetch-sales-intelligence.mjs");
|
||||
|
||||
let preparedRuntimeHomePromise = null;
|
||||
|
||||
export function testRuntimeHome() {
|
||||
return (
|
||||
process.env.ORACLE_SI_TEST_RUNTIME_HOME ||
|
||||
path.join(os.tmpdir(), "knowledge-one-view-cli-tests", "runtime")
|
||||
);
|
||||
}
|
||||
|
||||
async function prepareRuntimeHome() {
|
||||
if (process.env.ORACLE_SI_TEST_RUNTIME_HOME) {
|
||||
await fs.mkdir(process.env.ORACLE_SI_TEST_RUNTIME_HOME, { recursive: true });
|
||||
return process.env.ORACLE_SI_TEST_RUNTIME_HOME;
|
||||
}
|
||||
|
||||
const runtimeHome = testRuntimeHome();
|
||||
if (!process.env.ORACLE_SI_RUNTIME_HOME) {
|
||||
await fs.mkdir(runtimeHome, { recursive: true });
|
||||
return runtimeHome;
|
||||
}
|
||||
|
||||
if (!preparedRuntimeHomePromise) {
|
||||
preparedRuntimeHomePromise = (async () => {
|
||||
await fs.rm(runtimeHome, { recursive: true, force: true });
|
||||
await fs.mkdir(runtimeHome, { recursive: true });
|
||||
for (const fileName of ["auth-state.json", "session-meta.json"]) {
|
||||
await fs.copyFile(
|
||||
path.join(process.env.ORACLE_SI_RUNTIME_HOME, fileName),
|
||||
path.join(runtimeHome, fileName)
|
||||
);
|
||||
}
|
||||
return runtimeHome;
|
||||
})();
|
||||
}
|
||||
|
||||
return preparedRuntimeHomePromise;
|
||||
}
|
||||
|
||||
export function flagsInArgs(args) {
|
||||
return args.filter((arg) => String(arg).startsWith("--"));
|
||||
}
|
||||
|
||||
export function argValue(args, flagName) {
|
||||
const index = args.indexOf(flagName);
|
||||
return index >= 0 ? args[index + 1] : null;
|
||||
}
|
||||
|
||||
export function executionModes(args) {
|
||||
return ["--intent", "--view", "--query", "--sql"].filter((flagName) => args.includes(flagName));
|
||||
}
|
||||
|
||||
export function withoutFlags(args, flagsToRemove) {
|
||||
const flags = new Set(flagsToRemove);
|
||||
const next = [];
|
||||
for (let index = 0; index < args.length; index += 1) {
|
||||
const token = args[index];
|
||||
if (!flags.has(token)) {
|
||||
next.push(token);
|
||||
continue;
|
||||
}
|
||||
if (token !== "--query" && token !== "--render-sql" && args[index + 1] && !args[index + 1].startsWith("--")) {
|
||||
index += 1;
|
||||
}
|
||||
}
|
||||
return next;
|
||||
}
|
||||
|
||||
export async function runFetch(cliArgs, options = {}) {
|
||||
const {
|
||||
expectCode = 0,
|
||||
timeoutMs = 120000,
|
||||
runtimeHome: requestedRuntimeHome = null,
|
||||
} = options;
|
||||
const runtimeHome = requestedRuntimeHome || (await prepareRuntimeHome());
|
||||
const noCacheArgs = cliArgs.includes("--no-cache") ? [...cliArgs] : [...cliArgs, "--no-cache"];
|
||||
const finalArgs = noCacheArgs.includes("--runtime-home")
|
||||
? noCacheArgs
|
||||
: [...noCacheArgs, "--runtime-home", runtimeHome];
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const child = spawn(process.execPath, [fetchScriptPath, ...finalArgs], {
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
env: process.env,
|
||||
});
|
||||
let stdout = "";
|
||||
let stderr = "";
|
||||
let timedOut = false;
|
||||
const startedAt = process.hrtime.bigint();
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
timedOut = true;
|
||||
child.kill();
|
||||
}, timeoutMs);
|
||||
|
||||
child.stdout.setEncoding("utf8");
|
||||
child.stderr.setEncoding("utf8");
|
||||
child.stdout.on("data", (chunk) => {
|
||||
stdout += chunk;
|
||||
});
|
||||
child.stderr.on("data", (chunk) => {
|
||||
stderr += chunk;
|
||||
});
|
||||
|
||||
child.on("error", reject);
|
||||
child.on("close", (code) => {
|
||||
clearTimeout(timer);
|
||||
const durationMs = Number(process.hrtime.bigint() - startedAt) / 1_000_000;
|
||||
let json = null;
|
||||
try {
|
||||
json = stdout.trim() ? JSON.parse(stdout) : null;
|
||||
} catch {}
|
||||
|
||||
const result = {
|
||||
args: finalArgs,
|
||||
code,
|
||||
stdout,
|
||||
stderr,
|
||||
json,
|
||||
timedOut,
|
||||
durationMs,
|
||||
};
|
||||
|
||||
if (expectCode !== null && code !== expectCode) {
|
||||
reject(
|
||||
new Error(
|
||||
[
|
||||
`Unexpected exit code ${code}; expected ${expectCode}.`,
|
||||
`Command: ${process.execPath} ${fetchScriptPath} ${finalArgs.join(" ")}`,
|
||||
stderr.trim() || stdout.trim(),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n")
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (expectCode === 0 && (!json || typeof json !== "object")) {
|
||||
reject(
|
||||
new Error(
|
||||
[
|
||||
"Expected JSON output from fetch-sales-intelligence.mjs.",
|
||||
`Command: ${process.execPath} ${fetchScriptPath} ${finalArgs.join(" ")}`,
|
||||
stderr.trim() || stdout.trim(),
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join("\n")
|
||||
)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
resolve(result);
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user