UNPKG

@cowwoc/requirements

Version:

A fluent API for enforcing design contracts with automatic message generation.

168 lines 5.63 kB
/* * Copyright (c) 2016 Gili Tzabari * Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0 */ import { IllegalStateError, NEWLINE_MARKER, NEWLINE_PATTERN, sortByKeys, assertThatType, Type, assert } from "../../internal.mjs"; /** * Base implementation for all diff writers. */ class AbstractDiffWriter { /** * Maps each line number to its associated actual value. */ lineToActualLine = new Map(); /** * Maps each line number to its associated expected value. */ lineToExpectedLine = new Map(); /** * Maps each line number to an indication of whether the actual and expected values are equal. */ lineToEqualLine = new Map(); /** * A padding character used to align values vertically. */ paddingMarker; /** * The final list of lines in the actual value. */ actualLines = []; /** * The final list of lines in the expected value. */ expectedLines = []; /** * The final list that indicates which lines contain actual and expected values that are equal. */ equalLines = []; /** * The current line number of the actual value. */ actualLineNumber = 0; /** * The current line number of the expected value. */ expectedLineNumber = 0; /** * `true` if the writer has been flushed. */ flushed = false; /** * @param paddingMarker - a padding character used to align values vertically * @throws TypeError if `paddingMarker` is `undefined` or `null` * @throws RangeError if `paddingMarker` is empty */ constructor(paddingMarker) { assertThatType(paddingMarker, "paddingMarker", Type.STRING); assert(paddingMarker.length !== 0, undefined, "paddingMarker may not be empty"); this.paddingMarker = paddingMarker; } getPaddingMarker() { return this.paddingMarker; } /** * Adds a new line for the actual value. * * @param number - the line number to add */ addActualLine(number) { this.lineToActualLine.set(number, ""); if (!this.lineToEqualLine.has(this.actualLineNumber)) this.lineToEqualLine.set(this.actualLineNumber, true); } /** * Adds a new line for the expected value. * * @param number - the line number to initialize */ addExpectedLine(number) { this.lineToExpectedLine.set(number, ""); if (!this.lineToEqualLine.has(this.expectedLineNumber)) this.lineToEqualLine.set(this.expectedLineNumber, true); } /** * Splits text into one or more lines. * * @param text - some text * @param lineConsumer - consumes one line at a time * @throws IllegalStateError if the writer has already been flushed */ splitLines(text, lineConsumer) { if (this.flushed) throw new IllegalStateError("Writer has already been flushed"); const lines = text.split(NEWLINE_PATTERN); let line; for (let i = 0; i < lines.length; ++i) { const isLastLine = i === lines.length - 1; line = ""; line += lines[i]; if (!isLastLine) line += NEWLINE_MARKER; if (line.length !== 0) lineConsumer(line); if (!isLastLine) { this.writeActualNewline(); this.writeExpectedNewline(); } } } /** * Ends the current line. * * @throws IllegalStateError if the writer has already been flushed */ writeActualNewline() { if (this.flushed) throw new IllegalStateError("Writer has already been flushed"); ++this.actualLineNumber; this.addActualLine(this.actualLineNumber); if (!this.lineToExpectedLine.get(this.actualLineNumber)) this.addExpectedLine(this.actualLineNumber); } /** * Ends the current line. * * @throws IllegalStateError if the writer has already been flushed */ writeExpectedNewline() { if (this.flushed) throw new IllegalStateError("Writer has already been flushed"); ++this.expectedLineNumber; this.addExpectedLine(this.expectedLineNumber); if (!this.lineToActualLine.get(this.expectedLineNumber)) this.addActualLine(this.expectedLineNumber); } flush() { if (this.flushed) return; this.flushed = true; this.beforeFlush(); for (const actualLine of sortByKeys(this.lineToActualLine).values()) this.actualLines.push(actualLine); Object.freeze(this.actualLines); for (const expectedLine of sortByKeys(this.lineToExpectedLine).values()) this.expectedLines.push(expectedLine); Object.freeze(this.expectedLines); for (const equalLine of sortByKeys(this.lineToEqualLine).values()) this.equalLines.push(equalLine); Object.freeze(this.equalLines); this.afterFlush(); } getActualLines() { if (!this.flushed) throw new IllegalStateError("Writer must be flushed"); return this.actualLines; } getExpectedLines() { if (!this.flushed) throw new IllegalStateError("Writer must be flushed"); return this.expectedLines; } getEqualLines() { if (!this.flushed) throw new IllegalStateError("Writer must be flushed"); return this.equalLines; } } export { AbstractDiffWriter }; //# sourceMappingURL=AbstractDiffWriter.mjs.map