| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | export function createTestLog() { |
| | let events: unknown[] = [] |
| |
|
| | |
| | let pendingExpectation: null | { |
| | resolve: () => void |
| | reject: (error: Error) => void |
| | expectedEvents: Array<any> |
| | error: Error |
| | } = null |
| |
|
| | function log(value: unknown) { |
| | |
| | events.push(value) |
| |
|
| | |
| | |
| | |
| | pingExpectation() |
| | } |
| |
|
| | function assert(expectedEvents: any[]) { |
| | if (pendingExpectation !== null) { |
| | const error = new Error('Cannot assert while a waitFor() is pending.') |
| | Error.captureStackTrace(error, assert) |
| | throw error |
| | } |
| |
|
| | const actualEvents = events |
| | events = [] |
| |
|
| | if (!areLogsEqual(expectedEvents, actualEvents)) { |
| | |
| | |
| | const error = new Error( |
| | 'Expected sequence of events did not occur.\n\n' + |
| | createDiff(expectedEvents, actualEvents) |
| | ) |
| | Error.captureStackTrace(error, assert) |
| | throw error |
| | } |
| | } |
| |
|
| | function waitFor(expectedEvents: any[], timeout: number = 5000) { |
| | |
| | |
| |
|
| | |
| | |
| | |
| | const error = new Error() |
| | Error.captureStackTrace(error, waitFor) |
| |
|
| | if (pendingExpectation !== null) { |
| | error.message = 'A previous waitFor() is still pending.' |
| | throw error |
| | } |
| |
|
| | let resolve |
| | let reject |
| | const promise = new Promise<void>((res, rej) => { |
| | resolve = res |
| | reject = rej |
| | }) |
| |
|
| | const thisExpectation = { |
| | resolve, |
| | reject, |
| | expectedEvents, |
| | error, |
| | } |
| | pendingExpectation = thisExpectation |
| |
|
| | setTimeout(() => { |
| | if (pendingExpectation === thisExpectation) { |
| | error.message = `waitFor timed out after ${timeout}ms` |
| | reject(error) |
| | } |
| | }, timeout) |
| |
|
| | pingExpectation() |
| |
|
| | return promise |
| | } |
| |
|
| | function pingExpectation() { |
| | if (pendingExpectation !== null) { |
| | const expectedEvents = pendingExpectation.expectedEvents |
| | if (events.length < expectedEvents.length) { |
| | return |
| | } |
| |
|
| | if (areLogsEqual(expectedEvents, events)) { |
| | |
| | |
| | events = [] |
| | pendingExpectation.resolve() |
| | pendingExpectation = null |
| | } else { |
| | |
| | |
| |
|
| | |
| | |
| | |
| | const error = pendingExpectation.error |
| | error.message = |
| | 'Expected sequence of events did not occur.\n\n' + |
| | createDiff(expectedEvents, events) |
| |
|
| | events = [] |
| | pendingExpectation.reject(error) |
| | pendingExpectation = null |
| | } |
| | } |
| | } |
| |
|
| | function createDiff(expected, actual) { |
| | |
| | |
| | return ` |
| | Expected: ${JSON.stringify(expected)} |
| | Actual: ${JSON.stringify(actual)} |
| | ` |
| | } |
| |
|
| | function areLogsEqual(a, b) { |
| | if (a.length !== b.length) { |
| | return false |
| | } |
| | for (let i = 0; i < a.length; i++) { |
| | if (a[i] !== b[i]) { |
| | return false |
| | } |
| | } |
| | return true |
| | } |
| |
|
| | return { |
| | log, |
| | waitFor, |
| | assert, |
| | } |
| | } |
| |
|