diff --git a/src/vs/editor/test/common/controller/cursor.test.ts b/src/vs/editor/test/common/controller/cursor.test.ts index 9b6049c3b4f21b2988b7748f1d1307b87e6f4482..6e0a26aff1b4419a3e24f85e766d63d5292c3b1c 100644 --- a/src/vs/editor/test/common/controller/cursor.test.ts +++ b/src/vs/editor/test/common/controller/cursor.test.ts @@ -20,7 +20,6 @@ import {Model} from 'vs/editor/common/model/model'; import {IMode, IndentAction} from 'vs/editor/common/modes'; import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry'; import {MockConfiguration} from 'vs/editor/test/common/mocks/mockConfiguration'; -import {BracketMode} from 'vs/editor/test/common/testModes'; import {MockMode} from 'vs/editor/test/common/mocks/mockMode'; import {viewModelHelper} from 'vs/editor/test/common/editorTestUtils'; @@ -1129,6 +1128,19 @@ suite('Editor Controller - Regression tests', () => { }); test('issue #183: jump to matching bracket position', () => { + class BracketMode extends MockMode { + constructor() { + super(); + LanguageConfigurationRegistry.register(this.getId(), { + brackets: [ + ['{', '}'], + ['[', ']'], + ['(', ')'], + ] + }); + } + } + usingCursor({ text: [ 'var x = (3 + (5-7));' diff --git a/src/vs/editor/test/common/model/model.test.ts b/src/vs/editor/test/common/model/model.test.ts index 8246f33a0383423a71155ece548562b0c6a7dc7e..407a9bfe62b4ff4e1b34418e841733ff199deef7 100644 --- a/src/vs/editor/test/common/model/model.test.ts +++ b/src/vs/editor/test/common/model/model.test.ts @@ -13,24 +13,10 @@ import { IModelContentChangedLinesDeletedEvent, IModelContentChangedLinesInsertedEvent } from 'vs/editor/common/editorCommon'; import {Model} from 'vs/editor/common/model/model'; -import {BracketMode} from 'vs/editor/test/common/testModes'; import {TextModel, IParsedSearchRequest} from 'vs/editor/common/model/textModel'; // --------- utils -function isNotABracket(model:Model, lineNumber:number, column:number) { - var match = model.matchBracket(new Position(lineNumber, column)); - assert.equal(match, null, 'is not matching brackets at ' + lineNumber + ', ' + column); -} - -function isBracket(model:Model, lineNumber1:number, column11:number, column12:number, lineNumber2:number, column21:number, column22:number) { - var match = model.matchBracket(new Position(lineNumber1, column11)); - assert.deepEqual(match, [ - new Range(lineNumber1, column11, lineNumber1, column12), - new Range(lineNumber2, column21, lineNumber2, column22) - ], 'is matching brackets at ' + lineNumber1 + ', ' + column11); -} - var LINE1 = 'My First Line'; var LINE2 = '\t\tMy Second Line'; var LINE3 = ' Third Line'; @@ -378,112 +364,6 @@ suite('Editor Model - Model Line Separators', () => { }); -// --------- bracket matching - -suite('Editor Model - bracket Matching', () => { - - var thisModel: Model; - var bracketMode = new BracketMode(); - - setup(() => { - var text = - 'var bar = {' + '\n' + - 'foo: {' + '\n' + - '}, bar: {hallo: [{' + '\n' + - '}, {' + '\n' + - '}]}}'; - thisModel = Model.createFromString(text, undefined, bracketMode); - }); - - teardown(() => { - thisModel.destroy(); - }); - - test('Model bracket matching 1', () => { - - var brackets = [ - [1, 11, 12, 5, 4, 5], - [1, 12, 11, 5, 4, 5], - [5, 5, 4, 1, 11, 12], - - [2, 6, 7, 3, 1, 2], - [2, 7, 6, 3, 1, 2], - [3, 1, 2, 2, 6, 7], - [3, 2, 1, 2, 6, 7], - - [3, 9, 10, 5, 3, 4], - [3, 10, 9, 5, 3, 4], - [5, 4, 3, 3, 9, 10], - - [3, 17, 18, 5, 2, 3], - [3, 18, 17, 5, 2, 3], - [5, 3, 2, 3, 17, 18], - - [3, 19, 18, 4, 1, 2], - [4, 2, 1, 3, 18, 19], - [4, 1, 2, 3, 18, 19], - - [4, 4, 5, 5, 1, 2], - [4, 5, 4, 5, 1, 2], - [5, 2, 1, 4, 4, 5], - [5, 1, 2, 4, 4, 5] - ]; - var i, len, b, isABracket = {1:{}, 2:{}, 3:{}, 4:{}, 5:{}}; - - for (i = 0, len = brackets.length; i < len; i++) { - b = brackets[i]; - isBracket(thisModel, b[0], b[1], b[2], b[3], b[4], b[5]); - isABracket[b[0]][b[1]] = true; - } - - for (i = 1, len = thisModel.getLineCount(); i <= len; i++) { - var line = thisModel.getLineContent(i), j, lenJ; - for (j = 1, lenJ = line.length + 1; j <= lenJ; j++) { - if (!isABracket[i].hasOwnProperty(j)) { - isNotABracket(thisModel, i, j); - } - } - } - }); -}); - - -suite('Editor Model - bracket Matching 2', () => { - - var thisModel: Model; - var bracketMode = new BracketMode(); - - setup(() => { - var text = - ')]}{[(' + '\n' + - ')]}{[('; - thisModel = Model.createFromString(text, undefined, bracketMode); - }); - - teardown(() => { - thisModel.destroy(); - }); - - test('Model bracket matching', () => { - isNotABracket(thisModel, 1, 1); - isNotABracket(thisModel, 1, 2); - isNotABracket(thisModel, 1, 3); - isBracket(thisModel, 1, 4, 5, 2, 3, 4); - isBracket(thisModel, 1, 5, 4, 2, 3, 4); - isBracket(thisModel, 1, 6, 5, 2, 2, 3); - isBracket(thisModel, 1, 7, 6, 2, 1, 2); - - isBracket(thisModel, 2, 1, 2, 1, 6, 7); - isBracket(thisModel, 2, 2, 1, 1, 6, 7); - isBracket(thisModel, 2, 3, 2, 1, 5, 6); - isBracket(thisModel, 2, 4, 3, 1, 4, 5); - isNotABracket(thisModel, 2, 5); - isNotABracket(thisModel, 2, 6); - isNotABracket(thisModel, 2, 7); - }); -}); - - // --------- Words suite('Editor Model - Words', () => { diff --git a/src/vs/editor/test/common/model/textModelWithTokens.test.ts b/src/vs/editor/test/common/model/textModelWithTokens.test.ts index 107d4b22c88974312ea72ef17b2ab6eaa050c550..8d52ded0628883dc3f7d55af75bd473dd4de6a65 100644 --- a/src/vs/editor/test/common/model/textModelWithTokens.test.ts +++ b/src/vs/editor/test/common/model/textModelWithTokens.test.ts @@ -11,76 +11,27 @@ import {ITokenizationSupport} from 'vs/editor/common/modes'; import {MockMode} from 'vs/editor/test/common/mocks/mockMode'; import {Token} from 'vs/editor/common/core/token'; import {Range} from 'vs/editor/common/core/range'; +import {Position} from 'vs/editor/common/core/position'; import {IFoundBracket} from 'vs/editor/common/editorCommon'; import {TextModel} from 'vs/editor/common/model/textModel'; import {TextModelWithTokens} from 'vs/editor/common/model/textModelWithTokens'; +import {LanguageConfigurationRegistry} from 'vs/editor/common/modes/languageConfigurationRegistry'; suite('TextModelWithTokens', () => { - function assertViewLineTokens(model:Model, lineNumber:number, forceTokenization:boolean, expected:ViewLineToken[]): void { - let actual = model.getLineTokens(lineNumber, !forceTokenization).inflate(); - assert.deepEqual(actual, expected); - } - - test('Microsoft/monaco-editor#122: Unhandled Exception: TypeError: Unable to get property \'replace\' of undefined or null reference', () => { - let _tokenId = 0; - class IndicisiveMode extends MockMode { - public tokenizationSupport:ITokenizationSupport; - - constructor() { - super(); - this.tokenizationSupport = { - getInitialState: () => { - return null; - }, - tokenize: (line, state, offsetDelta, stopAtOffset) => { - let myId = ++_tokenId; - return { - tokens: [new Token(0, 'custom.'+myId)], - actualStopOffset: line.length, - endState: null, - modeTransitions: [], - retokenize: null - }; - } - }; + function testBrackets(contents: string[], brackets:string[][]): void { + function toRelaxedFoundBracket(a:IFoundBracket) { + if (!a) { + return null; } + return { + range: a.range.toString(), + open: a.open, + close: a.close, + isOpen: a.isOpen + }; } - let model = Model.createFromString('A model with\ntwo lines'); - assertViewLineTokens(model, 1, true, [new ViewLineToken(0, '')]); - assertViewLineTokens(model, 2, true, [new ViewLineToken(0, '')]); - - model.setMode(new IndicisiveMode()); - - assertViewLineTokens(model, 1, true, [new ViewLineToken(0, 'custom.1')]); - assertViewLineTokens(model, 2, true, [new ViewLineToken(0, 'custom.2')]); - - model.setMode(new IndicisiveMode()); - - assertViewLineTokens(model, 1, false, [new ViewLineToken(0, '')]); - assertViewLineTokens(model, 2, false, [new ViewLineToken(0, '')]); - - model.dispose(); - }); - -}); - -suite('TextModelWithTokens', () => { - - function toRelaxedFoundBracket(a:IFoundBracket) { - if (!a) { - return null; - } - return { - range: a.range.toString(), - open: a.open, - close: a.close, - isOpen: a.isOpen - }; - } - - function testBrackets(contents: string[], brackets:string[][]): void { let charIsBracket: {[char:string]:boolean} = {}; let charIsOpenBracket: {[char:string]:boolean} = {}; let openForChar: {[char:string]:string} = {}; @@ -183,4 +134,170 @@ suite('TextModelWithTokens', () => { ]); }); + +}); + +suite('TextModelWithTokens - bracket matching', () => { + + function isNotABracket(model:Model, lineNumber:number, column:number) { + let match = model.matchBracket(new Position(lineNumber, column)); + assert.equal(match, null, 'is not matching brackets at ' + lineNumber + ', ' + column); + } + + function isBracket(model:Model, lineNumber1:number, column11:number, column12:number, lineNumber2:number, column21:number, column22:number) { + let match = model.matchBracket(new Position(lineNumber1, column11)); + assert.deepEqual(match, [ + new Range(lineNumber1, column11, lineNumber1, column12), + new Range(lineNumber2, column21, lineNumber2, column22) + ], 'is matching brackets at ' + lineNumber1 + ', ' + column11); + } + + class BracketMode extends MockMode { + constructor() { + super(); + LanguageConfigurationRegistry.register(this.getId(), { + brackets: [ + ['{', '}'], + ['[', ']'], + ['(', ')'], + ] + }); + } + } + + test('bracket matching 1', () => { + let text = + ')]}{[(' + '\n' + + ')]}{[('; + let model = Model.createFromString(text, undefined, new BracketMode()); + + isNotABracket(model, 1, 1); + isNotABracket(model, 1, 2); + isNotABracket(model, 1, 3); + isBracket(model, 1, 4, 5, 2, 3, 4); + isBracket(model, 1, 5, 4, 2, 3, 4); + isBracket(model, 1, 6, 5, 2, 2, 3); + isBracket(model, 1, 7, 6, 2, 1, 2); + + isBracket(model, 2, 1, 2, 1, 6, 7); + isBracket(model, 2, 2, 1, 1, 6, 7); + isBracket(model, 2, 3, 2, 1, 5, 6); + isBracket(model, 2, 4, 3, 1, 4, 5); + isNotABracket(model, 2, 5); + isNotABracket(model, 2, 6); + isNotABracket(model, 2, 7); + + model.destroy(); + }); + + test('bracket matching 2', () => { + let text = + 'var bar = {' + '\n' + + 'foo: {' + '\n' + + '}, bar: {hallo: [{' + '\n' + + '}, {' + '\n' + + '}]}}'; + let model = Model.createFromString(text, undefined, new BracketMode()); + + let brackets = [ + [1, 11, 12, 5, 4, 5], + [1, 12, 11, 5, 4, 5], + [5, 5, 4, 1, 11, 12], + + [2, 6, 7, 3, 1, 2], + [2, 7, 6, 3, 1, 2], + [3, 1, 2, 2, 6, 7], + [3, 2, 1, 2, 6, 7], + + [3, 9, 10, 5, 3, 4], + [3, 10, 9, 5, 3, 4], + [5, 4, 3, 3, 9, 10], + + [3, 17, 18, 5, 2, 3], + [3, 18, 17, 5, 2, 3], + [5, 3, 2, 3, 17, 18], + + [3, 19, 18, 4, 1, 2], + [4, 2, 1, 3, 18, 19], + [4, 1, 2, 3, 18, 19], + + [4, 4, 5, 5, 1, 2], + [4, 5, 4, 5, 1, 2], + [5, 2, 1, 4, 4, 5], + [5, 1, 2, 4, 4, 5] + ]; + let i, len, b, isABracket = {1:{}, 2:{}, 3:{}, 4:{}, 5:{}}; + + for (i = 0, len = brackets.length; i < len; i++) { + b = brackets[i]; + isBracket(model, b[0], b[1], b[2], b[3], b[4], b[5]); + isABracket[b[0]][b[1]] = true; + } + + for (i = 1, len = model.getLineCount(); i <= len; i++) { + let line = model.getLineContent(i), j, lenJ; + for (j = 1, lenJ = line.length + 1; j <= lenJ; j++) { + if (!isABracket[i].hasOwnProperty(j)) { + isNotABracket(model, i, j); + } + } + } + + model.destroy(); + }); }); + + +suite('TextModelWithTokens regression tests', () => { + + test('Microsoft/monaco-editor#122: Unhandled Exception: TypeError: Unable to get property \'replace\' of undefined or null reference', () => { + function assertViewLineTokens(model:Model, lineNumber:number, forceTokenization:boolean, expected:ViewLineToken[]): void { + let actual = model.getLineTokens(lineNumber, !forceTokenization).inflate(); + assert.deepEqual(actual, expected); + } + + let _tokenId = 0; + class IndicisiveMode extends MockMode { + public tokenizationSupport:ITokenizationSupport; + + constructor() { + super(); + this.tokenizationSupport = { + getInitialState: () => { + return null; + }, + tokenize: (line, state, offsetDelta, stopAtOffset) => { + let myId = ++_tokenId; + return { + tokens: [new Token(0, 'custom.'+myId)], + actualStopOffset: line.length, + endState: null, + modeTransitions: [], + retokenize: null + }; + } + }; + } + } + let model = Model.createFromString('A model with\ntwo lines'); + + assertViewLineTokens(model, 1, true, [new ViewLineToken(0, '')]); + assertViewLineTokens(model, 2, true, [new ViewLineToken(0, '')]); + + model.setMode(new IndicisiveMode()); + + assertViewLineTokens(model, 1, true, [new ViewLineToken(0, 'custom.1')]); + assertViewLineTokens(model, 2, true, [new ViewLineToken(0, 'custom.2')]); + + model.setMode(new IndicisiveMode()); + + assertViewLineTokens(model, 1, false, [new ViewLineToken(0, '')]); + assertViewLineTokens(model, 2, false, [new ViewLineToken(0, '')]); + + model.dispose(); + }); + + // test('Microsoft/monaco-editor#133: Error: Cannot read property \'modeId\' of undefined', () => { + + // }); +}); \ No newline at end of file diff --git a/src/vs/editor/test/common/testModes.ts b/src/vs/editor/test/common/testModes.ts index 0bea638f3beb522aad076ddbe23c51cb6e69ab00..23e4f6a0a864249810f27a9dd0a811f5747fa9f9 100644 --- a/src/vs/editor/test/common/testModes.ts +++ b/src/vs/editor/test/common/testModes.ts @@ -138,20 +138,6 @@ export class ModelMode2 extends MockMode { } } -export class BracketMode extends MockMode { - - constructor() { - super(); - LanguageConfigurationRegistry.register(this.getId(), { - brackets: [ - ['{', '}'], - ['[', ']'], - ['(', ')'], - ] - }); - } -} - export class NState extends AbstractState { private n:number;