blob: 229f1b1126f4db5f8a6f1d5ca8de964fb4615eb5 [file] [log] [blame]
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('OverflowBar documented defaults', (WidgetTester tester) async {
final OverflowBar bar = OverflowBar();
expect(bar.spacing, 0);
expect(bar.alignment, null);
expect(bar.overflowSpacing, 0);
expect(bar.overflowDirection, VerticalDirection.down);
expect(bar.textDirection, null);
expect(bar.clipBehavior, Clip.none);
expect(bar.children, const <Widget>[]);
});
testWidgets('Empty OverflowBar', (WidgetTester tester) async {
const Size size = Size(16, 24);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints.tight(size),
child: OverflowBar(),
),
),
),
);
expect(tester.getSize(find.byType(OverflowBar)), size);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: OverflowBar(),
),
),
);
expect(tester.getSize(find.byType(OverflowBar)), Size.zero);
});
testWidgets('OverflowBar horizontal layout', (WidgetTester tester) async {
final Key child1Key = UniqueKey();
final Key child2Key = UniqueKey();
final Key child3Key = UniqueKey();
Widget buildFrame({ required double spacing, required TextDirection textDirection }) {
return Directionality(
textDirection: textDirection,
child: Align(
alignment: Alignment.topLeft,
child: OverflowBar(
spacing: spacing,
children: <Widget>[
SizedBox(width: 48, height: 48, key: child1Key),
SizedBox(width: 64, height: 64, key: child2Key),
SizedBox(width: 32, height: 32, key: child3Key),
],
),
),
);
}
// Children are vertically centered, start at x=0
await tester.pumpWidget(buildFrame(spacing: 0, textDirection: TextDirection.ltr));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(0, 8, 48, 56));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(48, 0, 112, 64));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(112, 16, 144, 48));
// Children are vertically centered, start at x=0
await tester.pumpWidget(buildFrame(spacing: 10, textDirection: TextDirection.ltr));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(0, 8, 48, 56));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(10.0 + 48, 0, 10.0 + 112, 64));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(10.0 + 112 + 10.0, 16, 10.0 + 10.0 + 144, 48));
// Children appear in reverse order for RTL
await tester.pumpWidget(buildFrame(spacing: 0, textDirection: TextDirection.rtl));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(0, 16, 32, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(32, 0, 96, 64));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(96, 8, 144, 56));
// Children appear in reverse order for RTL
await tester.pumpWidget(buildFrame(spacing: 10, textDirection: TextDirection.rtl));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(0, 16, 32, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(10.0 + 32, 0, 10.0 + 96, 64));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(10.0 + 96 + 10.0, 8, 10.0 + 10.0 + 144, 56));
});
testWidgets('OverflowBar vertical layout', (WidgetTester tester) async {
final Key child1Key = UniqueKey();
final Key child2Key = UniqueKey();
final Key child3Key = UniqueKey();
Widget buildFrame({
double overflowSpacing = 0,
VerticalDirection overflowDirection = VerticalDirection.down,
OverflowBarAlignment overflowAlignment = OverflowBarAlignment.start,
TextDirection textDirection = TextDirection.ltr,
}) {
return Directionality(
textDirection: textDirection,
child: Align(
alignment: Alignment.topLeft,
child: ConstrainedBox(
constraints: BoxConstraints.loose(const Size(100, double.infinity)),
child: OverflowBar(
overflowSpacing: overflowSpacing,
overflowAlignment: overflowAlignment,
overflowDirection: overflowDirection,
children: <Widget>[
SizedBox(width: 48, height: 48, key: child1Key),
SizedBox(width: 64, height: 64, key: child2Key),
SizedBox(width: 32, height: 32, key: child3Key),
],
),
),
),
);
}
// Children are left aligned
await tester.pumpWidget(buildFrame());
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(0, 0, 48, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(0, 48, 64, 112));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(0, 112, 32, 144));
// Children are left aligned
await tester.pumpWidget(buildFrame(overflowAlignment: OverflowBarAlignment.end, textDirection: TextDirection.rtl));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(0, 0, 48, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(0, 48, 64, 112));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(0, 112, 32, 144));
// Spaced children are left aligned
await tester.pumpWidget(buildFrame(overflowSpacing: 10));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(0, 0, 48, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(0, 10.0 + 48, 64, 10.0 + 112));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(0, 10.0 + 112 + 10.0, 32, 10.0 + 10.0 + 144));
// Left-aligned children appear in reverse order for VerticalDirection.up
await tester.pumpWidget(buildFrame(overflowDirection: VerticalDirection.up));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(0, 0, 32, 32));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(0, 32, 64, 96));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(0, 96, 48, 144));
// Left-aligned spaced children appear in reverse order for VerticalDirection.up
await tester.pumpWidget(buildFrame(overflowSpacing: 10, overflowDirection: VerticalDirection.up));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(0, 0, 32, 32));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(0, 10.0 + 32, 64, 10.0 + 96));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(0, 10.0 + 10.0 + 96, 48, 10.0 + 10.0 + 144));
// Children are right aligned
await tester.pumpWidget(buildFrame(overflowAlignment: OverflowBarAlignment.end));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(100.0 - 48, 0, 100, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(100.0 - 64, 48, 100, 112));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(100.0 - 32, 112, 100, 144));
// Children are right aligned
await tester.pumpWidget(buildFrame(textDirection: TextDirection.rtl));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(100.0 - 48, 0, 100, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(100.0 - 64, 48, 100, 112));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(100.0 - 32, 112, 100, 144));
// Children are centered
await tester.pumpWidget(buildFrame(overflowAlignment: OverflowBarAlignment.center));
expect(tester.getRect(find.byKey(child1Key)), const Rect.fromLTRB(100.0/2.0 - 48/2, 0, 100.0/2.0 + 48/2, 48));
expect(tester.getRect(find.byKey(child2Key)), const Rect.fromLTRB(100.0/2.0 - 64/2, 48, 100.0/2.0 + 64/2, 112));
expect(tester.getRect(find.byKey(child3Key)), const Rect.fromLTRB(100.0/2.0 - 32/2, 112, 100.0/2.0 + 32/2, 144));
});
testWidgets('OverflowBar intrinsic width', (WidgetTester tester) async {
Widget buildFrame({ required double width }) {
return Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Container(
width: width,
alignment: Alignment.topLeft,
child: IntrinsicWidth(
child: OverflowBar(
spacing: 4,
overflowSpacing: 8,
children: const <Widget>[
SizedBox(width: 48, height: 50),
SizedBox(width: 64, height: 25),
SizedBox(width: 32, height: 75),
],
),
),
),
),
);
}
await tester.pumpWidget(buildFrame(width: 800));
expect(tester.getSize(find.byType(OverflowBar)).width, 152); // 152 = 48 + 4 + 64 + 4 + 32
await tester.pumpWidget(buildFrame(width: 150));
expect(tester.getSize(find.byType(OverflowBar)).width, 150);
});
testWidgets('OverflowBar intrinsic height', (WidgetTester tester) async {
Widget buildFrame({ required double maxWidth }) {
return Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: Container(
width: maxWidth,
alignment: Alignment.topLeft,
child: IntrinsicHeight(
child: OverflowBar(
spacing: 4,
overflowSpacing: 8,
children: const <Widget>[
SizedBox(width: 48, height: 50),
SizedBox(width: 64, height: 25),
SizedBox(width: 32, height: 75),
],
),
),
),
),
);
}
await tester.pumpWidget(buildFrame(maxWidth: 800));
expect(tester.getSize(find.byType(OverflowBar)).height, 75); // 75 = max(50, 25, 75)
await tester.pumpWidget(buildFrame(maxWidth: 150));
expect(tester.getSize(find.byType(OverflowBar)).height, 166); // 166 = 50 + 8 + 25 + 8 + 75
});
testWidgets('OverflowBar is wider that its intrinsic width', (WidgetTester tester) async {
final Key key0 = UniqueKey();
final Key key1 = UniqueKey();
final Key key2 = UniqueKey();
Widget buildFrame(TextDirection textDirection) {
return Directionality(
textDirection: textDirection,
child: SizedBox(
width: 800,
// intrinsic width = 50 + 10 + 60 + 10 + 70 = 200
child: OverflowBar(
spacing: 10,
children: <Widget>[
SizedBox(key: key0, width: 50, height: 50),
SizedBox(key: key1, width: 60, height: 50),
SizedBox(key: key2, width: 70, height: 50),
],
),
),
);
}
await tester.pumpWidget(buildFrame(TextDirection.ltr));
expect(tester.getSize(find.byType(OverflowBar)), const Size(800.0, 600.0));
expect(tester.getTopLeft(find.byKey(key0)).dx, 0);
expect(tester.getTopLeft(find.byKey(key1)).dx, 60);
expect(tester.getTopLeft(find.byKey(key2)).dx, 130);
await tester.pumpWidget(buildFrame(TextDirection.rtl));
expect(tester.getSize(find.byType(OverflowBar)), const Size(800.0, 600.0));
expect(tester.getTopLeft(find.byKey(key0)).dx, 750);
expect(tester.getTopLeft(find.byKey(key1)).dx, 680);
expect(tester.getTopLeft(find.byKey(key2)).dx, 600);
});
testWidgets('OverflowBar with alignment should match Row with mainAxisAlignment', (WidgetTester tester) async {
final Key key0 = UniqueKey();
final Key key1 = UniqueKey();
final Key key2 = UniqueKey();
// This list of children appears in a Row and an OverflowBar, so each
// find.byKey() for key0, key1, key2 returns two widgets.
final List<Widget> children = <Widget>[
SizedBox(key: key0, width: 50, height: 50),
SizedBox(key: key1, width: 70, height: 50),
SizedBox(key: key2, width: 80, height: 50),
];
const List<MainAxisAlignment> allAlignments = <MainAxisAlignment>[
MainAxisAlignment.start,
MainAxisAlignment.center,
MainAxisAlignment.end,
MainAxisAlignment.spaceBetween,
MainAxisAlignment.spaceAround,
MainAxisAlignment.spaceEvenly,
];
const List<TextDirection> allTextDirections = <TextDirection>[
TextDirection.ltr,
TextDirection.rtl,
];
Widget buildFrame(MainAxisAlignment alignment, TextDirection textDirection) {
return Directionality(
textDirection: textDirection,
child: Column(
children: <Widget>[
OverflowBar(
alignment: alignment,
children: children,
),
Row(
mainAxisAlignment: alignment,
children: children,
),
],
),
);
}
// Each key from key0, key1, key2 maps to one child in the OverflowBar
// and a matching child in the Row. We expect the children to be the
// same size and for their left and right edges to align.
void testLayout() {
expect(tester.getSize(find.byType(OverflowBar)), const Size(800, 50));
for (final Key key in <Key>[key0, key1, key2]) {
final Finder matchingChildren = find.byKey(key);
expect(matchingChildren.evaluate().length, 2);
final Rect rect0 = tester.getRect(matchingChildren.first);
final Rect rect1 = tester.getRect(matchingChildren.last);
expect(rect0.size, rect1.size);
expect(rect0.left, rect1.left);
expect(rect0.right, rect1.right);
}
}
for (final MainAxisAlignment alignment in allAlignments) {
for (final TextDirection textDirection in allTextDirections) {
await tester.pumpWidget(buildFrame(alignment, textDirection));
testLayout();
}
}
});
}