test sweep: kernel extensions + scheduler residuals (T-91)

Cover the remaining catch / no-op branches in
kernel/src/extensions_manager.dart (duplicate register, unknown
activate, activate-throws, deactivate-throws, keybinding unbind
on deactivate, `all` getter passthrough) and exercise the
SchedulerService event surface (ProjectOpened starts the ticker,
ProjectClosed stops it cleanly). Pushes line coverage to 92.73%.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-05-14 14:39:45 +02:00
co-authored by Claude
parent b74ab54765
commit a3a10cddf3
2 changed files with 82 additions and 0 deletions
+26
View File
@@ -5,6 +5,7 @@ library;
import 'package:clide/kernel/src/dialog.dart';
import 'package:clide/kernel/src/events/bus.dart';
import 'package:clide/kernel/src/events/types.dart';
import 'package:clide/kernel/src/files.dart';
import 'package:clide/kernel/src/log.dart';
import 'package:clide/kernel/src/os.dart';
@@ -194,5 +195,30 @@ void main() {
s.start();
s.dispose();
});
test('ProjectOpened triggers the initial-cycle ticks', () async {
final bus = DaemonBus();
final s = SchedulerService(bus);
addTearDown(s.dispose);
s.start();
final ticks = <SchedulerTier>[];
final sub = bus.on<SchedulerTick>().listen((e) => ticks.add(e.tier));
addTearDown(sub.cancel);
bus.emit(const ProjectOpened(path: '/tmp/x'));
// The first stagger is 0 ms; pump to flush it onto the queue.
await Future<void>.delayed(const Duration(milliseconds: 50));
expect(ticks, isNotEmpty);
});
test('ProjectClosed stops the ticker without throwing', () async {
final bus = DaemonBus();
final s = SchedulerService(bus);
addTearDown(s.dispose);
s.start();
bus.emit(const ProjectOpened(path: '/tmp/x'));
await Future<void>.delayed(const Duration(milliseconds: 50));
bus.emit(const ProjectClosed());
// Smoke — no throw.
});
});
}