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,149 @@
|
||||
import "package:flutter/widgets.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:garage_ui/garage_ui.dart";
|
||||
|
||||
import "support/test_scheme.dart";
|
||||
|
||||
// A group inside a group. The inner one used to install its own scope over the
|
||||
// outer one's, so the outer's say was simply lost: the bottom row's field kept
|
||||
// the top corners the vertical group had flattened, and painted a top edge the
|
||||
// row above had already drawn.
|
||||
//
|
||||
// Corners are 0-or-1 keep factors, so composing is a product - a corner stays
|
||||
// round only where BOTH groups leave it alone.
|
||||
|
||||
void main() {
|
||||
ButtonGroupCorners cornersOf(WidgetTester tester, Type type) {
|
||||
final ctx = tester.element(find.byType(type));
|
||||
return ButtonGroupScope.maybeOf(ctx)!.corners;
|
||||
}
|
||||
|
||||
ButtonGroupScope scopeOf(WidgetTester tester, Key key) {
|
||||
return ButtonGroupScope.maybeOf(tester.element(find.byKey(key)))!;
|
||||
}
|
||||
|
||||
testWidgets("a horizontal group nested in a vertical one composes", (
|
||||
tester,
|
||||
) async {
|
||||
const top = Key("top");
|
||||
const bottomStart = Key("bottom-start");
|
||||
const bottomEnd = Key("bottom-end");
|
||||
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: GarageTheme(
|
||||
data: ThemeData(colorScheme: testScheme, density: const Density()),
|
||||
child: Center(
|
||||
child: SizedBox(
|
||||
width: 300,
|
||||
child: ButtonGroup.vertical(
|
||||
expands: true,
|
||||
children: [
|
||||
const SizedBox(key: top, height: 20),
|
||||
// no expands on the inner group - it keeps the
|
||||
// IntrinsicHeight that bounds it inside the vertical one.
|
||||
ButtonGroup.horizontal(
|
||||
children: const [
|
||||
Expanded(child: SizedBox(key: bottomStart, height: 20)),
|
||||
SizedBox(key: bottomEnd, height: 20, width: 20),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
// top row: vertical index 0 - both top corners live, bottom flattened
|
||||
// against the row below.
|
||||
final t = scopeOf(tester, top);
|
||||
expect(
|
||||
[t.corners.topStart, t.corners.topEnd],
|
||||
[1, 1],
|
||||
reason: "the top row keeps its top corners",
|
||||
);
|
||||
expect(
|
||||
[t.corners.bottomStart, t.corners.bottomEnd],
|
||||
[0, 0],
|
||||
reason: "the top row's bottom is a seam",
|
||||
);
|
||||
expect(t.hideTop, isFalse);
|
||||
expect(t.hideStart, isFalse);
|
||||
|
||||
// bottom-left: bottom of the vertical group AND start of the horizontal
|
||||
// one, so the ONLY surviving corner is bottom-start.
|
||||
final bs = scopeOf(tester, bottomStart);
|
||||
expect(
|
||||
[
|
||||
bs.corners.topStart,
|
||||
bs.corners.topEnd,
|
||||
bs.corners.bottomStart,
|
||||
bs.corners.bottomEnd,
|
||||
],
|
||||
[0, 0, 1, 0],
|
||||
reason: "only the outer bottom-start corner survives both groups",
|
||||
);
|
||||
expect(
|
||||
bs.hideTop,
|
||||
isTrue,
|
||||
reason: "the row above already painted this edge",
|
||||
);
|
||||
expect(bs.hideStart, isFalse, reason: "its the first in its own row");
|
||||
|
||||
// bottom-right: bottom of the vertical AND end of the horizontal, so only
|
||||
// bottom-end survives - and it gives up BOTH its top and its start edge,
|
||||
// which is the pair a single axis+index could never express.
|
||||
final be = scopeOf(tester, bottomEnd);
|
||||
expect(
|
||||
[
|
||||
be.corners.topStart,
|
||||
be.corners.topEnd,
|
||||
be.corners.bottomStart,
|
||||
be.corners.bottomEnd,
|
||||
],
|
||||
[0, 0, 0, 1],
|
||||
);
|
||||
expect(be.hideTop, isTrue, reason: "the row above painted the top edge");
|
||||
expect(
|
||||
be.hideStart,
|
||||
isTrue,
|
||||
reason: "the field beside it painted the start edge",
|
||||
);
|
||||
});
|
||||
|
||||
testWidgets("an unnested group is unchanged", (tester) async {
|
||||
const a = Key("a");
|
||||
await tester.pumpWidget(
|
||||
Directionality(
|
||||
textDirection: TextDirection.ltr,
|
||||
child: GarageTheme(
|
||||
data: ThemeData(colorScheme: testScheme, density: const Density()),
|
||||
child: Center(
|
||||
child: ButtonGroup.horizontal(
|
||||
children: const [
|
||||
SizedBox(key: a, height: 20, width: 20),
|
||||
SizedBox(height: 20, width: 20),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final s = scopeOf(tester, a);
|
||||
expect(
|
||||
[
|
||||
s.corners.topStart,
|
||||
s.corners.topEnd,
|
||||
s.corners.bottomStart,
|
||||
s.corners.bottomEnd,
|
||||
],
|
||||
[1, 0, 1, 0],
|
||||
);
|
||||
expect(s.hideTop, isFalse);
|
||||
expect(s.hideStart, isFalse);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user