mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-08 01:28:26 -05:00
Merge from vscode a348d103d1256a06a2c9b3f9b406298a9fef6898 (#15681)
* Merge from vscode a348d103d1256a06a2c9b3f9b406298a9fef6898 * Fixes and cleanup * Distro * Fix hygiene yarn * delete no yarn lock changes file * Fix hygiene * Fix layer check * Fix CI * Skip lib checks * Remove tests deleted in vs code * Fix tests * Distro * Fix tests and add removed extension point * Skip failing notebook tests for now * Disable broken tests and cleanup build folder * Update yarn.lock and fix smoke tests * Bump sqlite * fix contributed actions and file spacing * Fix user data path * Update yarn.locks Co-authored-by: ADS Merger <karlb@microsoft.com>
This commit is contained in:
@@ -1047,6 +1047,21 @@ suite('Editor Controller - Cursor', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('issue #118062: Column selection cannot select first position of a line', () => {
|
||||
withTestCodeEditor([
|
||||
'hello world',
|
||||
].join('\n'), {}, (editor, viewModel) => {
|
||||
|
||||
moveTo(editor, viewModel, 1, 2, false);
|
||||
assertCursor(viewModel, new Position(1, 2));
|
||||
|
||||
CoreNavigationCommands.CursorColumnSelectLeft.runCoreEditorCommand(viewModel, {});
|
||||
assertCursor(viewModel, [
|
||||
new Selection(1, 2, 1, 1)
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
test('column select with keyboard', () => {
|
||||
withTestCodeEditor([
|
||||
'var gulp = require("gulp");',
|
||||
@@ -2079,16 +2094,16 @@ suite('Editor Controller - Regression tests', () => {
|
||||
|
||||
// Typing sennsei in Japanese - Hiragana
|
||||
viewModel.type('s', 'keyboard');
|
||||
viewModel.replacePreviousChar('せ', 1);
|
||||
viewModel.replacePreviousChar('せn', 1);
|
||||
viewModel.replacePreviousChar('せん', 2);
|
||||
viewModel.replacePreviousChar('せんs', 2);
|
||||
viewModel.replacePreviousChar('せんせ', 3);
|
||||
viewModel.replacePreviousChar('せんせ', 3);
|
||||
viewModel.replacePreviousChar('せんせい', 3);
|
||||
viewModel.replacePreviousChar('せんせい', 4);
|
||||
viewModel.replacePreviousChar('せんせい', 4);
|
||||
viewModel.replacePreviousChar('せんせい', 4);
|
||||
viewModel.compositionType('せ', 1, 0, 0);
|
||||
viewModel.compositionType('せn', 1, 0, 0);
|
||||
viewModel.compositionType('せん', 2, 0, 0);
|
||||
viewModel.compositionType('せんs', 2, 0, 0);
|
||||
viewModel.compositionType('せんせ', 3, 0, 0);
|
||||
viewModel.compositionType('せんせ', 3, 0, 0);
|
||||
viewModel.compositionType('せんせい', 3, 0, 0);
|
||||
viewModel.compositionType('せんせい', 4, 0, 0);
|
||||
viewModel.compositionType('せんせい', 4, 0, 0);
|
||||
viewModel.compositionType('せんせい', 4, 0, 0);
|
||||
|
||||
assert.strictEqual(model.getLineContent(1), 'せんせい');
|
||||
assertCursor(viewModel, new Position(1, 5));
|
||||
@@ -5311,6 +5326,41 @@ suite('autoClosingPairs', () => {
|
||||
mode.dispose();
|
||||
});
|
||||
|
||||
test('issue #118270 - auto closing deletes only those characters that it inserted', () => {
|
||||
let mode = new AutoClosingMode();
|
||||
usingCursor({
|
||||
text: [
|
||||
'',
|
||||
'y=();'
|
||||
],
|
||||
languageIdentifier: mode.getLanguageIdentifier()
|
||||
}, (editor, model, viewModel) => {
|
||||
assertCursor(viewModel, new Position(1, 1));
|
||||
|
||||
viewModel.type('x=(', 'keyboard');
|
||||
assert.strictEqual(model.getLineContent(1), 'x=()');
|
||||
|
||||
viewModel.type('asd', 'keyboard');
|
||||
assert.strictEqual(model.getLineContent(1), 'x=(asd)');
|
||||
|
||||
CoreEditingCommands.DeleteLeft.runEditorCommand(null, editor, null);
|
||||
CoreEditingCommands.DeleteLeft.runEditorCommand(null, editor, null);
|
||||
CoreEditingCommands.DeleteLeft.runEditorCommand(null, editor, null);
|
||||
assert.strictEqual(model.getLineContent(1), 'x=()');
|
||||
|
||||
// delete closing char!
|
||||
CoreEditingCommands.DeleteLeft.runEditorCommand(null, editor, null);
|
||||
assert.strictEqual(model.getLineContent(1), 'x=');
|
||||
|
||||
// do not delete closing char!
|
||||
viewModel.setSelections('test', [new Selection(2, 4, 2, 4)]);
|
||||
CoreEditingCommands.DeleteLeft.runEditorCommand(null, editor, null);
|
||||
assert.strictEqual(model.getLineContent(2), 'y=);');
|
||||
|
||||
});
|
||||
mode.dispose();
|
||||
});
|
||||
|
||||
test('issue #78527 - does not close quote on odd count', () => {
|
||||
let mode = new AutoClosingMode();
|
||||
usingCursor({
|
||||
@@ -5449,7 +5499,7 @@ suite('autoClosingPairs', () => {
|
||||
// Typing ` + e on the mac US intl kb layout
|
||||
viewModel.startComposition();
|
||||
viewModel.type('`', 'keyboard');
|
||||
viewModel.replacePreviousChar('è', 1, 'keyboard');
|
||||
viewModel.compositionType('è', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
|
||||
assert.strictEqual(model.getValue(), 'è');
|
||||
@@ -5470,8 +5520,8 @@ suite('autoClosingPairs', () => {
|
||||
// Typing ` + e on the mac US intl kb layout
|
||||
viewModel.startComposition();
|
||||
viewModel.type('\'', 'keyboard');
|
||||
viewModel.replacePreviousChar('\'', 1, 'keyboard');
|
||||
viewModel.replacePreviousChar('\'', 1, 'keyboard');
|
||||
viewModel.compositionType('\'', 1, 0, 0, 'keyboard');
|
||||
viewModel.compositionType('\'', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
|
||||
assert.strictEqual(model.getValue(), '\'test\'');
|
||||
@@ -5550,8 +5600,8 @@ suite('autoClosingPairs', () => {
|
||||
viewModel.startComposition();
|
||||
viewModel.type('`', 'keyboard');
|
||||
moveDown(editor, viewModel, true);
|
||||
viewModel.replacePreviousChar('`', 1, 'keyboard');
|
||||
viewModel.replacePreviousChar('`', 1, 'keyboard');
|
||||
viewModel.compositionType('`', 1, 0, 0, 'keyboard');
|
||||
viewModel.compositionType('`', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
|
||||
assert.strictEqual(model.getValue(), '`hello\nworld');
|
||||
@@ -5575,14 +5625,14 @@ suite('autoClosingPairs', () => {
|
||||
// Typing ' + space
|
||||
viewModel.startComposition();
|
||||
viewModel.type('\'', 'keyboard');
|
||||
viewModel.replacePreviousChar('\'', 1, 'keyboard');
|
||||
viewModel.compositionType('\'', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
assert.strictEqual(model.getValue(), '\'\'');
|
||||
|
||||
// Typing one more ' + space
|
||||
viewModel.startComposition();
|
||||
viewModel.type('\'', 'keyboard');
|
||||
viewModel.replacePreviousChar('\'', 1, 'keyboard');
|
||||
viewModel.compositionType('\'', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
assert.strictEqual(model.getValue(), '\'\'');
|
||||
|
||||
@@ -5591,7 +5641,7 @@ suite('autoClosingPairs', () => {
|
||||
viewModel.setSelections('test', [new Selection(1, 5, 1, 5)]);
|
||||
viewModel.startComposition();
|
||||
viewModel.type('\'', 'keyboard');
|
||||
viewModel.replacePreviousChar('\'', 1, 'keyboard');
|
||||
viewModel.compositionType('\'', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
|
||||
assert.strictEqual(model.getValue(), '\'abc\'');
|
||||
@@ -5601,7 +5651,7 @@ suite('autoClosingPairs', () => {
|
||||
viewModel.setSelections('test', [new Selection(1, 10, 1, 10)]);
|
||||
viewModel.startComposition();
|
||||
viewModel.type('\'', 'keyboard');
|
||||
viewModel.replacePreviousChar('\'', 1, 'keyboard');
|
||||
viewModel.compositionType('\'', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
|
||||
assert.strictEqual(model.getValue(), '\'abc\'def \'\'');
|
||||
@@ -5611,7 +5661,7 @@ suite('autoClosingPairs', () => {
|
||||
viewModel.setSelections('test', [new Selection(1, 1, 1, 1)]);
|
||||
viewModel.startComposition();
|
||||
viewModel.type('\'', 'keyboard');
|
||||
viewModel.replacePreviousChar('\'', 1, 'keyboard');
|
||||
viewModel.compositionType('\'', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
|
||||
// No auto closing if it's after a word.
|
||||
@@ -5619,7 +5669,7 @@ suite('autoClosingPairs', () => {
|
||||
viewModel.setSelections('test', [new Selection(1, 4, 1, 4)]);
|
||||
viewModel.startComposition();
|
||||
viewModel.type('\'', 'keyboard');
|
||||
viewModel.replacePreviousChar('\'', 1, 'keyboard');
|
||||
viewModel.compositionType('\'', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
|
||||
assert.strictEqual(model.getValue(), 'abc\'');
|
||||
@@ -5640,7 +5690,7 @@ suite('autoClosingPairs', () => {
|
||||
// Typing a + backspace
|
||||
viewModel.startComposition();
|
||||
viewModel.type('a', 'keyboard');
|
||||
viewModel.replacePreviousChar('', 1, 'keyboard');
|
||||
viewModel.compositionType('', 1, 0, 0, 'keyboard');
|
||||
viewModel.endComposition('keyboard');
|
||||
assert.strictEqual(model.getValue(), '{}');
|
||||
});
|
||||
|
||||
@@ -151,9 +151,9 @@ function doCreateTest(description: string, inputStr: string, expectedStr: string
|
||||
};
|
||||
|
||||
handler.onType((e) => {
|
||||
console.log('type text: ' + e.text + ', replaceCharCnt: ' + e.replaceCharCnt);
|
||||
console.log('type text: ' + e.text + ', replaceCharCnt: ' + e.replacePrevCharCnt);
|
||||
let text = model.getModelLineContent(1);
|
||||
let preText = text.substring(0, cursorOffset - e.replaceCharCnt);
|
||||
let preText = text.substring(0, cursorOffset - e.replacePrevCharCnt);
|
||||
let postText = text.substring(cursorOffset + cursorLength);
|
||||
let midText = e.text;
|
||||
|
||||
|
||||
@@ -134,8 +134,12 @@ suite('TextAreaState', () => {
|
||||
let newState = TextAreaState.readFromTextArea(textArea);
|
||||
let actual = TextAreaState.deduceInput(prevState, newState, couldBeEmojiInput);
|
||||
|
||||
assert.strictEqual(actual.text, expected);
|
||||
assert.strictEqual(actual.replaceCharCnt, expectedCharReplaceCnt);
|
||||
assert.deepStrictEqual(actual, {
|
||||
text: expected,
|
||||
replacePrevCharCnt: expectedCharReplaceCnt,
|
||||
replaceNextCharCnt: 0,
|
||||
positionDelta: 0,
|
||||
});
|
||||
|
||||
textArea.dispose();
|
||||
}
|
||||
@@ -503,6 +507,82 @@ suite('TextAreaState', () => {
|
||||
);
|
||||
});
|
||||
|
||||
function testDeduceAndroidCompositionInput(
|
||||
prevState: TextAreaState | null,
|
||||
value: string, selectionStart: number, selectionEnd: number,
|
||||
expected: string, expectedReplacePrevCharCnt: number, expectedReplaceNextCharCnt: number, expectedPositionDelta: number): void {
|
||||
prevState = prevState || TextAreaState.EMPTY;
|
||||
|
||||
let textArea = new MockTextAreaWrapper();
|
||||
textArea._value = value;
|
||||
textArea._selectionStart = selectionStart;
|
||||
textArea._selectionEnd = selectionEnd;
|
||||
|
||||
let newState = TextAreaState.readFromTextArea(textArea);
|
||||
let actual = TextAreaState.deduceAndroidCompositionInput(prevState, newState);
|
||||
|
||||
assert.deepStrictEqual(actual, {
|
||||
text: expected,
|
||||
replacePrevCharCnt: expectedReplacePrevCharCnt,
|
||||
replaceNextCharCnt: expectedReplaceNextCharCnt,
|
||||
positionDelta: expectedPositionDelta,
|
||||
});
|
||||
|
||||
textArea.dispose();
|
||||
}
|
||||
|
||||
test('Android composition input 1', () => {
|
||||
testDeduceAndroidCompositionInput(
|
||||
new TextAreaState(
|
||||
'Microsoft',
|
||||
4, 4,
|
||||
null, null
|
||||
),
|
||||
'Microsoft',
|
||||
4, 4,
|
||||
'', 0, 0, 0,
|
||||
);
|
||||
});
|
||||
|
||||
test('Android composition input 2', () => {
|
||||
testDeduceAndroidCompositionInput(
|
||||
new TextAreaState(
|
||||
'Microsoft',
|
||||
4, 4,
|
||||
null, null
|
||||
),
|
||||
'Microsoft',
|
||||
0, 9,
|
||||
'', 0, 0, 5,
|
||||
);
|
||||
});
|
||||
|
||||
test('Android composition input 3', () => {
|
||||
testDeduceAndroidCompositionInput(
|
||||
new TextAreaState(
|
||||
'Microsoft',
|
||||
0, 9,
|
||||
null, null
|
||||
),
|
||||
'Microsoft\'s',
|
||||
11, 11,
|
||||
'\'s', 0, 0, 0,
|
||||
);
|
||||
});
|
||||
|
||||
test('Android backspace', () => {
|
||||
testDeduceAndroidCompositionInput(
|
||||
new TextAreaState(
|
||||
'undefinedVariable',
|
||||
2, 2,
|
||||
null, null
|
||||
),
|
||||
'udefinedVariable',
|
||||
1, 1,
|
||||
'', 1, 0, 0,
|
||||
);
|
||||
});
|
||||
|
||||
suite('PagedScreenReaderStrategy', () => {
|
||||
|
||||
function testPagedScreenReaderStrategy(lines: string[], selection: Selection, expected: TextAreaState): void {
|
||||
|
||||
@@ -32,11 +32,11 @@ class TestGlobalStyleSheet extends GlobalStyleSheet {
|
||||
super(null!);
|
||||
}
|
||||
|
||||
public insertRule(rule: string, index?: number): void {
|
||||
public override insertRule(rule: string, index?: number): void {
|
||||
this.rules.unshift(rule);
|
||||
}
|
||||
|
||||
public removeRulesContainingSelector(ruleName: string): void {
|
||||
public override removeRulesContainingSelector(ruleName: string): void {
|
||||
for (let i = 0; i < this.rules.length; i++) {
|
||||
if (this.rules[i].indexOf(ruleName) >= 0) {
|
||||
this.rules.splice(i, 1);
|
||||
@@ -52,18 +52,18 @@ class TestGlobalStyleSheet extends GlobalStyleSheet {
|
||||
|
||||
suite.skip('Decoration Render Options', () => { // {{SQL CARBON EDIT}} skip suite
|
||||
let options: IDecorationRenderOptions = {
|
||||
gutterIconPath: URI.parse('https://github.com/microsoft/vscode/blob/master/resources/linux/code.png'),
|
||||
gutterIconPath: URI.parse('https://github.com/microsoft/vscode/blob/main/resources/linux/code.png'),
|
||||
gutterIconSize: 'contain',
|
||||
backgroundColor: 'red',
|
||||
borderColor: 'yellow'
|
||||
};
|
||||
test('register and resolve decoration type', () => {
|
||||
let s = new TestCodeEditorServiceImpl(themeServiceMock);
|
||||
let s = new TestCodeEditorServiceImpl(null, themeServiceMock);
|
||||
s.registerDecorationType('example', options);
|
||||
assert.notStrictEqual(s.resolveDecorationOptions('example', false), undefined);
|
||||
});
|
||||
test('remove decoration type', () => {
|
||||
let s = new TestCodeEditorServiceImpl(themeServiceMock);
|
||||
let s = new TestCodeEditorServiceImpl(null, themeServiceMock);
|
||||
s.registerDecorationType('example', options);
|
||||
assert.notStrictEqual(s.resolveDecorationOptions('example', false), undefined);
|
||||
s.removeDecorationType('example');
|
||||
@@ -76,10 +76,10 @@ suite.skip('Decoration Render Options', () => { // {{SQL CARBON EDIT}} skip suit
|
||||
|
||||
test('css properties', () => {
|
||||
const styleSheet = new TestGlobalStyleSheet();
|
||||
const s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
const s = new TestCodeEditorServiceImpl(styleSheet, themeServiceMock);
|
||||
s.registerDecorationType('example', options);
|
||||
const sheet = readStyleSheet(styleSheet);
|
||||
assert(sheet.indexOf(`{background:url('https://github.com/microsoft/vscode/blob/master/resources/linux/code.png') center center no-repeat;background-size:contain;}`) >= 0);
|
||||
assert(sheet.indexOf(`{background:url('https://github.com/microsoft/vscode/blob/main/resources/linux/code.png') center center no-repeat;background-size:contain;}`) >= 0);
|
||||
assert(sheet.indexOf(`{background-color:red;border-color:yellow;box-sizing: border-box;}`) >= 0);
|
||||
});
|
||||
|
||||
@@ -93,7 +93,7 @@ suite.skip('Decoration Render Options', () => { // {{SQL CARBON EDIT}} skip suit
|
||||
const themeService = new TestThemeService(new TestColorTheme({
|
||||
editorBackground: '#FF0000'
|
||||
}));
|
||||
const s = new TestCodeEditorServiceImpl(themeService, styleSheet);
|
||||
const s = new TestCodeEditorServiceImpl(styleSheet, themeService);
|
||||
s.registerDecorationType('example', options);
|
||||
assert.strictEqual(readStyleSheet(styleSheet), '.monaco-editor .ced-example-0 {background-color:#ff0000;border-color:transparent;box-sizing: border-box;}');
|
||||
|
||||
@@ -126,7 +126,7 @@ suite.skip('Decoration Render Options', () => { // {{SQL CARBON EDIT}} skip suit
|
||||
editorBackground: '#FF0000',
|
||||
infoForeground: '#444444'
|
||||
}));
|
||||
const s = new TestCodeEditorServiceImpl(themeService, styleSheet);
|
||||
const s = new TestCodeEditorServiceImpl(styleSheet, themeService);
|
||||
s.registerDecorationType('example', options);
|
||||
const expected = [
|
||||
'.vs-dark.monaco-editor .ced-example-4::after, .hc-black.monaco-editor .ced-example-4::after {color:#444444 !important;}',
|
||||
@@ -142,7 +142,7 @@ suite.skip('Decoration Render Options', () => { // {{SQL CARBON EDIT}} skip suit
|
||||
|
||||
test('css properties, gutterIconPaths', () => {
|
||||
const styleSheet = new TestGlobalStyleSheet();
|
||||
const s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
const s = new TestCodeEditorServiceImpl(styleSheet, themeServiceMock);
|
||||
|
||||
// URI, only minimal encoding
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.parse('data:image/svg+xml;base64,PHN2ZyB4b+') });
|
||||
|
||||
@@ -32,47 +32,47 @@ suite('OpenerService', function () {
|
||||
test('delegate to editorService, scheme:///fff', async function () {
|
||||
const openerService = new OpenerService(editorService, NullCommandService);
|
||||
await openerService.open(URI.parse('another:///somepath'));
|
||||
assert.equal(editorService.lastInput!.options!.selection, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection, undefined);
|
||||
});
|
||||
|
||||
test('delegate to editorService, scheme:///fff#L123', async function () {
|
||||
const openerService = new OpenerService(editorService, NullCommandService);
|
||||
|
||||
await openerService.open(URI.parse('file:///somepath#L23'));
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.resource.fragment, '');
|
||||
|
||||
await openerService.open(URI.parse('another:///somepath#L23'));
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
|
||||
await openerService.open(URI.parse('another:///somepath#L23,45'));
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 45);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startColumn, 45);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.resource.fragment, '');
|
||||
});
|
||||
|
||||
test('delegate to editorService, scheme:///fff#123,123', async function () {
|
||||
const openerService = new OpenerService(editorService, NullCommandService);
|
||||
|
||||
await openerService.open(URI.parse('file:///somepath#23'));
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.resource.fragment, '');
|
||||
|
||||
await openerService.open(URI.parse('file:///somepath#23,45'));
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 45);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.startColumn, 45);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.strictEqual(editorService.lastInput!.resource.fragment, '');
|
||||
});
|
||||
|
||||
test('delegate to commandsService, command:someid', async function () {
|
||||
@@ -83,10 +83,37 @@ suite('OpenerService', function () {
|
||||
|
||||
assert.strictEqual(lastCommand, undefined);
|
||||
await openerService.open(URI.parse('command:' + id));
|
||||
|
||||
assert.strictEqual(lastCommand, undefined);
|
||||
});
|
||||
|
||||
|
||||
test('delegate to commandsService, command:someid', async function () {
|
||||
const openerService = new OpenerService(editorService, commandService);
|
||||
|
||||
const id = `aCommand${Math.random()}`;
|
||||
CommandsRegistry.registerCommand(id, function () { });
|
||||
|
||||
await openerService.open(URI.parse('command:' + id).with({ query: '\"123\"' }), { allowCommands: true });
|
||||
assert.strictEqual(lastCommand!.id, id);
|
||||
assert.strictEqual(lastCommand!.args.length, 1);
|
||||
assert.strictEqual(lastCommand!.args[0], '123');
|
||||
|
||||
await openerService.open(URI.parse('command:' + id), { allowCommands: true });
|
||||
assert.strictEqual(lastCommand!.id, id);
|
||||
assert.strictEqual(lastCommand!.args.length, 0);
|
||||
|
||||
await openerService.open(URI.parse('command:' + id).with({ query: '123' }), { allowCommands: true });
|
||||
assert.strictEqual(lastCommand!.id, id);
|
||||
assert.strictEqual(lastCommand!.args.length, 1);
|
||||
assert.strictEqual(lastCommand!.args[0], 123);
|
||||
|
||||
await openerService.open(URI.parse('command:' + id).with({ query: JSON.stringify([12, true]) }), { allowCommands: true });
|
||||
assert.strictEqual(lastCommand!.id, id);
|
||||
assert.strictEqual(lastCommand!.args.length, 2);
|
||||
assert.strictEqual(lastCommand!.args[0], 12);
|
||||
assert.strictEqual(lastCommand!.args[1], true);
|
||||
});
|
||||
|
||||
test('links are protected by validators', async function () {
|
||||
const openerService = new OpenerService(editorService, commandService);
|
||||
|
||||
@@ -94,8 +121,8 @@ suite('OpenerService', function () {
|
||||
|
||||
const httpResult = await openerService.open(URI.parse('https://www.microsoft.com'));
|
||||
const httpsResult = await openerService.open(URI.parse('https://www.microsoft.com'));
|
||||
assert.equal(httpResult, false);
|
||||
assert.equal(httpsResult, false);
|
||||
assert.strictEqual(httpResult, false);
|
||||
assert.strictEqual(httpsResult, false);
|
||||
});
|
||||
|
||||
test('delegate to commandsService, command:someid', async function () {
|
||||
@@ -139,9 +166,23 @@ suite('OpenerService', function () {
|
||||
});
|
||||
|
||||
await openerService.open(URI.parse('http://microsoft.com'));
|
||||
assert.equal(openCount, 1);
|
||||
assert.strictEqual(openCount, 1);
|
||||
await openerService.open(URI.parse('https://microsoft.com'));
|
||||
assert.equal(openCount, 2);
|
||||
assert.strictEqual(openCount, 2);
|
||||
});
|
||||
|
||||
test('links aren\'t manipulated before being passed to validator: PR #118226', async function () {
|
||||
const openerService = new OpenerService(editorService, commandService);
|
||||
|
||||
openerService.registerValidator({
|
||||
shouldOpen: (resource) => {
|
||||
// We don't want it to convert strings into URIs
|
||||
assert.strictEqual(resource instanceof URI, false);
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
});
|
||||
await openerService.open('https://wwww.microsoft.com');
|
||||
await openerService.open('https://www.microsoft.com??params=CountryCode%3DUSA%26Name%3Dvscode"');
|
||||
});
|
||||
|
||||
test('links validated by multiple validators', async function () {
|
||||
@@ -172,13 +213,13 @@ suite('OpenerService', function () {
|
||||
});
|
||||
|
||||
await openerService.open(URI.parse('http://microsoft.com'));
|
||||
assert.equal(openCount, 1);
|
||||
assert.equal(v1, 1);
|
||||
assert.equal(v2, 1);
|
||||
assert.strictEqual(openCount, 1);
|
||||
assert.strictEqual(v1, 1);
|
||||
assert.strictEqual(v2, 1);
|
||||
await openerService.open(URI.parse('https://microsoft.com'));
|
||||
assert.equal(openCount, 2);
|
||||
assert.equal(v1, 2);
|
||||
assert.equal(v2, 2);
|
||||
assert.strictEqual(openCount, 2);
|
||||
assert.strictEqual(v1, 2);
|
||||
assert.strictEqual(v2, 2);
|
||||
});
|
||||
|
||||
test('links invalidated by first validator do not continue validating', async function () {
|
||||
@@ -209,13 +250,13 @@ suite('OpenerService', function () {
|
||||
});
|
||||
|
||||
await openerService.open(URI.parse('http://microsoft.com'));
|
||||
assert.equal(openCount, 0);
|
||||
assert.equal(v1, 1);
|
||||
assert.equal(v2, 0);
|
||||
assert.strictEqual(openCount, 0);
|
||||
assert.strictEqual(v1, 1);
|
||||
assert.strictEqual(v2, 0);
|
||||
await openerService.open(URI.parse('https://microsoft.com'));
|
||||
assert.equal(openCount, 0);
|
||||
assert.equal(v1, 2);
|
||||
assert.equal(v2, 0);
|
||||
assert.strictEqual(openCount, 0);
|
||||
assert.strictEqual(v1, 2);
|
||||
assert.strictEqual(v2, 0);
|
||||
});
|
||||
|
||||
test('matchesScheme', function () {
|
||||
|
||||
@@ -23,6 +23,8 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
||||
import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKeybindingService';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { TestNotificationService } from 'vs/platform/notification/test/common/testNotificationService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
||||
|
||||
@@ -34,13 +36,20 @@ export interface ITestCodeEditor extends IActiveCodeEditor {
|
||||
export class TestCodeEditor extends CodeEditorWidget implements ICodeEditor {
|
||||
|
||||
//#region testing overrides
|
||||
protected _createConfiguration(options: Readonly<IEditorConstructionOptions>): IConfiguration {
|
||||
protected override _createConfiguration(options: Readonly<IEditorConstructionOptions>): IConfiguration {
|
||||
return new TestConfiguration(options);
|
||||
}
|
||||
protected _createView(viewModel: ViewModel): [View, boolean] {
|
||||
protected override _createView(viewModel: ViewModel): [View, boolean] {
|
||||
// Never create a view
|
||||
return [null! as View, false];
|
||||
}
|
||||
private _hasTextFocus = false;
|
||||
public setHasTextFocus(hasTextFocus: boolean): void {
|
||||
this._hasTextFocus = hasTextFocus;
|
||||
}
|
||||
public override hasTextFocus(): boolean {
|
||||
return this._hasTextFocus;
|
||||
}
|
||||
//#endregion
|
||||
|
||||
//#region Testing utils
|
||||
@@ -55,7 +64,7 @@ export class TestCodeEditor extends CodeEditorWidget implements ICodeEditor {
|
||||
}
|
||||
|
||||
class TestCodeEditorWithAutoModelDisposal extends TestCodeEditor {
|
||||
public dispose() {
|
||||
public override dispose() {
|
||||
super.dispose();
|
||||
if (this._modelData) {
|
||||
this._modelData.model.dispose();
|
||||
@@ -79,6 +88,11 @@ export interface TestCodeEditorCreationOptions extends editorOptions.IEditorOpti
|
||||
*/
|
||||
model?: ITextModel;
|
||||
serviceCollection?: ServiceCollection;
|
||||
/**
|
||||
* If the editor has text focus.
|
||||
* Defaults to true.
|
||||
*/
|
||||
hasTextFocus?: boolean;
|
||||
}
|
||||
|
||||
export function withTestCodeEditor(text: string | string[] | null, options: TestCodeEditorCreationOptions, callback: (editor: ITestCodeEditor, viewModel: ViewModel) => void): void {
|
||||
@@ -99,7 +113,7 @@ export function withTestCodeEditor(text: string | string[] | null, options: Test
|
||||
editor.dispose();
|
||||
}
|
||||
|
||||
export async function withAsyncTestCodeEditor(text: string | string[] | null, options: TestCodeEditorCreationOptions, callback: (editor: ITestCodeEditor, viewModel: ViewModel) => Promise<void>): Promise<void> {
|
||||
export async function withAsyncTestCodeEditor(text: string | string[] | null, options: TestCodeEditorCreationOptions, callback: (editor: ITestCodeEditor, viewModel: ViewModel, instantiationService: IInstantiationService) => Promise<void>): Promise<void> {
|
||||
// create a model if necessary and remember it in order to dispose it.
|
||||
if (!options.model) {
|
||||
if (typeof text === 'string') {
|
||||
@@ -109,15 +123,20 @@ export async function withAsyncTestCodeEditor(text: string | string[] | null, op
|
||||
}
|
||||
}
|
||||
|
||||
const editor = createTestCodeEditor(options);
|
||||
const [instantiationService, editor] = doCreateTestCodeEditor(options);
|
||||
const viewModel = editor.getViewModel()!;
|
||||
viewModel.setHasFocus(true);
|
||||
await callback(<ITestCodeEditor>editor, editor.getViewModel()!);
|
||||
await callback(<ITestCodeEditor>editor, editor.getViewModel()!, instantiationService);
|
||||
|
||||
editor.dispose();
|
||||
}
|
||||
|
||||
export function createTestCodeEditor(options: TestCodeEditorCreationOptions): ITestCodeEditor {
|
||||
const [, editor] = doCreateTestCodeEditor(options);
|
||||
return editor;
|
||||
}
|
||||
|
||||
function doCreateTestCodeEditor(options: TestCodeEditorCreationOptions): [IInstantiationService, ITestCodeEditor] {
|
||||
|
||||
const model = options.model;
|
||||
delete options.model;
|
||||
@@ -142,6 +161,9 @@ export function createTestCodeEditor(options: TestCodeEditorCreationOptions): IT
|
||||
if (!services.has(IThemeService)) {
|
||||
services.set(IThemeService, new TestThemeService());
|
||||
}
|
||||
if (!services.has(ITelemetryService)) {
|
||||
services.set(ITelemetryService, NullTelemetryService);
|
||||
}
|
||||
|
||||
const codeEditorWidgetOptions: ICodeEditorWidgetOptions = {
|
||||
contributions: []
|
||||
@@ -152,6 +174,10 @@ export function createTestCodeEditor(options: TestCodeEditorCreationOptions): IT
|
||||
options,
|
||||
codeEditorWidgetOptions
|
||||
);
|
||||
if (typeof options.hasTextFocus === 'undefined') {
|
||||
options.hasTextFocus = true;
|
||||
}
|
||||
editor.setHasTextFocus(options.hasTextFocus);
|
||||
editor.setModel(model);
|
||||
return <ITestCodeEditor>editor;
|
||||
return [instantiationService, <ITestCodeEditor>editor];
|
||||
}
|
||||
|
||||
@@ -35,10 +35,10 @@ export function testCommand(
|
||||
|
||||
cursor.executeCommand(commandFactory(cursor.getSelection()), 'tests');
|
||||
|
||||
assert.deepEqual(model.getLinesContent(), expectedLines);
|
||||
assert.deepStrictEqual(model.getLinesContent(), expectedLines);
|
||||
|
||||
let actualSelection = cursor.getSelection();
|
||||
assert.deepEqual(actualSelection.toString(), expectedSelection.toString());
|
||||
assert.deepStrictEqual(actualSelection.toString(), expectedSelection.toString());
|
||||
|
||||
});
|
||||
model.dispose();
|
||||
|
||||
@@ -53,7 +53,7 @@ suite('Common Editor Config', () => {
|
||||
});
|
||||
|
||||
class TestWrappingConfiguration extends TestConfiguration {
|
||||
protected _getEnvConfiguration(): IEnvConfiguration {
|
||||
protected override _getEnvConfiguration(): IEnvConfiguration {
|
||||
return {
|
||||
extraEditorClassName: '',
|
||||
outerWidth: 1000,
|
||||
|
||||
36
src/vs/editor/test/common/core/stringBuilder.test.ts
Normal file
36
src/vs/editor/test/common/core/stringBuilder.test.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { writeUInt16LE } from 'vs/base/common/buffer';
|
||||
import { decodeUTF16LE } from 'vs/editor/common/core/stringBuilder';
|
||||
|
||||
suite('decodeUTF16LE', () => {
|
||||
|
||||
test('issue #118041: unicode character undo bug 1', () => {
|
||||
const buff = new Uint8Array(2);
|
||||
writeUInt16LE(buff, ''.charCodeAt(0), 0);
|
||||
const actual = decodeUTF16LE(buff, 0, 1);
|
||||
assert.deepStrictEqual(actual, '');
|
||||
});
|
||||
|
||||
test('issue #118041: unicode character undo bug 2', () => {
|
||||
const buff = new Uint8Array(4);
|
||||
writeUInt16LE(buff, 'a'.charCodeAt(0), 0);
|
||||
writeUInt16LE(buff, 'a'.charCodeAt(1), 2);
|
||||
const actual = decodeUTF16LE(buff, 0, 2);
|
||||
assert.deepStrictEqual(actual, 'a');
|
||||
});
|
||||
|
||||
test('issue #118041: unicode character undo bug 3', () => {
|
||||
const buff = new Uint8Array(6);
|
||||
writeUInt16LE(buff, 'ab'.charCodeAt(0), 0);
|
||||
writeUInt16LE(buff, 'ab'.charCodeAt(1), 2);
|
||||
writeUInt16LE(buff, 'ab'.charCodeAt(2), 4);
|
||||
const actual = decodeUTF16LE(buff, 0, 3);
|
||||
assert.deepStrictEqual(actual, 'ab');
|
||||
});
|
||||
|
||||
});
|
||||
@@ -886,4 +886,34 @@ suite('Editor Diff - DiffComputer', () => {
|
||||
];
|
||||
assertDiff(original, modified, expected, false, false, false);
|
||||
});
|
||||
|
||||
test('issue #119051: gives preference to fewer diff hunks', () => {
|
||||
const original = [
|
||||
'1',
|
||||
'',
|
||||
'',
|
||||
'2',
|
||||
'',
|
||||
];
|
||||
const modified = [
|
||||
'1',
|
||||
'',
|
||||
'1.5',
|
||||
'',
|
||||
'',
|
||||
'2',
|
||||
'',
|
||||
'3',
|
||||
'',
|
||||
];
|
||||
const expected = [
|
||||
createLineChange(
|
||||
2, 0, 3, 4
|
||||
),
|
||||
createLineChange(
|
||||
5, 0, 8, 9
|
||||
)
|
||||
];
|
||||
assertDiff(original, modified, expected, false, false, false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -28,5 +28,4 @@ export class MockMode extends Disposable implements IMode {
|
||||
export class StaticLanguageSelector implements ILanguageSelection {
|
||||
readonly onDidChange: Event<LanguageIdentifier> = Event.None;
|
||||
constructor(public readonly languageIdentifier: LanguageIdentifier) { }
|
||||
public dispose(): void { }
|
||||
}
|
||||
|
||||
31
src/vs/editor/test/common/model/editStack.test.ts
Normal file
31
src/vs/editor/test/common/model/editStack.test.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { EndOfLineSequence } from 'vs/editor/common/model';
|
||||
import { SingleModelEditStackData } from 'vs/editor/common/model/editStack';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { TextChange } from 'vs/editor/common/model/textChange';
|
||||
|
||||
suite('EditStack', () => {
|
||||
|
||||
test('issue #118041: unicode character undo bug', () => {
|
||||
const stackData = new SingleModelEditStackData(
|
||||
1,
|
||||
2,
|
||||
EndOfLineSequence.LF,
|
||||
EndOfLineSequence.LF,
|
||||
[new Selection(10, 2, 10, 2)],
|
||||
[new Selection(10, 1, 10, 1)],
|
||||
[new TextChange(428, '', 428, '')]
|
||||
);
|
||||
|
||||
const buff = stackData.serialize();
|
||||
const actual = SingleModelEditStackData.deserialize(buff);
|
||||
|
||||
assert.deepStrictEqual(actual, stackData);
|
||||
});
|
||||
|
||||
});
|
||||
@@ -20,7 +20,7 @@ export function testApplyEditsWithSyncedModels(original: string[], edits: IIdent
|
||||
let inverseEdits = model.applyEdits(edits, true);
|
||||
|
||||
// Assert edits produced expected result
|
||||
assert.deepEqual(model.getValue(EndOfLinePreference.LF), expectedStr);
|
||||
assert.deepStrictEqual(model.getValue(EndOfLinePreference.LF), expectedStr);
|
||||
|
||||
assertMirrorModels();
|
||||
|
||||
@@ -28,7 +28,7 @@ export function testApplyEditsWithSyncedModels(original: string[], edits: IIdent
|
||||
let inverseInverseEdits = model.applyEdits(inverseEdits, true);
|
||||
|
||||
// Assert the inverse edits brought back model to original state
|
||||
assert.deepEqual(model.getValue(EndOfLinePreference.LF), originalStr);
|
||||
assert.deepStrictEqual(model.getValue(EndOfLinePreference.LF), originalStr);
|
||||
|
||||
if (!inputEditsAreInvalid) {
|
||||
const simplifyEdit = (edit: IIdentifiedSingleEditOperation) => {
|
||||
@@ -41,7 +41,7 @@ export function testApplyEditsWithSyncedModels(original: string[], edits: IIdent
|
||||
};
|
||||
};
|
||||
// Assert the inverse of the inverse edits are the original edits
|
||||
assert.deepEqual(inverseInverseEdits.map(simplifyEdit), edits.map(simplifyEdit));
|
||||
assert.deepStrictEqual(inverseInverseEdits.map(simplifyEdit), edits.map(simplifyEdit));
|
||||
}
|
||||
|
||||
assertMirrorModels();
|
||||
@@ -59,16 +59,16 @@ function assertOneDirectionLineMapping(model: TextModel, direction: AssertDocume
|
||||
let line = 1, column = 1, previousIsCarriageReturn = false;
|
||||
for (let offset = 0; offset <= allText.length; offset++) {
|
||||
// The position coordinate system cannot express the position between \r and \n
|
||||
let position = new Position(line, column + (previousIsCarriageReturn ? -1 : 0));
|
||||
let position: Position = new Position(line, column + (previousIsCarriageReturn ? -1 : 0));
|
||||
|
||||
if (direction === AssertDocumentLineMappingDirection.OffsetToPosition) {
|
||||
let actualPosition = model.getPositionAt(offset);
|
||||
assert.equal(actualPosition.toString(), position.toString(), msg + ' - getPositionAt mismatch for offset ' + offset);
|
||||
assert.strictEqual(actualPosition.toString(), position.toString(), msg + ' - getPositionAt mismatch for offset ' + offset);
|
||||
} else {
|
||||
// The position coordinate system cannot express the position between \r and \n
|
||||
let expectedOffset = offset + (previousIsCarriageReturn ? -1 : 0);
|
||||
let expectedOffset: number = offset + (previousIsCarriageReturn ? -1 : 0);
|
||||
let actualOffset = model.getOffsetAt(position);
|
||||
assert.equal(actualOffset, expectedOffset, msg + ' - getOffsetAt mismatch for position ' + position.toString());
|
||||
assert.strictEqual(actualOffset, expectedOffset, msg + ' - getOffsetAt mismatch for position ' + position.toString());
|
||||
}
|
||||
|
||||
if (allText.charAt(offset) === '\n') {
|
||||
@@ -112,8 +112,8 @@ export function assertSyncedModels(text: string, callback: (model: TextModel, as
|
||||
|
||||
let assertMirrorModels = () => {
|
||||
assertLineMapping(model, 'model');
|
||||
assert.equal(mirrorModel2.getText(), model.getValue(), 'mirror model 2 text OK');
|
||||
assert.equal(mirrorModel2.version, model.getVersionId(), 'mirror model 2 version OK');
|
||||
assert.strictEqual(mirrorModel2.getText(), model.getValue(), 'mirror model 2 text OK');
|
||||
assert.strictEqual(mirrorModel2.version, model.getVersionId(), 'mirror model 2 version OK');
|
||||
};
|
||||
|
||||
callback(model, assertMirrorModels);
|
||||
|
||||
@@ -119,6 +119,19 @@ suite('TextChangeCompressor', () => {
|
||||
);
|
||||
});
|
||||
|
||||
// test('issue #118041', () => {
|
||||
// assertCompression(
|
||||
// '',
|
||||
// [
|
||||
// { offset: 0, length: 1, text: '' },
|
||||
// ],
|
||||
// [
|
||||
// { offset: 1, length: 0, text: 'Z' },
|
||||
// { offset: 3, length: 3, text: 'Y' },
|
||||
// ]
|
||||
// );
|
||||
// })
|
||||
|
||||
test('gen1', () => {
|
||||
assertCompression(
|
||||
'kxm',
|
||||
@@ -267,3 +280,16 @@ suite('TextChangeCompressor', () => {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
suite('TextChange', () => {
|
||||
|
||||
test('issue #118041: unicode character undo bug', () => {
|
||||
const textChange = new TextChange(428, '', 428, '');
|
||||
const buff = new Uint8Array(textChange.writeSize());
|
||||
textChange.write(buff, 0);
|
||||
const actual: TextChange[] = [];
|
||||
TextChange.read(buff, 0, actual);
|
||||
assert.deepStrictEqual(actual[0], textChange);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1062,4 +1062,11 @@ suite('TextModel.createSnapshot', () => {
|
||||
model.dispose();
|
||||
});
|
||||
|
||||
test('issue #119632: invalid range', () => {
|
||||
const model = createTextModel('hello world!');
|
||||
const actual = model._validateRangeRelaxedNoAllocations(new Range(<any>undefined, 0, <any>undefined, 1));
|
||||
assert.deepStrictEqual(actual, new Range(1, 1, 1, 1));
|
||||
model.dispose();
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { TokenizationResult2 } from 'vs/editor/common/core/token';
|
||||
@@ -337,6 +337,97 @@ suite('TextModelWithTokens', () => {
|
||||
registration.dispose();
|
||||
});
|
||||
|
||||
test('issue #95843: Highlighting of closing braces is indicating wrong brace when cursor is behind opening brace', () => {
|
||||
const mode1 = new LanguageIdentifier('testMode1', 3);
|
||||
const mode2 = new LanguageIdentifier('testMode2', 4);
|
||||
const otherMetadata1 = (
|
||||
(mode1.id << MetadataConsts.LANGUAGEID_OFFSET)
|
||||
| (StandardTokenType.Other << MetadataConsts.TOKEN_TYPE_OFFSET)
|
||||
) >>> 0;
|
||||
const otherMetadata2 = (
|
||||
(mode2.id << MetadataConsts.LANGUAGEID_OFFSET)
|
||||
| (StandardTokenType.Other << MetadataConsts.TOKEN_TYPE_OFFSET)
|
||||
) >>> 0;
|
||||
|
||||
const tokenizationSupport: ITokenizationSupport = {
|
||||
getInitialState: () => NULL_STATE,
|
||||
tokenize: undefined!,
|
||||
tokenize2: (line, hasEOL, state) => {
|
||||
switch (line) {
|
||||
case 'function f() {': {
|
||||
const tokens = new Uint32Array([
|
||||
0, otherMetadata1,
|
||||
8, otherMetadata1,
|
||||
9, otherMetadata1,
|
||||
10, otherMetadata1,
|
||||
11, otherMetadata1,
|
||||
12, otherMetadata1,
|
||||
13, otherMetadata1,
|
||||
]);
|
||||
return new TokenizationResult2(tokens, state);
|
||||
}
|
||||
case ' return <p>{true}</p>;': {
|
||||
const tokens = new Uint32Array([
|
||||
0, otherMetadata1,
|
||||
2, otherMetadata1,
|
||||
8, otherMetadata1,
|
||||
9, otherMetadata2,
|
||||
10, otherMetadata2,
|
||||
11, otherMetadata2,
|
||||
12, otherMetadata2,
|
||||
13, otherMetadata1,
|
||||
17, otherMetadata2,
|
||||
18, otherMetadata2,
|
||||
20, otherMetadata2,
|
||||
21, otherMetadata2,
|
||||
22, otherMetadata2,
|
||||
]);
|
||||
return new TokenizationResult2(tokens, state);
|
||||
}
|
||||
case '}': {
|
||||
const tokens = new Uint32Array([
|
||||
0, otherMetadata1
|
||||
]);
|
||||
return new TokenizationResult2(tokens, state);
|
||||
}
|
||||
}
|
||||
throw new Error(`Unexpected`);
|
||||
}
|
||||
};
|
||||
|
||||
const disposableStore = new DisposableStore();
|
||||
|
||||
disposableStore.add(TokenizationRegistry.register(mode1.language, tokenizationSupport));
|
||||
disposableStore.add(LanguageConfigurationRegistry.register(mode1, {
|
||||
brackets: [
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')']
|
||||
],
|
||||
}));
|
||||
disposableStore.add(LanguageConfigurationRegistry.register(mode2, {
|
||||
brackets: [
|
||||
['{', '}'],
|
||||
['[', ']'],
|
||||
['(', ')']
|
||||
],
|
||||
}));
|
||||
|
||||
const model = disposableStore.add(createTextModel([
|
||||
'function f() {',
|
||||
' return <p>{true}</p>;',
|
||||
'}',
|
||||
].join('\n'), undefined, mode1));
|
||||
|
||||
model.forceTokenization(1);
|
||||
model.forceTokenization(2);
|
||||
model.forceTokenization(3);
|
||||
|
||||
assert.deepStrictEqual(model.matchBracket(new Position(2, 14)), [new Range(2, 13, 2, 14), new Range(2, 18, 2, 19)]);
|
||||
|
||||
disposableStore.dispose();
|
||||
});
|
||||
|
||||
test('issue #88075: TypeScript brace matching is incorrect in `${}` strings', () => {
|
||||
const mode = new LanguageIdentifier('testMode', 3);
|
||||
const otherMetadata = (
|
||||
|
||||
@@ -8,13 +8,13 @@ import { MultilineTokens2, SparseEncodedTokens, TokensStore2 } from 'vs/editor/c
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model';
|
||||
import { MetadataConsts, TokenMetadata, FontStyle } from 'vs/editor/common/modes';
|
||||
import { MetadataConsts, TokenMetadata, FontStyle, ColorId } from 'vs/editor/common/modes';
|
||||
import { createTextModel } from 'vs/editor/test/common/editorTestUtils';
|
||||
import { LineTokens } from 'vs/editor/common/core/lineTokens';
|
||||
|
||||
suite('TokensStore', () => {
|
||||
|
||||
const SEMANTIC_COLOR = 5;
|
||||
const SEMANTIC_COLOR: ColorId = 5;
|
||||
|
||||
function parseTokensState(state: string[]): { text: string; tokens: MultilineTokens2; } {
|
||||
let text: string[] = [];
|
||||
|
||||
@@ -243,60 +243,60 @@ suite('Token theme resolving', () => {
|
||||
});
|
||||
|
||||
test('defaults are inherited', () => {
|
||||
let actual = TokenTheme.createFromParsedTokenTheme([
|
||||
const actual = TokenTheme.createFromParsedTokenTheme([
|
||||
new ParsedTokenThemeRule('', -1, FontStyle.NotSet, 'F8F8F2', '272822'),
|
||||
new ParsedTokenThemeRule('var', -1, FontStyle.NotSet, 'ff0000', null)
|
||||
], []);
|
||||
let colorMap = new ColorMap();
|
||||
const colorMap = new ColorMap();
|
||||
const _A = colorMap.getId('F8F8F2');
|
||||
const _B = colorMap.getId('272822');
|
||||
const _C = colorMap.getId('ff0000');
|
||||
assert.deepStrictEqual(actual.getColorMap(), colorMap.getColorMap());
|
||||
let root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
const root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
'var': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _C, _B))
|
||||
});
|
||||
assert.deepEqual(actual.getThemeTrieElement(), root);
|
||||
assert.deepStrictEqual(actual.getThemeTrieElement(), root);
|
||||
});
|
||||
|
||||
test('same rules get merged', () => {
|
||||
let actual = TokenTheme.createFromParsedTokenTheme([
|
||||
const actual = TokenTheme.createFromParsedTokenTheme([
|
||||
new ParsedTokenThemeRule('', -1, FontStyle.NotSet, 'F8F8F2', '272822'),
|
||||
new ParsedTokenThemeRule('var', 1, FontStyle.Bold, null, null),
|
||||
new ParsedTokenThemeRule('var', 0, FontStyle.NotSet, 'ff0000', null),
|
||||
], []);
|
||||
let colorMap = new ColorMap();
|
||||
const colorMap = new ColorMap();
|
||||
const _A = colorMap.getId('F8F8F2');
|
||||
const _B = colorMap.getId('272822');
|
||||
const _C = colorMap.getId('ff0000');
|
||||
assert.deepStrictEqual(actual.getColorMap(), colorMap.getColorMap());
|
||||
let root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
const root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
'var': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _C, _B))
|
||||
});
|
||||
assert.deepEqual(actual.getThemeTrieElement(), root);
|
||||
assert.deepStrictEqual(actual.getThemeTrieElement(), root);
|
||||
});
|
||||
|
||||
test('rules are inherited 1', () => {
|
||||
let actual = TokenTheme.createFromParsedTokenTheme([
|
||||
const actual = TokenTheme.createFromParsedTokenTheme([
|
||||
new ParsedTokenThemeRule('', -1, FontStyle.NotSet, 'F8F8F2', '272822'),
|
||||
new ParsedTokenThemeRule('var', -1, FontStyle.Bold, 'ff0000', null),
|
||||
new ParsedTokenThemeRule('var.identifier', -1, FontStyle.NotSet, '00ff00', null),
|
||||
], []);
|
||||
let colorMap = new ColorMap();
|
||||
const colorMap = new ColorMap();
|
||||
const _A = colorMap.getId('F8F8F2');
|
||||
const _B = colorMap.getId('272822');
|
||||
const _C = colorMap.getId('ff0000');
|
||||
const _D = colorMap.getId('00ff00');
|
||||
assert.deepStrictEqual(actual.getColorMap(), colorMap.getColorMap());
|
||||
let root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
const root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
'var': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _C, _B), {
|
||||
'identifier': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _D, _B))
|
||||
})
|
||||
});
|
||||
assert.deepEqual(actual.getThemeTrieElement(), root);
|
||||
assert.deepStrictEqual(actual.getThemeTrieElement(), root);
|
||||
});
|
||||
|
||||
test('rules are inherited 2', () => {
|
||||
let actual = TokenTheme.createFromParsedTokenTheme([
|
||||
const actual = TokenTheme.createFromParsedTokenTheme([
|
||||
new ParsedTokenThemeRule('', -1, FontStyle.NotSet, 'F8F8F2', '272822'),
|
||||
new ParsedTokenThemeRule('var', -1, FontStyle.Bold, 'ff0000', null),
|
||||
new ParsedTokenThemeRule('var.identifier', -1, FontStyle.NotSet, '00ff00', null),
|
||||
@@ -306,7 +306,7 @@ suite('Token theme resolving', () => {
|
||||
new ParsedTokenThemeRule('constant.numeric.oct', 7, FontStyle.Bold | FontStyle.Italic | FontStyle.Underline, null, null),
|
||||
new ParsedTokenThemeRule('constant.numeric.dec', 8, FontStyle.None, '300000', null),
|
||||
], []);
|
||||
let colorMap = new ColorMap();
|
||||
const colorMap = new ColorMap();
|
||||
const _A = colorMap.getId('F8F8F2');
|
||||
const _B = colorMap.getId('272822');
|
||||
const _C = colorMap.getId('100000');
|
||||
@@ -315,7 +315,7 @@ suite('Token theme resolving', () => {
|
||||
const _F = colorMap.getId('ff0000');
|
||||
const _G = colorMap.getId('00ff00');
|
||||
assert.deepStrictEqual(actual.getColorMap(), colorMap.getColorMap());
|
||||
let root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
const root = new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.None, _A, _B), {
|
||||
'var': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _F, _B), {
|
||||
'identifier': new ExternalThemeTrieElement(new ThemeTrieElementRule(FontStyle.Bold, _G, _B))
|
||||
}),
|
||||
@@ -327,7 +327,7 @@ suite('Token theme resolving', () => {
|
||||
})
|
||||
})
|
||||
});
|
||||
assert.deepEqual(actual.getThemeTrieElement(), root);
|
||||
assert.deepStrictEqual(actual.getThemeTrieElement(), root);
|
||||
});
|
||||
|
||||
test('custom colors are first in color map', () => {
|
||||
|
||||
@@ -18,10 +18,10 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
let configurationValue: IConfigurationValue<any> = {};
|
||||
let updateArgs: any[];
|
||||
let configurationService = new class extends TestConfigurationService {
|
||||
inspect() {
|
||||
override inspect() {
|
||||
return configurationValue;
|
||||
}
|
||||
updateValue() {
|
||||
override updateValue() {
|
||||
updateArgs = [...arguments];
|
||||
return Promise.resolve();
|
||||
}
|
||||
@@ -40,13 +40,13 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
test('updateValue writes without target and overrides when no language is defined', async () => {
|
||||
const resource = URI.file('someFile');
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_LOCAL]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_LOCAL]);
|
||||
});
|
||||
|
||||
test('updateValue writes with target and without overrides when no language is defined', async () => {
|
||||
const resource = URI.file('someFile');
|
||||
await testObject.updateValue(resource, 'a', 'b', ConfigurationTarget.USER_LOCAL);
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_LOCAL]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_LOCAL]);
|
||||
});
|
||||
|
||||
test('updateValue writes into given memory target without overrides', async () => {
|
||||
@@ -59,7 +59,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b', ConfigurationTarget.MEMORY);
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.MEMORY]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.MEMORY]);
|
||||
});
|
||||
|
||||
test('updateValue writes into given workspace target without overrides', async () => {
|
||||
@@ -72,7 +72,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b', ConfigurationTarget.WORKSPACE);
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.WORKSPACE]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.WORKSPACE]);
|
||||
});
|
||||
|
||||
test('updateValue writes into given user target without overrides', async () => {
|
||||
@@ -85,7 +85,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b', ConfigurationTarget.USER);
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER]);
|
||||
});
|
||||
|
||||
test('updateValue writes into given workspace folder target with overrides', async () => {
|
||||
@@ -98,7 +98,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b', ConfigurationTarget.WORKSPACE_FOLDER);
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.WORKSPACE_FOLDER]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.WORKSPACE_FOLDER]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived workspace folder target without overrides', async () => {
|
||||
@@ -111,7 +111,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.WORKSPACE_FOLDER]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.WORKSPACE_FOLDER]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived workspace folder target with overrides', async () => {
|
||||
@@ -125,7 +125,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.WORKSPACE_FOLDER]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.WORKSPACE_FOLDER]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived workspace target without overrides', async () => {
|
||||
@@ -138,7 +138,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.WORKSPACE]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.WORKSPACE]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived workspace target with overrides', async () => {
|
||||
@@ -151,7 +151,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.WORKSPACE]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.WORKSPACE]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived workspace target with overrides and value defined in folder', async () => {
|
||||
@@ -165,7 +165,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.WORKSPACE]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.WORKSPACE]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user remote target without overrides', async () => {
|
||||
@@ -178,7 +178,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_REMOTE]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_REMOTE]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user remote target with overrides', async () => {
|
||||
@@ -191,7 +191,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_REMOTE]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_REMOTE]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user remote target with overrides and value defined in workspace', async () => {
|
||||
@@ -205,7 +205,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_REMOTE]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_REMOTE]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user remote target with overrides and value defined in workspace folder', async () => {
|
||||
@@ -220,7 +220,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_REMOTE]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_REMOTE]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user target without overrides', async () => {
|
||||
@@ -232,7 +232,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_LOCAL]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_LOCAL]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user target with overrides', async () => {
|
||||
@@ -244,7 +244,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', '2');
|
||||
assert.deepEqual(updateArgs, ['a', '2', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_LOCAL]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', '2', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_LOCAL]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user target with overrides and value is defined in remote', async () => {
|
||||
@@ -257,7 +257,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', '2');
|
||||
assert.deepEqual(updateArgs, ['a', '2', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_LOCAL]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', '2', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_LOCAL]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user target with overrides and value is defined in workspace', async () => {
|
||||
@@ -270,7 +270,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', '2');
|
||||
assert.deepEqual(updateArgs, ['a', '2', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_LOCAL]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', '2', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_LOCAL]);
|
||||
});
|
||||
|
||||
test('updateValue writes into derived user target with overrides and value is defined in workspace folder', async () => {
|
||||
@@ -284,7 +284,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', '2');
|
||||
assert.deepEqual(updateArgs, ['a', '2', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_LOCAL]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', '2', { resource, overrideIdentifier: language }, ConfigurationTarget.USER_LOCAL]);
|
||||
});
|
||||
|
||||
test('updateValue when not changed', async () => {
|
||||
@@ -295,7 +295,7 @@ suite('TextResourceConfigurationService - Update', () => {
|
||||
const resource = URI.file('someFile');
|
||||
|
||||
await testObject.updateValue(resource, 'a', 'b');
|
||||
assert.deepEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_LOCAL]);
|
||||
assert.deepStrictEqual(updateArgs, ['a', 'b', { resource }, ConfigurationTarget.USER_LOCAL]);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
@@ -1643,8 +1643,8 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
0,
|
||||
createViewLineTokens([createPart(0, 3)]),
|
||||
[
|
||||
new LineDecoration(1, 2, 'before', InlineDecorationType.Before),
|
||||
new LineDecoration(0, 1, 'after', InlineDecorationType.After),
|
||||
new LineDecoration(1, 1, 'before', InlineDecorationType.Before),
|
||||
new LineDecoration(1, 1, 'after', InlineDecorationType.After),
|
||||
],
|
||||
2,
|
||||
0,
|
||||
@@ -1668,6 +1668,47 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
assert.deepStrictEqual(actual.html, expected);
|
||||
});
|
||||
|
||||
test('issue #118759: enable multiple text editor decorations in empty lines', () => {
|
||||
|
||||
let actual = renderViewLine(new RenderLineInput(
|
||||
true,
|
||||
true,
|
||||
'',
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
createViewLineTokens([createPart(0, 3)]),
|
||||
[
|
||||
new LineDecoration(1, 1, 'after1', InlineDecorationType.After),
|
||||
new LineDecoration(1, 1, 'after2', InlineDecorationType.After),
|
||||
new LineDecoration(1, 1, 'before1', InlineDecorationType.Before),
|
||||
new LineDecoration(1, 1, 'before2', InlineDecorationType.Before),
|
||||
],
|
||||
2,
|
||||
0,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10000,
|
||||
'none',
|
||||
false,
|
||||
false,
|
||||
null
|
||||
));
|
||||
|
||||
let expected = [
|
||||
'<span>',
|
||||
'<span class="before1"></span>',
|
||||
'<span class="before2"></span>',
|
||||
'<span class="after1"></span>',
|
||||
'<span class="after2"></span>',
|
||||
'</span>'
|
||||
].join('');
|
||||
|
||||
assert.deepStrictEqual(actual.html, expected);
|
||||
});
|
||||
|
||||
test('issue #38935: GitLens end-of-line blame no longer rendering', () => {
|
||||
|
||||
let actual = renderViewLine(new RenderLineInput(
|
||||
@@ -2065,6 +2106,38 @@ suite('viewLineRenderer.renderLine 2', () => {
|
||||
assert.deepStrictEqual(actual.html, expected);
|
||||
});
|
||||
|
||||
test('issue #119416: Delete Control Character (U+007F / ) displayed as space', () => {
|
||||
const actual = renderViewLine(new RenderLineInput(
|
||||
false,
|
||||
false,
|
||||
'[' + String.fromCharCode(127) + '] [' + String.fromCharCode(0) + ']',
|
||||
false,
|
||||
true,
|
||||
false,
|
||||
0,
|
||||
createViewLineTokens([createPart(7, 3)]),
|
||||
[],
|
||||
4,
|
||||
0,
|
||||
10,
|
||||
10,
|
||||
10,
|
||||
10000,
|
||||
'none',
|
||||
true,
|
||||
true,
|
||||
null
|
||||
));
|
||||
|
||||
const expected = [
|
||||
'<span>',
|
||||
'<span class="mtk3">[\u2421]\u00a0[\u2400]</span>',
|
||||
'</span>'
|
||||
].join('');
|
||||
|
||||
assert.deepStrictEqual(actual.html, expected);
|
||||
});
|
||||
|
||||
|
||||
function createTestGetColumnOfLinePartOffset(lineContent: string, tabSize: number, parts: ViewLineToken[], expectedPartLengths: number[]): (partIndex: number, partLength: number, offset: number, expected: number) => void {
|
||||
let renderLineOutput = renderViewLine(new RenderLineInput(
|
||||
|
||||
@@ -66,7 +66,7 @@ suite('ViewModel', () => {
|
||||
|
||||
viewLineCount.push(viewModel.getLineCount());
|
||||
viewModel.addViewEventHandler(new class extends ViewEventHandler {
|
||||
handleEvents(events: ViewEvent[]): void {
|
||||
override handleEvents(events: ViewEvent[]): void {
|
||||
// Access the view model
|
||||
viewLineCount.push(viewModel.getLineCount());
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as assert from 'assert';
|
||||
import { StandardTokenType } from 'vs/editor/common/modes';
|
||||
import * as fs from 'fs';
|
||||
// import { getPathFromAmdModule } from 'vs/base/common/amd';
|
||||
// import { getPathFromAmdModule } from 'vs/base/test/node/testUtils';
|
||||
// import { parse } from 'vs/editor/common/modes/tokenization/typescript';
|
||||
import { toStandardTokenType } from 'vs/editor/common/modes/supports/tokenization';
|
||||
|
||||
|
||||
Reference in New Issue
Block a user