@cowwoc/requirements
Version:
A fluent API for enforcing design contracts with automatic message generation.
136 lines • 6.62 kB
JavaScript
/*
* Copyright (c) 2016 Gili Tzabari
* Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0
*/
import { AbstractDiffWriter, IllegalStateError, appendToValue } from "../../internal.mjs";
/**
* Base implementation for all color diff writers.
*/
class AbstractColorWriter extends AbstractDiffWriter {
/**
* A padding character used to align values vertically.
*/
static DIFF_PADDING = "/";
/**
* Maps from a line number in the actual value to the decoration at the end of the line.
*/
lineToActualDecoration = new Map();
/**
* Maps from a line number in the expected value to the decoration at the end of the line.
*/
lineToExpectedDecoration = new Map();
constructor() {
super(AbstractColorWriter.DIFF_PADDING);
this.addActualLine(0);
this.addExpectedLine(0);
}
addActualLine(number) {
super.addActualLine(number);
this.lineToActualDecoration.set(number, DecorationType.UNDECORATED);
}
addExpectedLine(number) {
super.addExpectedLine(number);
this.lineToExpectedDecoration.set(number, DecorationType.UNDECORATED);
}
writeEqual(text) {
if (this.flushed)
throw new IllegalStateError("Writer was already flushed");
if (text.length === 0)
return;
this.splitLines(text, (line) => {
const actualDecoration = this.lineToActualDecoration.get(this.actualLineNumber);
if (actualDecoration === DecorationType.EQUAL)
appendToValue(this.lineToActualLine, this.actualLineNumber, line);
else {
appendToValue(this.lineToActualLine, this.actualLineNumber, this.decorateEqualText(line));
this.lineToActualDecoration.set(this.actualLineNumber, DecorationType.EQUAL);
}
if (this.expectedLineNumber !== this.actualLineNumber) {
const length = line.length;
const padding = this.decoratePadding(this.getPaddingMarker().repeat(length));
appendToValue(this.lineToExpectedLine, this.actualLineNumber, padding);
this.lineToExpectedDecoration.set(this.actualLineNumber, DecorationType.EQUAL);
appendToValue(this.lineToActualLine, this.expectedLineNumber, padding);
this.lineToActualDecoration.set(this.expectedLineNumber, DecorationType.EQUAL);
}
const expectedDecoration = this.lineToExpectedDecoration.get(this.expectedLineNumber);
if (expectedDecoration === DecorationType.EQUAL)
appendToValue(this.lineToExpectedLine, this.expectedLineNumber, line);
else {
appendToValue(this.lineToExpectedLine, this.expectedLineNumber, this.decorateEqualText(line));
this.lineToExpectedDecoration.set(this.expectedLineNumber, DecorationType.EQUAL);
}
});
}
writeDeleted(text) {
if (this.flushed)
throw new IllegalStateError("Writer was already flushed");
if (text.length === 0)
return;
this.splitLines(text, (line) => {
const actualDecoration = this.lineToActualDecoration.get(this.actualLineNumber);
if (actualDecoration === DecorationType.DELETE)
appendToValue(this.lineToActualLine, this.actualLineNumber, line);
else {
appendToValue(this.lineToActualLine, this.actualLineNumber, this.decorateDeletedText(line));
this.lineToActualDecoration.set(this.actualLineNumber, DecorationType.DELETE);
}
const expectedDecoration = this.lineToExpectedDecoration.get(this.actualLineNumber);
const padding = this.getPaddingMarker().repeat(line.length);
if (expectedDecoration === DecorationType.DELETE)
appendToValue(this.lineToExpectedLine, this.actualLineNumber, padding);
else {
appendToValue(this.lineToExpectedLine, this.actualLineNumber, this.decoratePadding(padding));
this.lineToExpectedDecoration.set(this.actualLineNumber, DecorationType.DELETE);
}
this.lineToEqualLine.set(this.actualLineNumber, false);
});
}
writeInserted(text) {
if (this.flushed)
throw new IllegalStateError("Writer was already flushed");
if (text.length === 0)
return;
this.splitLines(text, (line) => {
const actualDecoration = this.lineToActualDecoration.get(this.expectedLineNumber);
const padding = this.getPaddingMarker().repeat(line.length);
if (actualDecoration === DecorationType.INSERT)
appendToValue(this.lineToActualLine, this.expectedLineNumber, this.decoratePadding(padding));
else {
appendToValue(this.lineToActualLine, this.expectedLineNumber, this.decoratePadding(padding));
this.lineToActualDecoration.set(this.expectedLineNumber, DecorationType.INSERT);
}
const expectedDecoration = this.lineToExpectedDecoration.get(this.expectedLineNumber);
if (expectedDecoration === DecorationType.INSERT)
appendToValue(this.lineToExpectedLine, this.expectedLineNumber, line);
else {
appendToValue(this.lineToExpectedLine, this.expectedLineNumber, this.decorateInsertedText(line));
this.lineToExpectedDecoration.set(this.expectedLineNumber, DecorationType.INSERT);
}
this.lineToEqualLine.set(this.expectedLineNumber, false);
});
}
beforeFlush() {
for (const entry of this.lineToActualDecoration.entries())
this.lineToActualDecoration.set(entry[0], DecorationType.UNDECORATED);
for (const entry of this.lineToExpectedDecoration.entries())
this.lineToExpectedDecoration.set(entry[0], DecorationType.UNDECORATED);
}
getDiffLines() {
if (!this.flushed)
throw new IllegalStateError("Writer must be flushed");
return [];
}
}
/**
* Possible types of decorations.
*/
var DecorationType;
(function (DecorationType) {
DecorationType[DecorationType["UNDECORATED"] = 0] = "UNDECORATED";
DecorationType[DecorationType["DELETE"] = 1] = "DELETE";
DecorationType[DecorationType["INSERT"] = 2] = "INSERT";
DecorationType[DecorationType["EQUAL"] = 3] = "EQUAL";
})(DecorationType || (DecorationType = {}));
export { AbstractColorWriter };
//# sourceMappingURL=AbstractColorWriter.mjs.map