import { readFile } from 'node:fs/promises' import path from 'node:path' import { fileURLToPath } from 'node:url' import test from 'brittle' import b4a from 'b4a' const __dirname = path.dirname(fileURLToPath(import.meta.url)) const AsyncFunction = Object.getPrototypeOf(async function () {}).constructor async function loadBin(name) { const runtime = await readFile(path.join(__dirname, '../lib/runtime.js'), 'utf8') const body = await readFile(path.join(__dirname, `../src/${name}.js`), 'utf8') return new AsyncFunction( 'ctx', 'argv', `${runtime}\n${body}\nif (typeof run === 'function') return await run(ctx, argv)\n` ) } function mkCtx(files = {}) { const logs = [] const errs = [] return { b4a, exitCode: 0, shellStdin: '', console: { log: (m) => logs.push(String(m)), error: (m) => errs.push(String(m)) }, vfs: { env: {}, async readFile(p) { return Object.prototype.hasOwnProperty.call(files, p) ? files[p] : null } }, _logs: logs, _errs: errs } } test('locale -a prints available locales', async (t) => { const run = await loadBin('locale') const ctx = mkCtx() await run(ctx, ['locale', '-a']) t.is(ctx.exitCode, 0) t.ok(ctx._logs.join('\n').includes('C.UTF-8')) }) test('iconv -l lists supported encodings', async (t) => { const run = await loadBin('iconv') const ctx = mkCtx() await run(ctx, ['iconv', '-l']) t.is(ctx.exitCode, 0) t.ok(ctx._logs.join('\n').includes('utf-16le')) }) test('getconf PAGE_SIZE alias resolves to 4096', async (t) => { const run = await loadBin('getconf') const ctx = mkCtx() await run(ctx, ['getconf', 'PAGE_SIZE']) t.is(ctx.exitCode, 0) t.is(ctx._logs[0], '4096') }) test('ssh-keygen help subcommand prints usage', async (t) => { const run = await loadBin('ssh-keygen') const ctx = mkCtx() await run(ctx, ['ssh-keygen', 'help']) t.is(ctx.exitCode, 0) t.ok(ctx._logs.join('\n').includes('Usage: ssh-keygen')) }) test('oidc-publish shows help when --help is non-positional', async (t) => { const run = await loadBin('oidc-publish') const ctx = mkCtx() await run(ctx, ['oidc-publish', '--json', '--help']) t.is(ctx.exitCode, 0) t.ok(ctx._logs.join('\n').includes('oidc-publish')) }) test('procstat emits empty-table hint when no processes', async (t) => { const run = await loadBin('procstat') const table = b4a.from(JSON.stringify({ schema: 1, processes: [] })) const ctx = mkCtx({ '/proc/bare_os/process_table.json': table }) await run(ctx, ['procstat']) t.is(ctx.exitCode, 0) const out = JSON.parse(ctx._logs.join('\n')) t.is(out.processCount, 0) t.ok(String(out.hint || '').includes('empty')) }) test('whois reports bounded timeout message', async (t) => { const run = await loadBin('whois') const ctx = mkCtx() ctx.vfs.env.BARE_OS_WHOIS_TIMEOUT_MS = '20' ctx.httpFetch = (_url, opts) => new Promise((resolve, reject) => { const sig = opts && opts.signal if (sig && typeof sig.addEventListener === 'function') { sig.addEventListener('abort', () => { reject(Object.assign(new Error('The operation was aborted'), { name: 'AbortError' })) }) } void resolve }) await run(ctx, ['whois', 'google.com']) t.is(ctx.exitCode, 1) const errJoined = ctx._errs.join('\n') t.ok(errJoined.includes('network timeout')) t.ok(errJoined.includes('exceeded 20ms')) })