import { test, afterEach } from 'node:test' import assert from 'node:assert/strict' import { separator, section, info, success, warn, fail, failError, } from '../logger.js' const realWrite = process.stderr.write const realStdoutWrite = process.stdout.write afterEach(() => { process.stderr.write = realWrite process.stdout.write = realStdoutWrite }) // 攔截寫入 stdout 的內容 function captureStdout(fn) { const chunks = [] process.stdout.write = (chunk) => { chunks.push(String(chunk)) return true } try { fn() } finally { process.stdout.write = realStdoutWrite } return chunks.join('') } test('info/success/warn 以正確前綴寫入 stdout', () => { assert.equal(captureStdout(() => info('hi')), '[INFO] hi\n') assert.equal(captureStdout(() => success('ok')), '[OK] ok\n') assert.equal(captureStdout(() => warn('careful')), '[WARN] careful\n') }) test('separator 輸出等號分隔線', () => { const out = captureStdout(() => separator()) assert.match(out, /^\n={50}\n$/) }) test('section 輸出分隔線、標題與虛線', () => { const out = captureStdout(() => section('參數檢查')) assert.match(out, /={50}\n參數檢查\n-{50}\n/) }) test('fail 寫入 stderr 而非 stdout', () => { const stdout = captureStdout(() => { const chunks = [] process.stderr.write = (chunk) => { chunks.push(String(chunk)) return true } fail('boom') assert.equal(chunks.join(''), '[ERR] boom\n') }) assert.equal(stdout, '') // fail 不應寫入 stdout }) // 攔截寫入 stderr 的內容 function captureStderr(fn) { const chunks = [] process.stderr.write = (chunk) => { chunks.push(String(chunk)) return true } try { fn() } finally { process.stderr.write = realWrite } return chunks.join('') } test('failError 對 Error 物件輸出名稱、訊息與堆疊', () => { const out = captureStderr(() => failError(new TypeError('boom'))) assert.match(out, /\[ERR\] TypeError: boom/) assert.match(out, /at /) // 堆疊內容 }) test('failError 對非 Error 值輸出其字串形式', () => { const out = captureStderr(() => failError('plain failure')) assert.match(out, /\[ERR\] plain failure/) })