blob: 37eb520071f44c98bc9494e6b33ab4e72b10602f [file] [log] [blame]
Mike Frysinger598e8012022-09-07 08:38:34 -04001// Copyright 2022 The ChromiumOS Authors
Jason Linabad7562022-08-22 14:49:05 +10002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/**
6 * @fileoverview Unit tests for terminal_emulator.js.
7 */
8
Mike Frysinger75895da2022-10-04 00:42:28 +05459import {lib} from './deps_local.concat.js';
10
Jason Linabad7562022-08-22 14:49:05 +100011import {sleep} from './terminal_common.js';
Jason Lin5690e752022-08-30 15:36:45 +100012import {encodeKeyCombo, Modifier, XtermTerminal, XtermTerminalTestParams}
13 from './terminal_emulator.js';
14import {MockFunction, MockObject} from './terminal_test_mocks.js';
Jason Linabad7562022-08-22 14:49:05 +100015
16describe('terminal_emulator_tests.js', function() {
17 describe('XtermTerminal', function() {
18 beforeEach(async function() {
19 this.mocks = {
Jason Line9231bc2022-09-01 13:54:02 +100020 term: new MockObject({
21 options: {},
22 parser: {
23 registerOscHandler: () => {},
24 },
25 }),
Jason Linabad7562022-08-22 14:49:05 +100026 fontManager: new MockObject(),
Jason Lin2649da22022-10-12 10:16:44 +110027 xtermInternal: new MockObject({
28 getActualCellDimensions: () => ({width: 9, height: 22}),
29 }),
Jason Linabad7562022-08-22 14:49:05 +100030 };
31 const testParams = {};
32 for (const prop in this.mocks) {
33 testParams[prop] = this.mocks[prop].proxy;
34 }
35
36 this.terminal = new XtermTerminal({
37 storage: new lib.Storage.Memory(),
38 profileId: 'test',
39 enableWebGL: true,
40 testParams: /** @type {!XtermTerminalTestParams} */(testParams),
41 });
Jason Linc2504ae2022-09-02 13:03:31 +100042
43 // Some hacking because we don't run the decorate() function. Maybe we
44 // should just run it.
45 this.terminal.container_ = /** @type {!Element} */({
46 offsetWidth: 1000,
47 offsetHeight: 500,
48 });
Jason Lin8de3d282022-09-01 21:29:05 +100049 this.terminal.inited_ = true;
Jason Linabad7562022-08-22 14:49:05 +100050 });
51
52 describe('updateFont_()', function() {
53 it('updates font', async function() {
54 const updateFontPromise = this.terminal.updateFont_('font one');
55 assert.deepEqual(
56 await this.mocks.fontManager.whenCalled('loadFont'),
57 [['font one']]);
58 assert.equal(this.mocks.term.baseObj.options.fontFamily, undefined);
59 assert.isNotNull(this.terminal.pendingFont_);
Jason Linc2504ae2022-09-02 13:03:31 +100060 assert.equal(this.mocks.term.popMethodHistory('resize').length, 0);
Jason Linabad7562022-08-22 14:49:05 +100061
62 await updateFontPromise;
63 assert.equal(this.mocks.term.baseObj.options.fontFamily, 'font one');
64 assert.isNull(this.terminal.pendingFont_);
65 await sleep(0);
Jason Linc2504ae2022-09-02 13:03:31 +100066 assert.equal(this.mocks.term.popMethodHistory('resize').length, 1);
Jason Linabad7562022-08-22 14:49:05 +100067 });
68
69 it('refresh font when the font is the same', async function() {
70 this.mocks.term.baseObj.options.fontFamily = 'font one';
71 const updateFontPromise = this.terminal.updateFont_('font one');
72 assert.deepEqual(
73 await this.mocks.fontManager.whenCalled('loadFont'),
74 [['font one']]);
75 assert.equal(this.mocks.term.baseObj.options.fontFamily, 'font one');
76 assert.isNotNull(this.terminal.pendingFont_);
Jason Linc2504ae2022-09-02 13:03:31 +100077 assert.equal(this.mocks.term.popMethodHistory('resize').length, 0);
Jason Linabad7562022-08-22 14:49:05 +100078
79 await updateFontPromise;
80 // Note the extra space at the end.
81 assert.equal(this.mocks.term.baseObj.options.fontFamily, 'font one ');
82 assert.isNull(this.terminal.pendingFont_);
83 await sleep(0);
Jason Linc2504ae2022-09-02 13:03:31 +100084 assert.equal(this.mocks.term.popMethodHistory('resize').length, 1);
Jason Linabad7562022-08-22 14:49:05 +100085 });
86
87 it('aborts if pendingFont_ was changed', async function() {
88 const updateFontPromise = this.terminal.updateFont_('font one');
89 assert.deepEqual(
90 await this.mocks.fontManager.whenCalled('loadFont'),
91 [['font one']]);
92 assert.equal(this.mocks.term.baseObj.options.fontFamily, undefined);
93 assert.isNotNull(this.terminal.pendingFont_);
Jason Linc2504ae2022-09-02 13:03:31 +100094 assert.equal(this.mocks.term.popMethodHistory('resize').length, 0);
Jason Linabad7562022-08-22 14:49:05 +100095
96 this.terminal.pendingFont_ = 'font two';
97
98 await updateFontPromise;
99 assert.equal(this.mocks.term.baseObj.options.fontFamily, undefined);
100 assert.equal(this.terminal.pendingFont_, 'font two');
101 await sleep(0);
Jason Linc2504ae2022-09-02 13:03:31 +1000102 assert.equal(this.mocks.term.popMethodHistory('resize').length, 0);
Jason Linabad7562022-08-22 14:49:05 +1000103 });
104 });
Jason Lin5690e752022-08-30 15:36:45 +1000105
106 it('customKeyEventHandler_', async function() {
107 const mockHandler = new MockFunction();
108 const fakeEvent = {
109 type: 'keydown',
110 keyCode: 65,
111 ctrlKey: true,
112 };
113 this.terminal.keyDownHandlers_.set(encodeKeyCombo(Modifier.Ctrl, 65),
114 mockHandler.proxy);
115 assert.isFalse(this.terminal.customKeyEventHandler_(fakeEvent));
116 const history = mockHandler.popHistory();
117 assert.equal(history.length, 1);
118 assert.equal(history[0][0], fakeEvent);
119
120 assert.isFalse(this.terminal.customKeyEventHandler_({...fakeEvent,
121 type: 'keypress'}));
122 assert.isEmpty(mockHandler.popHistory());
123
124 assert.isTrue(this.terminal.customKeyEventHandler_({...fakeEvent,
125 shiftKey: true}));
126 assert.isEmpty(mockHandler.popHistory());
127
128 assert.isTrue(this.terminal.customKeyEventHandler_({...fakeEvent,
129 keyCode: 66}));
130 assert.isEmpty(mockHandler.popHistory());
131
132 assert.isTrue(this.terminal.customKeyEventHandler_({...fakeEvent,
133 ctrlKey: false}));
134 assert.isEmpty(mockHandler.popHistory());
135 });
Jason Linabad7562022-08-22 14:49:05 +1000136 });
137});