Unverified Commit 0ea43037 authored by Kate Lovett's avatar Kate Lovett Committed by GitHub

Fix SnackBar assertions when configured with theme (#85150)

parent 144434ca
...@@ -255,14 +255,6 @@ class SnackBar extends StatefulWidget { ...@@ -255,14 +255,6 @@ class SnackBar extends StatefulWidget {
this.dismissDirection = DismissDirection.down, this.dismissDirection = DismissDirection.down,
}) : assert(elevation == null || elevation >= 0.0), }) : assert(elevation == null || elevation >= 0.0),
assert(content != null), assert(content != null),
assert(
margin == null || behavior == SnackBarBehavior.floating,
'Margin can only be used with floating behavior',
),
assert(
width == null || behavior == SnackBarBehavior.floating,
'Width can only be used with floating behavior',
),
assert( assert(
width == null || margin == null, width == null || margin == null,
'Width and margin can not be used together', 'Width and margin can not be used together',
...@@ -489,6 +481,26 @@ class _SnackBarState extends State<SnackBar> { ...@@ -489,6 +481,26 @@ class _SnackBarState extends State<SnackBar> {
final TextStyle? contentTextStyle = snackBarTheme.contentTextStyle ?? ThemeData(brightness: brightness).textTheme.subtitle1; final TextStyle? contentTextStyle = snackBarTheme.contentTextStyle ?? ThemeData(brightness: brightness).textTheme.subtitle1;
final SnackBarBehavior snackBarBehavior = widget.behavior ?? snackBarTheme.behavior ?? SnackBarBehavior.fixed; final SnackBarBehavior snackBarBehavior = widget.behavior ?? snackBarTheme.behavior ?? SnackBarBehavior.fixed;
assert((){
// Whether the behavior is set through the constructor or the theme,
// assert that our other properties are configured properly.
if (snackBarBehavior != SnackBarBehavior.floating) {
String message(String parameter) {
final String prefix = '$parameter can only be used with floating behavior.';
if (widget.behavior != null) {
return '$prefix SnackBarBehavior.fixed was set in the SnackBar constructor.';
} else if (snackBarTheme.behavior != null) {
return '$prefix SnackBarBehavior.fixed was set by the inherited SnackBarThemeData.';
} else {
return '$prefix SnackBarBehavior.fixed was set by default.';
}
}
assert(widget.margin == null, message('Margin'));
assert(widget.width == null, message('Width'));
}
return true;
}());
final bool isFloatingSnackBar = snackBarBehavior == SnackBarBehavior.floating; final bool isFloatingSnackBar = snackBarBehavior == SnackBarBehavior.floating;
final double horizontalPadding = isFloatingSnackBar ? 16.0 : 24.0; final double horizontalPadding = isFloatingSnackBar ? 16.0 : 24.0;
final EdgeInsetsGeometry padding = widget.padding final EdgeInsetsGeometry padding = widget.padding
......
...@@ -816,9 +816,9 @@ void main() { ...@@ -816,9 +816,9 @@ void main() {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
Scaffold.of(context).showSnackBar( Scaffold.of(context).showSnackBar(
SnackBar( const SnackBar(
content: const Text('I am a snack bar.'), content: Text('I am a snack bar.'),
margin: const EdgeInsets.all(padding), margin: EdgeInsets.all(padding),
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,
), ),
); );
...@@ -994,8 +994,8 @@ void main() { ...@@ -994,8 +994,8 @@ void main() {
return GestureDetector( return GestureDetector(
onTap: () { onTap: () {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( const SnackBar(
content: const Text('I am a snack bar.'), content: Text('I am a snack bar.'),
width: width, width: width,
behavior: SnackBarBehavior.floating, behavior: SnackBarBehavior.floating,
), ),
...@@ -2420,6 +2420,106 @@ void main() { ...@@ -2420,6 +2420,106 @@ void main() {
expect(find.text(snackBars[1]), findsNothing); expect(find.text(snackBars[1]), findsNothing);
expect(find.text(snackBars[2]), findsNothing); expect(find.text(snackBars[2]), findsNothing);
}); });
Widget _buildApp({
required SnackBarBehavior? behavior,
EdgeInsetsGeometry? margin,
double? width,
}) {
return MaterialApp(
home: Scaffold(
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.send),
onPressed: () {},
),
body: Builder(
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
behavior: behavior,
margin: margin,
width: width,
content: const Text('I am a snack bar.'),
duration: const Duration(seconds: 2),
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
));
},
child: const Text('X'),
);
},
),
),
);
}
testWidgets('Setting SnackBarBehavior.fixed will still assert for margin', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/84935
await tester.pumpWidget(_buildApp(
behavior: SnackBarBehavior.fixed,
margin: const EdgeInsets.all(8.0),
));
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
final AssertionError exception = tester.takeException() as AssertionError;
expect(
exception.message,
'Margin can only be used with floating behavior. SnackBarBehavior.fixed '
'was set in the SnackBar constructor.',
);
});
testWidgets('Default SnackBarBehavior will still assert for margin', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/84935
await tester.pumpWidget(_buildApp(
behavior: null,
margin: const EdgeInsets.all(8.0),
));
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
final AssertionError exception = tester.takeException() as AssertionError;
expect(
exception.message,
'Margin can only be used with floating behavior. SnackBarBehavior.fixed '
'was set by default.',
);
});
testWidgets('Setting SnackBarBehavior.fixed will still assert for width', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/84935
await tester.pumpWidget(_buildApp(
behavior: SnackBarBehavior.fixed,
width: 5.0,
));
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
final AssertionError exception = tester.takeException() as AssertionError;
expect(
exception.message,
'Width can only be used with floating behavior. SnackBarBehavior.fixed '
'was set in the SnackBar constructor.',
);
});
testWidgets('Default SnackBarBehavior will still assert for width', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/84935
await tester.pumpWidget(_buildApp(
behavior: null,
width: 5.0,
));
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
final AssertionError exception = tester.takeException() as AssertionError;
expect(
exception.message,
'Width can only be used with floating behavior. SnackBarBehavior.fixed '
'was set by default.',
);
});
} }
/// Start test for "SnackBar dismiss test". /// Start test for "SnackBar dismiss test".
......
...@@ -271,6 +271,97 @@ void main() { ...@@ -271,6 +271,97 @@ void main() {
expect(floatingActionButtonOriginBottomCenter.dy > floatingActionButtonBottomCenter.dy, true); expect(floatingActionButtonOriginBottomCenter.dy > floatingActionButtonBottomCenter.dy, true);
expect(snackBarTopCenter.dy > floatingActionButtonBottomCenter.dy, true); expect(snackBarTopCenter.dy > floatingActionButtonBottomCenter.dy, true);
}); });
Widget _buildApp({
required SnackBarBehavior themedBehavior,
EdgeInsetsGeometry? margin,
double? width,
}) {
return MaterialApp(
theme: ThemeData(
snackBarTheme: SnackBarThemeData(behavior: themedBehavior),
),
home: Scaffold(
floatingActionButton: FloatingActionButton(
child: const Icon(Icons.send),
onPressed: () {},
),
body: Builder(
builder: (BuildContext context) {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(SnackBar(
margin: margin,
width: width,
content: const Text('I am a snack bar.'),
duration: const Duration(seconds: 2),
action: SnackBarAction(label: 'ACTION', onPressed: () {}),
));
},
child: const Text('X'),
);
},
),
),
);
}
testWidgets('SnackBar theme behavior will assert properly for margin use', (WidgetTester tester) async {
// Regression test for https://github.com/flutter/flutter/issues/84935
// SnackBarBehavior.floating set in theme does not assert with margin
await tester.pumpWidget(_buildApp(
themedBehavior: SnackBarBehavior.floating,
margin: const EdgeInsets.all(8.0),
));
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
AssertionError? exception = tester.takeException() as AssertionError?;
expect(exception, isNull);
// SnackBarBehavior.fixed set in theme will still assert with margin
await tester.pumpWidget(_buildApp(
themedBehavior: SnackBarBehavior.fixed,
margin: const EdgeInsets.all(8.0),
));
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
exception = tester.takeException() as AssertionError;
expect(
exception.message,
'Margin can only be used with floating behavior. SnackBarBehavior.fixed '
'was set by the inherited SnackBarThemeData.',
);
});
testWidgets('SnackBar theme behavior will assert properly for width use', (WidgetTester tester) async {
// SnackBarBehavior.floating set in theme does not assert with width
await tester.pumpWidget(_buildApp(
themedBehavior: SnackBarBehavior.floating,
width: 5.0,
));
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
AssertionError? exception = tester.takeException() as AssertionError?;
expect(exception, isNull);
// SnackBarBehavior.fixed set in theme will still assert with width
await tester.pumpWidget(_buildApp(
themedBehavior: SnackBarBehavior.fixed,
width: 5.0,
));
await tester.tap(find.text('X'));
await tester.pump(); // start animation
await tester.pump(const Duration(milliseconds: 750));
exception = tester.takeException() as AssertionError;
expect(
exception.message,
'Width can only be used with floating behavior. SnackBarBehavior.fixed '
'was set by the inherited SnackBarThemeData.',
);
});
} }
SnackBarThemeData _snackBarTheme() { SnackBarThemeData _snackBarTheme() {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment