Skip to content

Commit f5ccf75

Browse files
authored
Merge branch 'master' into tyriar/faster_tasks
2 parents 771d5f5 + 0f15a78 commit f5ccf75

File tree

10 files changed

+490
-33
lines changed

10 files changed

+490
-33
lines changed
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
/**
2+
* Copyright (c) 2018 The xterm.js authors. All rights reserved.
3+
* @license MIT
4+
*/
5+
6+
import jsdom = require('jsdom');
7+
import { assert } from 'chai';
8+
import { SerializeAddon } from './SerializeAddon';
9+
import { Terminal } from 'browser/public/Terminal';
10+
import { ColorManager } from 'browser/ColorManager';
11+
import { SelectionModel } from 'browser/selection/SelectionModel';
12+
import { IBufferService } from 'common/services/Services';
13+
14+
function sgr(...seq: string[]): string {
15+
return `\x1b[${seq.join(';')}m`;
16+
}
17+
18+
function writeP(terminal: Terminal, data: string | Uint8Array): Promise<void> {
19+
return new Promise(r => terminal.write(data, r));
20+
}
21+
22+
class TestSelectionService {
23+
private _model: SelectionModel;
24+
private _hasSelection: boolean = false;
25+
26+
constructor(
27+
bufferService: IBufferService
28+
) {
29+
this._model = new SelectionModel(bufferService);
30+
}
31+
32+
public get model(): SelectionModel { return this._model; }
33+
34+
public get hasSelection(): boolean { return this._hasSelection; }
35+
36+
public get selectionStart(): [number, number] | undefined { return this._model.finalSelectionStart; }
37+
public get selectionEnd(): [number, number] | undefined { return this._model.finalSelectionEnd; }
38+
39+
public setSelection(col: number, row: number, length: number): void {
40+
this._model.selectionStart = [col, row];
41+
this._model.selectionStartLength = length;
42+
this._hasSelection = true;
43+
}
44+
}
45+
46+
describe('xterm-addon-serialize html', () => {
47+
let cm: ColorManager;
48+
let dom: jsdom.JSDOM;
49+
let document: Document;
50+
let window: jsdom.DOMWindow;
51+
52+
let serializeAddon: SerializeAddon;
53+
let terminal: Terminal;
54+
let selectionService: any;
55+
56+
before(() => {
57+
serializeAddon = new SerializeAddon();
58+
});
59+
60+
beforeEach(() => {
61+
dom = new jsdom.JSDOM('');
62+
window = dom.window;
63+
document = window.document;
64+
65+
(window as any).HTMLCanvasElement.prototype.getContext = () => ({
66+
createLinearGradient(): any {
67+
return null;
68+
},
69+
70+
fillRect(): void { },
71+
72+
getImageData(): any {
73+
return { data: [0, 0, 0, 0xFF] };
74+
}
75+
});
76+
77+
terminal = new Terminal({ cols: 10, rows: 2 });
78+
terminal.loadAddon(serializeAddon);
79+
80+
selectionService = new TestSelectionService((terminal as any)._core._bufferService);
81+
cm = new ColorManager(document, false);
82+
(terminal as any)._core._colorManager = cm;
83+
(terminal as any)._core._selectionService = selectionService;
84+
});
85+
86+
it('empty terminal with selection turned off', () => {
87+
const output = serializeAddon.serializeAsHTML();
88+
assert.notEqual(output, '');
89+
assert.equal((output.match(new RegExp('<div><span> {10}</span><\/div>', 'g')) || []).length, 2);
90+
});
91+
92+
it('empty terminal with no selection', () => {
93+
const output = serializeAddon.serializeAsHTML({
94+
onlySelection: true
95+
});
96+
assert.equal(output, '');
97+
});
98+
99+
it('basic terminal with selection', async () => {
100+
await writeP(terminal, ' terminal ');
101+
terminal.select(1, 0, 8);
102+
103+
const output = serializeAddon.serializeAsHTML({
104+
onlySelection: true
105+
});
106+
assert.equal((output.match(new RegExp('<div><span>terminal<\/span><\/div>', 'g')) || []).length, 1, output);
107+
});
108+
109+
it('cells with bold styling', async () => {
110+
await writeP(terminal, ' ' + sgr('1') + 'terminal' + sgr('22') + ' ');
111+
112+
const output = serializeAddon.serializeAsHTML();
113+
assert.equal((output.match(new RegExp('<span style=\'font-weight: bold;\'>terminal<\/span>', 'g')) || []).length, 1, output);
114+
});
115+
116+
it('cells with italic styling', async () => {
117+
await writeP(terminal, ' ' + sgr('3') + 'terminal' + sgr('23') + ' ');
118+
119+
const output = serializeAddon.serializeAsHTML();
120+
assert.equal((output.match(new RegExp('<span style=\'font-style: italic;\'>terminal<\/span>', 'g')) || []).length, 1, output);
121+
});
122+
123+
it('cells with inverse styling', async () => {
124+
await writeP(terminal, ' ' + sgr('7') + 'terminal' + sgr('27') + ' ');
125+
126+
const output = serializeAddon.serializeAsHTML();
127+
assert.equal((output.match(new RegExp('<span style=\'color: #000000; background-color: #BFBFBF;\'>terminal<\/span>', 'g')) || []).length, 1, output);
128+
});
129+
130+
it('cells with underline styling', async () => {
131+
await writeP(terminal, ' ' + sgr('4') + 'terminal' + sgr('24') + ' ');
132+
133+
const output = serializeAddon.serializeAsHTML();
134+
assert.equal((output.match(new RegExp('<span style=\'text-decoration: underline;\'>terminal<\/span>', 'g')) || []).length, 1, output);
135+
});
136+
137+
it('cells with invisible styling', async () => {
138+
await writeP(terminal, ' ' + sgr('8') + 'terminal' + sgr('28') + ' ');
139+
140+
const output = serializeAddon.serializeAsHTML();
141+
assert.equal((output.match(new RegExp('<span style=\'visibility: hidden;\'>terminal<\/span>', 'g')) || []).length, 1, output);
142+
});
143+
144+
it('cells with dim styling', async () => {
145+
await writeP(terminal, ' ' + sgr('2') + 'terminal' + sgr('22') + ' ');
146+
147+
const output = serializeAddon.serializeAsHTML();
148+
assert.equal((output.match(new RegExp('<span style=\'opacity: 0.5;\'>terminal<\/span>', 'g')) || []).length, 1, output);
149+
});
150+
151+
it('cells with strikethrough styling', async () => {
152+
await writeP(terminal, ' ' + sgr('9') + 'terminal' + sgr('29') + ' ');
153+
154+
const output = serializeAddon.serializeAsHTML();
155+
assert.equal((output.match(new RegExp('<span style=\'text-decoration: line-through;\'>terminal<\/span>', 'g')) || []).length, 1, output);
156+
});
157+
158+
it('cells with combined styling', async () => {
159+
await writeP(terminal, sgr('1') + ' ' + sgr('9') + 'termi' + sgr('22') + 'nal' + sgr('29') + ' ');
160+
161+
const output = serializeAddon.serializeAsHTML();
162+
assert.equal((output.match(new RegExp('<span style=\'font-weight: bold;\'> <\/span>', 'g')) || []).length, 1, output);
163+
assert.equal((output.match(new RegExp('<span style=\'font-weight: bold; text-decoration: line-through;\'>termi<\/span>', 'g')) || []).length, 1, output);
164+
assert.equal((output.match(new RegExp('<span style=\'text-decoration: line-through;\'>nal<\/span>', 'g')) || []).length, 1, output);
165+
});
166+
167+
it('cells with color styling', async () => {
168+
await writeP(terminal, ' ' + sgr('38;5;46') + 'terminal' + sgr('39') + ' ');
169+
170+
const output = serializeAddon.serializeAsHTML();
171+
assert.equal((output.match(new RegExp('<span style=\'color: #00ff00;\'>terminal<\/span>', 'g')) || []).length, 1, output);
172+
});
173+
174+
it('cells with background styling', async () => {
175+
await writeP(terminal, ' ' + sgr('48;5;46') + 'terminal' + sgr('49') + ' ');
176+
177+
const output = serializeAddon.serializeAsHTML();
178+
assert.equal((output.match(new RegExp('<span style=\'background-color: #00ff00;\'>terminal<\/span>', 'g')) || []).length, 1, output);
179+
});
180+
181+
it('empty terminal with default options', async () => {
182+
const output = serializeAddon.serializeAsHTML();
183+
assert.equal((output.match(new RegExp('color: #000000; background-color: #ffffff; font-family: courier-new, courier, monospace; font-size: 15px;', 'g')) || []).length, 1, output);
184+
});
185+
186+
it('empty terminal with custom options', async () => {
187+
terminal.options.fontFamily = 'verdana';
188+
terminal.options.fontSize = 20;
189+
terminal.options.theme = {
190+
foreground: '#ff00ff',
191+
background: '#00ff00'
192+
};
193+
const output = serializeAddon.serializeAsHTML({
194+
includeGlobalBackground: true
195+
});
196+
assert.equal((output.match(new RegExp('color: #ff00ff; background-color: #00ff00; font-family: verdana; font-size: 20px;', 'g')) || []).length, 1, output);
197+
});
198+
199+
it('empty terminal with background included', async () => {
200+
const output = serializeAddon.serializeAsHTML({
201+
includeGlobalBackground: true
202+
});
203+
assert.equal((output.match(new RegExp('color: #ffffff; background-color: #000000; font-family: courier-new, courier, monospace; font-size: 15px;', 'g')) || []).length, 1, output);
204+
});
205+
});

0 commit comments

Comments
 (0)