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 28s
Adds tests for the previously-uncovered ClideExtensionContext sugar (publish/subscribe/t/tr) and the default no-op ClideExtension lifecycle hooks, driving the real context the ExtensionManager builds, plus ExtensionScanner.defaultRoot + the no-arg discover() fallback. lib/extension/ goes 74.1% -> 100%; total 95.06% -> 95.23%. Floor unchanged (no integer crossing). Co-Authored-By: Claude <noreply@anthropic.com>
71 lines
2.7 KiB
Dart
71 lines
2.7 KiB
Dart
import 'dart:io';
|
|
|
|
import 'package:clide/extension/extension.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
group('ExtensionScanner', () {
|
|
late Directory root;
|
|
|
|
setUp(() async {
|
|
root = await Directory.systemTemp.createTemp('clide_ext_');
|
|
});
|
|
|
|
tearDown(() async {
|
|
try {
|
|
await root.delete(recursive: true);
|
|
} catch (_) {}
|
|
});
|
|
|
|
test('returns empty when directory is missing', () async {
|
|
final absent = Directory('${root.path}/absent');
|
|
final out = await const ExtensionScanner().discover(root: absent);
|
|
expect(out, isEmpty);
|
|
});
|
|
|
|
test('returns empty when directory exists but has no extensions', () async {
|
|
final out = await const ExtensionScanner().discover(root: root);
|
|
expect(out, isEmpty);
|
|
});
|
|
|
|
test('discovers extensions from their own subdirs', () async {
|
|
final a = Directory('${root.path}/ext.a')..createSync();
|
|
await File('${a.path}/manifest.yaml').writeAsString('id: ext.a\ntitle: A\nversion: 1.0.0\n');
|
|
final b = Directory('${root.path}/ext.b')..createSync();
|
|
await File('${b.path}/manifest.yaml').writeAsString('id: ext.b\ntitle: B\nversion: 1.2.0\n');
|
|
final out = await const ExtensionScanner().discover(root: root);
|
|
expect(out.map((m) => m.id).toSet(), {'ext.a', 'ext.b'});
|
|
});
|
|
|
|
test('skips a subdir without a manifest.yaml', () async {
|
|
final a = Directory('${root.path}/ext.a')..createSync();
|
|
await File('${a.path}/README.md').writeAsString('no manifest');
|
|
final out = await const ExtensionScanner().discover(root: root);
|
|
expect(out, isEmpty);
|
|
});
|
|
|
|
test('skips malformed manifests (non-fatal)', () async {
|
|
final bad = Directory('${root.path}/ext.bad')..createSync();
|
|
await File('${bad.path}/manifest.yaml').writeAsString('not a map');
|
|
final ok = Directory('${root.path}/ext.ok')..createSync();
|
|
await File('${ok.path}/manifest.yaml').writeAsString('id: ext.ok');
|
|
final out = await const ExtensionScanner().discover(root: root);
|
|
expect(out.map((m) => m.id).toList(), ['ext.ok']);
|
|
});
|
|
|
|
test('defaultRoot points at ~/.clide/extensions', () {
|
|
final scanner = ExtensionScanner();
|
|
final home = Platform.environment['HOME'] ?? '/tmp';
|
|
expect(scanner.defaultRoot().path, '$home/.clide/extensions');
|
|
});
|
|
|
|
test('discover() with no root falls back to defaultRoot', () async {
|
|
// Exercises the `root ?? defaultRoot()` fallback. The install
|
|
// root rarely exists in CI, so this returns a (possibly empty)
|
|
// list rather than throwing.
|
|
final out = await const ExtensionScanner().discover();
|
|
expect(out, isA<List<ExtensionManifest>>());
|
|
});
|
|
});
|
|
}
|