// tea / tea-cli: the plugin accepts either binary name. Each case runs in a child node with a PATH that // contains only the fake binaries below, so the result does not depend on what is installed on this machine. import test from 'node:test' import assert from 'node:assert/strict' import fs from 'node:fs' import os from 'node:os' import path from 'node:path' import { execFileSync } from 'node:child_process' const authUrl = new URL('../auth.mjs', import.meta.url).href // node's own directory (often /usr/bin) may hold a real tea-cli, so expose node alone through a private dir const NODE_ONLY = fs.mkdtempSync(path.join(os.tmpdir(), 'tea-node-')) fs.symlinkSync(process.execPath, path.join(NODE_ONLY, 'node')) test.after(() => fs.rmSync(NODE_ONLY, { recursive: true, force: true })) function fakeBin(names) { const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'tea-test-')) for (const n of names) { // ` --version` prints a marker; any other call (logins add …) echoes which binary ran. fs.writeFileSync(path.join(dir, n), `#!/bin/sh\nif [ "$1" = "--version" ]; then echo "Version: ${n}-fake"; else echo "ran:${n} $*"; fi\n`, { mode: 0o755 }) } return dir } function probe(names, script) { const dir = fakeBin(names) try { const out = execFileSync(process.execPath, ['--input-type=module', '-e', script], { env: { PATH: `${dir}:${NODE_ONLY}`, HOME: dir, XDG_CONFIG_HOME: dir }, encoding: 'utf8', }) return JSON.parse(out.trim().split('\n').pop()) } finally { fs.rmSync(dir, { recursive: true, force: true }) } } const status = `import { cliStatus } from ${JSON.stringify(authUrl)}; console.log(JSON.stringify((await cliStatus()).tea))` const login = `import { giteaLogin } from ${JSON.stringify(authUrl)}; try { console.log(JSON.stringify(await giteaLogin({ url: 'https://g.example', token: 't', name: 'n' }))) } catch (e) { console.log(JSON.stringify({ error: e.message })) }` test('only `tea` installed: it is detected and used', () => { const t = probe(['tea'], status) assert.equal(t.available, true) assert.equal(t.binary, 'tea') assert.match(probe(['tea'], login).message, /^ran:tea logins add /) }) test('only `tea-cli` installed: it is detected and used', () => { assert.equal(probe(['tea-cli'], status).binary, 'tea-cli') assert.match(probe(['tea-cli'], login).message, /^ran:tea-cli logins add /) }) test('both installed: tea-cli wins, tea is the fallback', () => { assert.equal(probe(['tea', 'tea-cli'], status).binary, 'tea-cli') }) test('neither installed: clear error naming both, and not cached as missing', () => { assert.equal(probe([], status).available, false) assert.match(probe([], login).error, /neither tea-cli nor tea/) })