// tslint:disable:no-invalid-this import chalk from "chalk"; import "jest"; import { EditorState } from "prosemirror-state"; import { Command } from "../types"; import { applyCommand } from "./applyCommand"; import { ExpectExtendSync } from "./expect"; import { buildEditorStateMatcher } from "./expect.toMatchEditorState"; const matcherName = "toMapEditorState"; const commandName = "command"; const oldStateName = "oldState"; const newStateName = "newState"; const matchEditorState = buildEditorStateMatcher({ matcherHint: { name: matcherName, received: commandName, expected: oldStateName, secondArgument: newStateName }, receivedExpr: chalk`(${commandName} → ${oldStateName})`, expectedExpr: newStateName }); const toMapEditorState: ExpectExtendSync = function(received, ...args) { const [oldState, newState] = args; const matcherHint = () => this.utils.matcherHint(`.${matcherName}`, commandName, oldStateName, { secondArgument: newStateName }); const notMatcherHint = () => this.utils.matcherHint(`.not.${matcherName}`, commandName, oldStateName, { secondArgument: newStateName }); if (!(oldState instanceof EditorState)) { return { message: () => `${matcherHint()}\n\n` + `Expected ${oldStateName} should be an EditorState (using instanceof):\n` + ` ${this.utils.printExpected(oldState)}`, pass: false }; } if (newState !== undefined && !(newState instanceof EditorState)) { return { message: () => `${matcherHint()}\n\n` + `Expected ${newStateName} should be undefined or an EditorState (using instanceof):\n` + ` ${this.utils.printExpected(newState)}`, pass: false }; } if (typeof received !== "function") { return { message: () => `${matcherHint()}\n\n` + `Expected ${commandName} should be a Command (using typeof x === "function"):\n` + ` ${this.utils.printReceived(received)}`, pass: false }; } const commandResult = applyCommand(received as Command, oldState); if (!commandResult.success) { return { message: () => `${matcherHint()}\n\n` + `Expected ${commandName}(${oldStateName}) to return true (using ===):\n` + ` ${this.utils.printExpected(true)}\n` + `Received:\n` + ` ${this.utils.printReceived(false)}`, pass: false }; } if (newState !== undefined) { const matchEditorStateResult = matchEditorState.call(this, commandResult.newState, newState); if (!matchEditorStateResult.pass) { return matchEditorStateResult; } } return { message: () => `${notMatcherHint()}\n\n` + (newState === undefined ? `Expected ${commandName}(${oldStateName}) to be (using ===):\n` + ` ${this.utils.printExpected(false)}\n` + `Received:\n` + ` ${this.utils.printReceived(true)}` : `Expected ${commandName} to not apply to ${oldStateName}, or not produce (using .eq):\n` + ` ${this.utils.printExpected(newState)}\n` + `Received:\n` + ` ${this.utils.printReceived(oldState)}`), pass: true }; }; declare global { namespace jest { interface Matchers { toMapEditorState(oldState: EditorState, newState?: EditorState): R; } } } expect.extend({ toMapEditorState });