mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
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
592 lines
23 KiB
Dart
592 lines
23 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/rendering.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
|
|
void main() {
|
|
test('MaterialBannerThemeData copyWith, ==, hashCode basics', () {
|
|
expect(const MaterialBannerThemeData(), const MaterialBannerThemeData().copyWith());
|
|
expect(
|
|
const MaterialBannerThemeData().hashCode,
|
|
const MaterialBannerThemeData().copyWith().hashCode,
|
|
);
|
|
});
|
|
|
|
test('MaterialBannerThemeData null fields by default', () {
|
|
const bannerTheme = MaterialBannerThemeData();
|
|
expect(bannerTheme.backgroundColor, null);
|
|
expect(bannerTheme.surfaceTintColor, null);
|
|
expect(bannerTheme.shadowColor, null);
|
|
expect(bannerTheme.dividerColor, null);
|
|
expect(bannerTheme.contentTextStyle, null);
|
|
expect(bannerTheme.elevation, null);
|
|
expect(bannerTheme.padding, null);
|
|
expect(bannerTheme.leadingPadding, null);
|
|
});
|
|
|
|
testWidgets('Default MaterialBannerThemeData debugFillProperties', (WidgetTester tester) async {
|
|
final builder = DiagnosticPropertiesBuilder();
|
|
const MaterialBannerThemeData().debugFillProperties(builder);
|
|
|
|
final List<String> description = builder.properties
|
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
|
.map((DiagnosticsNode node) => node.toString())
|
|
.toList();
|
|
|
|
expect(description, <String>[]);
|
|
});
|
|
|
|
testWidgets('MaterialBannerThemeData implements debugFillProperties', (
|
|
WidgetTester tester,
|
|
) async {
|
|
final builder = DiagnosticPropertiesBuilder();
|
|
const MaterialBannerThemeData(
|
|
backgroundColor: Color(0xfffffff0),
|
|
surfaceTintColor: Color(0xfffffff1),
|
|
shadowColor: Color(0xfffffff2),
|
|
dividerColor: Color(0xfffffff3),
|
|
contentTextStyle: TextStyle(color: Color(0xfffffff4)),
|
|
elevation: 4.0,
|
|
padding: EdgeInsets.all(20.0),
|
|
leadingPadding: EdgeInsets.only(left: 8.0),
|
|
).debugFillProperties(builder);
|
|
|
|
final List<String> description = builder.properties
|
|
.where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info))
|
|
.map((DiagnosticsNode node) => node.toString())
|
|
.toList();
|
|
|
|
expect(description, <String>[
|
|
'backgroundColor: ${const Color(0xfffffff0)}',
|
|
'surfaceTintColor: ${const Color(0xfffffff1)}',
|
|
'shadowColor: ${const Color(0xfffffff2)}',
|
|
'dividerColor: ${const Color(0xfffffff3)}',
|
|
'contentTextStyle: TextStyle(inherit: true, color: ${const Color(0xfffffff4)})',
|
|
'elevation: 4.0',
|
|
'padding: EdgeInsets.all(20.0)',
|
|
'leadingPadding: EdgeInsets(8.0, 0.0, 0.0, 0.0)',
|
|
]);
|
|
});
|
|
|
|
testWidgets('Material3 - Passing no MaterialBannerThemeData returns defaults', (
|
|
WidgetTester tester,
|
|
) async {
|
|
const contentText = 'Content';
|
|
final theme = ThemeData();
|
|
late final ThemeData localizedTheme;
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
builder: (BuildContext context, Widget? child) {
|
|
localizedTheme = Theme.of(context);
|
|
return child!;
|
|
},
|
|
home: Scaffold(
|
|
body: MaterialBanner(
|
|
content: const Text(contentText),
|
|
leading: const Icon(Icons.umbrella),
|
|
actions: <Widget>[TextButton(child: const Text('Action'), onPressed: () {})],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, theme.colorScheme.surfaceContainerLow);
|
|
expect(material.surfaceTintColor, Colors.transparent);
|
|
expect(material.shadowColor, null);
|
|
expect(material.elevation, 0.0);
|
|
|
|
final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
|
|
expect(content.text.style, localizedTheme.textTheme.bodyMedium);
|
|
|
|
final Offset rowTopLeft = tester.getTopLeft(find.byType(Row));
|
|
final Offset materialTopLeft = tester.getTopLeft(_materialFinder());
|
|
final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.umbrella));
|
|
expect(rowTopLeft.dy - materialTopLeft.dy, 2.0); // Default single line top padding.
|
|
expect(rowTopLeft.dx - materialTopLeft.dx, 16.0); // Default single line start padding.
|
|
expect(leadingTopLeft.dy - materialTopLeft.dy, 16); // Default leading padding.
|
|
expect(leadingTopLeft.dx - materialTopLeft.dx, 16); // Default leading padding.
|
|
|
|
final Divider divider = tester.widget<Divider>(find.byType(Divider));
|
|
expect(divider.color, theme.colorScheme.outlineVariant);
|
|
});
|
|
|
|
testWidgets(
|
|
'Material3 - Passing no MaterialBannerThemeData returns defaults when presented by ScaffoldMessenger',
|
|
(WidgetTester tester) async {
|
|
const contentText = 'Content';
|
|
const tapTarget = Key('tap-target');
|
|
final theme = ThemeData();
|
|
late final ThemeData localizedTheme;
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: theme,
|
|
home: Scaffold(
|
|
body: Builder(
|
|
builder: (BuildContext context) {
|
|
localizedTheme = Theme.of(context);
|
|
return GestureDetector(
|
|
key: tapTarget,
|
|
onTap: () {
|
|
ScaffoldMessenger.of(context).showMaterialBanner(
|
|
MaterialBanner(
|
|
content: const Text(contentText),
|
|
leading: const Icon(Icons.umbrella),
|
|
actions: <Widget>[
|
|
TextButton(child: const Text('Action'), onPressed: () {}),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
behavior: HitTestBehavior.opaque,
|
|
child: const SizedBox(height: 100.0, width: 100.0),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.byKey(tapTarget));
|
|
await tester.pumpAndSettle();
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, theme.colorScheme.surfaceContainerLow);
|
|
expect(material.surfaceTintColor, Colors.transparent);
|
|
expect(material.shadowColor, null);
|
|
expect(material.elevation, 0.0);
|
|
|
|
final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
|
|
expect(content.text.style, localizedTheme.textTheme.bodyMedium);
|
|
|
|
final Offset rowTopLeft = tester.getTopLeft(find.byType(Row));
|
|
final Offset materialTopLeft = tester.getTopLeft(_materialFinder());
|
|
final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.umbrella));
|
|
expect(rowTopLeft.dy - materialTopLeft.dy, 2.0); // Default single line top padding.
|
|
expect(rowTopLeft.dx - materialTopLeft.dx, 16.0); // Default single line start padding.
|
|
expect(leadingTopLeft.dy - materialTopLeft.dy, 16); // Default leading padding.
|
|
expect(leadingTopLeft.dx - materialTopLeft.dx, 16); // Default leading padding.
|
|
|
|
final Divider divider = tester.widget<Divider>(find.byType(Divider));
|
|
expect(divider.color, theme.colorScheme.outlineVariant);
|
|
},
|
|
);
|
|
|
|
testWidgets('MaterialBanner uses values from MaterialBannerThemeData', (
|
|
WidgetTester tester,
|
|
) async {
|
|
final MaterialBannerThemeData bannerTheme = _bannerTheme();
|
|
const contentText = 'Content';
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(bannerTheme: bannerTheme),
|
|
home: Scaffold(
|
|
body: MaterialBanner(
|
|
leading: const Icon(Icons.ac_unit),
|
|
content: const Text(contentText),
|
|
actions: <Widget>[TextButton(child: const Text('Action'), onPressed: () {})],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, bannerTheme.backgroundColor);
|
|
expect(material.surfaceTintColor, bannerTheme.surfaceTintColor);
|
|
expect(material.shadowColor, bannerTheme.shadowColor);
|
|
expect(material.elevation, bannerTheme.elevation);
|
|
|
|
final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
|
|
expect(content.text.style, bannerTheme.contentTextStyle);
|
|
|
|
final Offset contentTopLeft = tester.getTopLeft(_textFinder(contentText));
|
|
final Offset materialTopLeft = tester.getTopLeft(_materialFinder());
|
|
final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.ac_unit));
|
|
expect(contentTopLeft.dy - materialTopLeft.dy, 24);
|
|
expect(contentTopLeft.dx - materialTopLeft.dx, 41);
|
|
expect(leadingTopLeft.dy - materialTopLeft.dy, 19);
|
|
expect(leadingTopLeft.dx - materialTopLeft.dx, 11);
|
|
|
|
expect(find.byType(Divider), findsNothing);
|
|
});
|
|
|
|
testWidgets(
|
|
'MaterialBanner uses values from MaterialBannerThemeData when presented by ScaffoldMessenger',
|
|
(WidgetTester tester) async {
|
|
final MaterialBannerThemeData bannerTheme = _bannerTheme();
|
|
const contentText = 'Content';
|
|
const tapTarget = Key('tap-target');
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(bannerTheme: bannerTheme),
|
|
home: Scaffold(
|
|
body: Builder(
|
|
builder: (BuildContext context) {
|
|
return GestureDetector(
|
|
key: tapTarget,
|
|
onTap: () {
|
|
ScaffoldMessenger.of(context).showMaterialBanner(
|
|
MaterialBanner(
|
|
leading: const Icon(Icons.ac_unit),
|
|
content: const Text(contentText),
|
|
actions: <Widget>[
|
|
TextButton(child: const Text('Action'), onPressed: () {}),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
behavior: HitTestBehavior.opaque,
|
|
child: const SizedBox(height: 100.0, width: 100.0),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.byKey(tapTarget));
|
|
await tester.pumpAndSettle();
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, bannerTheme.backgroundColor);
|
|
expect(material.surfaceTintColor, bannerTheme.surfaceTintColor);
|
|
expect(material.shadowColor, bannerTheme.shadowColor);
|
|
expect(material.elevation, bannerTheme.elevation);
|
|
|
|
final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
|
|
expect(content.text.style, bannerTheme.contentTextStyle);
|
|
|
|
final Offset contentTopLeft = tester.getTopLeft(_textFinder(contentText));
|
|
final Offset materialTopLeft = tester.getTopLeft(_materialFinder());
|
|
final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.ac_unit));
|
|
expect(contentTopLeft.dy - materialTopLeft.dy, 24);
|
|
expect(contentTopLeft.dx - materialTopLeft.dx, 41);
|
|
expect(leadingTopLeft.dy - materialTopLeft.dy, 19);
|
|
expect(leadingTopLeft.dx - materialTopLeft.dx, 11);
|
|
|
|
expect(find.byType(Divider), findsNothing);
|
|
},
|
|
);
|
|
|
|
testWidgets('MaterialBanner widget properties take priority over theme', (
|
|
WidgetTester tester,
|
|
) async {
|
|
const Color backgroundColor = Colors.purple;
|
|
const Color surfaceTintColor = Colors.red;
|
|
const Color shadowColor = Colors.orange;
|
|
const textStyle = TextStyle(color: Colors.green);
|
|
final MaterialBannerThemeData bannerTheme = _bannerTheme();
|
|
const contentText = 'Content';
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(bannerTheme: bannerTheme),
|
|
home: Scaffold(
|
|
body: MaterialBanner(
|
|
backgroundColor: backgroundColor,
|
|
surfaceTintColor: surfaceTintColor,
|
|
shadowColor: shadowColor,
|
|
elevation: 6.0,
|
|
leading: const Icon(Icons.ac_unit),
|
|
contentTextStyle: textStyle,
|
|
content: const Text(contentText),
|
|
padding: const EdgeInsets.all(10),
|
|
leadingPadding: const EdgeInsets.all(12),
|
|
actions: <Widget>[TextButton(child: const Text('Action'), onPressed: () {})],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, backgroundColor);
|
|
expect(material.surfaceTintColor, surfaceTintColor);
|
|
expect(material.shadowColor, shadowColor);
|
|
expect(material.elevation, 6.0);
|
|
|
|
final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
|
|
expect(content.text.style, textStyle);
|
|
|
|
final Offset contentTopLeft = tester.getTopLeft(_textFinder(contentText));
|
|
final Offset materialTopLeft = tester.getTopLeft(_materialFinder());
|
|
final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.ac_unit));
|
|
expect(contentTopLeft.dy - materialTopLeft.dy, 29);
|
|
expect(contentTopLeft.dx - materialTopLeft.dx, 58);
|
|
expect(leadingTopLeft.dy - materialTopLeft.dy, 24);
|
|
expect(leadingTopLeft.dx - materialTopLeft.dx, 22);
|
|
|
|
expect(find.byType(Divider), findsNothing);
|
|
});
|
|
|
|
testWidgets(
|
|
'MaterialBanner widget properties take priority over theme when presented by ScaffoldMessenger',
|
|
(WidgetTester tester) async {
|
|
const Color backgroundColor = Colors.purple;
|
|
const elevation = 6.0;
|
|
const textStyle = TextStyle(color: Colors.green);
|
|
final MaterialBannerThemeData bannerTheme = _bannerTheme();
|
|
const contentText = 'Content';
|
|
const tapTarget = Key('tap-target');
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(bannerTheme: bannerTheme),
|
|
home: Scaffold(
|
|
body: Builder(
|
|
builder: (BuildContext context) {
|
|
return GestureDetector(
|
|
key: tapTarget,
|
|
onTap: () {
|
|
ScaffoldMessenger.of(context).showMaterialBanner(
|
|
MaterialBanner(
|
|
backgroundColor: backgroundColor,
|
|
elevation: elevation,
|
|
leading: const Icon(Icons.ac_unit),
|
|
contentTextStyle: textStyle,
|
|
content: const Text(contentText),
|
|
padding: const EdgeInsets.all(10),
|
|
leadingPadding: const EdgeInsets.all(12),
|
|
actions: <Widget>[
|
|
TextButton(child: const Text('Action'), onPressed: () {}),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
behavior: HitTestBehavior.opaque,
|
|
child: const SizedBox(height: 100.0, width: 100.0),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.byKey(tapTarget));
|
|
await tester.pumpAndSettle();
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, backgroundColor);
|
|
expect(material.elevation, elevation);
|
|
|
|
final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
|
|
expect(content.text.style, textStyle);
|
|
|
|
final Offset contentTopLeft = tester.getTopLeft(_textFinder(contentText));
|
|
final Offset materialTopLeft = tester.getTopLeft(_materialFinder());
|
|
final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.ac_unit));
|
|
expect(contentTopLeft.dy - materialTopLeft.dy, 29);
|
|
expect(contentTopLeft.dx - materialTopLeft.dx, 58);
|
|
expect(leadingTopLeft.dy - materialTopLeft.dy, 24);
|
|
expect(leadingTopLeft.dx - materialTopLeft.dx, 22);
|
|
|
|
expect(find.byType(Divider), findsNothing);
|
|
},
|
|
);
|
|
|
|
testWidgets('MaterialBanner uses color scheme when necessary', (WidgetTester tester) async {
|
|
final ColorScheme colorScheme = const ColorScheme.light().copyWith(surface: Colors.purple);
|
|
const contentText = 'Content';
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(colorScheme: colorScheme),
|
|
home: Scaffold(
|
|
body: MaterialBanner(
|
|
content: const Text(contentText),
|
|
actions: <Widget>[TextButton(child: const Text('Action'), onPressed: () {})],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, colorScheme.surfaceContainerLow);
|
|
});
|
|
|
|
testWidgets(
|
|
'MaterialBanner uses color scheme when necessary when presented by ScaffoldMessenger',
|
|
(WidgetTester tester) async {
|
|
final ColorScheme colorScheme = const ColorScheme.light().copyWith(surface: Colors.purple);
|
|
const contentText = 'Content';
|
|
const tapTarget = Key('tap-target');
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(colorScheme: colorScheme),
|
|
home: Scaffold(
|
|
body: Builder(
|
|
builder: (BuildContext context) {
|
|
return GestureDetector(
|
|
key: tapTarget,
|
|
onTap: () {
|
|
ScaffoldMessenger.of(context).showMaterialBanner(
|
|
MaterialBanner(
|
|
content: const Text(contentText),
|
|
actions: <Widget>[
|
|
TextButton(child: const Text('Action'), onPressed: () {}),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
behavior: HitTestBehavior.opaque,
|
|
child: const SizedBox(height: 100.0, width: 100.0),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.byKey(tapTarget));
|
|
await tester.pumpAndSettle();
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, colorScheme.surfaceContainerLow);
|
|
},
|
|
);
|
|
|
|
group('Material 2', () {
|
|
// These tests are only relevant for Material 2. Once Material 2
|
|
// support is deprecated and the APIs are removed, these tests
|
|
// can be deleted.
|
|
|
|
testWidgets('Material2 - Passing no MaterialBannerThemeData returns defaults', (
|
|
WidgetTester tester,
|
|
) async {
|
|
const contentText = 'Content';
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(useMaterial3: false),
|
|
home: Scaffold(
|
|
body: MaterialBanner(
|
|
content: const Text(contentText),
|
|
leading: const Icon(Icons.umbrella),
|
|
actions: <Widget>[TextButton(child: const Text('Action'), onPressed: () {})],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, const Color(0xffffffff));
|
|
expect(material.surfaceTintColor, null);
|
|
expect(material.shadowColor, null);
|
|
expect(material.elevation, 0.0);
|
|
|
|
final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
|
|
// Default value for ThemeData.typography is Typography.material2014()
|
|
expect(
|
|
content.text.style,
|
|
Typography.material2014().englishLike.bodyMedium!.merge(
|
|
Typography.material2014().black.bodyMedium,
|
|
),
|
|
);
|
|
|
|
final Offset rowTopLeft = tester.getTopLeft(find.byType(Row));
|
|
final Offset materialTopLeft = tester.getTopLeft(_materialFinder());
|
|
final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.umbrella));
|
|
expect(rowTopLeft.dy - materialTopLeft.dy, 2.0); // Default single line top padding.
|
|
expect(rowTopLeft.dx - materialTopLeft.dx, 16.0); // Default single line start padding.
|
|
expect(leadingTopLeft.dy - materialTopLeft.dy, 16); // Default leading padding.
|
|
expect(leadingTopLeft.dx - materialTopLeft.dx, 16); // Default leading padding.
|
|
|
|
final Divider divider = tester.widget<Divider>(find.byType(Divider));
|
|
expect(divider.color, null);
|
|
});
|
|
|
|
testWidgets(
|
|
'Material2 - Passing no MaterialBannerThemeData returns defaults when presented by ScaffoldMessenger',
|
|
(WidgetTester tester) async {
|
|
const contentText = 'Content';
|
|
const tapTarget = Key('tap-target');
|
|
|
|
await tester.pumpWidget(
|
|
MaterialApp(
|
|
theme: ThemeData(useMaterial3: false),
|
|
home: Scaffold(
|
|
body: Builder(
|
|
builder: (BuildContext context) {
|
|
return GestureDetector(
|
|
key: tapTarget,
|
|
onTap: () {
|
|
ScaffoldMessenger.of(context).showMaterialBanner(
|
|
MaterialBanner(
|
|
content: const Text(contentText),
|
|
leading: const Icon(Icons.umbrella),
|
|
actions: <Widget>[
|
|
TextButton(child: const Text('Action'), onPressed: () {}),
|
|
],
|
|
),
|
|
);
|
|
},
|
|
behavior: HitTestBehavior.opaque,
|
|
child: const SizedBox(height: 100.0, width: 100.0),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.tap(find.byKey(tapTarget));
|
|
await tester.pumpAndSettle();
|
|
|
|
final Material material = _getMaterialFromText(tester, contentText);
|
|
expect(material.color, const Color(0xffffffff));
|
|
expect(material.surfaceTintColor, null);
|
|
expect(material.shadowColor, null);
|
|
expect(material.elevation, 0.0);
|
|
|
|
final RenderParagraph content = _getTextRenderObjectFromDialog(tester, contentText);
|
|
// Default value for ThemeData.typography is Typography.material2014()
|
|
expect(
|
|
content.text.style,
|
|
Typography.material2014().englishLike.bodyMedium!.merge(
|
|
Typography.material2014().black.bodyMedium,
|
|
),
|
|
);
|
|
|
|
final Offset rowTopLeft = tester.getTopLeft(find.byType(Row));
|
|
final Offset materialTopLeft = tester.getTopLeft(_materialFinder());
|
|
final Offset leadingTopLeft = tester.getTopLeft(find.byIcon(Icons.umbrella));
|
|
expect(rowTopLeft.dy - materialTopLeft.dy, 2.0); // Default single line top padding.
|
|
expect(rowTopLeft.dx - materialTopLeft.dx, 16.0); // Default single line start padding.
|
|
expect(leadingTopLeft.dy - materialTopLeft.dy, 16); // Default leading padding.
|
|
expect(leadingTopLeft.dx - materialTopLeft.dx, 16); // Default leading padding.
|
|
|
|
final Divider divider = tester.widget<Divider>(find.byType(Divider));
|
|
expect(divider.color, null);
|
|
},
|
|
);
|
|
});
|
|
}
|
|
|
|
MaterialBannerThemeData _bannerTheme() {
|
|
return const MaterialBannerThemeData(
|
|
backgroundColor: Colors.orange,
|
|
surfaceTintColor: Colors.yellow,
|
|
shadowColor: Colors.red,
|
|
dividerColor: Colors.green,
|
|
contentTextStyle: TextStyle(color: Colors.pink),
|
|
elevation: 4.0,
|
|
padding: EdgeInsets.all(5),
|
|
leadingPadding: EdgeInsets.all(6),
|
|
);
|
|
}
|
|
|
|
Material _getMaterialFromText(WidgetTester tester, String text) {
|
|
return tester.widget<Material>(find.widgetWithText(Material, text).first);
|
|
}
|
|
|
|
Finder _materialFinder() {
|
|
return find.descendant(of: find.byType(MaterialBanner), matching: find.byType(Material)).first;
|
|
}
|
|
|
|
RenderParagraph _getTextRenderObjectFromDialog(WidgetTester tester, String text) {
|
|
return tester.element<StatelessElement>(_textFinder(text)).renderObject! as RenderParagraph;
|
|
}
|
|
|
|
Finder _textFinder(String text) {
|
|
return find.descendant(of: find.byType(MaterialBanner), matching: find.text(text));
|
|
}
|