/** * Focused smoke for `[` / `test` builtins and $(( $var … )) (avoids full test.js brittle/os.cwd failure path). */ import test from 'brittle' import b4a from 'b4a' import Hyperdrive from 'hyperdrive' import Corestore from 'corestore' import { mkdirSync, rmSync } from 'node:fs' import path from 'node:path' import { fileURLToPath } from 'node:url' import { readFile } from 'node:fs/promises' const __dirname = path.dirname(fileURLToPath(import.meta.url)) import { createBareOsIpc } from './lib/bare-os-ipc.js' import { createVfs } from './lib/vfs.js' import { runBinCommand } from './lib/kernel-runner.js' import { execShellLine, expandWord } from './lib/shell.js' function testCorestoreDir(name) { const dir = path.join( __dirname, '.test-data', name + '-' + process.pid + '-' + Math.random().toString(36).slice(2) ) mkdirSync(path.dirname(dir), { recursive: true }) return dir } function testCtx(drive, personal, env) { const shellEnv = { HOME: '/home/user', PATH: '/bin', USER: 'user', UID: '1000', GID: '1000', PWD: '/home/user', BARE_OS_EXIT_STATUS: '0', BARE_OS_SSH_LISTEN_PORT: '0', ...env } const bareOsIpc = createBareOsIpc() const vfs = createVfs(drive, personal, shellEnv, null, { bareOsIpc }) return { drive, personalDrive: personal, vfs, bareOsIpc, env: shellEnv, console, b4a } } async function readBuiltBin(name) { const root = path.join(__dirname, '..', '..') return readFile(path.join(root, 'kernel', 'bin', name), 'utf8') } test('execShellLine test [ builtins and $(( $var + … ))', async (t) => { const dir = testCorestoreDir('shbracket-smoke') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('pshbrk-sm')) await drive.ready() await personal.ready() await drive.put('/bin/test', b4a.from(await readBuiltBin('test'))) const ctx = testCtx(drive, personal) ctx.runBinCommand = function (argv, ro) { return runBinCommand(this, argv, ro) } ctx.exitCode = 0 await execShellLine(ctx, 'a=1; test 2 -eq $((a+1))') t.is(ctx.exitCode, 0) ctx.exitCode = 0 await execShellLine(ctx, 'a=1; [ 2 -eq $(($a+1)) ]') t.is(ctx.exitCode, 0) await store.close() rmSync(dir, { recursive: true, force: true }) }) test('expandWord arithmetic honors $var inside $(( ))', (t) => { t.is(expandWord('$(( $a + 1 ))', { a: '2' }), '3') t.is(expandWord('$(( $a+1 ))', { a: '2' }), '3') }) test('execShellLine merges identity from child command context', async (t) => { const dir = testCorestoreDir('shell-identity-merge') const store = new Corestore(dir) const drive = new Hyperdrive(store) const personal = new Hyperdrive(store.namespace('psh-ident-merge')) await drive.ready() await personal.ready() await drive.put( '/bin/login', b4a.from(`async function run(ctx) { ctx.vfs.env.BARE_OS_IDENTITY = 'unlocked' ctx.identity = { state: 'unlocked', publicKey: new Uint8Array(32), secretKey: new Uint8Array(64) } ctx.console.log('Unlocked as test-user') } `) ) await drive.put( '/bin/savevault', b4a.from(`async function run(ctx) { if (!ctx.identity?.secretKey || ctx.identity.state !== 'unlocked') { throw new Error('Not logged in') } ctx.console.log('Vault saved (0 files)') } `) ) const lines = [] const errs = [] const ctx = testCtx(drive, personal) ctx.console = { log(...args) { lines.push(args.map((a) => String(a)).join(' ')) }, error(...args) { errs.push(args.map((a) => String(a)).join(' ')) } } ctx.identity = { state: 'guest', publicKey: null, secretKey: null } ctx.runBinCommand = function (argv, ro) { return runBinCommand(this, argv, ro) } await execShellLine(ctx, 'savevault') t.ok(errs.includes('Not logged in')) errs.length = 0 await execShellLine(ctx, 'login') t.is(ctx.identity?.state, 'unlocked') t.ok(ctx.identity?.secretKey instanceof Uint8Array) await execShellLine(ctx, 'savevault') t.alike(errs, []) t.ok(lines.includes('Vault saved (0 files)')) await store.close() rmSync(dir, { recursive: true, force: true }) })