From 6057586ff30ecd837dca9acec3c2222f06c4ccba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 2 Sep 2018 17:52:56 +0200 Subject: [PATCH 1/2] fixes #1647 --- src/addons/search/SearchHelper.ts | 2 +- src/addons/search/search.test.ts | 53 +++++++++++++++++++++++++++++++ 2 files changed, 54 insertions(+), 1 deletion(-) create mode 100644 src/addons/search/search.test.ts diff --git a/src/addons/search/SearchHelper.ts b/src/addons/search/SearchHelper.ts index 5ba81aa05a..9b5c06f3be 100644 --- a/src/addons/search/SearchHelper.ts +++ b/src/addons/search/SearchHelper.ts @@ -117,7 +117,7 @@ export class SearchHelper implements ISearchHelper { if (searchIndex >= 0) { const line = this._terminal._core.buffer.lines.get(y); for (let i = 0; i < searchIndex; i++) { - const charData = line[i]; + const charData = line.get(i); // Adjust the searchIndex to normalize emoji into single chars const char = charData[1/*CHAR_DATA_CHAR_INDEX*/]; if (char.length > 1) { diff --git a/src/addons/search/search.test.ts b/src/addons/search/search.test.ts new file mode 100644 index 0000000000..7ecb32d34f --- /dev/null +++ b/src/addons/search/search.test.ts @@ -0,0 +1,53 @@ +/** + * Copyright (c) 2018 The xterm.js authors. All rights reserved. + * @license MIT + */ + +import { assert, expect } from 'chai'; +import * as search from './search'; +import { SearchHelper } from './SearchHelper'; +import { ISearchHelper } from './Interfaces'; + + +class MockTerminalPlain {} + +class MockTerminal { + private _core: any; + public searchHelper: ISearchHelper; + constructor(options: any) { + this._core = new (require('../../../lib/Terminal').Terminal)(options); + this.searchHelper = new SearchHelper(this as any); + } + get core(): any { + return this._core; + } +} + +describe('search addon', function(): void { + describe('apply', () => { + it('should register findNext and findPrevious', () => { + search.apply(MockTerminalPlain); + assert.equal(typeof (MockTerminalPlain).prototype.findNext, 'function'); + assert.equal(typeof (MockTerminalPlain).prototype.findPrevious, 'function'); + }); + }); + it('Searchhelper - should find correct position', function(done: () => void): void { + search.apply(MockTerminal); + const term = new MockTerminal({cols: 20, rows: 3}); + term.core.write('Hello World\r\ntest\n123....hello'); + setTimeout(() => { + const hello0 = (term.searchHelper as any)._findInLine('Hello', 0); + const hello1 = (term.searchHelper as any)._findInLine('Hello', 1); + const hello2 = (term.searchHelper as any)._findInLine('Hello', 2); + expect(hello0).eql({col: 0, row: 0, term: 'Hello'}); + expect(hello1).eql(undefined); + expect(hello2).eql({col: 11, row: 2, term: 'Hello'}); + done(); + }, 100); + }); + // selection stuff not testable - depends on window + // the plugin is imho to high level and does more than searching + // maybe separate into: + // - a search addon - get positions for a term + // - a mark addon - highlight positions in output +}); From 559e932a2e4c7da649171cefea298183659b5af1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rg=20Breitbart?= Date: Sun, 2 Sep 2018 21:46:20 +0200 Subject: [PATCH 2/2] remove comment and setTimeout --- src/addons/search/search.test.ts | 28 ++++++++++++---------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/src/addons/search/search.test.ts b/src/addons/search/search.test.ts index 7ecb32d34f..91ecc4efbd 100644 --- a/src/addons/search/search.test.ts +++ b/src/addons/search/search.test.ts @@ -21,6 +21,9 @@ class MockTerminal { get core(): any { return this._core; } + pushWriteData(): void { + this._core._innerWrite(); + } } describe('search addon', function(): void { @@ -30,24 +33,17 @@ describe('search addon', function(): void { assert.equal(typeof (MockTerminalPlain).prototype.findNext, 'function'); assert.equal(typeof (MockTerminalPlain).prototype.findPrevious, 'function'); }); - }); - it('Searchhelper - should find correct position', function(done: () => void): void { + }); + it('Searchhelper - should find correct position', function(): void { search.apply(MockTerminal); const term = new MockTerminal({cols: 20, rows: 3}); term.core.write('Hello World\r\ntest\n123....hello'); - setTimeout(() => { - const hello0 = (term.searchHelper as any)._findInLine('Hello', 0); - const hello1 = (term.searchHelper as any)._findInLine('Hello', 1); - const hello2 = (term.searchHelper as any)._findInLine('Hello', 2); - expect(hello0).eql({col: 0, row: 0, term: 'Hello'}); - expect(hello1).eql(undefined); - expect(hello2).eql({col: 11, row: 2, term: 'Hello'}); - done(); - }, 100); + term.pushWriteData(); + const hello0 = (term.searchHelper as any)._findInLine('Hello', 0); + const hello1 = (term.searchHelper as any)._findInLine('Hello', 1); + const hello2 = (term.searchHelper as any)._findInLine('Hello', 2); + expect(hello0).eql({col: 0, row: 0, term: 'Hello'}); + expect(hello1).eql(undefined); + expect(hello2).eql({col: 11, row: 2, term: 'Hello'}); }); - // selection stuff not testable - depends on window - // the plugin is imho to high level and does more than searching - // maybe separate into: - // - a search addon - get positions for a term - // - a mark addon - highlight positions in output });