// 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. // This file is run as part of a reduced test set in CI on Mac and Windows // machines. @Tags(['reduced-test-set']) library; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/rendering.dart'; import 'package:flutter_test/flutter_test.dart'; MaterialApp _appWithDialog( WidgetTester tester, Widget dialog, { ThemeData? theme, DialogThemeData? dialogTheme, }) { Widget dialogBuilder = Builder( builder: (BuildContext context) { return Center( child: ElevatedButton( child: const Text('X'), onPressed: () { showDialog( context: context, builder: (BuildContext context) { return RepaintBoundary(key: _painterKey, child: dialog); }, ); }, ), ); }, ); if (dialogTheme != null) { dialogBuilder = DialogTheme(data: dialogTheme, child: dialogBuilder); } return MaterialApp( theme: theme, home: Material(child: dialogBuilder), ); } final Key _painterKey = UniqueKey(); Material _getMaterialAlertDialog(WidgetTester tester) { return tester.widget( find.descendant(of: find.byType(AlertDialog), matching: find.byType(Material)), ); } Material _getMaterialDialog(WidgetTester tester) { return tester.widget( find.descendant(of: find.byType(Dialog), matching: find.byType(Material)), ); } RenderParagraph _getTextRenderObject(WidgetTester tester, String text) { return tester.element(find.text(text)).renderObject! as RenderParagraph; } RenderParagraph _getIconRenderObject(WidgetTester tester, IconData icon) { return tester.renderObject( find.descendant(of: find.byIcon(icon), matching: find.byType(RichText)), ); } void main() { test('DialogThemeData copyWith, ==, hashCode basics', () { expect(const DialogThemeData(), const DialogThemeData().copyWith()); expect(const DialogThemeData().hashCode, const DialogThemeData().copyWith().hashCode); }); test('DialogThemeData lerp special cases', () { expect(DialogThemeData.lerp(null, null, 0), const DialogThemeData()); const theme = DialogThemeData(); expect(identical(DialogThemeData.lerp(theme, theme, 0.5), theme), true); }); test('DialogThemeData defaults', () { const dialogThemeData = DialogThemeData(); expect(dialogThemeData.backgroundColor, null); expect(dialogThemeData.elevation, null); expect(dialogThemeData.shadowColor, null); expect(dialogThemeData.surfaceTintColor, null); expect(dialogThemeData.shape, null); expect(dialogThemeData.alignment, null); expect(dialogThemeData.iconColor, null); expect(dialogThemeData.titleTextStyle, null); expect(dialogThemeData.contentTextStyle, null); expect(dialogThemeData.actionsPadding, null); expect(dialogThemeData.barrierColor, null); expect(dialogThemeData.insetPadding, null); expect(dialogThemeData.clipBehavior, null); expect(dialogThemeData.constraints, null); const dialogTheme = DialogTheme(data: DialogThemeData(), child: SizedBox()); expect(dialogTheme.backgroundColor, null); expect(dialogTheme.elevation, null); expect(dialogTheme.shadowColor, null); expect(dialogTheme.surfaceTintColor, null); expect(dialogTheme.shape, null); expect(dialogTheme.alignment, null); expect(dialogTheme.iconColor, null); expect(dialogTheme.titleTextStyle, null); expect(dialogTheme.contentTextStyle, null); expect(dialogTheme.actionsPadding, null); expect(dialogTheme.barrierColor, null); expect(dialogTheme.insetPadding, null); expect(dialogTheme.clipBehavior, null); expect(dialogThemeData.constraints, null); }); testWidgets('Default DialogThemeData debugFillProperties', (WidgetTester tester) async { final builder = DiagnosticPropertiesBuilder(); const DialogThemeData().debugFillProperties(builder); final List description = builder.properties .where((DiagnosticsNode node) => !node.isFiltered(DiagnosticLevel.info)) .map((DiagnosticsNode node) => node.toString()) .toList(); expect(description, []); }); testWidgets('DialogThemeData implements debugFillProperties', (WidgetTester tester) async { final builder = DiagnosticPropertiesBuilder(); const DialogThemeData( backgroundColor: Color(0xff123456), elevation: 8.0, shadowColor: Color(0xff000001), surfaceTintColor: Color(0xff000002), shape: BeveledRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(20.5))), alignment: Alignment.bottomLeft, iconColor: Color(0xff654321), titleTextStyle: TextStyle(color: Color(0xffffffff)), contentTextStyle: TextStyle(color: Color(0xff000000)), actionsPadding: EdgeInsets.all(8.0), barrierColor: Color(0xff000005), insetPadding: EdgeInsets.all(20.0), clipBehavior: Clip.antiAlias, ).debugFillProperties(builder); final List description = builder.properties .where((DiagnosticsNode n) => !n.isFiltered(DiagnosticLevel.info)) .map((DiagnosticsNode n) => n.toString()) .toList(); expect(description, [ 'backgroundColor: ${const Color(0xff123456)}', 'elevation: 8.0', 'shadowColor: ${const Color(0xff000001)}', 'surfaceTintColor: ${const Color(0xff000002)}', 'shape: BeveledRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(20.5))', 'alignment: Alignment.bottomLeft', 'iconColor: ${const Color(0xff654321)}', 'titleTextStyle: TextStyle(inherit: true, color: ${const Color(0xffffffff)})', 'contentTextStyle: TextStyle(inherit: true, color: ${const Color(0xff000000)})', 'actionsPadding: EdgeInsets.all(8.0)', 'barrierColor: ${const Color(0xff000005)}', 'insetPadding: EdgeInsets.all(20.0)', 'clipBehavior: Clip.antiAlias', ]); }); testWidgets('Local DialogThemeData overrides dialog defaults', (WidgetTester tester) async { const themeBackgroundColor = Color(0xff123456); const themeElevation = 8.0; const themeShadowColor = Color(0xff000001); const themeSurfaceTintColor = Color(0xff000002); const themeShape = BeveledRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(20.5)), ); const AlignmentGeometry themeAlignment = Alignment.bottomLeft; const themeIconColor = Color(0xff654321); const themeTitleTextStyle = TextStyle(color: Color(0xffffffff)); const themeContentTextStyle = TextStyle(color: Color(0xff000000)); const EdgeInsetsGeometry themeActionsPadding = EdgeInsets.all(8.0); const themeBarrierColor = Color(0xff000005); const themeInsetPadding = EdgeInsets.all(30.0); const Clip themeClipBehavior = Clip.antiAlias; const dialog = AlertDialog( title: Text('Title'), content: Text('Content'), icon: Icon(Icons.search), actions: [Icon(Icons.cancel)], ); const dialogTheme = DialogThemeData( backgroundColor: themeBackgroundColor, elevation: themeElevation, shadowColor: themeShadowColor, surfaceTintColor: themeSurfaceTintColor, shape: themeShape, alignment: themeAlignment, iconColor: themeIconColor, titleTextStyle: themeTitleTextStyle, contentTextStyle: themeContentTextStyle, actionsPadding: themeActionsPadding, barrierColor: themeBarrierColor, insetPadding: themeInsetPadding, clipBehavior: themeClipBehavior, ); await tester.pumpWidget(_appWithDialog(tester, dialog, dialogTheme: dialogTheme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Material materialWidget = _getMaterialAlertDialog(tester); expect(materialWidget.color, themeBackgroundColor); expect(materialWidget.elevation, themeElevation); expect(materialWidget.shadowColor, themeShadowColor); expect(materialWidget.surfaceTintColor, themeSurfaceTintColor); expect(materialWidget.shape, themeShape); expect(materialWidget.clipBehavior, Clip.antiAlias); final Offset bottomLeft = tester.getBottomLeft( find.descendant(of: find.byType(Dialog), matching: find.byType(Material)), ); expect(bottomLeft.dx, 30.0); // 30 is the padding value. expect(bottomLeft.dy, 570.0); // 600 - 30 expect(_getIconRenderObject(tester, Icons.search).text.style?.color, themeIconColor); expect(_getTextRenderObject(tester, 'Title').text.style?.color, themeTitleTextStyle.color); expect(_getTextRenderObject(tester, 'Content').text.style?.color, themeContentTextStyle.color); final ModalBarrier modalBarrier = tester.widget(find.byType(ModalBarrier).last); expect(modalBarrier.color, themeBarrierColor); final Finder findPadding = find .ancestor(of: find.byIcon(Icons.cancel), matching: find.byType(Padding)) .first; final Padding padding = tester.widget(findPadding); expect(padding.padding, themeActionsPadding); }); testWidgets('Local DialogThemeData overrides global dialogTheme', (WidgetTester tester) async { const themeBackgroundColor = Color(0xff123456); const themeElevation = 8.0; const themeShadowColor = Color(0xff000001); const themeSurfaceTintColor = Color(0xff000002); const themeShape = BeveledRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(20.5)), ); const AlignmentGeometry themeAlignment = Alignment.bottomLeft; const themeIconColor = Color(0xff654321); const themeTitleTextStyle = TextStyle(color: Color(0xffffffff)); const themeContentTextStyle = TextStyle(color: Color(0xff000000)); const EdgeInsetsGeometry themeActionsPadding = EdgeInsets.all(8.0); const themeBarrierColor = Color(0xff000005); const themeInsetPadding = EdgeInsets.all(30.0); const Clip themeClipBehavior = Clip.antiAlias; const globalBackgroundColor = Color(0xff654321); const globalElevation = 7.0; const globalShadowColor = Color(0xff200001); const globalSurfaceTintColor = Color(0xff222002); const globalShape = BeveledRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(25.5)), ); const AlignmentGeometry globalAlignment = Alignment.centerRight; const globalIconColor = Color(0xff666666); const globalTitleTextStyle = TextStyle(color: Color(0xff000000)); const globalContentTextStyle = TextStyle(color: Color(0xffdddddd)); const EdgeInsetsGeometry globalActionsPadding = EdgeInsets.all(18.0); const globalBarrierColor = Color(0xff111115); const globalInsetPadding = EdgeInsets.all(35.0); const Clip globalClipBehavior = Clip.hardEdge; const dialog = AlertDialog( title: Text('Title'), content: Text('Content'), icon: Icon(Icons.search), actions: [Icon(Icons.cancel)], ); const dialogTheme = DialogThemeData( backgroundColor: themeBackgroundColor, elevation: themeElevation, shadowColor: themeShadowColor, surfaceTintColor: themeSurfaceTintColor, shape: themeShape, alignment: themeAlignment, iconColor: themeIconColor, titleTextStyle: themeTitleTextStyle, contentTextStyle: themeContentTextStyle, actionsPadding: themeActionsPadding, barrierColor: themeBarrierColor, insetPadding: themeInsetPadding, clipBehavior: themeClipBehavior, ); const globalDialogTheme = DialogThemeData( backgroundColor: globalBackgroundColor, elevation: globalElevation, shadowColor: globalShadowColor, surfaceTintColor: globalSurfaceTintColor, shape: globalShape, alignment: globalAlignment, iconColor: globalIconColor, titleTextStyle: globalTitleTextStyle, contentTextStyle: globalContentTextStyle, actionsPadding: globalActionsPadding, barrierColor: globalBarrierColor, insetPadding: globalInsetPadding, clipBehavior: globalClipBehavior, ); await tester.pumpWidget( _appWithDialog( tester, dialog, dialogTheme: dialogTheme, theme: ThemeData(dialogTheme: globalDialogTheme), ), ); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Material materialWidget = _getMaterialAlertDialog(tester); expect(materialWidget.color, themeBackgroundColor); expect(materialWidget.elevation, themeElevation); expect(materialWidget.shadowColor, themeShadowColor); expect(materialWidget.surfaceTintColor, themeSurfaceTintColor); expect(materialWidget.shape, themeShape); expect(materialWidget.clipBehavior, Clip.antiAlias); final Offset bottomLeft = tester.getBottomLeft( find.descendant(of: find.byType(Dialog), matching: find.byType(Material)), ); expect(bottomLeft.dx, 30.0); // 30 is the padding value. expect(bottomLeft.dy, 570.0); // 600 - 30 expect(_getIconRenderObject(tester, Icons.search).text.style?.color, themeIconColor); expect(_getTextRenderObject(tester, 'Title').text.style?.color, themeTitleTextStyle.color); expect(_getTextRenderObject(tester, 'Content').text.style?.color, themeContentTextStyle.color); final ModalBarrier modalBarrier = tester.widget(find.byType(ModalBarrier).last); expect(modalBarrier.color, themeBarrierColor); final Finder findPadding = find .ancestor(of: find.byIcon(Icons.cancel), matching: find.byType(Padding)) .first; final Padding padding = tester.widget(findPadding); expect(padding.padding, themeActionsPadding); }); testWidgets('Dialog background color', (WidgetTester tester) async { const Color customColor = Colors.pink; const dialog = AlertDialog(title: Text('Title'), actions: []); final theme = ThemeData(dialogTheme: const DialogThemeData(backgroundColor: customColor)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Material materialWidget = _getMaterialAlertDialog(tester); expect(materialWidget.color, customColor); }); testWidgets('Custom dialog elevation', (WidgetTester tester) async { const customElevation = 12.0; const shadowColor = Color(0xFF000001); const surfaceTintColor = Color(0xFF000002); const dialog = AlertDialog(title: Text('Title'), actions: []); final theme = ThemeData( dialogTheme: const DialogThemeData( elevation: customElevation, shadowColor: shadowColor, surfaceTintColor: surfaceTintColor, ), ); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Material materialWidget = _getMaterialAlertDialog(tester); expect(materialWidget.elevation, customElevation); expect(materialWidget.shadowColor, shadowColor); expect(materialWidget.surfaceTintColor, surfaceTintColor); }); testWidgets('Custom dialog shape', (WidgetTester tester) async { const customBorder = RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(16.0)), ); const dialog = AlertDialog(title: Text('Title'), actions: []); final theme = ThemeData(dialogTheme: const DialogThemeData(shape: customBorder)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Material materialWidget = _getMaterialAlertDialog(tester); expect(materialWidget.shape, customBorder); }); testWidgets('Custom dialog alignment', (WidgetTester tester) async { const dialog = AlertDialog(title: Text('Title'), actions: []); final theme = ThemeData(dialogTheme: const DialogThemeData(alignment: Alignment.bottomLeft)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Offset bottomLeft = tester.getBottomLeft( find.descendant(of: find.byType(Dialog), matching: find.byType(Material)), ); expect(bottomLeft.dx, 40.0); expect(bottomLeft.dy, 576.0); }); testWidgets('Material3 - Dialog alignment takes priority over theme', ( WidgetTester tester, ) async { const dialog = AlertDialog( title: Text('Title'), actions: [], alignment: Alignment.topRight, ); final theme = ThemeData(dialogTheme: const DialogThemeData(alignment: Alignment.bottomLeft)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Offset bottomLeft = tester.getBottomLeft( find.descendant(of: find.byType(Dialog), matching: find.byType(Material)), ); expect(bottomLeft.dx, 480.0); expect(bottomLeft.dy, 124.0); }); testWidgets('Material2 - Dialog alignment takes priority over theme', ( WidgetTester tester, ) async { const dialog = AlertDialog( title: Text('Title'), actions: [], alignment: Alignment.topRight, ); final theme = ThemeData( useMaterial3: false, dialogTheme: const DialogThemeData(alignment: Alignment.bottomLeft), ); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Offset bottomLeft = tester.getBottomLeft( find.descendant(of: find.byType(Dialog), matching: find.byType(Material)), ); expect(bottomLeft.dx, 480.0); expect(bottomLeft.dy, 104.0); }); testWidgets('Material3 - Custom dialog shape matches golden', (WidgetTester tester) async { const customBorder = RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(16.0)), ); const dialog = AlertDialog(title: Text('Title'), actions: []); final theme = ThemeData(dialogTheme: const DialogThemeData(shape: customBorder)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); await expectLater( find.byKey(_painterKey), matchesGoldenFile('m3_dialog_theme.dialog_with_custom_border.png'), ); }); testWidgets('Material2 - Custom dialog shape matches golden', (WidgetTester tester) async { const customBorder = RoundedRectangleBorder( borderRadius: BorderRadius.all(Radius.circular(16.0)), ); const dialog = AlertDialog(title: Text('Title'), actions: []); final theme = ThemeData( useMaterial3: false, dialogTheme: const DialogThemeData(shape: customBorder), ); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); await expectLater( find.byKey(_painterKey), matchesGoldenFile('m2_dialog_theme.dialog_with_custom_border.png'), ); }); testWidgets('Custom Icon Color - Constructor Param - highest preference', ( WidgetTester tester, ) async { const Color iconColor = Colors.pink, dialogThemeColor = Colors.green, iconThemeColor = Colors.yellow; final theme = ThemeData( iconTheme: const IconThemeData(color: iconThemeColor), dialogTheme: const DialogThemeData(iconColor: dialogThemeColor), ); const dialog = AlertDialog( icon: Icon(Icons.ac_unit), iconColor: iconColor, actions: [], ); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); // first is Text('X') final RichText text = tester.widget(find.byType(RichText).last); expect(text.text.style!.color, iconColor); }); testWidgets('Custom Icon Color - Dialog Theme - preference over Theme', ( WidgetTester tester, ) async { const Color dialogThemeColor = Colors.green, iconThemeColor = Colors.yellow; final theme = ThemeData( iconTheme: const IconThemeData(color: iconThemeColor), dialogTheme: const DialogThemeData(iconColor: dialogThemeColor), ); const dialog = AlertDialog(icon: Icon(Icons.ac_unit), actions: []); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); // first is Text('X') final RichText text = tester.widget(find.byType(RichText).last); expect(text.text.style!.color, dialogThemeColor); }); testWidgets('Material3 - Custom Icon Color - Theme - lowest preference', ( WidgetTester tester, ) async { final theme = ThemeData(); const dialog = AlertDialog(icon: Icon(Icons.ac_unit), actions: []); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); // first is Text('X') final RichText text = tester.widget(find.byType(RichText).last); expect(text.text.style!.color, theme.colorScheme.secondary); }); testWidgets('Material2 - Custom Icon Color - Theme - lowest preference', ( WidgetTester tester, ) async { const Color iconThemeColor = Colors.yellow; final theme = ThemeData( useMaterial3: false, iconTheme: const IconThemeData(color: iconThemeColor), ); const dialog = AlertDialog(icon: Icon(Icons.ac_unit), actions: []); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); // first is Text('X') final RichText text = tester.widget(find.byType(RichText).last); expect(text.text.style!.color, iconThemeColor); }); testWidgets('Custom Title Text Style - Constructor Param', (WidgetTester tester) async { const titleText = 'Title'; const titleTextStyle = TextStyle(color: Colors.pink); const dialog = AlertDialog( title: Text(titleText), titleTextStyle: titleTextStyle, actions: [], ); await tester.pumpWidget(_appWithDialog(tester, dialog)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph title = _getTextRenderObject(tester, titleText); expect(title.text.style, titleTextStyle); }); testWidgets('Custom Title Text Style - Dialog Theme', (WidgetTester tester) async { const titleText = 'Title'; const titleTextStyle = TextStyle(color: Colors.pink); const dialog = AlertDialog(title: Text(titleText), actions: []); final theme = ThemeData(dialogTheme: const DialogThemeData(titleTextStyle: titleTextStyle)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph title = _getTextRenderObject(tester, titleText); expect(title.text.style, titleTextStyle); }); testWidgets('Material3 - Custom Title Text Style - Theme', (WidgetTester tester) async { const titleText = 'Title'; const titleTextStyle = TextStyle(color: Colors.pink); const dialog = AlertDialog(title: Text(titleText)); final theme = ThemeData(textTheme: const TextTheme(headlineSmall: titleTextStyle)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph title = _getTextRenderObject(tester, titleText); expect(title.text.style!.color, titleTextStyle.color); }); testWidgets('Material2 - Custom Title Text Style - Theme', (WidgetTester tester) async { const titleText = 'Title'; const titleTextStyle = TextStyle(color: Colors.pink); const dialog = AlertDialog(title: Text(titleText)); final theme = ThemeData( useMaterial3: false, textTheme: const TextTheme(titleLarge: titleTextStyle), ); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph title = _getTextRenderObject(tester, titleText); expect(title.text.style!.color, titleTextStyle.color); }); testWidgets('Simple Dialog - Custom Title Text Style - Constructor Param', ( WidgetTester tester, ) async { const titleText = 'Title'; const titleTextStyle = TextStyle(color: Colors.pink); const dialog = SimpleDialog(title: Text(titleText), titleTextStyle: titleTextStyle); await tester.pumpWidget(_appWithDialog(tester, dialog)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph title = _getTextRenderObject(tester, titleText); expect(title.text.style, titleTextStyle); }); testWidgets('Simple Dialog - Custom Title Text Style - Dialog Theme', ( WidgetTester tester, ) async { const titleText = 'Title'; const titleTextStyle = TextStyle(color: Colors.pink); const dialog = SimpleDialog(title: Text(titleText)); final theme = ThemeData(dialogTheme: const DialogThemeData(titleTextStyle: titleTextStyle)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph title = _getTextRenderObject(tester, titleText); expect(title.text.style, titleTextStyle); }); testWidgets('Simple Dialog - Custom Title Text Style - Theme', (WidgetTester tester) async { const titleText = 'Title'; const titleTextStyle = TextStyle(color: Colors.pink); const dialog = SimpleDialog(title: Text(titleText)); final theme = ThemeData(textTheme: const TextTheme(titleLarge: titleTextStyle)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph title = _getTextRenderObject(tester, titleText); expect(title.text.style!.color, titleTextStyle.color); }); testWidgets('Custom Content Text Style - Constructor Param', (WidgetTester tester) async { const contentText = 'Content'; const contentTextStyle = TextStyle(color: Colors.pink); const dialog = AlertDialog( content: Text(contentText), contentTextStyle: contentTextStyle, actions: [], ); await tester.pumpWidget(_appWithDialog(tester, dialog)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph content = _getTextRenderObject(tester, contentText); expect(content.text.style, contentTextStyle); }); testWidgets('Custom Content Text Style - Dialog Theme', (WidgetTester tester) async { const contentText = 'Content'; const contentTextStyle = TextStyle(color: Colors.pink); const dialog = AlertDialog(content: Text(contentText), actions: []); final theme = ThemeData(dialogTheme: const DialogThemeData(contentTextStyle: contentTextStyle)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph content = _getTextRenderObject(tester, contentText); expect(content.text.style, contentTextStyle); }); testWidgets('Material3 - Custom Content Text Style - Theme', (WidgetTester tester) async { const contentText = 'Content'; const contentTextStyle = TextStyle(color: Colors.pink); const dialog = AlertDialog(content: Text(contentText)); final theme = ThemeData(textTheme: const TextTheme(bodyMedium: contentTextStyle)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph content = _getTextRenderObject(tester, contentText); expect(content.text.style!.color, contentTextStyle.color); }); testWidgets('Material2 - Custom Content Text Style - Theme', (WidgetTester tester) async { const contentText = 'Content'; const contentTextStyle = TextStyle(color: Colors.pink); const dialog = AlertDialog(content: Text(contentText)); final theme = ThemeData( useMaterial3: false, textTheme: const TextTheme(titleMedium: contentTextStyle), ); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final RenderParagraph content = _getTextRenderObject(tester, contentText); expect(content.text.style!.color, contentTextStyle.color); }); testWidgets('Custom barrierColor - Theme', (WidgetTester tester) async { const Color barrierColor = Colors.blue; const dialog = SimpleDialog(); final theme = ThemeData(dialogTheme: const DialogThemeData(barrierColor: barrierColor)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final ModalBarrier modalBarrier = tester.widget(find.byType(ModalBarrier).last); expect(modalBarrier.color, barrierColor); }); testWidgets('DialogTheme.insetPadding updates Dialog insetPadding', (WidgetTester tester) async { // The default testing screen (800, 600) const screenRect = Rect.fromLTRB(0.0, 0.0, 800.0, 600.0); const dialogTheme = DialogThemeData(insetPadding: EdgeInsets.fromLTRB(10, 15, 20, 25)); const dialog = Dialog(child: Placeholder()); await tester.pumpWidget( _appWithDialog(tester, dialog, theme: ThemeData(dialogTheme: dialogTheme)), ); await tester.tap(find.text('X')); await tester.pump(); expect( tester.getRect(find.byType(Placeholder)), Rect.fromLTRB( screenRect.left + dialogTheme.insetPadding!.left, screenRect.top + dialogTheme.insetPadding!.top, screenRect.right - dialogTheme.insetPadding!.right, screenRect.bottom - dialogTheme.insetPadding!.bottom, ), ); }); testWidgets('DialogTheme.clipBehavior updates the dialogs clip behavior', ( WidgetTester tester, ) async { const dialogTheme = DialogThemeData(clipBehavior: Clip.hardEdge); const dialog = Dialog(child: Placeholder()); await tester.pumpWidget( _appWithDialog(tester, dialog, theme: ThemeData(dialogTheme: dialogTheme)), ); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Material materialWidget = _getMaterialDialog(tester); expect(materialWidget.clipBehavior, dialogTheme.clipBehavior); }); testWidgets('Dialog.clipBehavior takes priority over theme', (WidgetTester tester) async { const dialog = Dialog(clipBehavior: Clip.antiAlias, child: Placeholder()); final theme = ThemeData(dialogTheme: const DialogThemeData(clipBehavior: Clip.hardEdge)); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Material materialWidget = _getMaterialDialog(tester); expect(materialWidget.clipBehavior, Clip.antiAlias); }); testWidgets('Material2 - Dialog.clipBehavior takes priority over theme', ( WidgetTester tester, ) async { const dialog = Dialog(clipBehavior: Clip.antiAlias, child: Placeholder()); final theme = ThemeData( useMaterial3: false, dialogTheme: const DialogThemeData(clipBehavior: Clip.hardEdge), ); await tester.pumpWidget(_appWithDialog(tester, dialog, theme: theme)); await tester.tap(find.text('X')); await tester.pumpAndSettle(); final Material materialWidget = _getMaterialDialog(tester); expect(materialWidget.clipBehavior, Clip.antiAlias); }); testWidgets('DialogThemeData.constraints is respected if Dialog.constraints is null', ( WidgetTester tester, ) async { const themeConstraints = BoxConstraints(maxWidth: 500, maxHeight: 500); const dialogTheme = DialogThemeData(alignment: Alignment.center, constraints: themeConstraints); final dialog = Dialog( child: SizedBox.expand(child: Container(color: Colors.amber)), ); await tester.pumpWidget( _appWithDialog(tester, dialog, theme: ThemeData(dialogTheme: dialogTheme)), ); await tester.tap(find.text('X')); await tester.pumpAndSettle(); // Verify that the dialog respects the constraints from the theme final Finder dialogFinder = find.byType(Container); final RenderBox renderBox = tester.renderObject(dialogFinder); expect(renderBox.constraints.maxWidth, themeConstraints.maxWidth); expect(renderBox.constraints.maxHeight, themeConstraints.maxHeight); }); }