| 45 | const kSource = Symbol('kSource'); // Placeholder standing for input readback |
| 46 | |
| 47 | async function runReplTests(socket, prompt, tests) { |
| 48 | let lineBuffer = ''; |
| 49 | |
| 50 | for (const { send, expect } of tests) { |
| 51 | // Expect can be a single line or multiple lines |
| 52 | const expectedLines = Array.isArray(expect) ? expect : [ expect ]; |
| 53 | |
| 54 | console.error('\n------------'); |
| 55 | console.error('out:', JSON.stringify(send)); |
| 56 | socket.write(`${send}\n`); |
| 57 | |
| 58 | for (let expectedLine of expectedLines) { |
| 59 | // Special value: kSource refers to last sent source text |
| 60 | if (expectedLine === kSource) |
| 61 | expectedLine = send; |
| 62 | |
| 63 | while (!lineBuffer.includes('\n')) { |
| 64 | lineBuffer += await event(socket, expect); |
| 65 | |
| 66 | // Cut away the initial prompt |
| 67 | while (lineBuffer.startsWith(prompt)) |
| 68 | lineBuffer = lineBuffer.slice(prompt.length); |
| 69 | |
| 70 | // Allow to match partial text if no newline was received, because |
| 71 | // sending newlines from the REPL itself would be redundant |
| 72 | // (e.g. in the `| ` multiline prompt: The user already pressed |
| 73 | // enter for that, so the REPL shouldn't do it again!). |
| 74 | if (lineBuffer === expectedLine && !expectedLine.includes('\n')) |
| 75 | lineBuffer += '\n'; |
| 76 | } |
| 77 | |
| 78 | // Split off the current line. |
| 79 | const newlineOffset = lineBuffer.indexOf('\n'); |
| 80 | let actualLine = lineBuffer.slice(0, newlineOffset); |
| 81 | lineBuffer = lineBuffer.slice(newlineOffset + 1); |
| 82 | |
| 83 | // This might have been skipped in the loop above because the buffer |
| 84 | // already contained a \n to begin with and the entire loop was skipped. |
| 85 | while (actualLine.startsWith(prompt)) |
| 86 | actualLine = actualLine.slice(prompt.length); |
| 87 | |
| 88 | console.error('in:', JSON.stringify(actualLine)); |
| 89 | |
| 90 | // Match a string directly, or a RegExp. |
| 91 | if (typeof expectedLine === 'string') { |
| 92 | assert.strictEqual(actualLine, expectedLine); |
| 93 | } else { |
| 94 | assert.match(actualLine, expectedLine); |
| 95 | } |
| 96 | } |
| 97 | } |
| 98 | |
| 99 | const remainder = socket.read(); |
| 100 | assert(remainder === '' || remainder === null); |
| 101 | } |
| 102 | |
| 103 | const unixTests = [ |
| 104 | { |