dart format whole tree

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
2026-05-03 21:51:59 +02:00
co-authored by Claude
parent c436e72c5c
commit 9c7ec008dc
102 changed files with 1176 additions and 1282 deletions
+2 -4
View File
@@ -33,14 +33,12 @@ void main() {
expect(node.hasFocus, isTrue);
});
testWidgets('interactive widgets expose tap actions to a11y',
(tester) async {
testWidgets('interactive widgets expose tap actions to a11y', (tester) async {
await tester.pumpWidget(
harness(f, ClideButton(label: 'Save', onPressed: () {})),
);
final handle = tester.ensureSemantics();
final data =
tester.getSemantics(find.byType(ClideButton)).getSemanticsData();
final data = tester.getSemantics(find.byType(ClideButton)).getSemanticsData();
expect(data.hasAction(SemanticsAction.tap), isTrue);
handle.dispose();
});
+3 -7
View File
@@ -34,19 +34,15 @@ void main() {
test('tab contributions carry title + i18n key + namespace', () {
final tabs = ext.contributions.whereType<TabContribution>().toList();
for (final t in tabs) {
expect(t.title, isNotEmpty,
reason: '${ext.id} tab ${t.id} missing English title');
expect(t.title, isNotEmpty, reason: '${ext.id} tab ${t.id} missing English title');
if (t.titleKey != null) {
expect(t.i18nNamespace, isNotNull,
reason:
'${ext.id} tab ${t.id} has titleKey but no namespace');
expect(t.i18nNamespace, isNotNull, reason: '${ext.id} tab ${t.id} has titleKey but no namespace');
}
}
});
test('command contributions carry stable ids', () {
final cmds =
ext.contributions.whereType<CommandContribution>().toList();
final cmds = ext.contributions.whereType<CommandContribution>().toList();
for (final c in cmds) {
expect(c.command, isNotEmpty);
expect(c.id, isNotEmpty);
+1 -4
View File
@@ -20,10 +20,7 @@ void main() {
test('contributes a statusbar item', () async {
f.services.extensions.register(IpcStatusExtension());
await f.services.extensions.activateAll();
final items = f.services.panels
.contributionsFor(Slots.statusbar)
.whereType<StatusItemContribution>()
.toList();
final items = f.services.panels.contributionsFor(Slots.statusbar).whereType<StatusItemContribution>().toList();
expect(items, hasLength(1));
expect(items.first.priority, 100);
});
+1 -2
View File
@@ -80,8 +80,7 @@ void main() {
expect(find.text('Cancel'), findsOneWidget);
});
testWidgets('tapping a row calls controller.select + onDismiss',
(tester) async {
testWidgets('tapping a row calls controller.select + onDismiss', (tester) async {
String? dismissed;
await tester.pumpWidget(
harness(
+1 -3
View File
@@ -20,9 +20,7 @@ void main() {
'builtin.welcome': {
const Locale('en', 'US'): const {
'title': {'translation': 'clide'},
'subtitle': {
'translation': 'Flutter desktop IDE for Claude Code'
},
'subtitle': {'translation': 'Flutter desktop IDE for Claude Code'},
'open-project': {'translation': 'Open project'},
'open-project.hint': {'translation': 'Pick a git repository'},
'tab.title': {'translation': 'Welcome'},
+4 -12
View File
@@ -49,10 +49,7 @@ void main() {
);
// Wait for the "listening" line on stderr so we know it's ready.
final ready = Completer<void>();
daemon.stderr
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((line) {
daemon.stderr.transform(utf8.decoder).transform(const LineSplitter()).listen((line) {
if (!ready.isCompleted && line.contains('listening')) {
ready.complete();
}
@@ -62,8 +59,7 @@ void main() {
tearDown(() async {
daemon.kill(ProcessSignal.sigterm);
await daemon.exitCode.timeout(const Duration(seconds: 3),
onTimeout: () {
await daemon.exitCode.timeout(const Duration(seconds: 3), onTimeout: () {
daemon.kill(ProcessSignal.sigkill);
return -1;
});
@@ -129,10 +125,7 @@ void main() {
);
final received = <Map<String, Object?>>[];
final sub = tail.stdout
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((line) {
final sub = tail.stdout.transform(utf8.decoder).transform(const LineSplitter()).listen((line) {
if (line.isEmpty) return;
received.add(jsonDecode(line) as Map<String, Object?>);
});
@@ -149,8 +142,7 @@ void main() {
}
tail.kill(ProcessSignal.sigint);
await tail.exitCode.timeout(const Duration(seconds: 2),
onTimeout: () {
await tail.exitCode.timeout(const Duration(seconds: 2), onTimeout: () {
tail.kill(ProcessSignal.sigkill);
return -1;
});
+22 -9
View File
@@ -44,8 +44,7 @@ void main() {
if (sandbox.existsSync()) sandbox.deleteSync(recursive: true);
});
Future<IpcResponse> call(String cmd,
[Map<String, Object?> args = const {}]) {
Future<IpcResponse> call(String cmd, [Map<String, Object?> args = const {}]) {
return dispatcher.dispatch(IpcRequest(id: '1', cmd: cmd, args: args));
}
@@ -66,7 +65,9 @@ void main() {
test('git.stage + git.status shows staged file', () async {
await File('${sandbox.path}/new.txt').writeAsString('x');
final stage = await call('git.stage', {'paths': ['new.txt']});
final stage = await call('git.stage', {
'paths': ['new.txt']
});
expect(stage.ok, isTrue);
final r = await call('git.status');
@@ -82,8 +83,12 @@ void main() {
test('git.unstage removes from staging', () async {
await File('${sandbox.path}/new.txt').writeAsString('x');
await call('git.stage', {'paths': ['new.txt']});
final unstage = await call('git.unstage', {'paths': ['new.txt']});
await call('git.stage', {
'paths': ['new.txt']
});
final unstage = await call('git.unstage', {
'paths': ['new.txt']
});
expect(unstage.ok, isTrue);
final r = await call('git.status');
@@ -93,7 +98,9 @@ void main() {
test('git.commit creates a commit', () async {
await File('${sandbox.path}/c.txt').writeAsString('x');
await call('git.stage', {'paths': ['c.txt']});
await call('git.stage', {
'paths': ['c.txt']
});
final r = await call('git.commit', {'message': 'test commit'});
expect(r.ok, isTrue);
expect(r.data['hash'], hasLength(40));
@@ -115,7 +122,9 @@ void main() {
test('git.diff --staged returns staged diffs', () async {
await File('${sandbox.path}/file.txt').writeAsString('modified\n');
await call('git.stage', {'paths': ['file.txt']});
await call('git.stage', {
'paths': ['file.txt']
});
final r = await call('git.diff', {'staged': true});
expect(r.ok, isTrue);
final diffs = r.data['diffs'] as List;
@@ -131,7 +140,9 @@ void main() {
test('git.discard restores a file', () async {
await File('${sandbox.path}/file.txt').writeAsString('changed');
final r = await call('git.discard', {'paths': ['file.txt']});
final r = await call('git.discard', {
'paths': ['file.txt']
});
expect(r.ok, isTrue);
final content = await File('${sandbox.path}/file.txt').readAsString();
expect(content, 'hello\n');
@@ -145,7 +156,9 @@ void main() {
test('mutations emit git.changed events', () async {
await File('${sandbox.path}/e.txt').writeAsString('x');
await call('git.stage', {'paths': ['e.txt']});
await call('git.stage', {
'paths': ['e.txt']
});
expect(
sink.events,
contains(predicate<IpcEvent>((e) => e.kind == 'git.changed')),
+3 -13
View File
@@ -71,19 +71,14 @@ void main() {
}
final lines = <String>[];
final done = Completer<void>();
final sub = socket
.cast<List<int>>()
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((line) {
final sub = socket.cast<List<int>>().transform(utf8.decoder).transform(const LineSplitter()).listen((line) {
lines.add(line);
if (lines.length == 5) done.complete();
});
await done.future.timeout(const Duration(seconds: 2));
await sub.cancel();
await socket.close();
final ids =
lines.map((l) => (IpcMessage.decode(l) as IpcResponse).id).toSet();
final ids = lines.map((l) => (IpcMessage.decode(l) as IpcResponse).id).toSet();
expect(ids, {'0', '1', '2', '3', '4'});
});
@@ -112,12 +107,7 @@ Future<String> _send(String socketPath, String line) async {
0,
);
socket.writeln(line);
final resp = await socket
.cast<List<int>>()
.transform(utf8.decoder)
.transform(const LineSplitter())
.first
.timeout(const Duration(seconds: 2));
final resp = await socket.cast<List<int>>().transform(utf8.decoder).transform(const LineSplitter()).first.timeout(const Duration(seconds: 2));
await socket.close();
return resp;
}
+4 -14
View File
@@ -15,8 +15,7 @@ void main() {
group('bin/clide --daemon (subprocess)', () {
setUpAll(() {
if (!binary.existsSync()) {
markTestSkipped(
'bin/clide not built; run `make build` first to enable this suite');
markTestSkipped('bin/clide not built; run `make build` first to enable this suite');
}
});
@@ -41,10 +40,7 @@ void main() {
// Wait for "listening on ..." on stderr before connecting.
final ready = Completer<void>();
final stderrLines = <String>[];
final sub = process.stderr
.transform(utf8.decoder)
.transform(const LineSplitter())
.listen((line) {
final sub = process.stderr.transform(utf8.decoder).transform(const LineSplitter()).listen((line) {
stderrLines.add(line);
if (line.contains('listening')) ready.complete();
});
@@ -58,12 +54,7 @@ void main() {
0,
).timeout(const Duration(seconds: 3));
sock.writeln(IpcRequest(id: '1', cmd: 'ping').encode());
final line = await sock
.cast<List<int>>()
.transform(utf8.decoder)
.transform(const LineSplitter())
.first
.timeout(const Duration(seconds: 3));
final line = await sock.cast<List<int>>().transform(utf8.decoder).transform(const LineSplitter()).first.timeout(const Duration(seconds: 3));
await sock.close();
final resp = IpcMessage.decode(line) as IpcResponse;
expect(resp.ok, true);
@@ -71,8 +62,7 @@ void main() {
// Clean shutdown
process.kill(ProcessSignal.sigterm);
final exitCode =
await process.exitCode.timeout(const Duration(seconds: 3));
final exitCode = await process.exitCode.timeout(const Duration(seconds: 3));
expect(exitCode, 0);
// Socket file should be unlinked
+1 -2
View File
@@ -76,8 +76,7 @@ void main() {
expect(sink.ofKind('editor.saved'), hasLength(1));
});
test('close picks a new active buffer when the active one closes',
() async {
test('close picks a new active buffer when the active one closes', () async {
final a = await reg.open('README.md');
await File('${sandbox.path}/b.txt').writeAsString('two');
final b = await reg.open('b.txt');
+2 -4
View File
@@ -30,11 +30,9 @@ void main() {
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');
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');
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'});
});
+2 -4
View File
@@ -185,8 +185,7 @@ index abc..def 100644
});
test('returns unstaged diff after modification', () async {
await File('${sandbox.path}/file.txt')
.writeAsString('line1\nmodified\n');
await File('${sandbox.path}/file.txt').writeAsString('line1\nmodified\n');
final diffs = await gitDiff(sandbox);
expect(diffs, hasLength(1));
expect(diffs.first.path, 'file.txt');
@@ -194,8 +193,7 @@ index abc..def 100644
});
test('returns staged diff with staged: true', () async {
await File('${sandbox.path}/file.txt')
.writeAsString('line1\nmodified\n');
await File('${sandbox.path}/file.txt').writeAsString('line1\nmodified\n');
await Process.run(
'git',
['add', 'file.txt'],
+2 -4
View File
@@ -4,12 +4,10 @@ import 'package:clide/kernel/kernel.dart';
/// A DaemonClient that doesn't actually open a socket. Use in tests
/// that need a connected-state observable but not a real daemon.
class FakeDaemonClient extends DaemonClient {
FakeDaemonClient({required super.log, required super.events})
: super(socketPath: '/dev/null/fake-clide.sock');
FakeDaemonClient({required super.log, required super.events}) : super(socketPath: '/dev/null/fake-clide.sock');
bool _fakeConnected = false;
final Map<String, Future<IpcResponse> Function(Map<String, Object?>)> _stubs =
{};
final Map<String, Future<IpcResponse> Function(Map<String, Object?>)> _stubs = {};
@override
bool get isConnected => _fakeConnected;
+1 -2
View File
@@ -9,8 +9,7 @@ import 'fake_ipc.dart';
/// No real daemon, no real filesystem outside a temp dir, no asset
/// bundle — i18n catalogs are passed as literals.
class KernelFixture {
KernelFixture._(
{required this.services, required this.ipc, required this.tempDir});
KernelFixture._({required this.services, required this.ipc, required this.tempDir});
final KernelServices services;
final FakeDaemonClient ipc;
+1 -2
View File
@@ -117,8 +117,7 @@ void main() {
});
test('throws on malformed JSON', () {
expect(() => IpcMessage.decode('{this is not json'),
throwsA(isA<FormatException>()));
expect(() => IpcMessage.decode('{this is not json'), throwsA(isA<FormatException>()));
});
});
}
+1 -2
View File
@@ -3,8 +3,7 @@ import 'package:clide/extension/extension.dart';
import 'package:clide/kernel/kernel.dart';
import 'package:flutter_test/flutter_test.dart';
CommandContribution _cmd(String name, Future<IpcResponse> Function() run) =>
CommandContribution(
CommandContribution _cmd(String name, Future<IpcResponse> Function() run) => CommandContribution(
id: name,
command: name,
title: 'cmd $name',
+2 -6
View File
@@ -172,12 +172,8 @@ void main() {
test('emits ExtensionActivated / ExtensionDeactivated events', () async {
final activated = <String>[];
final deactivated = <String>[];
final s1 = f.services.events
.on<ExtensionActivated>()
.listen((e) => activated.add(e.id));
final s2 = f.services.events
.on<ExtensionDeactivated>()
.listen((e) => deactivated.add(e.id));
final s1 = f.services.events.on<ExtensionActivated>().listen((e) => activated.add(e.id));
final s2 = f.services.events.on<ExtensionDeactivated>().listen((e) => deactivated.add(e.id));
f.services.extensions.register(_Ext(id: 'e'));
await f.services.extensions.activateAll();
await Future<void>.delayed(Duration.zero);
+2 -4
View File
@@ -85,8 +85,7 @@ void main() {
);
});
test('falls through to default-locale when current locale is empty',
() async {
test('falls through to default-locale when current locale is empty', () async {
final i = build(catalogs: {
'builtin.x': {
const Locale('en', 'US'): {
@@ -143,8 +142,7 @@ void main() {
expect(i.string('k', namespace: 'b', placeholder: '-'), 'B');
});
test('setLocale refreshes cached namespaces and notifies listeners',
() async {
test('setLocale refreshes cached namespaces and notifies listeners', () async {
final i = build(catalogs: {
'x': {
const Locale('en', 'US'): {
+1 -4
View File
@@ -32,10 +32,7 @@ void main() {
test('honors initialName when present', () {
final c = ThemeController(
bundled: [
_def('a', const Color(0xFF000000)),
_def('b', const Color(0xFF999999))
],
bundled: [_def('a', const Color(0xFF000000)), _def('b', const Color(0xFF999999))],
initialName: 'b',
);
expect(c.currentName, 'b');
+1 -2
View File
@@ -35,8 +35,7 @@ semantic:
mainchrome: red
focus: "#123456"
''');
expect(
def.semanticOverride!.lookup('mainchrome'), const Color(0xFFFF0000));
expect(def.semanticOverride!.lookup('mainchrome'), const Color(0xFFFF0000));
expect(def.semanticOverride!.lookup('focus'), const Color(0xFF123456));
});
+1 -2
View File
@@ -126,8 +126,7 @@ void main() {
'ext.sqlite.table.background': '#ABCDEF',
},
);
expect(tokens.extensionTokens['ext.sqlite.table.background'],
const Color(0xFFABCDEF));
expect(tokens.extensionTokens['ext.sqlite.table.background'], const Color(0xFFABCDEF));
});
});
+4 -8
View File
@@ -24,8 +24,7 @@ void main() {
expect(find.text('Save'), findsOneWidget);
});
testWidgets('emits a Semantics node with button: true + label',
(tester) async {
testWidgets('emits a Semantics node with button: true + label', (tester) async {
await tester.pumpWidget(
harness(f, ClideButton(label: 'Commit', onPressed: () {})),
);
@@ -38,8 +37,7 @@ void main() {
);
});
testWidgets('semanticLabel overrides the visible label for a11y',
(tester) async {
testWidgets('semanticLabel overrides the visible label for a11y', (tester) async {
await tester.pumpWidget(
harness(
f,
@@ -54,8 +52,7 @@ void main() {
expect(semantics.label, 'Save document');
});
testWidgets('semanticHint propagates to the Semantics node',
(tester) async {
testWidgets('semanticHint propagates to the Semantics node', (tester) async {
await tester.pumpWidget(
harness(
f,
@@ -75,8 +72,7 @@ void main() {
harness(f, const ClideButton(label: 'Nope', onPressed: null)),
);
final semantics = tester.getSemantics(find.byType(ClideButton));
expect(
semantics.getSemanticsData().hasAction(SemanticsAction.tap), isFalse);
expect(semantics.getSemanticsData().hasAction(SemanticsAction.tap), isFalse);
});
testWidgets('tap invokes onPressed', (tester) async {
+2 -4
View File
@@ -11,16 +11,14 @@ void main() {
setUp(() async => f = await KernelFixture.create());
tearDown(() async => f.dispose());
testWidgets('renders a 1px horizontal container by default',
(tester) async {
testWidgets('renders a 1px horizontal container by default', (tester) async {
await tester.pumpWidget(harness(f, const ClideDivider()));
final c = tester.widget<Container>(find.byType(Container));
expect(c.constraints?.maxHeight, 1.0);
expect(c.color, f.services.theme.current.surface.dividerColor);
});
testWidgets('vertical axis yields a width-constrained container',
(tester) async {
testWidgets('vertical axis yields a width-constrained container', (tester) async {
await tester.pumpWidget(
harness(f, const ClideDivider(axis: Axis.vertical, thickness: 2)),
);
+1 -2
View File
@@ -11,8 +11,7 @@ void main() {
setUp(() async => f = await KernelFixture.create());
tearDown(() async => f.dispose());
testWidgets('sizes a SizedBox + CustomPaint to the given size',
(tester) async {
testWidgets('sizes a SizedBox + CustomPaint to the given size', (tester) async {
await tester.pumpWidget(
harness(f, const ClideIcon(FolderIcon(), size: 24)),
);
+2 -4
View File
@@ -12,15 +12,13 @@ void main() {
setUp(() async => f = await KernelFixture.create());
tearDown(() async => f.dispose());
testWidgets('default background comes from panelBackground token',
(tester) async {
testWidgets('default background comes from panelBackground token', (tester) async {
await tester.pumpWidget(
harness(f, const ClideSurface(child: Text('x'))),
);
final container = tester.widget<Container>(find.byType(Container));
final decoration = container.decoration as BoxDecoration;
expect(
decoration.color, f.services.theme.current.surface.panelBackground);
expect(decoration.color, f.services.theme.current.surface.panelBackground);
});
testWidgets('explicit color overrides the token default', (tester) async {
+2 -4
View File
@@ -26,13 +26,11 @@ void main() {
testWidgets('muted mode uses globalTextMuted', (tester) async {
await tester.pumpWidget(harness(f, const ClideText('x', muted: true)));
final text = tester.widget<Text>(find.byType(Text));
expect(
text.style!.color, f.services.theme.current.surface.globalTextMuted);
expect(text.style!.color, f.services.theme.current.surface.globalTextMuted);
});
testWidgets('explicit color wins over tokens', (tester) async {
await tester.pumpWidget(
harness(f, const ClideText('x', color: Color(0xFFAABBCC))));
await tester.pumpWidget(harness(f, const ClideText('x', color: Color(0xFFAABBCC))));
final text = tester.widget<Text>(find.byType(Text));
expect(text.style!.color, const Color(0xFFAABBCC));
});