Download test/full.test.mjs from teddyoas/Asnip: direct link, hf CLI and curl.
- Browser
- Download file 11 kB
-
https://huggingface.co/teddyoas/Asnip/resolve/main/test/full.test.mjs
- Command line
-
hf download hf://teddyoas/Asnip/test/full.test.mjs
-
curl -L -o full.test.mjs https://huggingface.co/teddyoas/Asnip/resolve/main/test/full.test.mjs
11 kB
| // Phantom β comprehensive tool & edge-case tests | |
| // Run: node --test test/full.test.mjs | |
| import { describe, it } from "node:test"; | |
| import assert from "node:assert/strict"; | |
| import { hackerTools } from "../lib/tools.mjs"; | |
| import { runTool, runPipe } from "../lib/runtime.mjs"; | |
| const tools = hackerTools; | |
| // ββ decode (handles both encode + decode) βββββββββββββββ | |
| describe("decode tool", () => { | |
| it("decodes base64", async () => { | |
| const r = await tools.decode("aGVsbG8gd29ybGQ="); | |
| assert.match(r, /hello world/); | |
| }); | |
| it("decodes url", async () => { | |
| const r = await tools.decode("hello%20world"); | |
| assert.match(r, /hello world/); | |
| }); | |
| it("handles empty input gracefully", async () => { | |
| const r = await tools.decode(""); | |
| assert.ok(r.length > 0); | |
| }); | |
| it("handles hex input", async () => { | |
| const r = await tools.decode("68656c6c6f"); | |
| assert.match(r, /hello/); | |
| }); | |
| }); | |
| describe("hash tool", () => { | |
| it("produces multiple hash formats", async () => { | |
| const r = await tools.hash("hello"); | |
| assert.match(r, /MD5/); | |
| assert.match(r, /SHA256/); | |
| assert.match(r, /SHA1/); | |
| }); | |
| it("produces known md5", async () => { | |
| const r = await tools.hash("hello"); | |
| assert.match(r, /5d41402abc4b2a76b9719d911017c592/); | |
| }); | |
| it("produces known sha256", async () => { | |
| const r = await tools.hash("hello"); | |
| assert.match(r, /2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824/); | |
| }); | |
| }); | |
| // ββ file_search (built-in) ββββββββββββββββββββββββββββββ | |
| describe("file_search", () => { | |
| it("finds own source file", async () => { | |
| const r = await tools.file_search("test/full.test.mjs"); | |
| assert.match(r, /full\.test\.mjs/); | |
| }); | |
| it("returns message for no matches", async () => { | |
| const r = await tools.file_search("__nonexistent_file_xyz__"); | |
| assert.ok(r.length > 0); | |
| }); | |
| }); | |
| // ββ Shell tool ββββββββββββββββββββββββββββββββββββββββββ | |
| describe("shell tool", () => { | |
| it("handles very long command", async () => { | |
| const long = "echo " + "a".repeat(500); | |
| const r = await tools.shell(long); | |
| assert.match(r, /a{500}/); | |
| }); | |
| it("handles special characters", async () => { | |
| const r = await tools.shell("echo 'hello world test'"); | |
| assert.match(r, /hello world/); | |
| }); | |
| it("handles multiline output", async () => { | |
| const r = await tools.shell("seq 1 20"); | |
| const lines = r.trim().split("\n"); | |
| assert.equal(lines.length, 20); | |
| }); | |
| it("stderr is captured with stdout", async () => { | |
| const r = await tools.shell("echo stderr_test >&2 && echo stdout_ok"); | |
| assert.match(r, /stdout_ok/); | |
| }); | |
| }); | |
| // ββ Web tool ββββββββββββββββββββββββββββββββββββββββββββ | |
| describe("web_fetch", () => { | |
| it("fetches a page", async () => { | |
| const r = await tools.web_fetch("https://example.com"); | |
| assert.ok(r.includes("Example Domain") || r.includes("example")); | |
| }); | |
| it("handles invalid URL gracefully", async () => { | |
| const r = await tools.web_fetch("not-a-valid-url"); | |
| assert.ok(r.length > 0); | |
| }); | |
| it("handles empty URL gracefully", async () => { | |
| const r = await tools.web_fetch(""); | |
| assert.ok(r.length > 0); | |
| }); | |
| }); | |
| // ββ Knowledge tools βββββββββββββββββββββββββββββββββββββ | |
| describe("hackbook tool", () => { | |
| it("lists categories", async () => { | |
| const r = await tools.hackbook("list"); | |
| assert.ok(r.includes("Categories") || r.includes("PHANTOM HACKBOOK")); | |
| }); | |
| it("returns content for a valid category", async () => { | |
| const r = await tools.hackbook("sql-injection"); | |
| assert.ok(r.length > 0); | |
| }); | |
| it("handles unknown category gracefully", async () => { | |
| const r = await tools.hackbook("__nonexistent__"); | |
| assert.ok(r.length > 0); | |
| }); | |
| }); | |
| // ββ Batch tool ββββββββββββββββββββββββββββββββββββββββββ | |
| describe("batch tool", () => { | |
| it("shows usage for empty input", async () => { | |
| const r = await tools.batch(""); | |
| assert.match(r, /Usage/); | |
| }); | |
| it("returns error for missing file", async () => { | |
| const r = await tools.batch("shell|cat /tmp/nonexistent_phantom_test_xyz"); | |
| assert.ok(r.includes("Error") || r.includes("error") || r.includes("ENOENT")); | |
| }); | |
| }); | |
| describe("install tool", () => { | |
| it("shows usage for empty input", async () => { | |
| const r = await tools.install(""); | |
| assert.match(r, /Usage|@install/i); | |
| }); | |
| it("shows tool list on empty input", async () => { | |
| const r = await tools.install(""); | |
| assert.match(r, /nmap/); | |
| }); | |
| it("all keyword starts bulk install", async () => { | |
| const r = await tools.install("all"); | |
| assert.match(r, /Bulk installing|Done/); | |
| }); | |
| }); | |
| // ββ runTool wrapper βββββββββββββββββββββββββββββββββββββ | |
| describe("runTool extras", () => { | |
| it("returns error for empty tool name", async () => { | |
| const r = await runTool(tools, "", "test"); | |
| assert.match(r, /Unknown tool|empty/i); | |
| }); | |
| it("JSON mode with pipe input", async () => { | |
| const r = await runTool(tools, "shell", "echo pipe_json", { json: true, pipe: true }); | |
| const p = JSON.parse(r); | |
| assert.equal(p.ok, true); | |
| }); | |
| it("--help returns usage for any tool", async () => { | |
| const r = await runTool(tools, "shell", "--help"); | |
| assert.match(r, /Usage.*@shell/); | |
| }); | |
| it("--help via -h works", async () => { | |
| const r = await runTool(tools, "hash", "-h"); | |
| assert.match(r, /Usage.*@hash/); | |
| }); | |
| it("--help returns JSON when json=true", async () => { | |
| const r = await runTool(tools, "decode", "--help", { json: true }); | |
| const p = JSON.parse(r); | |
| assert.equal(p.ok, true); | |
| assert.equal(p.help, true); | |
| }); | |
| }); | |
| // ββ config tool βββββββββββββββββββββββββββββββββββββββββ | |
| describe("config tool", () => { | |
| it("list returns config path", async () => { | |
| const r = await tools.config(""); | |
| assert.match(r, /No settings saved|Config/); | |
| // config.json path is shown when there are settings, but not when empty | |
| }); | |
| it("path subcommand returns path", async () => { | |
| const r = await tools.config("path"); | |
| assert.match(r, /config\.json/); | |
| }); | |
| it("invalid subcommand shows usage", async () => { | |
| const r = await tools.config("blah"); | |
| assert.match(r, /Usage.*@config/); | |
| }); | |
| }); | |
| // ββ exit command βββββββββββββββββββββββββββββββββββββββ | |
| describe("exit command", () => { | |
| it("exit via stdin exits cleanly", async () => { | |
| const { execSync } = await import("child_process"); | |
| try { | |
| execSync("echo exit | timeout 5 node phantom.mjs", { cwd: "/root/usb/Phantom", encoding: "utf-8", timeout: 8000 }); | |
| } catch (e) { | |
| assert.fail(`exit should not throw: ${e.stderr}`); | |
| } | |
| }); | |
| it("quit via stdin exits cleanly", async () => { | |
| const { execSync } = await import("child_process"); | |
| try { | |
| execSync("echo quit | timeout 5 node phantom.mjs", { cwd: "/root/usb/Phantom", encoding: "utf-8", timeout: 8000 }); | |
| } catch (e) { | |
| assert.fail(`quit should not throw: ${e.stderr}`); | |
| } | |
| }); | |
| }); | |
| // ββ runPipe chaining ββββββββββββββββββββββββββββββββββββ | |
| describe("runPipe extras", () => { | |
| it("three-tool chain runs without error", async () => { | |
| const r = await runPipe(tools, "shell|echo aaaa | hash | decode"); | |
| assert.ok(r.length > 10); | |
| }); | |
| it("invalid tool in chain returns error", async () => { | |
| const r = await runPipe(tools, "shell|echo ok | nonexistent_tool_xyz"); | |
| assert.match(r, /Unknown tool|not found|error/i); | |
| }); | |
| }); | |
| // ββ CLI flags βββββββββββββββββββββββββββββββββββββββββββ | |
| describe("CLI flags", () => { | |
| it("--version prints version", async () => { | |
| const { execSync } = await import("child_process"); | |
| const out = execSync("node phantom.mjs --version 2>&1", { cwd: "/root/usb/Phantom", encoding: "utf-8", timeout: 8000 }); | |
| assert.match(out, /0\.2\.0|Phantom/); | |
| }); | |
| it("--quiet via env var", async () => { | |
| const { execSync } = await import("child_process"); | |
| const out = execSync("PHANTOM_QUIET=1 node phantom.mjs --list 2>&1", { cwd: "/root/usb/Phantom", encoding: "utf-8", timeout: 15000 }); | |
| // Should suppress banner art but still show tools | |
| assert.ok(out.length > 0); | |
| }); | |
| it("--help shows PHANTOM", async () => { | |
| const { execSync } = await import("child_process"); | |
| const out = execSync("node phantom.mjs --help 2>&1", { cwd: "/root/usb/Phantom", encoding: "utf-8", timeout: 8000 }); | |
| assert.match(out, /PHANTOM/i); | |
| }); | |
| }); | |
| // ββ Scope βββββββββββββββββββββββββββββββββββββββββββββββ | |
| describe("scope tool", () => { | |
| it("shows scope state by default", async () => { | |
| const r = await tools.scope(""); | |
| assert.match(r, /Commands|Scope|No targets|Usage/i); | |
| }); | |
| }); | |
| // ββ Schedule ββββββββββββββββββββββββββββββββββββββββββββ | |
| describe("schedule tool", () => { | |
| it("lists schedules", async () => { | |
| const r = await tools.schedule("list"); | |
| assert.ok(r.length > 0); | |
| }); | |
| it("shows usage for invalid input", async () => { | |
| const r = await tools.schedule("blah"); | |
| assert.match(r, /Usage|Invalid|Error/i); | |
| }); | |
| }); | |
| // ββ Tools list completeness βββββββββββββββββββββββββββββ | |
| describe("tool count and structure", () => { | |
| it("has 108+ tools", () => { | |
| assert.ok(Object.keys(tools).length >= 108); | |
| }); | |
| it("all tools are async functions", () => { | |
| for (const [name, fn] of Object.entries(tools)) { | |
| assert.equal(typeof fn, "function", `${name} should be a function`); | |
| assert.match(fn.constructor.name, /Async/, `${name} should be async`); | |
| } | |
| }); | |
| it("all tool names are lowercase", () => { | |
| for (const name of Object.keys(tools)) { | |
| assert.equal(name, name.toLowerCase(), `${name} should be lowercase`); | |
| } | |
| }); | |
| it("key tools exist", () => { | |
| const required = ["shell", "decode", "hash", "web_fetch", "file_search", "batch", "scope", "schedule", "hackbook"]; | |
| for (const t of required) { | |
| assert.ok(tools[t], `Missing required tool: ${t}`); | |
| } | |
| }); | |
| }); | |