import test from 'brittle' import { readFile } from 'node:fs/promises' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' import { attachBareOsTuiSdk } from '../../bare-os-booter/lib/bare-os-tui-sdk.js' const __dirname = dirname(fileURLToPath(import.meta.url)) const libPath = join(__dirname, '../lib/p2p-suite-tui.js') async function loadP2pTui() { const src = await readFile(libPath, 'utf8') const hook = {} new Function( 'exports', src + '\nexports.bareP2pCreateSimpleTuiApp = bareP2pCreateSimpleTuiApp;\nexports.bareP2pRunSimpleTui = bareP2pRunSimpleTui;\n' )(hook) return hook } function makeStream(isTTY, writes) { return { isTTY: !!isTTY, raw: false, columns: 80, rows: 24, write(s) { writes.push(String(s)) }, setRawMode(v) { this.raw = !!v }, resume() {}, pause() {}, on() {}, removeListener() {} } } function makeCtx() { const writes = [] const stdin = makeStream(true, writes) const stdout = makeStream(true, writes) const ctx = { env: {}, console: { error() {}, log() {} }, replStdin: stdin, replStdout: stdout, suspendReplForSubprocess() {}, resumeReplAfterSubprocess() {} } attachBareOsTuiSdk(ctx) return ctx } test('p2p-suite-tui source prefers ctx.tui.run', async (t) => { const src = await readFile(libPath, 'utf8') t.ok(src.includes('ctx.tui.run'), 'TEA path uses ctx.tui.run') t.ok(src.includes('bareP2pCreateSimpleTuiApp'), 'exports TEA factory') t.ok(src.includes('bareP2pRunSimpleTuiLegacy'), 'keeps pre-SDK fallback') }) test('p2p TEA app loads renderLines and quits on q', async (t) => { const hook = await loadP2pTui() const ctx = makeCtx() let loads = 0 const app = hook.bareP2pCreateSimpleTuiApp(ctx, { title: 'dhttop', subtitle: 'dht operations · q quit · r refresh', renderLines: async () => { loads++ return ['peers: 3', 'firewalled: no'] } }) const initCmd = app.init() t.ok(typeof initCmd === 'function') const loaded = await initCmd() app.update(loaded) t.is(loads, 1) const plain = ctx.tui.style.stripAnsi(app.view()) t.ok(plain.includes('dhttop'), 'title in view') t.ok(plain.includes('peers: 3'), 'body from renderLines') t.ok(plain.includes('firewalled: no')) const r = ctx.tui.decode('r')[0] const pair = app.update(r) t.ok(typeof pair[1] === 'function', 'r returns a refresh cmd') const again = await pair[1]() app.update(again) t.is(loads, 2) const q = ctx.tui.decode('q')[0] const quitPair = app.update(q) t.is(typeof quitPair[1], 'function') const quitMsg = quitPair[1]() t.is(quitMsg.type, 'quit') }) test('p2p TEA app onRefresh runs before reload', async (t) => { const hook = await loadP2pTui() const ctx = makeCtx() const order = [] const app = hook.bareP2pCreateSimpleTuiApp(ctx, { title: 'swarmmap', renderLines: async () => { order.push('load') return ['ok'] }, onRefresh: async () => { order.push('refresh') } }) await app.update(ctx.tui.decode('r')[0])[1]() t.alike(order, ['refresh', 'load']) })