(output)
| 246 | } |
| 247 | |
| 248 | function parseNodeTest(output) { |
| 249 | // TAP-like output from node:test |
| 250 | const result = { passed: 0, failed: 0, errors: 0, skipped: 0, failures: [] }; |
| 251 | |
| 252 | // "# pass N" and "# fail N" |
| 253 | const passLine = output.match(/^# pass\s+(\d+)/m); if (passLine) result.passed = parseInt(passLine[1], 10); |
| 254 | const failLine = output.match(/^# fail\s+(\d+)/m); if (failLine) result.failed = parseInt(failLine[1], 10); |
| 255 | const skipLine = output.match(/^# skip\s+(\d+)/m); if (skipLine) result.skipped = parseInt(skipLine[1], 10); |
| 256 | |
| 257 | // "not ok N - test name" |
| 258 | const notOkRe = /^not ok \d+\s*-\s*(.+)$/mg; |
| 259 | let m; |
| 260 | while ((m = notOkRe.exec(output)) !== null) { |
| 261 | // YAML block following "not ok" has the message |
| 262 | const rest = output.slice(m.index + m[0].length); |
| 263 | const msgLine = rest.match(/message: (.+)/); |
| 264 | result.failures.push({ name: m[1].trim(), message: (msgLine ? msgLine[1] : '').trim().slice(0, 200) }); |
| 265 | } |
| 266 | |
| 267 | return result; |
| 268 | } |
| 269 | |
| 270 | function parseGeneric(output, exitCode) { |
| 271 | // Last-resort heuristic: look for common pass/fail keywords |
no outgoing calls
no test coverage detected