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

636 lines
24 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/material.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
testWidgets('ButtonBar default control smoketest', (WidgetTester tester) async {
await tester.pumpWidget(
const Directionality(textDirection: TextDirection.ltr, child: ButtonBar()),
);
});
group('alignment', () {
testWidgets('default alignment is MainAxisAlignment.end', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(home: ButtonBar(children: <Widget>[SizedBox(width: 10.0, height: 10.0)])),
);
final Finder child = find.byType(SizedBox);
// Should be positioned to the right of the bar,
expect(tester.getRect(child).left, 782.0); // bar width - default padding - 10
expect(tester.getRect(child).right, 792.0); // bar width - default padding
});
testWidgets('ButtonBarTheme.alignment overrides default', (WidgetTester tester) async {
await tester.pumpWidget(
const MaterialApp(
home: ButtonBarTheme(
data: ButtonBarThemeData(alignment: MainAxisAlignment.center),
child: ButtonBar(children: <Widget>[SizedBox(width: 10.0, height: 10.0)]),
),
),
);
final Finder child = find.byType(SizedBox);
// Should be positioned in the center
expect(tester.getRect(child).left, 395.0); // (bar width - padding) / 2 - 10 / 2
expect(tester.getRect(child).right, 405.0); // (bar width - padding) / 2 - 10 / 2 + 10
});
testWidgets('ButtonBar.alignment overrides ButtonBarTheme.alignment and default', (
WidgetTester tester,
) async {
await tester.pumpWidget(
const MaterialApp(
home: ButtonBarTheme(
data: ButtonBarThemeData(alignment: MainAxisAlignment.center),
child: ButtonBar(
alignment: MainAxisAlignment.start,
children: <Widget>[SizedBox(width: 10.0, height: 10.0)],
),
),
),
);
final Finder child = find.byType(SizedBox);
// Should be positioned on the left
expect(tester.getRect(child).left, 8.0); // padding
expect(tester.getRect(child).right, 18.0); // padding + 10
});
});
group('mainAxisSize', () {
testWidgets('Default mainAxisSize is MainAxisSize.max', (WidgetTester tester) async {
const buttonBarKey = Key('row');
const child0Key = Key('child0');
const child1Key = Key('child1');
const child2Key = Key('child2');
await tester.pumpWidget(
const MaterialApp(
home: Center(
child: ButtonBar(
key: buttonBarKey,
// buttonPadding set to zero to simplify test calculations.
buttonPadding: EdgeInsets.zero,
children: <Widget>[
SizedBox(key: child0Key, width: 100.0, height: 100.0),
SizedBox(key: child1Key, width: 100.0, height: 100.0),
SizedBox(key: child2Key, width: 100.0, height: 100.0),
],
),
),
),
);
// ButtonBar should take up all the space it is provided by its parent.
final Rect buttonBarRect = tester.getRect(find.byKey(buttonBarKey));
expect(buttonBarRect.size.width, equals(800.0));
expect(buttonBarRect.size.height, equals(100.0));
// The children of [ButtonBar] are aligned by [MainAxisAlignment.end] by
// default.
Rect childRect;
childRect = tester.getRect(find.byKey(child0Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
expect(childRect.right, 800.0 - 200.0);
childRect = tester.getRect(find.byKey(child1Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
expect(childRect.right, 800.0 - 100.0);
childRect = tester.getRect(find.byKey(child2Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
expect(childRect.right, 800.0);
});
testWidgets('ButtonBarTheme.mainAxisSize overrides default', (WidgetTester tester) async {
const buttonBarKey = Key('row');
const child0Key = Key('child0');
const child1Key = Key('child1');
const child2Key = Key('child2');
await tester.pumpWidget(
const MaterialApp(
home: ButtonBarTheme(
data: ButtonBarThemeData(mainAxisSize: MainAxisSize.min),
child: Center(
child: ButtonBar(
key: buttonBarKey,
// buttonPadding set to zero to simplify test calculations.
buttonPadding: EdgeInsets.zero,
children: <Widget>[
SizedBox(key: child0Key, width: 100.0, height: 100.0),
SizedBox(key: child1Key, width: 100.0, height: 100.0),
SizedBox(key: child2Key, width: 100.0, height: 100.0),
],
),
),
),
),
);
// ButtonBar should take up minimum space it requires.
final Rect buttonBarRect = tester.getRect(find.byKey(buttonBarKey));
expect(buttonBarRect.size.width, equals(300.0));
expect(buttonBarRect.size.height, equals(100.0));
Rect childRect;
childRect = tester.getRect(find.byKey(child0Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
// Should be a center aligned because of [Center] widget.
// First child is on the left side of the button bar.
expect(childRect.left, (800.0 - buttonBarRect.width) / 2.0);
childRect = tester.getRect(find.byKey(child1Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
// Should be a center aligned because of [Center] widget.
// Second child is on the center the button bar.
expect(childRect.left, ((800.0 - buttonBarRect.width) / 2.0) + 100.0);
childRect = tester.getRect(find.byKey(child2Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
// Should be a center aligned because of [Center] widget.
// Third child is on the right side of the button bar.
expect(childRect.left, ((800.0 - buttonBarRect.width) / 2.0) + 200.0);
});
testWidgets('ButtonBar.mainAxisSize overrides ButtonBarTheme.mainAxisSize and default', (
WidgetTester tester,
) async {
const buttonBarKey = Key('row');
const child0Key = Key('child0');
const child1Key = Key('child1');
const child2Key = Key('child2');
await tester.pumpWidget(
const MaterialApp(
home: ButtonBarTheme(
data: ButtonBarThemeData(mainAxisSize: MainAxisSize.min),
child: Center(
child: ButtonBar(
key: buttonBarKey,
// buttonPadding set to zero to simplify test calculations.
buttonPadding: EdgeInsets.zero,
mainAxisSize: MainAxisSize.max,
children: <Widget>[
SizedBox(key: child0Key, width: 100.0, height: 100.0),
SizedBox(key: child1Key, width: 100.0, height: 100.0),
SizedBox(key: child2Key, width: 100.0, height: 100.0),
],
),
),
),
),
);
// ButtonBar should take up all the space it is provided by its parent.
final Rect buttonBarRect = tester.getRect(find.byKey(buttonBarKey));
expect(buttonBarRect.size.width, equals(800.0));
expect(buttonBarRect.size.height, equals(100.0));
// The children of [ButtonBar] are aligned by [MainAxisAlignment.end] by
// default.
Rect childRect;
childRect = tester.getRect(find.byKey(child0Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
expect(childRect.right, 800.0 - 200.0);
childRect = tester.getRect(find.byKey(child1Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
expect(childRect.right, 800.0 - 100.0);
childRect = tester.getRect(find.byKey(child2Key));
expect(childRect.size.width, equals(100.0));
expect(childRect.size.height, equals(100.0));
expect(childRect.right, 800.0);
});
});
group('button properties override ButtonTheme', () {
testWidgets('default button properties override ButtonTheme properties', (
WidgetTester tester,
) async {
late BuildContext capturedContext;
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
children: <Widget>[
Builder(
builder: (BuildContext context) {
capturedContext = context;
return Container();
},
),
],
),
),
);
final ButtonThemeData buttonTheme = ButtonTheme.of(capturedContext);
expect(buttonTheme.textTheme, equals(ButtonTextTheme.primary));
expect(buttonTheme.minWidth, equals(64.0));
expect(buttonTheme.height, equals(36.0));
expect(buttonTheme.padding, equals(const EdgeInsets.symmetric(horizontal: 8.0)));
expect(buttonTheme.alignedDropdown, equals(false));
expect(buttonTheme.layoutBehavior, equals(ButtonBarLayoutBehavior.padded));
});
testWidgets('ButtonBarTheme button properties override defaults and ButtonTheme properties', (
WidgetTester tester,
) async {
late BuildContext capturedContext;
await tester.pumpWidget(
MaterialApp(
home: ButtonBarTheme(
data: const ButtonBarThemeData(
buttonTextTheme: ButtonTextTheme.primary,
buttonMinWidth: 42.0,
buttonHeight: 84.0,
buttonPadding: EdgeInsets.fromLTRB(10, 20, 30, 40),
buttonAlignedDropdown: true,
layoutBehavior: ButtonBarLayoutBehavior.constrained,
),
child: ButtonBar(
children: <Widget>[
Builder(
builder: (BuildContext context) {
capturedContext = context;
return Container();
},
),
],
),
),
),
);
final ButtonThemeData buttonTheme = ButtonTheme.of(capturedContext);
expect(buttonTheme.textTheme, equals(ButtonTextTheme.primary));
expect(buttonTheme.minWidth, equals(42.0));
expect(buttonTheme.height, equals(84.0));
expect(buttonTheme.padding, equals(const EdgeInsets.fromLTRB(10, 20, 30, 40)));
expect(buttonTheme.alignedDropdown, equals(true));
expect(buttonTheme.layoutBehavior, equals(ButtonBarLayoutBehavior.constrained));
});
testWidgets(
'ButtonBar button properties override ButtonBarTheme, defaults and ButtonTheme properties',
(WidgetTester tester) async {
late BuildContext capturedContext;
await tester.pumpWidget(
MaterialApp(
home: ButtonBarTheme(
data: const ButtonBarThemeData(
buttonTextTheme: ButtonTextTheme.accent,
buttonMinWidth: 4242.0,
buttonHeight: 8484.0,
buttonPadding: EdgeInsets.fromLTRB(50, 60, 70, 80),
buttonAlignedDropdown: false,
layoutBehavior: ButtonBarLayoutBehavior.padded,
),
child: ButtonBar(
buttonTextTheme: ButtonTextTheme.primary,
buttonMinWidth: 42.0,
buttonHeight: 84.0,
buttonPadding: const EdgeInsets.fromLTRB(10, 20, 30, 40),
buttonAlignedDropdown: true,
layoutBehavior: ButtonBarLayoutBehavior.constrained,
children: <Widget>[
Builder(
builder: (BuildContext context) {
capturedContext = context;
return Container();
},
),
],
),
),
),
);
final ButtonThemeData buttonTheme = ButtonTheme.of(capturedContext);
expect(buttonTheme.textTheme, equals(ButtonTextTheme.primary));
expect(buttonTheme.minWidth, equals(42.0));
expect(buttonTheme.height, equals(84.0));
expect(buttonTheme.padding, equals(const EdgeInsets.fromLTRB(10, 20, 30, 40)));
expect(buttonTheme.alignedDropdown, equals(true));
expect(buttonTheme.layoutBehavior, equals(ButtonBarLayoutBehavior.constrained));
},
);
});
group('layoutBehavior', () {
testWidgets('ButtonBar has a min height of 52 when using ButtonBarLayoutBehavior.constrained', (
WidgetTester tester,
) async {
await tester.pumpWidget(
const SingleChildScrollView(
child: ListBody(
children: <Widget>[
Directionality(
textDirection: TextDirection.ltr,
child: ButtonBar(
layoutBehavior: ButtonBarLayoutBehavior.constrained,
children: <Widget>[SizedBox(width: 10.0, height: 10.0)],
),
),
],
),
),
);
final Finder buttonBar = find.byType(ButtonBar);
expect(tester.getBottomRight(buttonBar).dy - tester.getTopRight(buttonBar).dy, 52.0);
});
testWidgets('ButtonBar has padding applied when using ButtonBarLayoutBehavior.padded', (
WidgetTester tester,
) async {
await tester.pumpWidget(
const SingleChildScrollView(
child: ListBody(
children: <Widget>[
Directionality(
textDirection: TextDirection.ltr,
child: ButtonBar(
layoutBehavior: ButtonBarLayoutBehavior.padded,
children: <Widget>[SizedBox(width: 10.0, height: 10.0)],
),
),
],
),
),
);
final Finder buttonBar = find.byType(ButtonBar);
expect(tester.getBottomRight(buttonBar).dy - tester.getTopRight(buttonBar).dy, 26.0);
});
});
group("ButtonBar's children wrap when they overflow horizontally", () {
testWidgets("ButtonBar's children wrap when buttons overflow", (WidgetTester tester) async {
final Key keyOne = UniqueKey();
final Key keyTwo = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 800.0),
SizedBox(key: keyTwo, height: 50.0, width: 800.0),
],
),
),
);
// Second [Container] should wrap around to the next column since
// they take up max width constraint.
final Rect containerOneRect = tester.getRect(find.byKey(keyOne));
final Rect containerTwoRect = tester.getRect(find.byKey(keyTwo));
expect(containerOneRect.bottom, containerTwoRect.top);
expect(containerOneRect.left, containerTwoRect.left);
});
testWidgets("ButtonBar's children overflow defaults - MainAxisAlignment.end", (
WidgetTester tester,
) async {
final Key keyOne = UniqueKey();
final Key keyTwo = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
// Set padding to zero to align buttons with edge of button bar.
buttonPadding: EdgeInsets.zero,
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 500.0),
SizedBox(key: keyTwo, height: 50.0, width: 500.0),
],
),
),
);
final Rect buttonBarRect = tester.getRect(find.byType(ButtonBar));
final Rect containerOneRect = tester.getRect(find.byKey(keyOne));
final Rect containerTwoRect = tester.getRect(find.byKey(keyTwo));
// Second [Container] should wrap around to the next row.
expect(containerOneRect.bottom, containerTwoRect.top);
// Second [Container] should align to the start of the ButtonBar.
expect(containerOneRect.right, containerTwoRect.right);
expect(containerOneRect.right, buttonBarRect.right);
});
testWidgets("ButtonBar's children overflow - MainAxisAlignment.start", (
WidgetTester tester,
) async {
final Key keyOne = UniqueKey();
final Key keyTwo = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
alignment: MainAxisAlignment.start,
// Set padding to zero to align buttons with edge of button bar.
buttonPadding: EdgeInsets.zero,
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 500.0),
SizedBox(key: keyTwo, height: 50.0, width: 500.0),
],
),
),
);
final Rect buttonBarRect = tester.getRect(find.byType(ButtonBar));
final Rect containerOneRect = tester.getRect(find.byKey(keyOne));
final Rect containerTwoRect = tester.getRect(find.byKey(keyTwo));
// Second [Container] should wrap around to the next row.
expect(containerOneRect.bottom, containerTwoRect.top);
// [Container]s should align to the end of the ButtonBar.
expect(containerOneRect.left, containerTwoRect.left);
expect(containerOneRect.left, buttonBarRect.left);
});
testWidgets("ButtonBar's children overflow - MainAxisAlignment.center", (
WidgetTester tester,
) async {
final Key keyOne = UniqueKey();
final Key keyTwo = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
alignment: MainAxisAlignment.center,
// Set padding to zero to align buttons with edge of button bar.
buttonPadding: EdgeInsets.zero,
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 500.0),
SizedBox(key: keyTwo, height: 50.0, width: 500.0),
],
),
),
);
final Rect buttonBarRect = tester.getRect(find.byType(ButtonBar));
final Rect containerOneRect = tester.getRect(find.byKey(keyOne));
final Rect containerTwoRect = tester.getRect(find.byKey(keyTwo));
// Second [Container] should wrap around to the next row.
expect(containerOneRect.bottom, containerTwoRect.top);
// [Container]s should center themselves in the ButtonBar.
expect(containerOneRect.center.dx, containerTwoRect.center.dx);
expect(containerOneRect.center.dx, buttonBarRect.center.dx);
});
testWidgets("ButtonBar's children default to MainAxisAlignment.start for horizontal "
'alignment when overflowing in spaceBetween, spaceAround and spaceEvenly '
'cases when overflowing.', (WidgetTester tester) async {
final Key keyOne = UniqueKey();
final Key keyTwo = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
alignment: MainAxisAlignment.spaceEvenly,
// Set padding to zero to align buttons with edge of button bar.
buttonPadding: EdgeInsets.zero,
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 500.0),
SizedBox(key: keyTwo, height: 50.0, width: 500.0),
],
),
),
);
Rect buttonBarRect = tester.getRect(find.byType(ButtonBar));
Rect containerOneRect = tester.getRect(find.byKey(keyOne));
Rect containerTwoRect = tester.getRect(find.byKey(keyTwo));
// Second [Container] should wrap around to the next row.
expect(containerOneRect.bottom, containerTwoRect.top);
// Should align horizontally to the start of the button bar.
expect(containerOneRect.left, containerTwoRect.left);
expect(containerOneRect.left, buttonBarRect.left);
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
alignment: MainAxisAlignment.spaceAround,
// Set padding to zero to align buttons with edge of button bar.
buttonPadding: EdgeInsets.zero,
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 500.0),
SizedBox(key: keyTwo, height: 50.0, width: 500.0),
],
),
),
);
buttonBarRect = tester.getRect(find.byType(ButtonBar));
containerOneRect = tester.getRect(find.byKey(keyOne));
containerTwoRect = tester.getRect(find.byKey(keyTwo));
// Second [Container] should wrap around to the next row.
expect(containerOneRect.bottom, containerTwoRect.top);
// Should align horizontally to the start of the button bar.
expect(containerOneRect.left, containerTwoRect.left);
expect(containerOneRect.left, buttonBarRect.left);
});
testWidgets("ButtonBar's children respects verticalDirection when overflowing", (
WidgetTester tester,
) async {
final Key keyOne = UniqueKey();
final Key keyTwo = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
alignment: MainAxisAlignment.center,
// Set padding to zero to align buttons with edge of button bar.
buttonPadding: EdgeInsets.zero,
// Set the vertical direction to start from the bottom and lay
// out upwards.
overflowDirection: VerticalDirection.up,
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 500.0),
SizedBox(key: keyTwo, height: 50.0, width: 500.0),
],
),
),
);
final Rect containerOneRect = tester.getRect(find.byKey(keyOne));
final Rect containerTwoRect = tester.getRect(find.byKey(keyTwo));
// Second [Container] should appear above first container.
expect(containerTwoRect.bottom, lessThanOrEqualTo(containerOneRect.top));
});
testWidgets('ButtonBar has no spacing by default when overflowing', (
WidgetTester tester,
) async {
final Key keyOne = UniqueKey();
final Key keyTwo = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
alignment: MainAxisAlignment.center,
// Set padding to zero to align buttons with edge of button bar.
buttonPadding: EdgeInsets.zero,
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 500.0),
SizedBox(key: keyTwo, height: 50.0, width: 500.0),
],
),
),
);
final Rect containerOneRect = tester.getRect(find.byKey(keyOne));
final Rect containerTwoRect = tester.getRect(find.byKey(keyTwo));
expect(containerOneRect.bottom, containerTwoRect.top);
});
testWidgets("ButtonBar's children respects overflowButtonSpacing when overflowing", (
WidgetTester tester,
) async {
final Key keyOne = UniqueKey();
final Key keyTwo = UniqueKey();
await tester.pumpWidget(
MaterialApp(
home: ButtonBar(
alignment: MainAxisAlignment.center,
// Set padding to zero to align buttons with edge of button bar.
buttonPadding: EdgeInsets.zero,
// Set the overflow button spacing to ensure add some space between
// buttons in an overflow case.
overflowButtonSpacing: 10.0,
children: <Widget>[
SizedBox(key: keyOne, height: 50.0, width: 500.0),
SizedBox(key: keyTwo, height: 50.0, width: 500.0),
],
),
),
);
final Rect containerOneRect = tester.getRect(find.byKey(keyOne));
final Rect containerTwoRect = tester.getRect(find.byKey(keyTwo));
expect(containerOneRect.bottom, containerTwoRect.top - 10.0);
});
});
testWidgets('_RenderButtonBarRow.constraints does not work before layout', (
WidgetTester tester,
) async {
await tester.pumpWidget(
const MaterialApp(home: ButtonBar()),
duration: Duration.zero,
phase: EnginePhase.build,
);
final Finder buttonBar = find.byWidgetPredicate(
(Widget w) => '${w.runtimeType}' == '_ButtonBarRow',
);
final renderButtonBar = tester.renderObject(buttonBar) as RenderBox;
expect(renderButtonBar.debugNeedsLayout, isTrue);
expect(() => renderButtonBar.constraints, throwsStateError);
});
}