Add a bunch of reflow tests

This commit is contained in:
Daniel Imms
2018-12-28 14:55:15 -08:00
parent a33e8a6af7
commit 2a0da173f2
2 changed files with 128 additions and 5 deletions
+115
View File
@@ -233,6 +233,121 @@ describe('Buffer', () => {
}
});
});
describe('reflow', () => {
beforeEach(() => {
terminal.eraseAttr = () => DEFAULT_ATTR;
// Needed until the setting is removed
terminal.options.experimentalBufferLineImpl = 'TypedArray';
});
it('should not wrap empty lines', () => {
buffer.fillViewportRows();
assert.equal(buffer.lines.length, INIT_ROWS);
buffer.resize(INIT_COLS - 5, INIT_ROWS);
assert.equal(buffer.lines.length, INIT_ROWS);
});
it('should shrink row length', () => {
buffer.fillViewportRows();
buffer.resize(5, 10);
assert.equal(buffer.lines.length, 10);
assert.equal(buffer.lines.get(0).length, 5);
assert.equal(buffer.lines.get(1).length, 5);
assert.equal(buffer.lines.get(2).length, 5);
assert.equal(buffer.lines.get(3).length, 5);
assert.equal(buffer.lines.get(4).length, 5);
assert.equal(buffer.lines.get(5).length, 5);
assert.equal(buffer.lines.get(6).length, 5);
assert.equal(buffer.lines.get(7).length, 5);
assert.equal(buffer.lines.get(8).length, 5);
assert.equal(buffer.lines.get(9).length, 5);
});
it('should wrap and unwrap lines', () => {
buffer.fillViewportRows();
buffer.resize(5, 10);
terminal.cols = 5;
const firstLine = buffer.lines.get(0);
for (let i = 0; i < 5; i++) {
const code = 'a'.charCodeAt(0) + i;
const char = String.fromCharCode(code);
firstLine.set(i, [null, char, 1, code]);
}
assert.equal(buffer.lines.get(0).length, 5);
assert.equal(buffer.lines.get(0).translateToString(), 'abcde');
buffer.resize(1, 10);
terminal.cols = 1;
assert.equal(buffer.lines.length, 10);
assert.equal(buffer.lines.get(0).translateToString(), 'a');
assert.equal(buffer.lines.get(1).translateToString(), 'b');
assert.equal(buffer.lines.get(2).translateToString(), 'c');
assert.equal(buffer.lines.get(3).translateToString(), 'd');
assert.equal(buffer.lines.get(4).translateToString(), 'e');
assert.equal(buffer.lines.get(5).translateToString(), ' ');
assert.equal(buffer.lines.get(6).translateToString(), ' ');
assert.equal(buffer.lines.get(7).translateToString(), ' ');
assert.equal(buffer.lines.get(8).translateToString(), ' ');
assert.equal(buffer.lines.get(9).translateToString(), ' ');
buffer.resize(5, 10);
terminal.cols = 5;
assert.equal(buffer.lines.length, 10);
assert.equal(buffer.lines.get(0).translateToString(), 'abcde');
assert.equal(buffer.lines.get(1).translateToString(), ' ');
assert.equal(buffer.lines.get(2).translateToString(), ' ');
assert.equal(buffer.lines.get(3).translateToString(), ' ');
assert.equal(buffer.lines.get(4).translateToString(), ' ');
assert.equal(buffer.lines.get(5).translateToString(), ' ');
assert.equal(buffer.lines.get(6).translateToString(), ' ');
assert.equal(buffer.lines.get(7).translateToString(), ' ');
assert.equal(buffer.lines.get(8).translateToString(), ' ');
assert.equal(buffer.lines.get(9).translateToString(), ' ');
});
it('should discard parts of wrapped lines that go out of the scrollback', () => {
buffer.fillViewportRows();
terminal.options.scrollback = 1;
buffer.resize(10, 5);
terminal.cols = 10;
terminal.rows = 5;
const lastLine = buffer.lines.get(4);
for (let i = 0; i < 10; i++) {
const code = 'a'.charCodeAt(0) + i;
const char = String.fromCharCode(code);
lastLine.set(i, [null, char, 1, code]);
}
assert.equal(buffer.lines.length, 5);
buffer.y = 4;
buffer.resize(2, 5);
terminal.cols = 2;
assert.equal(buffer.y, 4);
assert.equal(buffer.ybase, 1);
assert.equal(buffer.lines.length, 6);
assert.equal(buffer.lines.get(0).translateToString(), ' ');
assert.equal(buffer.lines.get(1).translateToString(), 'ab');
assert.equal(buffer.lines.get(2).translateToString(), 'cd');
assert.equal(buffer.lines.get(3).translateToString(), 'ef');
assert.equal(buffer.lines.get(4).translateToString(), 'gh');
assert.equal(buffer.lines.get(5).translateToString(), 'ij');
buffer.resize(1, 5);
terminal.cols = 1;
assert.equal(buffer.y, 4);
assert.equal(buffer.ybase, 1);
assert.equal(buffer.lines.length, 6);
assert.equal(buffer.lines.get(0).translateToString(), 'e');
assert.equal(buffer.lines.get(1).translateToString(), 'f');
assert.equal(buffer.lines.get(2).translateToString(), 'g');
assert.equal(buffer.lines.get(3).translateToString(), 'h');
assert.equal(buffer.lines.get(4).translateToString(), 'i');
assert.equal(buffer.lines.get(5).translateToString(), 'j');
buffer.resize(10, 5);
terminal.cols = 10;
assert.equal(buffer.y, 0);
assert.equal(buffer.ybase, 0);
assert.equal(buffer.lines.length, 5);
assert.equal(buffer.lines.get(0).translateToString(), 'efghij ');
assert.equal(buffer.lines.get(1).translateToString(), ' ');
assert.equal(buffer.lines.get(2).translateToString(), ' ');
assert.equal(buffer.lines.get(3).translateToString(), ' ');
assert.equal(buffer.lines.get(4).translateToString(), ' ');
});
});
});
describe('buffer marked to have no scrollback', () => {
+13 -5
View File
@@ -164,9 +164,9 @@ export class Buffer implements IBuffer {
if (this.lines.length > 0) {
// Deal with columns increasing (reducing needs to happen after reflow)
if (this._terminal.cols < newCols) {
const ch: CharData = [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE]; // does xterm use the default attr?
const fillCharData: CharData = [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE];
for (let i = 0; i < this.lines.length; i++) {
this.lines.get(i).resize(newCols, ch);
this.lines.get(i).resize(newCols, fillCharData);
}
}
@@ -237,9 +237,11 @@ export class Buffer implements IBuffer {
if (this._terminal.options.experimentalBufferLineImpl === 'TypedArray') {
this._reflow(newCols);
// Trim the end of the line off if cols shrunk
if (this._terminal.cols > newCols) {
const fillCharData: CharData = [DEFAULT_ATTR, NULL_CELL_CHAR, NULL_CELL_WIDTH, NULL_CELL_CODE];
for (let i = 0; i < this.lines.length; i++) {
this.lines.get(i).resize(newCols, null);
this.lines.get(i).resize(newCols, fillCharData);
}
}
}
@@ -273,7 +275,7 @@ export class Buffer implements IBuffer {
// Check how many lines it's wrapped for
const wrappedLines: BufferLine[] = [this.lines.get(y) as BufferLine];
while (nextLine.isWrapped) {
while (nextLine.isWrapped && i < this.lines.length) {
wrappedLines.push(nextLine);
nextLine = this.lines.get(++i) as BufferLine;
}
@@ -361,7 +363,13 @@ export class Buffer implements IBuffer {
const cellsNeeded = (wrappedLines.length - 1) * this._terminal.cols + lastLineLength;
const linesNeeded = Math.ceil(cellsNeeded / newCols);
const linesToAdd = linesNeeded - wrappedLines.length;
const trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);
let trimmedLines: number;
if (this.ybase === 0 && this.y !== this.lines.length - 1) {
// If the top section of the buffer is not yet filled
trimmedLines = Math.max(0, this.y - this.lines.maxLength + linesToAdd);
} else {
trimmedLines = Math.max(0, this.lines.length - this.lines.maxLength + linesToAdd);
}
// Add the new lines
const newLines: BufferLine[] = [];