} suite('SuggestModel - Context', function () { <ins> const OUTER_LANGUAGE_ID = new LanguageIdentifier('outerMode', 3); const INNER_LANGUAGE_ID = new LanguageIdentifier('innerMode', 4); class OuterMode extends MockMode { constructor() { super(OUTER_LANGUAGE_ID); this._register(LanguageConfigurationRegistry.register(this.getLanguageIdentifier(), {})); this._register(TokenizationRegistry.register(this.getLanguageIdentifier().language, { getInitialState: (): IState => NULL_STATE, tokenize: undefined, tokenize2: (line: string, state: IState): TokenizationResult2 => { const tokensArr: number[] = []; let prevLanguageId: LanguageIdentifier = undefined; for (let i = 0; i < line.length; i++) { const languageId = (line.charAt(i) === 'x' ? INNER_LANGUAGE_ID : OUTER_LANGUAGE_ID); if (prevLanguageId !== languageId) { tokensArr.push(i); tokensArr.push((languageId.id << MetadataConsts.LANGUAGEID_OFFSET)); } prevLanguageId = languageId; } const tokens = new Uint32Array(tokensArr.length); for (let i = 0; i < tokens.length; i++) { tokens[i] = tokensArr[i]; } return new TokenizationResult2(tokens, state); } })); } } </ins> <del> let model: TextModel; </del> <ins> class InnerMode extends MockMode { constructor() { super(INNER_LANGUAGE_ID); this._register(LanguageConfigurationRegistry.register(this.getLanguageIdentifier(), {})); } } </ins> <del> setup(function () { model = TextModel.createFromString('Das Pferd frisst keinen Gurkensalat - Philipp Reis 1861.nWer hat's erfunden?'); </del> <ins> const assertAutoTrigger = (model: TextModel, offset: number, expected: boolean, message?: string): void => { const pos = model.getPositionAt(offset); const editor = createMockEditor(model); editor.setPosition(pos); assert.equal(LineContext.shouldAutoTrigger(editor), expected, message); editor.dispose(); }; let disposables: Disposable[] = []; setup(() => { disposables = []; </ins> }); teardown(function () { <del> model.dispose(); </del> <ins> dispose(disposables); disposables = []; </ins> }); test('Context - shouldAutoTrigger', function () { <ins> const model = TextModel.createFromString('Das Pferd frisst keinen Gurkensalat - Philipp Reis 1861.nWer hat's erfunden?'); disposables.push(model); </ins> <del> function assertAutoTrigger(offset: number, expected: boolean): void { const pos = model.getPositionAt(offset); const editor = createMockEditor(model); editor.setPosition(pos); assert.equal(LineContext.shouldAutoTrigger(editor), expected); editor.dispose(); } assertAutoTrigger(3, true); // end of word, Das| assertAutoTrigger(4, false); // no word Das | assertAutoTrigger(1, false); // middle of word D|as assertAutoTrigger(55, false); // number, 1861| </del> <ins> assertAutoTrigger(model, 3, true, 'end of word, Das|'); assertAutoTrigger(model, 4, false, 'no word Das |'); assertAutoTrigger(model, 1, false, 'middle of word D|as'); assertAutoTrigger(model, 55, false, 'number, 1861|'); </ins> }); <ins> test('shouldAutoTrigger at embedded language boundaries', () => { const outerMode = new OuterMode(); const innerMode = new InnerMode(); disposables.push(outerMode, innerMode); const model = TextModel.createFromString('a<xx>a<x>', undefined, outerMode.getLanguageIdentifier()); disposables.push(model); assertAutoTrigger(model, 1, true, 'a|<x — should trigger at end of word'); assertAutoTrigger(model, 2, false, 'a<|x — should NOT trigger at start of word'); assertAutoTrigger(model, 3, false, 'a<x|x —  should NOT trigger in middle of word'); assertAutoTrigger(model, 4, true, 'a<xx|> — should trigger at boundary between languages'); assertAutoTrigger(model, 5, false, 'a<xx>|a — should NOT trigger at start of word'); assertAutoTrigger(model, 6, true, 'a<xx>a|< — should trigger at end of word'); assertAutoTrigger(model, 8, true, 'a<xx>a<x|> — should trigger at end of word at boundary'); }); </ins> }); suite('SuggestModel - TriggerAndCancelOracle', function () {