diff --git a/src/vs/editor/contrib/indentation/test/browser/indentation.test.ts b/src/vs/editor/contrib/indentation/test/browser/indentation.test.ts index 2bd3cef54b7..154cd68a303 100644 --- a/src/vs/editor/contrib/indentation/test/browser/indentation.test.ts +++ b/src/vs/editor/contrib/indentation/test/browser/indentation.test.ts @@ -6,20 +6,31 @@ import * as assert from 'assert'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ensureNoDisposablesAreLeakedInTestSuite } from 'vs/base/test/common/utils'; +import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; +import { createTextModel } from 'vs/editor/test/common/testTextModel'; +import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; -import { MetadataConsts, StandardTokenType } from 'vs/editor/common/encodedTokenAttributes'; -import { EncodedTokenizationResult, IState, TokenizationRegistry } from 'vs/editor/common/languages'; +import { MetadataConsts } from 'vs/editor/common/encodedTokenAttributes'; +import { EncodedTokenizationResult, IState, ITokenizationSupport, TokenizationRegistry } from 'vs/editor/common/languages'; import { ILanguageService } from 'vs/editor/common/languages/language'; -import { ILanguageConfigurationService } from 'vs/editor/common/languages/languageConfigurationRegistry'; import { NullState } from 'vs/editor/common/languages/nullTokenize'; import { AutoIndentOnPaste, IndentationToSpacesCommand, IndentationToTabsCommand } from 'vs/editor/contrib/indentation/browser/indentation'; import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor'; import { testCommand } from 'vs/editor/test/browser/testCommand'; import { javascriptIndentationRules } from 'vs/editor/test/common/modes/supports/javascriptIndentationRules'; import { javascriptOnEnterRules } from 'vs/editor/test/common/modes/supports/javascriptOnEnterRules'; -import { createModelServices, createTextModel } from 'vs/editor/test/common/testTextModel'; -import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; + +// optional: could move the workbench code to editor folder +// pull the two test files together +// for the failing tests add .skip +// Then start changing the regex +// Then only after change the code + +enum Language { + TypeScript, + Ruby +} function testIndentationToSpacesCommand(lines: string[], selection: Selection, tabSize: number, expectedLines: string[], expectedSelection: Selection): void { testCommand(lines, null, selection, (accessor, sel) => new IndentationToSpacesCommand(sel, tabSize), expectedLines, expectedSelection); @@ -29,354 +40,250 @@ function testIndentationToTabsCommand(lines: string[], selection: Selection, tab testCommand(lines, null, selection, (accessor, sel) => new IndentationToTabsCommand(sel, tabSize), expectedLines, expectedSelection); } -suite('Indentation - TypeScript/Javascript', () => { +function registerLanguage(instantiationService: TestInstantiationService, languageId: string, language: Language, disposables: DisposableStore) { + const languageService = instantiationService.get(ILanguageService); + registerLanguageConfiguration(instantiationService, languageId, language, disposables); + disposables.add(languageService.registerLanguage({ id: languageId })); +} - let languageId: string; - let disposables: DisposableStore; - - setup(() => { - disposables = new DisposableStore(); - languageId = 'ts-test'; - }); - - teardown(() => { - disposables.dispose(); - }); - - ensureNoDisposablesAreLeakedInTestSuite(); - - suite('Change Indentation to Spaces', () => { - - setup(() => { - const instantiationService = createModelServices(disposables); - instantiateContext(instantiationService, true); - }); - - test('single tabs only at start of line', function () { - testIndentationToSpacesCommand( - [ - 'first', - 'second line', - 'third line', - '\tfourth line', - '\tfifth' +function registerLanguageConfiguration(instantiationService: TestInstantiationService, languageId: string, language: Language, disposables: DisposableStore) { + const languageConfigurationService = instantiationService.get(ILanguageConfigurationService); + switch (language) { + case Language.TypeScript: + disposables.add(languageConfigurationService.register(languageId, { + brackets: [ + ['{', '}'], + ['[', ']'], + ['(', ')'] ], - new Selection(2, 3, 2, 3), - 4, - [ - 'first', - 'second line', - 'third line', - ' fourth line', - ' fifth' - ], - new Selection(2, 3, 2, 3) - ); - }); - - test('multiple tabs at start of line', function () { - testIndentationToSpacesCommand( - [ - '\t\tfirst', - '\tsecond line', - '\t\t\t third line', - 'fourth line', - 'fifth' - ], - new Selection(1, 5, 1, 5), - 3, - [ - ' first', - ' second line', - ' third line', - 'fourth line', - 'fifth' - ], - new Selection(1, 9, 1, 9) - ); - }); - - test('multiple tabs', function () { - testIndentationToSpacesCommand( - [ - '\t\tfirst\t', - '\tsecond \t line \t', - '\t\t\t third line', - ' \tfourth line', - 'fifth' - ], - new Selection(1, 5, 1, 5), - 2, - [ - ' first\t', - ' second \t line \t', - ' third line', - ' fourth line', - 'fifth' - ], - new Selection(1, 7, 1, 7) - ); - }); - - test('empty lines', function () { - testIndentationToSpacesCommand( - [ - '\t\t\t', - '\t', - '\t\t' - ], - new Selection(1, 4, 1, 4), - 2, - [ - ' ', - ' ', - ' ' - ], - new Selection(1, 4, 1, 4) - ); - }); - }); - - suite('Change Indentation to Tabs', () => { - - test('spaces only at start of line', function () { - testIndentationToTabsCommand( - [ - ' first', - 'second line', - ' third line', - 'fourth line', - 'fifth' - ], - new Selection(2, 3, 2, 3), - 4, - [ - '\tfirst', - 'second line', - '\tthird line', - 'fourth line', - 'fifth' - ], - new Selection(2, 3, 2, 3) - ); - }); - - test('multiple spaces at start of line', function () { - testIndentationToTabsCommand( - [ - 'first', - ' second line', - ' third line', - 'fourth line', - ' fifth' - ], - new Selection(1, 5, 1, 5), - 3, - [ - 'first', - '\tsecond line', - '\t\t\t third line', - 'fourth line', - '\t fifth' - ], - new Selection(1, 5, 1, 5) - ); - }); - - test('multiple spaces', function () { - testIndentationToTabsCommand( - [ - ' first ', - ' second line \t', - ' third line', - ' fourth line', - 'fifth' - ], - new Selection(1, 8, 1, 8), - 2, - [ - '\t\t\tfirst ', - '\tsecond line \t', - '\t\t\t third line', - '\t fourth line', - 'fifth' - ], - new Selection(1, 5, 1, 5) - ); - }); - - test('issue #45996', function () { - testIndentationToSpacesCommand( - [ - '\tabc', - ], - new Selection(1, 3, 1, 3), - 4, - [ - ' abc', - ], - new Selection(1, 6, 1, 6) - ); - }); - }); - - suite('Auto Indent On Paste', () => { - - test('issue #119225: Do not add extra leading space when pasting JSDoc', () => { - const model = createTextModel("", languageId, {}); - disposables.add(model); - withTestCodeEditor(model, { autoIndent: 'full' }, (editor, viewModel, instantiationService) => { - - instantiateContext(instantiationService); - const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste); - const pasteText = [ - '/**', - ' * JSDoc', - ' */', - 'function a() {}' - ].join('\n'); - - viewModel.paste(pasteText, true, undefined, 'keyboard'); - autoIndentOnPasteController.trigger(new Range(1, 1, 4, 16)); - assert.strictEqual(model.getValue(), pasteText); - }); - }); - }); - - suite('Keep Indent On Paste', () => { - - test('issue #167299: Blank line removes indent', () => { - const model = createTextModel("", languageId, {}); - disposables.add(model); - withTestCodeEditor(model, { autoIndent: 'full' }, (editor, viewModel, instantiationService) => { - - instantiateContext(instantiationService); - const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste); - const pasteText = [ - '', - 'export type IncludeReference =', - ' | BaseReference', - ' | SelfReference', - ' | RelativeReference;', - '', - 'export const enum IncludeReferenceKind {', - ' Base,', - ' Self,', - ' RelativeReference,', - '}' - ].join('\n'); - - viewModel.paste(pasteText, true, undefined, 'keyboard'); - autoIndentOnPasteController.trigger(new Range(1, 1, 11, 2)); - assert.strictEqual(model.getValue(), pasteText); - }); - }); - - // TODO: tokenization is not corerct, hence why the test does not reflect the real behavior - test('issue #181065: Incorrect paste', () => { - const model = createTextModel("", languageId, {}); - disposables.add(model); - withTestCodeEditor(model, { autoIndent: 'full' }, (editor, viewModel, instantiationService) => { - - instantiateContext(instantiationService); - const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste); - const pasteText = [ - '/**', - ' * @typedef {', - ' * }', - ' */', - ].join('\n'); - - viewModel.paste(pasteText, true, undefined, 'keyboard'); - autoIndentOnPasteController.trigger(new Range(1, 1, 4, 4)); - assert.strictEqual(model.getValue(), pasteText); - }); - }); - }); - - // suite('Auto Indent On Type', () => { - // test('issue #193875: incorrect indentation', () => { - // const model = createTextModel([ - // '{', - // ' for(;;)', - // ' for(;;) {}', - // '}' - // ].join('\n'), languageId, {}); - // disposables.add(model); - // withTestCodeEditor(model, { autoIndent: 'full' }, (editor, viewModel, instantiationService) => { - // instantiateContext(instantiationService); - // // viewModel.type([ - // // '{', - // // ' for(;;)', - // // ' for(;;) {}', - // // '}' - // // ].join('\n')); - // viewModel.setSelections('test', [new Selection(3, 11, 3, 11)]); - // viewModel.type("\n", 'keyboard'); - // assert.strictEqual(model.getValue(), [ - // '{', - // ' for(;;)', - // ' for(;;) {', - // '}', - // '}' - // ].join('\n')); - // }); - // }); - // }); - - function instantiateContext(instantiationService: TestInstantiationService, includeTokenization: boolean = false) { - const languageService = instantiationService.get(ILanguageService); - const languageConfigurationService = instantiationService.get(ILanguageConfigurationService); - disposables.add(languageService.registerLanguage({ id: languageId })); - disposables.add(languageConfigurationService.register(languageId, { - brackets: [ - ['{', '}'], - ['[', ']'], - ['(', ')'] - ], - comments: { - lineComment: '//', - blockComment: ['/*', '*/'] - }, - indentationRules: javascriptIndentationRules, - onEnterRules: javascriptOnEnterRules - })); - if (includeTokenization) { - disposables.add(TokenizationRegistry.register(languageId, { - getInitialState: (): IState => NullState, - tokenize: () => { - throw new Error('not implemented'); + comments: { + lineComment: '//', + blockComment: ['/*', '*/'] }, - tokenizeEncoded: (line: string, hasEOL: boolean, state: IState): EncodedTokenizationResult => { - console.log('tokenizeEncoded', line, hasEOL, state); - const tokensArr: number[] = []; - if (line.indexOf('*') !== -1) { - console.log('first'); - tokensArr.push(0); - tokensArr.push(StandardTokenType.Comment << MetadataConsts.TOKEN_TYPE_OFFSET); - } else { - console.log('second'); - tokensArr.push(0); - tokensArr.push(StandardTokenType.Other << MetadataConsts.TOKEN_TYPE_OFFSET); - } - const tokens = new Uint32Array(tokensArr.length); - for (let i = 0; i < tokens.length; i++) { - tokens[i] = tokensArr[i]; - } - return new EncodedTokenizationResult(tokens, state); - } + indentationRules: javascriptIndentationRules, + onEnterRules: javascriptOnEnterRules })); - } + break; + case Language.Ruby: + disposables.add(languageConfigurationService.register(languageId, { + brackets: [ + ['{', '}'], + ['[', ']'], + ['(', ')'] + ], + indentationRules: { + decreaseIndentPattern: /^\s*([}\]]([,)]?\s*(#|$)|\.[a-zA-Z_]\w*\b)|(end|rescue|ensure|else|elsif)\b|(in|when)\s)/, + increaseIndentPattern: /^\s*((begin|class|(private|protected)\s+def|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|in|while|case)|([^#]*\sdo\b)|([^#]*=\s*(case|if|unless)))\b([^#\{;]|(\"|'|\/).*\4)*(#.*)?$/, + }, + })); + break; } +} + +function registerTokens(instantiationService: TestInstantiationService, tokens: { startIndex: number; value: number }[][], languageId: string, disposables: DisposableStore) { + let lineIndex = 0; + const languageService = instantiationService.get(ILanguageService); + const tokenizationSupport: ITokenizationSupport = { + getInitialState: () => NullState, + tokenize: undefined!, + tokenizeEncoded: (line: string, hasEOL: boolean, state: IState): EncodedTokenizationResult => { + const tokensOnLine = tokens[lineIndex++]; + const encodedLanguageId = languageService.languageIdCodec.encodeLanguageId(languageId); + const result = new Uint32Array(2 * tokensOnLine.length); + for (let i = 0; i < tokensOnLine.length; i++) { + result[2 * i] = tokensOnLine[i].startIndex; + result[2 * i + 1] = + ( + (encodedLanguageId << MetadataConsts.LANGUAGEID_OFFSET) + | (tokensOnLine[i].value << MetadataConsts.TOKEN_TYPE_OFFSET) + ); + } + return new EncodedTokenizationResult(result, state); + } + }; + disposables.add(TokenizationRegistry.register(languageId, tokenizationSupport)); +} + +suite('Change Indentation to Spaces - TypeScript/Javascript', () => { + + ensureNoDisposablesAreLeakedInTestSuite(); + + test('single tabs only at start of line', function () { + testIndentationToSpacesCommand( + [ + 'first', + 'second line', + 'third line', + '\tfourth line', + '\tfifth' + ], + new Selection(2, 3, 2, 3), + 4, + [ + 'first', + 'second line', + 'third line', + ' fourth line', + ' fifth' + ], + new Selection(2, 3, 2, 3) + ); + }); + + test('multiple tabs at start of line', function () { + testIndentationToSpacesCommand( + [ + '\t\tfirst', + '\tsecond line', + '\t\t\t third line', + 'fourth line', + 'fifth' + ], + new Selection(1, 5, 1, 5), + 3, + [ + ' first', + ' second line', + ' third line', + 'fourth line', + 'fifth' + ], + new Selection(1, 9, 1, 9) + ); + }); + + test('multiple tabs', function () { + testIndentationToSpacesCommand( + [ + '\t\tfirst\t', + '\tsecond \t line \t', + '\t\t\t third line', + ' \tfourth line', + 'fifth' + ], + new Selection(1, 5, 1, 5), + 2, + [ + ' first\t', + ' second \t line \t', + ' third line', + ' fourth line', + 'fifth' + ], + new Selection(1, 7, 1, 7) + ); + }); + + test('empty lines', function () { + testIndentationToSpacesCommand( + [ + '\t\t\t', + '\t', + '\t\t' + ], + new Selection(1, 4, 1, 4), + 2, + [ + ' ', + ' ', + ' ' + ], + new Selection(1, 4, 1, 4) + ); + }); }); -suite('Indentation - Ruby', () => { +suite('Change Indentation to Tabs - TypeScript/Javascript', () => { - let languageId: string; + ensureNoDisposablesAreLeakedInTestSuite(); + + test('spaces only at start of line', function () { + testIndentationToTabsCommand( + [ + ' first', + 'second line', + ' third line', + 'fourth line', + 'fifth' + ], + new Selection(2, 3, 2, 3), + 4, + [ + '\tfirst', + 'second line', + '\tthird line', + 'fourth line', + 'fifth' + ], + new Selection(2, 3, 2, 3) + ); + }); + + test('multiple spaces at start of line', function () { + testIndentationToTabsCommand( + [ + 'first', + ' second line', + ' third line', + 'fourth line', + ' fifth' + ], + new Selection(1, 5, 1, 5), + 3, + [ + 'first', + '\tsecond line', + '\t\t\t third line', + 'fourth line', + '\t fifth' + ], + new Selection(1, 5, 1, 5) + ); + }); + + test('multiple spaces', function () { + testIndentationToTabsCommand( + [ + ' first ', + ' second line \t', + ' third line', + ' fourth line', + 'fifth' + ], + new Selection(1, 8, 1, 8), + 2, + [ + '\t\t\tfirst ', + '\tsecond line \t', + '\t\t\t third line', + '\t fourth line', + 'fifth' + ], + new Selection(1, 5, 1, 5) + ); + }); + + test('issue #45996', function () { + testIndentationToSpacesCommand( + [ + '\tabc', + ], + new Selection(1, 3, 1, 3), + 4, + [ + ' abc', + ], + new Selection(1, 6, 1, 6) + ); + }); +}); + +suite('Full Auto Indent On Paste - TypeScript/JavaScript', () => { + + const languageId = 'ts-test'; let disposables: DisposableStore; setup(() => { - languageId = 'ruby-test'; disposables = new DisposableStore(); }); @@ -386,45 +293,198 @@ suite('Indentation - Ruby', () => { ensureNoDisposablesAreLeakedInTestSuite(); - suite('Auto Indent On Type', () => { + test('issue #119225: Do not add extra leading space when pasting JSDoc', () => { - test('issue #198350: in or when incorrectly match non keywords for Ruby', () => { - const model = createTextModel("", languageId, {}); - disposables.add(model); + const model = createTextModel("", languageId, {}); + disposables.add(model); - withTestCodeEditor(model, { autoIndent: "full" }, (editor, viewModel, instantiationService) => { - - instantiateContext(instantiationService); - - viewModel.type("def foo\n i"); - viewModel.type("n", 'keyboard'); - assert.strictEqual(model.getValue(), "def foo\n in"); - viewModel.type(" ", 'keyboard'); - assert.strictEqual(model.getValue(), "def foo\nin "); - - viewModel.model.setValue(""); - viewModel.type(" # in"); - assert.strictEqual(model.getValue(), " # in"); - viewModel.type(" ", 'keyboard'); - assert.strictEqual(model.getValue(), " # in "); - }); + withTestCodeEditor(model, { autoIndent: 'full' }, (editor, viewModel, instantiationService) => { + const pasteText = [ + '/**', + ' * JSDoc', + ' */', + 'function a() {}' + ].join('\n'); + const tokens = [ + [ + { startIndex: 0, value: 1 }, + { startIndex: 3, value: 1 }, + ], + [ + { startIndex: 0, value: 1 }, + { startIndex: 2, value: 1 }, + { startIndex: 8, value: 1 }, + ], + [ + { startIndex: 0, value: 1 }, + { startIndex: 1, value: 1 }, + { startIndex: 3, value: 0 }, + ], + [ + { startIndex: 0, value: 0 }, + { startIndex: 8, value: 0 }, + { startIndex: 9, value: 0 }, + { startIndex: 10, value: 0 }, + { startIndex: 11, value: 0 }, + { startIndex: 12, value: 0 }, + { startIndex: 13, value: 0 }, + { startIndex: 14, value: 0 }, + { startIndex: 15, value: 0 }, + ] + ]; + registerLanguage(instantiationService, languageId, Language.TypeScript, disposables); + registerTokens(instantiationService, tokens, languageId, disposables); + const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste); + viewModel.paste(pasteText, true, undefined, 'keyboard'); + autoIndentOnPasteController.trigger(new Range(1, 1, 4, 16)); + assert.strictEqual(model.getValue(), pasteText); }); }); - function instantiateContext(instantiationService: TestInstantiationService) { - const languageService = instantiationService.get(ILanguageService); - const languageConfigurationService = instantiationService.get(ILanguageConfigurationService); - disposables.add(languageService.registerLanguage({ id: languageId })); - disposables.add(languageConfigurationService.register(languageId, { - brackets: [ - ['{', '}'], - ['[', ']'], - ['(', ')'] - ], - indentationRules: { - decreaseIndentPattern: /^\s*([}\]]([,)]?\s*(#|$)|\.[a-zA-Z_]\w*\b)|(end|rescue|ensure|else|elsif)\b|(in|when)\s)/, - increaseIndentPattern: /^\s*((begin|class|(private|protected)\s+def|def|else|elsif|ensure|for|if|module|rescue|unless|until|when|in|while|case)|([^#]*\sdo\b)|([^#]*=\s*(case|if|unless)))\b([^#\{;]|(\"|'|\/).*\4)*(#.*)?$/, - }, - })); - } + test('issue #167299: Blank line removes indent', () => { + + const model = createTextModel("", languageId, {}); + disposables.add(model); + + withTestCodeEditor(model, { autoIndent: 'full' }, (editor, viewModel, instantiationService) => { + const pasteText = [ + '', + 'export type IncludeReference =', + ' | BaseReference', + ' | SelfReference', + ' | RelativeReference;', + '', + 'export const enum IncludeReferenceKind {', + ' Base,', + ' Self,', + ' RelativeReference,', + '}' + ].join('\n'); + // no need for tokenization because there are no comments + + registerLanguage(instantiationService, languageId, Language.TypeScript, disposables); + const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste); + viewModel.paste(pasteText, true, undefined, 'keyboard'); + autoIndentOnPasteController.trigger(new Range(1, 1, 11, 2)); + assert.strictEqual(model.getValue(), pasteText); + }); + }); + + test('issue #181065: Incorrect paste of object within comment', () => { + + const model = createTextModel("", languageId, {}); + disposables.add(model); + + withTestCodeEditor(model, { autoIndent: 'full' }, (editor, viewModel, instantiationService) => { + const text = [ + '/**', + ' * @typedef {', + ' * }', + ' */' + ].join('\n'); + const tokens = [ + [ + { startIndex: 0, value: 1 }, + { startIndex: 3, value: 1 }, + ], + [ + { startIndex: 0, value: 1 }, + { startIndex: 2, value: 1 }, + { startIndex: 3, value: 1 }, + { startIndex: 11, value: 1 }, + { startIndex: 12, value: 0 }, + { startIndex: 13, value: 0 }, + ], + [ + { startIndex: 0, value: 1 }, + { startIndex: 2, value: 0 }, + { startIndex: 3, value: 0 }, + { startIndex: 4, value: 0 }, + ], + [ + { startIndex: 0, value: 1 }, + { startIndex: 1, value: 1 }, + { startIndex: 3, value: 0 }, + ] + ]; + registerLanguage(instantiationService, languageId, Language.TypeScript, disposables); + registerTokens(instantiationService, tokens, languageId, disposables); + const autoIndentOnPasteController = editor.registerAndInstantiateContribution(AutoIndentOnPaste.ID, AutoIndentOnPaste); + viewModel.paste(text, true, undefined, 'keyboard'); + autoIndentOnPasteController.trigger(new Range(1, 1, 4, 4)); + assert.strictEqual(model.getValue(), text); + }); + }); +}); + +// suite('Auto Indent On Type - TypeScript/JavaScript', () => { +// test('issue #193875: incorrect indentation', () => { +// const model = createTextModel([ +// '{', +// ' for(;;)', +// ' for(;;) {}', +// '}' +// ].join('\n'), languageId, {}); +// disposables.add(model); +// withTestCodeEditor(model, { autoIndent: 'full' }, (editor, viewModel, instantiationService) => { +// instantiateContext(instantiationService); +// // viewModel.type([ +// // '{', +// // ' for(;;)', +// // ' for(;;) {}', +// // '}' +// // ].join('\n')); +// viewModel.setSelections('test', [new Selection(3, 11, 3, 11)]); +// viewModel.type("\n", 'keyboard'); +// assert.strictEqual(model.getValue(), [ +// '{', +// ' for(;;)', +// ' for(;;) {', +// '}', +// '}' +// ].join('\n')); +// }); +// }); +// }); + +suite('Auto Dedent On Type - Ruby', () => { + + const languageId = "ruby-test"; + let disposables: DisposableStore; + + setup(() => { + disposables = new DisposableStore(); + }); + + teardown(() => { + disposables.dispose(); + }); + + ensureNoDisposablesAreLeakedInTestSuite(); + + test('issue #198350: in or when incorrectly match non keywords for Ruby', () => { + + const model = createTextModel("", languageId, {}); + disposables.add(model); + + withTestCodeEditor(model, { autoIndent: "full" }, (editor, viewModel, instantiationService) => { + + registerLanguage(instantiationService, languageId, Language.Ruby, disposables); + + // TODO@aiday-mar: requires registering the tokens ? + + viewModel.model.setValue(""); + viewModel.type("def foo\n i"); + viewModel.type("n", 'keyboard'); + assert.strictEqual(model.getValue(), "def foo\n in"); + viewModel.type(" ", 'keyboard'); + assert.strictEqual(model.getValue(), "def foo\nin "); + + viewModel.model.setValue(""); + viewModel.type(" # in"); + assert.strictEqual(model.getValue(), " # in"); + viewModel.type(" ", 'keyboard'); + assert.strictEqual(model.getValue(), " # in "); + }); + }); });