From 93f22df8f4f275cfb58f141ae7ac149eb5d030f4 Mon Sep 17 00:00:00 2001 From: SuperCLI Dev Date: Tue, 14 Jul 2026 07:03:05 +0000 Subject: [PATCH 1/3] test: add plugin routing tests for bundled sq plugin --- __tests__/sq-plugin.test.js | 82 +++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 __tests__/sq-plugin.test.js diff --git a/__tests__/sq-plugin.test.js b/__tests__/sq-plugin.test.js new file mode 100644 index 000000000..c31d3fb67 --- /dev/null +++ b/__tests__/sq-plugin.test.js @@ -0,0 +1,82 @@ +const fs = require("fs") +const os = require("os") +const path = require("path") +const { execSync } = require("child_process") + +const CLI = path.join(__dirname, "..", "cli", "supercli.js") + +function runNoServer(args, options = {}) { + try { + const env = { ...process.env } + delete env.SUPERCLI_SERVER + const out = execSync(`node ${CLI} ${args}`, { + encoding: "utf-8", + timeout: 15000, + env: { ...env, ...(options.env || {}) } + }) + return { ok: true, output: out.trim(), code: 0 } + } catch (err) { + return { + ok: false, + output: (err.stdout || "").trim(), + stderr: (err.stderr || "").trim(), + code: err.status + } + } +} + +function writeFakeSqBinary(dir) { + const bin = path.join(dir, "sq") + fs.writeFileSync(bin, [ + "#!/usr/bin/env node", + "const args = process.argv.slice(2);", + "if (args[0] === 'version') { console.log('sq v0.48.0-test'); process.exit(0); }", + "console.log(JSON.stringify({ ok: true, args }));" + ].join("\n"), "utf-8") + fs.chmodSync(bin, 0o755) + return bin +} + +describe("sq plugin", () => { + const fakeDir = fs.mkdtempSync(path.join(os.tmpdir(), "dcli-sq-")) + const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "dcli-home-sq-")) + writeFakeSqBinary(fakeDir) + const env = { ...process.env, PATH: `${fakeDir}:${process.env.PATH || ""}`, SUPERCLI_HOME: tempHome } + + beforeAll(() => { + runNoServer("plugins install ./plugins/sq --on-conflict replace --json", { env }) + }) + + afterAll(() => { + runNoServer("plugins remove sq --json", { env }) + fs.rmSync(fakeDir, { recursive: true, force: true }) + fs.rmSync(tempHome, { recursive: true, force: true }) + }) + + test("routes a subcommand through namespace passthrough", () => { + const r = runNoServer("sq inspect --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.command).toBe("sq.passthrough") + expect(data.data.args).toContain("inspect") + expect(data.data.args).toContain("--json") + }) + + test("passes multiple arguments through in order", () => { + const r = runNoServer("sq .data --format json --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.command).toBe("sq.passthrough") + expect(data.data.args).toContain(".data") + expect(data.data.args).toContain("--format") + expect(data.data.args).toContain("json") + }) + + test("doctor reports sq dependency as healthy", () => { + const r = runNoServer("plugins doctor sq --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.ok).toBe(true) + expect(data.checks.some(c => c.type === "binary" && c.binary === "sq" && c.ok === true)).toBe(true) + }) +}) From cb77f4377ebcaf7348d04abff7efd64bc9f6f0c4 Mon Sep 17 00:00:00 2001 From: SuperCLI Dev Date: Tue, 14 Jul 2026 07:03:41 +0000 Subject: [PATCH 2/3] test: add plugin routing tests for bundled httprobe plugin --- __tests__/httprobe-plugin.test.js | 69 +++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 __tests__/httprobe-plugin.test.js diff --git a/__tests__/httprobe-plugin.test.js b/__tests__/httprobe-plugin.test.js new file mode 100644 index 000000000..90768554b --- /dev/null +++ b/__tests__/httprobe-plugin.test.js @@ -0,0 +1,69 @@ +const fs = require("fs") +const os = require("os") +const path = require("path") +const { execSync } = require("child_process") + +const CLI = path.join(__dirname, "..", "cli", "supercli.js") + +function runNoServer(args, options = {}) { + try { + const env = { ...process.env } + delete env.SUPERCLI_SERVER + const out = execSync(`node ${CLI} ${args}`, { + encoding: "utf-8", + timeout: 15000, + env: { ...env, ...(options.env || {}) } + }) + return { ok: true, output: out.trim(), code: 0 } + } catch (err) { + return { + ok: false, + output: (err.stdout || "").trim(), + stderr: (err.stderr || "").trim(), + code: err.status + } + } +} + +function writeFakeHttprobeBinary(dir) { + const bin = path.join(dir, "httprobe") + fs.writeFileSync(bin, [ + "#!/usr/bin/env node", + "console.log('https://example.com');" + ].join("\n"), "utf-8") + fs.chmodSync(bin, 0o755) + return bin +} + +describe("httprobe plugin", () => { + const fakeDir = fs.mkdtempSync(path.join(os.tmpdir(), "dcli-httprobe-")) + const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "dcli-home-httprobe-")) + writeFakeHttprobeBinary(fakeDir) + const env = { ...process.env, PATH: `${fakeDir}:${process.env.PATH || ""}`, SUPERCLI_HOME: tempHome } + + beforeAll(() => { + runNoServer("plugins install ./plugins/httprobe --on-conflict replace --json", { env }) + }) + + afterAll(() => { + runNoServer("plugins remove httprobe --json", { env }) + fs.rmSync(fakeDir, { recursive: true, force: true }) + fs.rmSync(tempHome, { recursive: true, force: true }) + }) + + test("routes the domain probe command", () => { + const r = runNoServer("httprobe domain probe --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.command).toBe("httprobe.domain.probe") + expect(data.data.raw).toBe("https://example.com") + }) + + test("doctor reports httprobe dependency as healthy", () => { + const r = runNoServer("plugins doctor httprobe --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.ok).toBe(true) + expect(data.checks.some(c => c.type === "binary" && c.binary === "httprobe" && c.ok === true)).toBe(true) + }) +}) From 82f7196b060645fb75d0b74171a6e1cde6af36b6 Mon Sep 17 00:00:00 2001 From: SuperCLI Dev Date: Tue, 14 Jul 2026 07:04:21 +0000 Subject: [PATCH 3/3] test: add plugin routing tests for bundled lazysql plugin --- __tests__/lazysql-plugin.test.js | 89 ++++++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 __tests__/lazysql-plugin.test.js diff --git a/__tests__/lazysql-plugin.test.js b/__tests__/lazysql-plugin.test.js new file mode 100644 index 000000000..cc8d12d8b --- /dev/null +++ b/__tests__/lazysql-plugin.test.js @@ -0,0 +1,89 @@ +const fs = require("fs") +const os = require("os") +const path = require("path") +const { execSync } = require("child_process") + +const CLI = path.join(__dirname, "..", "cli", "supercli.js") + +function runNoServer(args, options = {}) { + try { + const env = { ...process.env } + delete env.SUPERCLI_SERVER + const out = execSync(`node ${CLI} ${args}`, { + encoding: "utf-8", + timeout: 15000, + env: { ...env, ...(options.env || {}) } + }) + return { ok: true, output: out.trim(), code: 0 } + } catch (err) { + return { + ok: false, + output: (err.stdout || "").trim(), + stderr: (err.stderr || "").trim(), + code: err.status + } + } +} + +function writeFakeLazysqlBinary(dir) { + const bin = path.join(dir, "lazysql") + fs.writeFileSync(bin, [ + "#!/usr/bin/env node", + "const args = process.argv.slice(2);", + "if (args[0] === '--version') { console.log('lazysql v0.3.0-test'); process.exit(0); }", + "console.log(JSON.stringify({ ok: true, args }));" + ].join("\n"), "utf-8") + fs.chmodSync(bin, 0o755) + return bin +} + +describe("lazysql plugin", () => { + const fakeDir = fs.mkdtempSync(path.join(os.tmpdir(), "dcli-lazysql-")) + const tempHome = fs.mkdtempSync(path.join(os.tmpdir(), "dcli-home-lazysql-")) + writeFakeLazysqlBinary(fakeDir) + const env = { ...process.env, PATH: `${fakeDir}:${process.env.PATH || ""}`, SUPERCLI_HOME: tempHome } + + beforeAll(() => { + runNoServer("plugins install ./plugins/lazysql --on-conflict replace --json", { env }) + }) + + afterAll(() => { + runNoServer("plugins remove lazysql --json", { env }) + fs.rmSync(fakeDir, { recursive: true, force: true }) + fs.rmSync(tempHome, { recursive: true, force: true }) + }) + + test("routes the self version command", () => { + const r = runNoServer("lazysql self version --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.command).toBe("lazysql.self.version") + expect(data.data.raw).toBe("lazysql v0.3.0-test") + }) + + test("routes connection open with a positional url", () => { + const r = runNoServer("lazysql connection open postgres://x --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.command).toBe("lazysql.connection.open") + const inner = JSON.parse(data.data.raw) + expect(inner.args).toContain("postgres://x") + }) + + test("supports namespace passthrough for unknown subcommands", () => { + const r = runNoServer("lazysql somecmd --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.command).toBe("lazysql.passthrough") + const inner = JSON.parse(data.data.raw) + expect(inner.args).toContain("somecmd") + }) + + test("doctor reports lazysql dependency as healthy", () => { + const r = runNoServer("plugins doctor lazysql --json", { env }) + expect(r.ok).toBe(true) + const data = JSON.parse(r.output) + expect(data.ok).toBe(true) + expect(data.checks.some(c => c.type === "binary" && c.binary === "lazysql" && c.ok === true)).toBe(true) + }) +})