Files
omp-debug/test/debug.test.mjs
T

71 lines
3.4 KiB
JavaScript

import test from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import * as plugin from '../index.js'
import { ADAPTERS } from '../lib/session.js'
function harness() {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'omp-debug-'))
const tools = new Map()
const effects = []
const ctx = { tools: { register(d) { tools.set(d.name, d); return () => {} } }, effect(fn) { effects.push(fn()) } }
plugin.apply(ctx, { stopWaitMs: 15000 })
const exec = { agent: { session: { header: { cwd: dir } } } }
const call = async (args) => (await tools.get('debug').execute(args, exec)).text
return { dir, call, cleanup: async () => { await call({ action: 'terminate' }).catch(() => {}); fs.rmSync(dir, { recursive: true, force: true }) } }
}
test('adapters lists availability', async () => {
const h = harness()
const t = await h.call({ action: 'adapters' })
assert.match(t, /debugpy/)
await h.cleanup()
})
test('python: breakpoint, inspect, evaluate, step, continue to exit', { skip: !ADAPTERS.debugpy.detect(), timeout: 60000 }, async () => {
const h = harness()
fs.writeFileSync(path.join(h.dir, 'p.py'), 'def add(a, b):\n c = a + b\n return c\n\nx = add(2, 3)\nprint("result", x)\n')
assert.match(await h.call({ action: 'set_breakpoint', file: 'p.py', line: 2 }), /queued/)
const l = await h.call({ action: 'launch', program: 'p.py' })
assert.match(l, /Stopped \(breakpoint\).* in add at .*p\.py:2/s)
assert.match(l, /→2: c = a \+ b/)
const sc = await h.call({ action: 'scopes' })
assert.match(sc, /a: int = 2/)
assert.equal((await h.call({ action: 'evaluate', expression: 'a * 10' })).split(' ')[0], '20')
const st = await h.call({ action: 'step_over' })
assert.match(st, /p\.py:3/)
const tr = await h.call({ action: 'stack_trace' })
assert.match(tr, /#0 add/)
const c = await h.call({ action: 'continue' })
assert.match(c, /terminated/i)
assert.match(c, /result 5/)
assert.doesNotMatch(c, /Traceback|NoMoreMessages|E\+\d{5}/)
await h.cleanup()
})
test('python: terminate a stopped session cleanly', { skip: !ADAPTERS.debugpy.detect(), timeout: 60000 }, async () => {
const h = harness()
fs.writeFileSync(path.join(h.dir, 't.py'), 'import time\nfor i in range(100):\n time.sleep(0.05)\nprint("done")\n')
await h.call({ action: 'set_breakpoint', file: 't.py', line: 3 })
assert.match(await h.call({ action: 'launch', program: 't.py' }), /Stopped \(breakpoint\)/)
const t = await h.call({ action: 'terminate' })
assert.match(t, /^Session dbg\d+ terminated\./)
assert.doesNotMatch(t, /Traceback|NoMoreMessages|E\+\d{5}|couldn't handle/)
assert.match(await h.call({ action: 'sessions' }), /terminated/)
await h.cleanup()
})
test('node: breakpoint and evaluate via js-debug', { skip: !ADAPTERS.node.detect(), timeout: 90000 }, async () => {
const h = harness()
fs.writeFileSync(path.join(h.dir, 'n.js'), 'function mul(a, b) {\n const r = a * b\n return r\n}\nconsole.log("got", mul(6, 7))\n')
await h.call({ action: 'set_breakpoint', file: 'n.js', line: 3 })
const l = await h.call({ action: 'launch', program: 'n.js' })
assert.match(l, /Stopped.*n\.js:3/s, l)
assert.match(await h.call({ action: 'evaluate', expression: 'r + 1' }), /^43/)
const c = await h.call({ action: 'continue' })
assert.match(c, /got 42|terminated|running/i)
await h.cleanup()
})