Files
xterm.js/src/browser/services/SelectionService.test.ts
T

520 lines
25 KiB
TypeScript
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* Copyright (c) 2017 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { assert } from 'chai';
import { SelectionService, SelectionMode } from './SelectionService';
import { SelectionModel } from '../selection/SelectionModel';
import { IBuffer, IBufferLine } from '../../common/buffer/Types';
import { MockBufferService, MockOptionsService, MockCoreService, MockMouseStateService, createCellData } from '../../common/TestUtils.test';
import { BufferLine } from '../../common/buffer/BufferLine';
import { IBufferService, IOptionsService } from '../../common/services/Services';
import { MockCoreBrowserService, MockMouseService, MockRenderService } from '../TestUtils.test';
import { CellData } from '../../common/buffer/CellData';
import { IRenderService } from './Services';
class TestSelectionService extends SelectionService {
constructor(
bufferService: IBufferService,
optionsService: IOptionsService,
renderService: IRenderService,
public readonly mouseStateService: MockMouseStateService
) {
super(null!, null!, null!, bufferService, new MockCoreService(), new MockMouseService(), optionsService, mouseStateService, renderService, new MockCoreBrowserService());
}
public get model(): SelectionModel { return this._model; }
public set selectionMode(mode: SelectionMode) { this._activeSelectionMode = mode; }
public selectLineAt(line: number): void { this._selectLineAt(line); }
public selectWordAt(coords: [number, number]): void { this._selectWordAt(coords, true); }
public areCoordsInSelection(coords: [number, number], start: [number, number], end: [number, number]): boolean { return this._areCoordsInSelection(coords, start, end); }
// Disable DOM interaction
public enable(): void {}
public disable(): void {}
public refresh(): void {}
}
describe('SelectionService', () => {
let buffer: IBuffer;
let bufferService: IBufferService;
let optionsService: IOptionsService;
let mouseStateService: MockMouseStateService;
let selectionService: TestSelectionService;
beforeEach(() => {
optionsService = new MockOptionsService();
mouseStateService = new MockMouseStateService();
bufferService = new MockBufferService(20, 20, optionsService);
buffer = bufferService.buffer;
const renderService = new MockRenderService();
renderService.dimensions.css.canvas.height = 10 * 20;
renderService.dimensions.css.canvas.width = 10 * 20;
selectionService = new TestSelectionService(bufferService, optionsService, renderService, mouseStateService);
});
function stringToRow(text: string): IBufferLine {
const result = new BufferLine(text.length);
for (let i = 0; i < text.length; i++) {
result.setCell(i, createCellData(0, text.charAt(i), 1));
}
return result;
}
function stringArrayToRow(chars: string[]): IBufferLine {
const line = new BufferLine(chars.length);
chars.map((c, idx) => line.setCell(idx, createCellData(0, c, 1)));
return line;
}
describe('_selectWordAt', () => {
it('should expand selection for normal width chars', () => {
buffer.lines.set(0, stringToRow('foo bar'));
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, 'foo');
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, 'foo');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, 'foo');
selectionService.selectWordAt([3, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([4, 0]);
assert.equal(selectionService.selectionText, 'bar');
selectionService.selectWordAt([5, 0]);
assert.equal(selectionService.selectionText, 'bar');
selectionService.selectWordAt([6, 0]);
assert.equal(selectionService.selectionText, 'bar');
});
it('should expand selection for whitespace', () => {
buffer.lines.set(0, stringToRow('a b'));
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, 'a');
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([3, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([4, 0]);
assert.equal(selectionService.selectionText, 'b');
});
it('should expand selection for wide characters', () => {
// Wide characters use a special format
const data: [number, string, number, number][] = [
[0, '中', 2, '中'.charCodeAt(0)],
[0, '', 0, 0],
[0, '文', 2, '文'.charCodeAt(0)],
[0, '', 0, 0],
[0, ' ', 1, ' '.charCodeAt(0)],
[0, 'a', 1, 'a'.charCodeAt(0)],
[0, '中', 2, '中'.charCodeAt(0)],
[0, '', 0, 0],
[0, '文', 2, '文'.charCodeAt(0)],
[0, '', 0, ''.charCodeAt(0)],
[0, 'b', 1, 'b'.charCodeAt(0)],
[0, ' ', 1, ' '.charCodeAt(0)],
[0, 'f', 1, 'f'.charCodeAt(0)],
[0, 'o', 1, 'o'.charCodeAt(0)],
[0, 'o', 1, 'o'.charCodeAt(0)]
];
const line = new BufferLine(data.length);
for (let i = 0; i < data.length; ++i) line.setCell(i, CellData.fromCharData(data[i]));
buffer.lines.set(0, line);
// Ensure wide characters take up 2 columns
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, '中文');
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, '中文');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, '中文');
selectionService.selectWordAt([3, 0]);
assert.equal(selectionService.selectionText, '中文');
selectionService.selectWordAt([4, 0]);
assert.equal(selectionService.selectionText, ' ');
// Ensure wide characters work when wrapped in normal width characters
selectionService.selectWordAt([5, 0]);
assert.equal(selectionService.selectionText, 'a中文b');
selectionService.selectWordAt([6, 0]);
assert.equal(selectionService.selectionText, 'a中文b');
selectionService.selectWordAt([7, 0]);
assert.equal(selectionService.selectionText, 'a中文b');
selectionService.selectWordAt([8, 0]);
assert.equal(selectionService.selectionText, 'a中文b');
selectionService.selectWordAt([9, 0]);
assert.equal(selectionService.selectionText, 'a中文b');
selectionService.selectWordAt([10, 0]);
assert.equal(selectionService.selectionText, 'a中文b');
selectionService.selectWordAt([11, 0]);
assert.equal(selectionService.selectionText, ' ');
// Ensure normal width characters work fine in a line containing wide characters
selectionService.selectWordAt([12, 0]);
assert.equal(selectionService.selectionText, 'foo');
selectionService.selectWordAt([13, 0]);
assert.equal(selectionService.selectionText, 'foo');
selectionService.selectWordAt([14, 0]);
assert.equal(selectionService.selectionText, 'foo');
});
it('should select up to non-path characters that are commonly adjacent to paths', () => {
buffer.lines.set(0, stringToRow('(cd)[ef]{gh}\'ij"'));
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, '(cd');
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, 'cd');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, 'cd');
selectionService.selectWordAt([3, 0]);
assert.equal(selectionService.selectionText, 'cd)');
selectionService.selectWordAt([4, 0]);
assert.equal(selectionService.selectionText, '[ef');
selectionService.selectWordAt([5, 0]);
assert.equal(selectionService.selectionText, 'ef');
selectionService.selectWordAt([6, 0]);
assert.equal(selectionService.selectionText, 'ef');
selectionService.selectWordAt([7, 0]);
assert.equal(selectionService.selectionText, 'ef]');
selectionService.selectWordAt([8, 0]);
assert.equal(selectionService.selectionText, '{gh');
selectionService.selectWordAt([9, 0]);
assert.equal(selectionService.selectionText, 'gh');
selectionService.selectWordAt([10, 0]);
assert.equal(selectionService.selectionText, 'gh');
selectionService.selectWordAt([11, 0]);
assert.equal(selectionService.selectionText, 'gh}');
selectionService.selectWordAt([12, 0]);
assert.equal(selectionService.selectionText, '\'ij');
selectionService.selectWordAt([13, 0]);
assert.equal(selectionService.selectionText, 'ij');
selectionService.selectWordAt([14, 0]);
assert.equal(selectionService.selectionText, 'ij');
selectionService.selectWordAt([15, 0]);
assert.equal(selectionService.selectionText, 'ij"');
});
it('should expand upwards or downards for wrapped lines', () => {
buffer.lines.set(0, stringToRow(' foo'));
buffer.lines.set(1, stringToRow('bar '));
buffer.lines.get(1)!.isWrapped = true;
selectionService.selectWordAt([1, 1]);
assert.equal(selectionService.selectionText, 'foobar');
selectionService.model.clearSelection();
selectionService.selectWordAt([18, 0]);
assert.equal(selectionService.selectionText, 'foobar');
});
it('should expand both upwards and downwards for word wrapped over many lines', () => {
const expectedText = 'fooaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbbccccccccccccccccccccbar';
buffer.lines.set(0, stringToRow(' foo'));
buffer.lines.set(1, stringToRow('aaaaaaaaaaaaaaaaaaaa'));
buffer.lines.set(2, stringToRow('bbbbbbbbbbbbbbbbbbbb'));
buffer.lines.set(3, stringToRow('cccccccccccccccccccc'));
buffer.lines.set(4, stringToRow('bar '));
buffer.lines.get(1)!.isWrapped = true;
buffer.lines.get(2)!.isWrapped = true;
buffer.lines.get(3)!.isWrapped = true;
buffer.lines.get(4)!.isWrapped = true;
selectionService.selectWordAt([18, 0]);
assert.equal(selectionService.selectionText, expectedText);
selectionService.model.clearSelection();
selectionService.selectWordAt([10, 1]);
assert.equal(selectionService.selectionText, expectedText);
selectionService.model.clearSelection();
selectionService.selectWordAt([10, 2]);
assert.equal(selectionService.selectionText, expectedText);
selectionService.model.clearSelection();
selectionService.selectWordAt([10, 3]);
assert.equal(selectionService.selectionText, expectedText);
selectionService.model.clearSelection();
selectionService.selectWordAt([1, 4]);
assert.equal(selectionService.selectionText, expectedText);
});
describe('emoji', () => {
it('should treat a single emoji as a word when wrapped in spaces', () => {
buffer.lines.set(0, stringToRow(' ⚽ a')); // The a is here to prevent the space being trimmed in selectionText
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, '⚽');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, ' ');
});
it('should treat multiple emojis as a word when wrapped in spaces', () => {
buffer.lines.set(0, stringToRow(' ⚽⚽ a')); // The a is here to prevent the space being trimmed in selectionText
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, '⚽⚽');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, '⚽⚽');
selectionService.selectWordAt([3, 0]);
assert.equal(selectionService.selectionText, ' ');
});
it('should treat emojis using the zero-width-joiner as a single word', () => {
// Note that the first 3 emojis include the invisible ZWJ char
buffer.lines.set(0, stringArrayToRow([
' ', '👨‍', '👩‍', '👧‍', '👦', ' ', 'a'
])); // The a is here to prevent the space being trimmed in selectionText
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, ' ');
// ZWJ emojis do not combine in the terminal so the family emoji used here consumed 4 cells
// The selection text should retain ZWJ chars despite not combining on the terminal
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, '👨‍👩‍👧‍👦');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, '👨‍👩‍👧‍👦');
selectionService.selectWordAt([3, 0]);
assert.equal(selectionService.selectionText, '👨‍👩‍👧‍👦');
selectionService.selectWordAt([4, 0]);
assert.equal(selectionService.selectionText, '👨‍👩‍👧‍👦');
selectionService.selectWordAt([5, 0]);
assert.equal(selectionService.selectionText, ' ');
});
it('should treat emojis and characters joined together as a word', () => {
buffer.lines.set(0, stringToRow(' ⚽ab cd⚽ ef⚽gh')); // The a is here to prevent the space being trimmed in selectionText
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, '⚽ab');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, '⚽ab');
selectionService.selectWordAt([3, 0]);
assert.equal(selectionService.selectionText, '⚽ab');
selectionService.selectWordAt([4, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([5, 0]);
assert.equal(selectionService.selectionText, 'cd⚽');
selectionService.selectWordAt([6, 0]);
assert.equal(selectionService.selectionText, 'cd⚽');
selectionService.selectWordAt([7, 0]);
assert.equal(selectionService.selectionText, 'cd⚽');
selectionService.selectWordAt([8, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([9, 0]);
assert.equal(selectionService.selectionText, 'ef⚽gh');
selectionService.selectWordAt([10, 0]);
assert.equal(selectionService.selectionText, 'ef⚽gh');
selectionService.selectWordAt([11, 0]);
assert.equal(selectionService.selectionText, 'ef⚽gh');
selectionService.selectWordAt([12, 0]);
assert.equal(selectionService.selectionText, 'ef⚽gh');
selectionService.selectWordAt([13, 0]);
assert.equal(selectionService.selectionText, 'ef⚽gh');
});
it('should treat complex emojis and characters joined together as a word', () => {
// This emoji is the flag for England and is made up of: 1F3F4 E0067 E0062 E0065 E006E E0067 E007F
buffer.lines.set(0, stringArrayToRow([
' ', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', 'a', 'b', ' ', 'c', 'd', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', ' ', 'e', 'f', '🏴󠁧󠁢󠁥󠁮󠁧󠁿', 'g', 'h', ' ', 'a'
])); // The a is here to prevent the space being trimmed in selectionText
selectionService.selectWordAt([0, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([1, 0]);
assert.equal(selectionService.selectionText, '🏴󠁧󠁢󠁥󠁮󠁧󠁿ab');
selectionService.selectWordAt([2, 0]);
assert.equal(selectionService.selectionText, '🏴󠁧󠁢󠁥󠁮󠁧󠁿ab');
selectionService.selectWordAt([3, 0]);
assert.equal(selectionService.selectionText, '🏴󠁧󠁢󠁥󠁮󠁧󠁿ab');
selectionService.selectWordAt([4, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([5, 0]);
assert.equal(selectionService.selectionText, 'cd🏴󠁧󠁢󠁥󠁮󠁧󠁿');
selectionService.selectWordAt([6, 0]);
assert.equal(selectionService.selectionText, 'cd🏴󠁧󠁢󠁥󠁮󠁧󠁿');
selectionService.selectWordAt([7, 0]);
assert.equal(selectionService.selectionText, 'cd🏴󠁧󠁢󠁥󠁮󠁧󠁿');
selectionService.selectWordAt([8, 0]);
assert.equal(selectionService.selectionText, ' ');
selectionService.selectWordAt([9, 0]);
assert.equal(selectionService.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh');
selectionService.selectWordAt([10, 0]);
assert.equal(selectionService.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh');
selectionService.selectWordAt([11, 0]);
assert.equal(selectionService.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh');
selectionService.selectWordAt([12, 0]);
assert.equal(selectionService.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh');
selectionService.selectWordAt([13, 0]);
assert.equal(selectionService.selectionText, 'ef🏴󠁧󠁢󠁥󠁮󠁧󠁿gh');
});
});
});
describe('_selectLineAt', () => {
it('should select the entire line', () => {
buffer.lines.set(0, stringToRow('foo bar'));
selectionService.selectLineAt(0);
assert.equal(selectionService.selectionText, 'foo bar', 'The selected text is correct');
assert.deepEqual(selectionService.model.selectionStart, [0, 0]);
assert.deepEqual(selectionService.model.selectionEnd, undefined);
assert.deepEqual(selectionService.model.selectionStartLength, 20);
assert.deepEqual(selectionService.model.finalSelectionStart, [0, 0]);
assert.deepEqual(selectionService.model.finalSelectionEnd, [bufferService.cols, 0], 'The actual selection spans the entire column');
});
it('should select the entire wrapped line', () => {
buffer.lines.set(0, stringToRow('foo'));
const line2 = stringToRow('bar');
line2.isWrapped = true;
buffer.lines.set(1, line2);
selectionService.selectLineAt(0);
assert.equal(selectionService.selectionText, 'foobar', 'The selected text is correct');
assert.deepEqual(selectionService.model.selectionStart, [0, 0]);
assert.deepEqual(selectionService.model.selectionEnd, undefined);
assert.deepEqual(selectionService.model.selectionStartLength, 40);
assert.deepEqual(selectionService.model.finalSelectionStart, [0, 0]);
assert.deepEqual(selectionService.model.finalSelectionEnd, [bufferService.cols, 1], 'The actual selection spans the entire column');
});
});
describe('selectAll', () => {
it('should select the entire buffer, beyond the viewport', () => {
bufferService.resize(20, 5);
buffer.lines.set(0, stringToRow('1'));
buffer.lines.set(1, stringToRow('2'));
buffer.lines.set(2, stringToRow('3'));
buffer.lines.set(3, stringToRow('4'));
buffer.lines.set(4, stringToRow('5'));
selectionService.selectAll();
assert.equal(selectionService.selectionText, '1\n2\n3\n4\n5');
});
});
describe('selectLines', () => {
it('should select a single line', () => {
buffer.lines.length = 3;
buffer.lines.set(0, stringToRow('1'));
buffer.lines.set(1, stringToRow('2'));
buffer.lines.set(2, stringToRow('3'));
selectionService.selectLines(1, 1);
assert.deepEqual(selectionService.model.finalSelectionStart, [0, 1]);
assert.deepEqual(selectionService.model.finalSelectionEnd, [bufferService.cols, 1]);
});
it('should select multiple lines', () => {
buffer.lines.length = 5;
buffer.lines.set(0, stringToRow('1'));
buffer.lines.set(1, stringToRow('2'));
buffer.lines.set(2, stringToRow('3'));
buffer.lines.set(3, stringToRow('4'));
buffer.lines.set(4, stringToRow('5'));
selectionService.selectLines(1, 3);
assert.deepEqual(selectionService.model.finalSelectionStart, [0, 1]);
assert.deepEqual(selectionService.model.finalSelectionEnd, [bufferService.cols, 3]);
});
it('should select the to the start when requesting a negative row', () => {
buffer.lines.length = 2;
buffer.lines.set(0, stringToRow('1'));
buffer.lines.set(1, stringToRow('2'));
selectionService.selectLines(-1, 0);
assert.deepEqual(selectionService.model.finalSelectionStart, [0, 0]);
assert.deepEqual(selectionService.model.finalSelectionEnd, [bufferService.cols, 0]);
});
it('should select the to the end when requesting beyond the final row', () => {
buffer.lines.length = 2;
buffer.lines.set(0, stringToRow('1'));
buffer.lines.set(1, stringToRow('2'));
selectionService.selectLines(1, 2);
assert.deepEqual(selectionService.model.finalSelectionStart, [0, 1]);
assert.deepEqual(selectionService.model.finalSelectionEnd, [bufferService.cols, 1]);
});
});
describe('hasSelection', () => {
it('should return whether there is a selection', () => {
selectionService.model.selectionStart = [0, 0];
selectionService.model.selectionStartLength = 0;
assert.equal(selectionService.hasSelection, false);
selectionService.model.selectionEnd = [0, 0];
assert.equal(selectionService.hasSelection, false);
selectionService.model.selectionEnd = [1, 0];
assert.equal(selectionService.hasSelection, true);
selectionService.model.selectionEnd = [0, 1];
assert.equal(selectionService.hasSelection, true);
selectionService.model.selectionEnd = [1, 1];
assert.equal(selectionService.hasSelection, true);
});
});
describe('column selection', () => {
it('should select a column of text', () => {
buffer.lines.length = 3;
buffer.lines.set(0, stringToRow('abcdefghij'));
buffer.lines.set(1, stringToRow('klmnopqrst'));
buffer.lines.set(2, stringToRow('uvwxyz'));
selectionService.selectionMode = SelectionMode.COLUMN;
selectionService.model.selectionStart = [2, 0];
selectionService.model.selectionEnd = [4, 2];
assert.equal(selectionService.selectionText, 'cd\nmn\nwx');
});
it('should select a column of text without chopping up double width characters', () => {
buffer.lines.length = 3;
buffer.lines.set(0, stringToRow('a'));
buffer.lines.set(1, stringToRow('語'));
buffer.lines.set(2, stringToRow('b'));
selectionService.selectionMode = SelectionMode.COLUMN;
selectionService.model.selectionStart = [0, 0];
selectionService.model.selectionEnd = [1, 2];
assert.equal(selectionService.selectionText, 'a\n語\nb');
});
it('should select a column of text with single character emojis', () => {
buffer.lines.length = 3;
buffer.lines.set(0, stringToRow('a'));
buffer.lines.set(1, stringToRow('☃'));
buffer.lines.set(2, stringToRow('c'));
selectionService.selectionMode = SelectionMode.COLUMN;
selectionService.model.selectionStart = [0, 0];
selectionService.model.selectionEnd = [1, 2];
assert.equal(selectionService.selectionText, 'a\n☃\nc');
});
it('should select a column of text with double character emojis', () => {
// TODO the case this is testing works for me in the demo webapp,
// but doing it programmatically fails.
buffer.lines.length = 3;
buffer.lines.set(0, stringToRow('a '));
buffer.lines.set(1, stringArrayToRow(['😁', ' ']));
buffer.lines.set(2, stringToRow('c '));
selectionService.selectionMode = SelectionMode.COLUMN;
selectionService.model.selectionStart = [0, 0];
selectionService.model.selectionEnd = [1, 2];
assert.equal(selectionService.selectionText, 'a\n😁\nc');
});
});
describe('_areCoordsInSelection', () => {
it('should return whether coords are in the selection', () => {
assert.isFalse(selectionService.areCoordsInSelection([0, 0], [2, 0], [2, 1]));
assert.isFalse(selectionService.areCoordsInSelection([1, 0], [2, 0], [2, 1]));
assert.isTrue(selectionService.areCoordsInSelection([2, 0], [2, 0], [2, 1]));
assert.isTrue(selectionService.areCoordsInSelection([10, 0], [2, 0], [2, 1]));
assert.isTrue(selectionService.areCoordsInSelection([0, 1], [2, 0], [2, 1]));
assert.isTrue(selectionService.areCoordsInSelection([1, 1], [2, 0], [2, 1]));
assert.isFalse(selectionService.areCoordsInSelection([2, 1], [2, 0], [2, 1]));
});
});
describe('shouldForceSelection', () => {
it('should force selection without alt when mouseEventsRequireAlt is enabled', () => {
optionsService.options.mouseEventsRequireAlt = true;
mouseStateService.areMouseEventsActive = true;
assert.isTrue(selectionService.shouldForceSelection({ altKey: false } as MouseEvent));
assert.isFalse(selectionService.shouldForceSelection({ altKey: true } as MouseEvent));
});
it('should take precedence over macOptionClickForcesSelection', () => {
optionsService.options.mouseEventsRequireAlt = true;
optionsService.options.macOptionClickForcesSelection = true;
mouseStateService.areMouseEventsActive = true;
assert.isFalse(selectionService.shouldForceSelection({ altKey: true } as MouseEvent));
});
});
});