flutter_flutter/packages/flutter/test/widgets/overflow_bar_test.dart
Kate Lovett 9d96df2364
Modernize framework lints (#179089)
WIP

Commits separated as follows:
- Update lints in analysis_options files
- Run `dart fix --apply`
- Clean up leftover analysis issues 
- Run `dart format .` in the right places.

Local analysis and testing passes. Checking CI now.

Part of https://github.com/flutter/flutter/issues/178827
- Adoption of flutter_lints in examples/api coming in a separate change
(cc @loic-sharma)

## Pre-launch Checklist

- [ ] I read the [Contributor Guide] and followed the process outlined
there for submitting PRs.
- [ ] I read the [Tree Hygiene] wiki page, which explains my
responsibilities.
- [ ] I read and followed the [Flutter Style Guide], including [Features
we expect every widget to implement].
- [ ] I signed the [CLA].
- [ ] I listed at least one issue that this PR fixes in the description
above.
- [ ] I updated/added relevant documentation (doc comments with `///`).
- [ ] I added new tests to check the change I am making, or this PR is
[test-exempt].
- [ ] I followed the [breaking change policy] and added [Data Driven
Fixes] where supported.
- [ ] All existing and new tests are passing.

If you need help, consider asking for advice on the #hackers-new channel
on [Discord].

**Note**: The Flutter team is currently trialing the use of [Gemini Code
Assist for
GitHub](https://developers.google.com/gemini-code-assist/docs/review-github-code).
Comments from the `gemini-code-assist` bot should not be taken as
authoritative feedback from the Flutter team. If you find its comments
useful you can update your code accordingly, but if you are unsure or
disagree with the feedback, please feel free to wait for a Flutter team
member's review for guidance on which automated comments should be
addressed.

<!-- Links -->
[Contributor Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#overview
[Tree Hygiene]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md
[test-exempt]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#tests
[Flutter Style Guide]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md
[Features we expect every widget to implement]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Style-guide-for-Flutter-repo.md#features-we-expect-every-widget-to-implement
[CLA]: https://cla.developers.google.com/
[flutter/tests]: https://github.com/flutter/tests
[breaking change policy]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Tree-hygiene.md#handling-breaking-changes
[Discord]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Chat.md
[Data Driven Fixes]:
https://github.com/flutter/flutter/blob/main/docs/contributing/Data-driven-Fixes.md
2025-11-26 01:10:39 +00:00

365 lines
14 KiB
Dart

// 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 {
const 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.children, const <Widget>[]);
});
testWidgets('Empty OverflowBar', (WidgetTester tester) async {
const size = Size(16, 24);
await tester.pumpWidget(
Directionality(
textDirection: TextDirection.ltr,
child: Center(
child: ConstrainedBox(
constraints: BoxConstraints.tight(size),
child: const OverflowBar(),
),
),
),
);
expect(tester.getSize(find.byType(OverflowBar)), size);
await tester.pumpWidget(
const 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: const IntrinsicWidth(
child: OverflowBar(
spacing: 4,
overflowSpacing: 8,
children: <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: const IntrinsicHeight(
child: OverflowBar(
spacing: 4,
overflowSpacing: 8,
children: <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 children = <Widget>[
SizedBox(key: key0, width: 50, height: 50),
SizedBox(key: key1, width: 70, height: 50),
SizedBox(key: key2, width: 80, height: 50),
];
const allAlignments = <MainAxisAlignment>[
MainAxisAlignment.start,
MainAxisAlignment.center,
MainAxisAlignment.end,
MainAxisAlignment.spaceBetween,
MainAxisAlignment.spaceAround,
MainAxisAlignment.spaceEvenly,
];
const 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 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 alignment in allAlignments) {
for (final textDirection in allTextDirections) {
await tester.pumpWidget(buildFrame(alignment, textDirection));
testLayout();
}
}
});
}