Files
clide/test/search/match_test.dart
T
jpmschweitzerandClaude Opus 4.8 399a4d3a3f add workspace grep engine + search.grep/cancel, editor.open --line
The pure-Dart content-search engine behind find-in-files (D-79): walks
the ignore-pruned workspace, fans files across worker isolates
(Isolate.run) for parallelism, matches each line with a literal
indexOf fast-path or a RegExp, and streams match batches with
cooperative cancellation. No ripgrep dependency; the search.grep IPC
contract is engine-agnostic so an rg accelerator can slot in later.

search.grep returns a searchId and streams search.match / search.done
(or search.error) events, mirroring files.watch; search.cancel stops
an in-flight search. The service reuses the files service's resolved
ignore set so both honour the same ignore_files: layering.

editor.open gains an optional 1-based line argument: it converts the
line to a byte offset and sets the initial selection, enabling
click-to-line from search results.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-31 20:31:18 +02:00

40 lines
1.4 KiB
Dart

/// Round-trip tests for the search data types (T-52).
library;
import 'package:clide/src/search/match.dart';
import 'package:test/test.dart';
void main() {
test('SearchMatch JSON round-trips', () {
const m = SearchMatch(path: 'lib/a.dart', line: 12, matchStart: 4, matchEnd: 8, preview: 'final x = 1;');
final back = SearchMatch.fromJson(m.toJson());
expect(back.path, m.path);
expect(back.line, m.line);
expect(back.matchStart, m.matchStart);
expect(back.matchEnd, m.matchEnd);
expect(back.preview, m.preview);
});
test('SearchQuery JSON round-trips', () {
const q = SearchQuery(pattern: 'foo', regex: true, ignoreCase: true, include: ['*.dart'], exclude: ['build/**']);
final back = SearchQuery.fromJson(q.toJson());
expect(back.pattern, 'foo');
expect(back.regex, isTrue);
expect(back.ignoreCase, isTrue);
expect(back.include, ['*.dart']);
expect(back.exclude, ['build/**']);
});
test('SearchQuery.fromJson tolerates missing/odd fields', () {
final q = SearchQuery.fromJson(const {'pattern': 'x'});
expect(q.regex, isFalse);
expect(q.ignoreCase, isFalse);
expect(q.include, isEmpty);
expect(q.exclude, isEmpty);
final q2 = SearchQuery.fromJson(const {});
expect(q2.pattern, '');
final q3 = SearchQuery.fromJson(const {'pattern': 'x', 'include': 'not-a-list'});
expect(q3.include, isEmpty);
});
}