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 {
this.dismissDirection = DismissDirection.down,
}) : assert(elevation == null || elevation >= 0.0),
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(
width == null || margin == null,
'Width and margin can not be used together',
......@@ -489,6 +481,26 @@ class _SnackBarState extends State<SnackBar> {
final TextStyle? contentTextStyle = snackBarTheme.contentTextStyle ?? ThemeData(brightness: brightness).textTheme.subtitle1;
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 double horizontalPadding = isFloatingSnackBar ? 16.0 : 24.0;
final EdgeInsetsGeometry padding = widget.padding
......
......@@ -816,9 +816,9 @@ void main() {
return GestureDetector(
onTap: () {
Scaffold.of(context).showSnackBar(
SnackBar(
content: const Text('I am a snack bar.'),
margin: const EdgeInsets.all(padding),
const SnackBar(
content: Text('I am a snack bar.'),
margin: EdgeInsets.all(padding),
behavior: SnackBarBehavior.floating,
),
);
......@@ -994,8 +994,8 @@ void main() {
return GestureDetector(
onTap: () {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: const Text('I am a snack bar.'),
const SnackBar(
content: Text('I am a snack bar.'),
width: width,
behavior: SnackBarBehavior.floating,
),
......@@ -2420,6 +2420,106 @@ void main() {
expect(find.text(snackBars[1]), 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".
......
......@@ -271,6 +271,97 @@ void main() {
expect(floatingActionButtonOriginBottomCenter.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() {
......
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