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
142 lines
4.7 KiB
Dart
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));
|
|
});
|
|
}
|