Files
clide/test/extension/src/host_test.dart
T
jpmschweitzerandClaude fd72940d2d
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
test: cover lib/extension/ to 100% (T-89)
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>
2026-05-22 09:02:15 +02:00

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>>());
});
});
}