garage_auth, garage_entitlements, garage_iap and garage_ui, moved out of Garage-Services and Metro-Map-Maker into one public repo. MIT, one readme, docs under docs/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013F4NWNvYcdeSgqbWMT1VQ7
132 lines
3.6 KiB
Dart
132 lines
3.6 KiB
Dart
import "package:flutter/widgets.dart";
|
|
import "package:flutter_test/flutter_test.dart";
|
|
import "package:garage_ui/garage_ui.dart";
|
|
|
|
import "support/test_scheme.dart";
|
|
|
|
// The actions band. Before this existed a Save button had to go in `rows`,
|
|
// where it read as one more property that happened to be a button - no
|
|
// separator, no tone, and lined up against the property split like a value.
|
|
|
|
Widget _host(Widget child, {Density density = const Density()}) =>
|
|
Directionality(
|
|
textDirection: TextDirection.ltr,
|
|
child: GarageTheme(
|
|
data: ThemeData(colorScheme: testScheme, density: density),
|
|
child: Center(child: SizedBox(width: 420, child: child)),
|
|
),
|
|
);
|
|
|
|
Widget _section({List<Widget> actions = const [], bool collapsed = false}) =>
|
|
PropertiesSection(
|
|
title: "Profile",
|
|
scheme: testScheme,
|
|
collapsed: collapsed,
|
|
onToggle: () {},
|
|
actions: actions,
|
|
rows: [
|
|
PropertyRow(
|
|
label: "Username",
|
|
scheme: testScheme,
|
|
child: const SizedBox(),
|
|
),
|
|
],
|
|
);
|
|
|
|
Color? _bandColour(WidgetTester tester) {
|
|
final containers = find
|
|
.ancestor(
|
|
of: find.text("Save"),
|
|
matching: find.byType(Container),
|
|
)
|
|
.evaluate()
|
|
.map((e) => e.widget as Container)
|
|
.where((c) => c.color != null);
|
|
return containers.isEmpty ? null : containers.first.color;
|
|
}
|
|
|
|
void main() {
|
|
testWidgets("no actions means no band and no separator", (tester) async {
|
|
await tester.pumpWidget(_host(_section()));
|
|
expect(find.byType(Divider), findsNothing);
|
|
});
|
|
|
|
testWidgets("actions get a separator and the muted band", (tester) async {
|
|
await tester.pumpWidget(
|
|
_host(
|
|
_section(
|
|
actions: [
|
|
Button(
|
|
style: const ButtonStyle.primary(),
|
|
onPressed: () {},
|
|
child: const Text("Save"),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(find.byType(Divider), findsOneWidget);
|
|
// toned OFF the section, not the same fill
|
|
expect(_bandColour(tester), testScheme.muted);
|
|
expect(_bandColour(tester),
|
|
isNot(testScheme.card));
|
|
});
|
|
|
|
testWidgets("the band spans the section, not just its buttons", (
|
|
tester,
|
|
) async {
|
|
await tester.pumpWidget(
|
|
_host(
|
|
_section(
|
|
actions: [
|
|
Button(
|
|
style: const ButtonStyle.primary(),
|
|
onPressed: () {},
|
|
child: const Text("Save"),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
|
|
const density = Density();
|
|
final content = tester.getRect(
|
|
find
|
|
.ancestor(of: find.text("Save"), matching: find.byType(Row))
|
|
.first,
|
|
);
|
|
final divider = tester.getRect(find.byType(Divider));
|
|
|
|
// the BAND spans the section edge to edge - its content is inset by the
|
|
// same buttonPaddingX a row uses, so the buttons line up with the controls
|
|
// above them rather than sitting on the section's edge.
|
|
expect(content.width, divider.width - density.buttonPaddingX * 2);
|
|
// and the whole thing sits under the rows
|
|
expect(
|
|
content.top,
|
|
greaterThan(tester.getRect(find.text("Username")).bottom),
|
|
);
|
|
});
|
|
|
|
testWidgets("actions collapse with the rows", (tester) async {
|
|
await tester.pumpWidget(
|
|
_host(
|
|
_section(
|
|
collapsed: true,
|
|
actions: [
|
|
Button(
|
|
style: const ButtonStyle.primary(),
|
|
onPressed: () {},
|
|
child: const Text("Save"),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
|
|
expect(find.text("Save"), findsNothing);
|
|
expect(find.byType(Divider), findsNothing);
|
|
});
|
|
}
|