113 lines
3.4 KiB
JavaScript
113 lines
3.4 KiB
JavaScript
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'))
|
|
})
|