@@ -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();
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
});
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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'},
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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')),
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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'});
|
||||
});
|
||||
|
||||
@@ -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'],
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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>()));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -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',
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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'): {
|
||||
|
||||
@@ -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');
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)),
|
||||
);
|
||||
|
||||
@@ -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)),
|
||||
);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user