Files
Garage-SDKs/garage_ui/test/select_popup_spacing_test.dart
T
ImBenjiandClaude Opus 5.5 b269201919 The Garage SDKs, in the open
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
2026-09-23 18:49:21 +01:00

142 lines
4.7 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 rows sat flush against each other and the surface took the same radius
// they do, so the corner gap didnt match the gap down the sides.
const _density = Density();
Widget _host() => Directionality(
textDirection: TextDirection.ltr,
child: GarageTheme(
data: ThemeData(colorScheme: testScheme, density: _density),
child: Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 600,
height: 400,
child: Overlay(
initialEntries: [
OverlayEntry(
builder: (_) => Align(
alignment: Alignment.topLeft,
child: SizedBox(
width: 160,
child: Select<String>(
value: "normal",
itemBuilder: (ctx, v) => const Text("Normal"),
onChanged: (_) {},
popup: const SelectPopup(
items: SelectItemList(
children: [
SelectItemButton<String>(
value: "normal",
child: Text("Normal"),
),
SelectItemButton<String>(
value: "comfortable",
child: Text("Comfortable"),
),
],
),
),
),
),
),
),
],
),
),
),
),
);
Rect _rowOf(WidgetTester tester, String label) => tester.getRect(
find.ancestor(
of: find.text(label),
matching: find.byType(SelectItemButton<String>),
),
);
void main() {
testWidgets("theres air between one row and the next", (tester) async {
await tester.pumpWidget(_host());
await tester.tap(find.byType(Select<String>));
await tester.pumpAndSettle();
final first = _rowOf(tester, "Normal");
final second = _rowOf(tester, "Comfortable");
final gap = second.top - first.bottom;
expect(gap, greaterThan(0), reason: "rows were flush");
expect(gap, closeTo(_density.gapXxs, 0.5));
});
testWidgets("the surface rounds around the rows, less a couple of px", (
tester,
) async {
await tester.pumpWidget(_host());
await tester.tap(find.byType(Select<String>));
await tester.pumpAndSettle();
final theme = ThemeData(colorScheme: testScheme, density: _density);
final inset = theme.density.containerGap * 0.5;
final border = theme.density.controlBorderWidth;
// the surface is the one decorated box wrapping the rows
final surface = tester.widgetList<Container>(find.byType(Container)).where((
c,
) {
final d = c.decoration;
return d is BoxDecoration && d.borderRadius != null && d.border != null;
});
expect(surface, isNotEmpty);
final radii = surface
.map((c) => ((c.decoration as BoxDecoration).borderRadius
as BorderRadius).topLeft.x)
.toList();
final expected = theme.radiusMd + inset + border - 2;
expect(
radii.any((r) => (r - expected).abs() < 0.01),
isTrue,
reason: "wanted a surface at $expected, saw $radii",
);
});
testWidgets("it hangs off the trigger by gapSm, not the container gap", (
tester,
) async {
await tester.pumpWidget(_host());
final trigger = tester.getRect(find.byType(Select<String>));
await tester.tap(find.byType(Select<String>));
await tester.pumpAndSettle();
final scroller = tester.getRect(find.byType(SingleChildScrollView).first);
// the scroller starts just inside the surface's border, so back that off
// to get the surface's own top edge
final border = _density.controlBorderWidth;
final toSurface = scroller.top - border - trigger.bottom;
expect(toSurface, closeTo(_density.gapSm, 0.5));
expect(toSurface, lessThan(_density.containerGap));
});
testWidgets("the rows still sit inside the padding", (tester) async {
await tester.pumpWidget(_host());
await tester.tap(find.byType(Select<String>));
await tester.pumpAndSettle();
final row = _rowOf(tester, "Normal");
final theme = ThemeData(colorScheme: testScheme, density: _density);
final inset = theme.density.containerGap * 0.5;
// the scroller holds the padding, so the row starts one inset inside it
final scroller = tester.getRect(find.byType(SingleChildScrollView).first);
expect(row.left - scroller.left, closeTo(inset, 0.5));
expect(row.top - scroller.top, closeTo(inset, 0.5));
});
}