import test from 'brittle' import { readFile } from 'node:fs/promises' import { dirname, join } from 'node:path' import { fileURLToPath } from 'node:url' const __dirname = dirname(fileURLToPath(import.meta.url)) async function load() { const parts = await Promise.all([ readFile(join(__dirname, '../lib/irc-parse.js'), 'utf8'), readFile(join(__dirname, '../lib/irc-isupport.js'), 'utf8'), readFile(join(__dirname, '../lib/irc-sasl.js'), 'utf8'), readFile(join(__dirname, '../lib/irc-state.js'), 'utf8'), readFile(join(__dirname, '../lib/irc-config.js'), 'utf8'), readFile(join(__dirname, '../lib/irc-client.js'), 'utf8'), readFile(join(__dirname, '../lib/irc-commands.js'), 'utf8') ]) const hook = {} new Function( 'exports', parts.join('\n') + ` exports.bareIrcCreateClient = bareIrcCreateClient; exports.bareIrcRunSlash = bareIrcRunSlash; exports.bareIrcRandomNick = bareIrcRandomNick; exports.bareIrcNickLooksMachine = bareIrcNickLooksMachine; exports.bareIrcResolveConnect = bareIrcResolveConnect; ` )(hook) return hook } function client() { const writes = [] const c = { opts: { nick: 'alice' }, state: null, sendRaw: function (cmd, params) { writes.push({ cmd: cmd, params: params || [] }) return true }, sendPrivmsg: function (t, text) { writes.push({ cmd: 'PRIVMSG', params: [t, text] }) return true }, join: function (ch, key) { writes.push({ cmd: 'JOIN', params: key ? [ch, key] : [ch] }) }, part: function (ch, reason) { writes.push({ cmd: 'PART', params: reason ? [ch, reason] : [ch] }) }, quit: function (reason) { writes.push({ cmd: 'QUIT', params: [reason || 'Leaving'] }) }, list: function (pat) { writes.push({ cmd: 'LIST', params: pat ? [pat] : [] }) } } c._writes = writes return c } test('machine hostname is not used as nick', async (t) => { const h = await load() t.ok(h.bareIrcNickLooksMachine('ce6601f481ec')) t.ok(h.bareIrcNickLooksMachine('a1b2c3d4e5f6')) t.absent(h.bareIrcNickLooksMachine('raven')) const nick = h.bareIrcRandomNick() t.ok(/^os[a-z0-9]{5}$/.test(nick)) const spec = h.bareIrcResolveConnect( { env: { USER: 'ce6601f481ec' } }, { rest: [] }, { config: {}, secrets: {} } ) t.ok(spec.generatedNick) t.ok(spec.nick) t.absent(spec.nick === 'ce6601f481ec') }) test('slash /query and /msg without args return usage not unknown', async (t) => { const h = await load() const c = client() c.state = h.bareIrcCreateClient({ nick: 'alice' }).state const q = h.bareIrcRunSlash(c, '/query', { buf: { kind: 'server', name: '*server' } }) t.ok(q.usage && q.usage.indexOf('/query') >= 0) t.ok(q.ok) const m = h.bareIrcRunSlash(c, '/msg', { buf: { kind: 'server', name: '*server' } }) t.ok(m.usage && m.usage.indexOf('/msg') >= 0) }) test('slash /rooms opens browser; /join sends JOIN', async (t) => { const h = await load() const c = client() c.state = h.bareIrcCreateClient({ nick: 'alice' }).state const rooms = h.bareIrcRunSlash(c, '/rooms linux', { buf: { kind: 'server', name: '*server' } }) t.ok(rooms.rooms) t.is(rooms.roomsQuery, 'linux') const j = h.bareIrcRunSlash(c, '/join #libera', { buf: { kind: 'server', name: '*server' } }) t.ok(j.ok) t.ok(c._writes.some((w) => w.cmd === 'JOIN' && w.params[0] === '#libera')) }) test('LIST numerics fill channelList; self JOIN switches buffer', async (t) => { const h = await load() const writes = [] const sock = { writes: writes, write: function (x) { writes.push(String(x)) return true }, on: function () {}, end: function () {} } const c = h.bareIrcCreateClient({ nick: 'alice' }) c.attach(sock) c.handleMessage({ command: '322', params: ['alice', '#linux', '42', 'Linux talk'] }) c.handleMessage({ command: '323', params: ['alice', 'End of /LIST'] }) t.is(c.state.channelList.length, 1) t.is(c.state.channelList[0].name, '#linux') t.is(c.state.channelList[0].users, 42) c.handleMessage({ command: 'JOIN', nick: 'alice', params: ['#linux'] }) t.ok(c.state.currentId.indexOf('channel:') === 0) const buf = c.state.buffers[c.state.currentId] t.is(buf.name, '#linux') })