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
This commit is contained in:
@@ -0,0 +1,141 @@
|
||||
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));
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user