| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260 |
- import 'package:flutter_test/flutter_test.dart';
- import 'package:mockito/annotations.dart';
- import 'package:mockito/mockito.dart';
- import 'package:xterm/buffer/buffer.dart';
- import 'package:xterm/buffer/line/line.dart';
- import 'package:xterm/terminal/terminal_search.dart';
- import 'package:xterm/terminal/terminal_search_interaction.dart';
- import 'package:xterm/util/circular_list.dart';
- import 'terminal_search_test.mocks.dart';
- class TerminalSearchTestCircularList extends CircularList<BufferLine> {
- TerminalSearchTestCircularList(int maxLines) : super(maxLines);
- }
- @GenerateMocks([
- TerminalSearchInteraction,
- Buffer,
- TerminalSearchTestCircularList,
- BufferLine
- ])
- void main() {
- group('Terminal Search Tests', () {
- test('Creation works', () {});
- test('Doesn\'t trigger anything when not activated', () {
- final fixture = _TestFixture();
- verifyNoMoreInteractions(fixture.terminalSearchInteractionMock);
- final task = fixture.uut.createSearchTask('testsearch');
- task.pattern = "some test";
- task.isActive = false;
- task.searchResult;
- });
- test('Basic search works', () {
- final fixture = _TestFixture();
- fixture.expectTerminalSearchContent(['Simple Content']);
- final task = fixture.uut.createSearchTask('testsearch');
- task.isActive = true;
- task.pattern = 'content';
- task.options = TerminalSearchOptions(
- caseSensitive: false, matchWholeWord: false, useRegex: false);
- final result = task.searchResult;
- expect(result.allHits.length, 1);
- expect(result.allHits[0].startLineIndex, 0);
- expect(result.allHits[0].startIndex, 7);
- expect(result.allHits[0].endLineIndex, 0);
- expect(result.allHits[0].endIndex, 14);
- });
- test('Multiline search works', () {
- final fixture = _TestFixture();
- fixture.expectTerminalSearchContent(['Simple Content', 'Second Line']);
- final task = fixture.uut.createSearchTask('testsearch');
- task.isActive = true;
- task.pattern = 'line';
- task.options = TerminalSearchOptions(
- caseSensitive: false, matchWholeWord: false, useRegex: false);
- final result = task.searchResult;
- expect(result.allHits.length, 1);
- expect(result.allHits[0].startLineIndex, 1);
- expect(result.allHits[0].startIndex, 7);
- expect(result.allHits[0].endLineIndex, 1);
- expect(result.allHits[0].endIndex, 11);
- });
- test('Finding strings directly on line break works', () {
- final fixture = _TestFixture();
- fixture.expectTerminalSearchContent([
- 'The search hit is '.padRight(fixture.terminalWidth - 3) + 'spl',
- 'it over two lines',
- ]);
- final task = fixture.uut.createSearchTask('testsearch');
- task.isActive = true;
- task.pattern = 'split';
- task.options = TerminalSearchOptions(
- caseSensitive: false, matchWholeWord: false, useRegex: false);
- final result = task.searchResult;
- expect(result.allHits.length, 1);
- expect(result.allHits[0].startLineIndex, 0);
- expect(result.allHits[0].startIndex, 77);
- expect(result.allHits[0].endLineIndex, 1);
- expect(result.allHits[0].endIndex, 2);
- });
- });
- test('Option: case sensitivity works', () {
- final fixture = _TestFixture();
- fixture.expectTerminalSearchContent(['Simple Content', 'Second Line']);
- final task = fixture.uut.createSearchTask('testsearch');
- task.isActive = true;
- task.pattern = 'line';
- task.options = TerminalSearchOptions(
- caseSensitive: true, matchWholeWord: false, useRegex: false);
- final result = task.searchResult;
- expect(result.allHits.length, 0);
- task.pattern = 'Line';
- final secondResult = task.searchResult;
- expect(secondResult.allHits.length, 1);
- expect(secondResult.allHits[0].startLineIndex, 1);
- expect(secondResult.allHits[0].startIndex, 7);
- expect(secondResult.allHits[0].endLineIndex, 1);
- expect(secondResult.allHits[0].endIndex, 11);
- });
- test('Option: whole word works', () {
- final fixture = _TestFixture();
- fixture.expectTerminalSearchContent(['Simple Content', 'Second Line']);
- final task = fixture.uut.createSearchTask('testsearch');
- task.isActive = true;
- task.pattern = 'lin';
- task.options = TerminalSearchOptions(
- caseSensitive: false, matchWholeWord: true, useRegex: false);
- final result = task.searchResult;
- expect(result.allHits.length, 0);
- task.pattern = 'line';
- final secondResult = task.searchResult;
- expect(secondResult.allHits.length, 1);
- expect(secondResult.allHits[0].startLineIndex, 1);
- expect(secondResult.allHits[0].startIndex, 7);
- expect(secondResult.allHits[0].endLineIndex, 1);
- expect(secondResult.allHits[0].endIndex, 11);
- });
- test('Option: regex works', () {
- final fixture = _TestFixture();
- fixture.expectTerminalSearchContent(['Simple Content', 'Second Line']);
- final task = fixture.uut.createSearchTask('testsearch');
- task.isActive = true;
- task.options = TerminalSearchOptions(
- caseSensitive: false, matchWholeWord: false, useRegex: true);
- task.pattern =
- r'(^|\s)\w{4}($|\s)'; // match exactly 4 characters (and the whitespace before and/or after)
- final secondResult = task.searchResult;
- expect(secondResult.allHits.length, 1);
- expect(secondResult.allHits[0].startLineIndex, 1);
- expect(secondResult.allHits[0].startIndex, 6);
- expect(secondResult.allHits[0].endLineIndex, 1);
- expect(secondResult.allHits[0].endIndex, 12);
- });
- test('Retrigger search when a BufferLine got dirty works', () {
- final fixture = _TestFixture();
- fixture.expectTerminalSearchContent(
- ['Simple Content', 'Second Line', 'Third row']);
- final task = fixture.uut.createSearchTask('testsearch');
- task.isActive = true;
- task.options = TerminalSearchOptions(
- caseSensitive: false, matchWholeWord: false, useRegex: false);
- task.pattern = 'line';
- final result = task.searchResult;
- expect(result.allHits.length, 1);
- // overwrite expectations, nothing dirty => no new search
- fixture.expectTerminalSearchContent(
- ['Simple Content', 'Second Line', 'Third line'],
- isSearchStringCached: false);
- final secondResult = task.searchResult;
- expect(secondResult.allHits.length,
- 1); // nothing was dirty => we get the cached search result
- // overwrite expectations, one line is dirty => new search
- fixture.expectTerminalSearchContent(
- ['Simple Content', 'Second Line', 'Third line'],
- isSearchStringCached: false,
- dirtyIndices: [1]);
- final thirdResult = task.searchResult;
- expect(thirdResult.allHits.length,
- 2); //search has happened again so the new content is found
- // overwrite expectations, content has changed => new search
- fixture.expectTerminalSearchContent(
- ['First line', 'Second Line', 'Third line'],
- isSearchStringCached: false,
- dirtyIndices: [0]);
- final fourthResult = task.searchResult;
- expect(fourthResult.allHits.length,
- 3); //search has happened again so the new content is found
- });
- }
- class _TestFixture {
- _TestFixture({
- this.terminalWidth = 80,
- }) {
- uut = TerminalSearch(terminalSearchInteractionMock);
- when(terminalSearchInteractionMock.terminalWidth).thenReturn(terminalWidth);
- }
- final int terminalWidth;
- void expectTerminalSearchContent(
- List<String> lines, {
- isUsingAltBuffer = false,
- isSearchStringCached = true,
- List<int>? dirtyIndices,
- }) {
- final buffer = _getBuffer(lines,
- isCached: isSearchStringCached, dirtyIndices: dirtyIndices);
- when(terminalSearchInteractionMock.buffer).thenReturn(buffer);
- when(terminalSearchInteractionMock.isUsingAltBuffer())
- .thenReturn(isUsingAltBuffer);
- }
- final terminalSearchInteractionMock = MockTerminalSearchInteraction();
- late final TerminalSearch uut;
- MockBuffer _getBuffer(
- List<String> lines, {
- isCached = true,
- List<int>? dirtyIndices,
- }) {
- final result = MockBuffer();
- final circularList = MockTerminalSearchTestCircularList();
- when(result.lines).thenReturn(circularList);
- final bufferLines = _getBufferLinesWithSearchContent(
- lines,
- isCached: isCached,
- dirtyIndices: dirtyIndices,
- );
- when(circularList[any]).thenAnswer(
- (realInvocation) => bufferLines[realInvocation.positionalArguments[0]]);
- when(circularList.length).thenReturn(bufferLines.length);
- return result;
- }
- List<MockBufferLine> _getBufferLinesWithSearchContent(
- List<String> content, {
- isCached = true,
- List<int>? dirtyIndices,
- }) {
- final result = List<MockBufferLine>.empty(growable: true);
- for (int i = 0; i < content.length; i++) {
- final bl = MockBufferLine();
- when(bl.hasCachedSearchString).thenReturn(isCached);
- when(bl.toSearchString(any)).thenReturn(content[i]);
- if (dirtyIndices?.contains(i) ?? false) {
- when(bl.isTagDirty(any)).thenReturn(true);
- } else {
- when(bl.isTagDirty(any)).thenReturn(false);
- }
- result.add(bl);
- }
- return result;
- }
- }
|