test sweep: cover kernel/src/syntax (T-91)
test / unit + widget + golden + a11y (push) Failing after 31s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 1m2s
test / unit + widget + golden + a11y (push) Failing after 31s
test / integration_test (xvfb) (push) Has been skipped
test / bundle smoke (xvfb 5s) (push) Has been skipped
test / daemon subprocess + web WASM smoke (push) Has been skipped
test / dart doc (lib API) (push) Failing after 1m2s
Two test files covering the pure-Dart and fallback paths of the
tree-sitter integration. The native-FFI parsing depth stays
untested — DynamicLibrary.open('libtree-sitter.so') doesn't resolve
under the flutter test runner because the bundled lib sits at
native/linux-x64/ rather than on the linker search path. Real
parsing coverage would need an integration-test harness that copies
or symlinks the lib into the runner's working directory.
- test/kernel/src/syntax/language_map_test.dart (6 tests): every
branch of grammarForPath — common extensions, case-insensitive
matching, special filenames (Makefile / Dockerfile / .gitignore /
justfile), no-dot/no-special-match fallthrough, unknown extension.
- test/kernel/src/syntax/tree_sitter_service_test.dart (9 tests):
graceful-fallback paths of TreeSitterService when the library
can't load — hasGrammar / languageFor / highlight all short-
circuit cleanly, plus SyntaxResult.empty and SyntaxSpan field
storage.
Coverage: language_map.dart 0/7 -> 7/7; tree_sitter_service.dart
1/131 -> 22/131 (the rest is deep FFI work); tree_sitter_ffi.dart
0/15 -> 1/15 (init entry only).
Total coverage 75.11% -> 75.42%.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,66 @@
|
||||
/// Tests the graceful-fallback paths of `TreeSitterService` when the
|
||||
/// native `libtree-sitter` library isn't dlopen-resolvable. In that
|
||||
/// environment the service short-circuits every public method without
|
||||
/// throwing — which is also how the running app behaves on platforms
|
||||
/// where the library hasn't been bundled.
|
||||
library;
|
||||
|
||||
import 'package:clide/kernel/src/syntax/tree_sitter_service.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
group('TreeSitterService — fallback paths', () {
|
||||
final svc = TreeSitterService.shared;
|
||||
|
||||
test('hasGrammar(path) returns false for an unknown extension', () async {
|
||||
expect(await svc.hasGrammar('foo.unknownextension'), isFalse);
|
||||
});
|
||||
|
||||
test('hasGrammar(path) returns false when the library cannot load', () async {
|
||||
// 'foo.dart' resolves to grammar "dart", which still requires the
|
||||
// native library + asset to actually load. In the test runner the
|
||||
// native lib isn't on the dlopen search path, so _init() fails and
|
||||
// hasGrammar reports false.
|
||||
expect(await svc.hasGrammar('foo.dart'), isFalse);
|
||||
});
|
||||
|
||||
test('languageFor(path) returns null when the language is unknown', () async {
|
||||
expect(await svc.languageFor('foo.unknownextension'), isNull);
|
||||
});
|
||||
|
||||
test('languageFor(path) returns null when the library cannot load', () async {
|
||||
expect(await svc.languageFor('foo.dart'), isNull);
|
||||
});
|
||||
|
||||
test('highlight returns an empty result for unknown extensions', () async {
|
||||
final r = await svc.highlight('foo.unknownextension', 'whatever');
|
||||
expect(r.spans, isEmpty);
|
||||
});
|
||||
|
||||
test('highlight returns an empty result when the library cannot load', () async {
|
||||
final r = await svc.highlight('foo.dart', 'void main() {}');
|
||||
expect(r.spans, isEmpty);
|
||||
});
|
||||
|
||||
test('loadedLanguages getter returns a list (may be empty)', () {
|
||||
// Just exercise the getter — the actual contents depend on the
|
||||
// environment.
|
||||
expect(svc.loadedLanguages, isA<List<String>>());
|
||||
});
|
||||
});
|
||||
|
||||
group('SyntaxResult / SyntaxSpan', () {
|
||||
test('SyntaxResult.empty has no spans', () {
|
||||
expect(SyntaxResult.empty.spans, isEmpty);
|
||||
});
|
||||
|
||||
test('SyntaxSpan stores start / end / role', () {
|
||||
const s = SyntaxSpan(start: 3, end: 7, role: 'keyword');
|
||||
expect(s.start, 3);
|
||||
expect(s.end, 7);
|
||||
expect(s.role, 'keyword');
|
||||
});
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user