import "package:flutter/widgets.dart"; import "package:flutter_test/flutter_test.dart"; import "package:garage_ui/garage_ui.dart"; import "support/test_scheme.dart"; Widget _host(Widget child) => Directionality( textDirection: TextDirection.ltr, child: GarageTheme( data: ThemeData(colorScheme: testScheme, density: const Density()), child: Align( alignment: Alignment.topLeft, child: SizedBox(width: 400, child: child), ), ), ); void main() { testWidgets("rules go between entries, not around them", (tester) async { await tester.pumpWidget( _host( SettingsList( children: [ SettingsRow(label: "Full name", field: const Text("Benjamin")), SettingsRow(label: "Nickname", field: const Text("Benji")), SettingsRow(label: "Work", field: const Text("Engineering")), ], ), ), ); // three rows, two rules - a rule above the first or below the last would // draw the box this exists to not be expect(find.byType(Divider), findsNWidgets(2)); }); testWidgets("the rule runs wider than the rows it separates", ( tester, ) async { await tester.pumpWidget( _host( SettingsList( children: [ SettingsRow(label: "Read", field: const Text("Optional")), SettingsRow(label: "Change", field: const Text("Optional")), ], ), ), ); final rule = tester.getRect(find.byType(Divider)); final row = tester.getRect(find.byType(SettingsRow).first); // overshoots at both ends - a rule that stops where its content stops // reads as the edge of a box rather than a divider expect(rule.left, lessThan(row.left)); expect(rule.right, greaterThan(row.right)); }); testWidgets("one entry has no rule at all", (tester) async { await tester.pumpWidget( _host( SettingsList( children: [ SettingsRow(label: "Full name", field: const Text("Benjamin")), ], ), ), ); expect(find.byType(Divider), findsNothing); }); testWidgets("label takes the room the field doesnt", (tester) async { await tester.pumpWidget( _host( SettingsList( children: [ SettingsRow( label: "What best describes your work?", field: const SizedBox(width: 120, height: 20), ), ], ), ), ); final label = tester.getRect(find.text("What best describes your work?")); final field = tester.getRect(find.byType(SizedBox).last); final row = tester.getRect(find.byType(SettingsRow)); // label on the left, field hard against the right edge - not floating in // the middle at the left of its own share of the row expect(label.left, lessThan(field.left)); expect(field.width, 120); expect(field.right, closeTo(row.right, 1)); expect(tester.takeException(), isNull); }); testWidgets("a field with flex children inside it doesnt assert", ( tester, ) async { // the field slot is bounded, not unbounded - a ButtonGroup with `fill`, // or anything else holding an Expanded, needs a width to divide up. await tester.pumpWidget( _host( SettingsList( children: [ SettingsRow( label: "Read", field: ButtonGroup.horizontal( fill: true, children: [ Button( style: const ButtonStyle.outline(), onPressed: () {}, child: const Text("Off"), ), Button( style: const ButtonStyle.outline(), onPressed: () {}, child: const Text("Required"), ), ], ), ), ], ), ), ); expect(tester.takeException(), isNull); }); testWidgets("a long label doesnt push the field off the row", ( tester, ) async { await tester.pumpWidget( _host( SettingsList( children: [ SettingsRow( label: "See your account, passkeys and sign-in activity, and " "everything else besides", field: const SizedBox(width: 120, height: 20), ), ], ), ), ); expect(tester.takeException(), isNull); expect(tester.getSize(find.byType(SizedBox).last).width, 120); }); }