// @flow import { check, failFast } from './ipc-helpers'; export class IpcChain { _expectedCalls: Array; _recordedCalls: Array; _mockIpc: {}; _done: (?Error) => void; _aborted: boolean; constructor(mockIpc: {}) { this._expectedCalls = []; this._recordedCalls = []; this._mockIpc = mockIpc; this._aborted = false; } expect(ipcCall: string): StepBuilder { const builder = new StepBuilder(ipcCall); this._expectedCalls.push(ipcCall); this._addStep(builder); return builder; } _addStep(step: StepBuilder) { this._mockIpc[step.ipcCall] = (...args: Array) => { return new Promise((r) => this._stepPromiseCallback(step, r, args)); }; } _stepPromiseCallback(step: StepBuilder, resolve: (?R) => void, args: Array) { if (this._aborted) { return; } this._registerCall(step.ipcCall); const inputValidation = step.inputValidation; if (inputValidation) { const failedInputValidation = failFast(() => { inputValidation(...args); }, this._done); if (failedInputValidation) { this._abort(); return; } } if (this._isLastCall()) { this._ensureChainCalledCorrectly(); } resolve(step.returnValue); } _abort() { this._aborted = true; } _isLastCall(): boolean { return this._recordedCalls.length === this._expectedCalls.length; } _ensureChainCalledCorrectly() { check(() => { expect(this._expectedCalls).to.deep.equal(this._recordedCalls); }, this._done); } _registerCall(ipcCall: string) { this._recordedCalls.push(ipcCall); } onSuccessOrFailure(done: (*) => void) { this._done = done; } } class StepBuilder { ipcCall: string; inputValidation: ?(...args: Array) => void; returnValue: ?R; constructor(ipcCall: string) { this.ipcCall = ipcCall; } withInputValidation(iv: (...args: Array) => void): this { this.inputValidation = iv; return this; } withReturnValue(rv: R): this { this.returnValue = rv; return this; } }