Add tests for `keybindings.dart` (KeyEvent → Keybinding mapping, parse-error edges, resolver entries view), `toolchain_paths.dart` (the Flutter-free `ToolchainView.resolved` static view), and several `widgets/src/` primitives: tooltip hover/overlay, palette filter + submit, multitab controller `copyWith` + size getters, and additional markdown branches (h3–h6 headings, tables, strikethrough, default block fallback, record-link tap). Unfreezes the pre-push coverage floor that was held at 90 on 2026-05-14 by mistake and ratchets to 93. Tidies eight test files that had accumulated unused imports flagged by `unnecessary_import`. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
207 lines
7.9 KiB
Dart
207 lines
7.9 KiB
Dart
/// Unit tests for `ProjectManager` and `RecentProject` in
|
|
/// `lib/kernel/src/project.dart`. Uses an injected `onValidateProject`
|
|
/// hook so the manager doesn't shell out to git in tests.
|
|
library;
|
|
|
|
import 'dart:convert';
|
|
import 'dart:io';
|
|
|
|
import 'package:clide/kernel/kernel.dart';
|
|
import 'package:test/test.dart';
|
|
|
|
Future<ProjectManager> _build({
|
|
Future<String?> Function(String path)? onValidateProject,
|
|
Map<String, Object?> initialSettings = const {},
|
|
}) async {
|
|
final tmp = await Directory.systemTemp.createTemp('clide-project-test-');
|
|
final settings = SettingsStore(appDir: tmp);
|
|
await settings.load();
|
|
for (final entry in initialSettings.entries) {
|
|
await settings.set<Object>(entry.key, entry.value!);
|
|
}
|
|
final toolchain = Toolchain();
|
|
toolchain.applyResolved(const ResolvedPaths(git: '/usr/bin/git'));
|
|
final pm = ProjectManager(
|
|
log: Logger(minLevel: LogLevel.error),
|
|
events: DaemonBus(),
|
|
settings: settings,
|
|
toolchain: toolchain,
|
|
onValidateProject: onValidateProject,
|
|
);
|
|
addTearDown(() async {
|
|
if (tmp.existsSync()) tmp.deleteSync(recursive: true);
|
|
});
|
|
return pm;
|
|
}
|
|
|
|
void main() {
|
|
group('RecentProject', () {
|
|
test(r'relativePath collapses $HOME prefix to ~', () {
|
|
final home = Platform.environment['HOME'] ?? '';
|
|
if (home.isEmpty) return;
|
|
final p = RecentProject(path: '$home/projects/clide', name: 'clide', lastOpened: DateTime.now());
|
|
expect(p.relativePath, startsWith('~/'));
|
|
});
|
|
|
|
test(r'relativePath returns the absolute path when not under $HOME', () {
|
|
final p = RecentProject(path: '/elsewhere/repo', name: 'repo', lastOpened: DateTime.now());
|
|
// If $HOME is /elsewhere... we'd collapse. Otherwise absolute is preserved.
|
|
if (!'/elsewhere/repo'.startsWith(Platform.environment['HOME'] ?? ' |