| // 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('BottomSheetThemeData copyWith, ==, hashCode basics', () { |
| expect(const BottomSheetThemeData(), const BottomSheetThemeData().copyWith()); |
| expect(const BottomSheetThemeData().hashCode, const BottomSheetThemeData().copyWith().hashCode); |
| }); |
| |
| test('BottomSheetThemeData null fields by default', () { |
| const BottomSheetThemeData bottomSheetTheme = BottomSheetThemeData(); |
| expect(bottomSheetTheme.backgroundColor, null); |
| expect(bottomSheetTheme.elevation, null); |
| expect(bottomSheetTheme.shape, null); |
| expect(bottomSheetTheme.clipBehavior, null); |
| expect(bottomSheetTheme.constraints, null); |
| }); |
| |
| testWidgets('Default BottomSheetThemeData debugFillProperties', (WidgetTester tester) async { |
| final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); |
| const BottomSheetThemeData().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('BottomSheetThemeData implements debugFillProperties', (WidgetTester tester) async { |
| final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); |
| const BottomSheetThemeData( |
| backgroundColor: Color(0xFFFFFFFF), |
| elevation: 2.0, |
| shape: RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(2.0))), |
| clipBehavior: Clip.antiAlias, |
| constraints: BoxConstraints(minWidth: 200, maxWidth: 640), |
| ).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: Color(0xffffffff)', |
| 'elevation: 2.0', |
| 'shape: RoundedRectangleBorder(BorderSide(width: 0.0, style: none), BorderRadius.circular(2.0))', |
| 'clipBehavior: Clip.antiAlias', |
| 'constraints: BoxConstraints(200.0<=w<=640.0, 0.0<=h<=Infinity)', |
| ]); |
| }); |
| |
| testWidgets('Passing no BottomSheetThemeData returns defaults', (WidgetTester tester) async { |
| await tester.pumpWidget(MaterialApp( |
| home: Scaffold( |
| body: BottomSheet( |
| onClosing: () {}, |
| builder: (BuildContext context) { |
| return Container(); |
| }, |
| ), |
| ), |
| )); |
| |
| final Material material = tester.widget<Material>( |
| find.descendant( |
| of: find.byType(BottomSheet), |
| matching: find.byType(Material), |
| ), |
| ); |
| expect(material.color, null); |
| expect(material.elevation, 0.0); |
| expect(material.shape, null); |
| expect(material.clipBehavior, Clip.none); |
| }); |
| |
| testWidgets('BottomSheet uses values from BottomSheetThemeData', (WidgetTester tester) async { |
| final BottomSheetThemeData bottomSheetTheme = _bottomSheetTheme(); |
| |
| await tester.pumpWidget(MaterialApp( |
| theme: ThemeData(bottomSheetTheme: bottomSheetTheme), |
| home: Scaffold( |
| body: BottomSheet( |
| onClosing: () {}, |
| builder: (BuildContext context) { |
| return Container(); |
| }, |
| ), |
| ), |
| )); |
| |
| final Material material = tester.widget<Material>( |
| find.descendant( |
| of: find.byType(BottomSheet), |
| matching: find.byType(Material), |
| ), |
| ); |
| expect(material.color, bottomSheetTheme.backgroundColor); |
| expect(material.elevation, bottomSheetTheme.elevation); |
| expect(material.shape, bottomSheetTheme.shape); |
| expect(material.clipBehavior, bottomSheetTheme.clipBehavior); |
| }); |
| |
| testWidgets('BottomSheet widget properties take priority over theme', (WidgetTester tester) async { |
| const Color backgroundColor = Colors.purple; |
| const double elevation = 7.0; |
| const ShapeBorder shape = RoundedRectangleBorder( |
| borderRadius: BorderRadius.all(Radius.circular(9.0)), |
| ); |
| const Clip clipBehavior = Clip.hardEdge; |
| |
| await tester.pumpWidget(MaterialApp( |
| theme: ThemeData(bottomSheetTheme: _bottomSheetTheme()), |
| home: Scaffold( |
| body: BottomSheet( |
| backgroundColor: backgroundColor, |
| elevation: elevation, |
| shape: shape, |
| clipBehavior: Clip.hardEdge, |
| onClosing: () {}, |
| builder: (BuildContext context) { |
| return Container(); |
| }, |
| ), |
| ), |
| )); |
| |
| final Material material = tester.widget<Material>( |
| find.descendant( |
| of: find.byType(BottomSheet), |
| matching: find.byType(Material), |
| ), |
| ); |
| expect(material.color, backgroundColor); |
| expect(material.elevation, elevation); |
| expect(material.shape, shape); |
| expect(material.clipBehavior, clipBehavior); |
| }); |
| |
| testWidgets('Modal bottom sheet-specific parameters are used for modal bottom sheets', (WidgetTester tester) async { |
| const double modalElevation = 5.0; |
| const double persistentElevation = 7.0; |
| const Color modalBackgroundColor = Colors.yellow; |
| const Color modalBarrierColor = Colors.blue; |
| const Color persistentBackgroundColor = Colors.red; |
| const BottomSheetThemeData bottomSheetTheme = BottomSheetThemeData( |
| elevation: persistentElevation, |
| modalElevation: modalElevation, |
| backgroundColor: persistentBackgroundColor, |
| modalBackgroundColor: modalBackgroundColor, |
| modalBarrierColor:modalBarrierColor, |
| ); |
| |
| await tester.pumpWidget(bottomSheetWithElevations(bottomSheetTheme)); |
| await tester.tap(find.text('Show Modal')); |
| await tester.pumpAndSettle(); |
| |
| final Material material = tester.widget<Material>( |
| find.descendant( |
| of: find.byType(BottomSheet), |
| matching: find.byType(Material), |
| ), |
| ); |
| expect(material.elevation, modalElevation); |
| expect(material.color, modalBackgroundColor); |
| |
| final ModalBarrier modalBarrier = tester.widget(find.byType(ModalBarrier).last); |
| expect(modalBarrier.color, modalBarrierColor); |
| }); |
| |
| testWidgets('General bottom sheet parameters take priority over modal bottom sheet-specific parameters for persistent bottom sheets', (WidgetTester tester) async { |
| const double modalElevation = 5.0; |
| const double persistentElevation = 7.0; |
| const Color modalBackgroundColor = Colors.yellow; |
| const Color persistentBackgroundColor = Colors.red; |
| const BottomSheetThemeData bottomSheetTheme = BottomSheetThemeData( |
| elevation: persistentElevation, |
| modalElevation: modalElevation, |
| backgroundColor: persistentBackgroundColor, |
| modalBackgroundColor: modalBackgroundColor, |
| ); |
| |
| await tester.pumpWidget(bottomSheetWithElevations(bottomSheetTheme)); |
| await tester.tap(find.text('Show Persistent')); |
| await tester.pumpAndSettle(); |
| |
| final Material material = tester.widget<Material>( |
| find.descendant( |
| of: find.byType(BottomSheet), |
| matching: find.byType(Material), |
| ), |
| ); |
| expect(material.elevation, persistentElevation); |
| expect(material.color, persistentBackgroundColor); |
| }); |
| |
| testWidgets("Modal bottom sheet-specific parameters don't apply to persistent bottom sheets", (WidgetTester tester) async { |
| const double modalElevation = 5.0; |
| const Color modalBackgroundColor = Colors.yellow; |
| const BottomSheetThemeData bottomSheetTheme = BottomSheetThemeData( |
| modalElevation: modalElevation, |
| modalBackgroundColor: modalBackgroundColor, |
| ); |
| |
| await tester.pumpWidget(bottomSheetWithElevations(bottomSheetTheme)); |
| await tester.tap(find.text('Show Persistent')); |
| await tester.pumpAndSettle(); |
| |
| final Material material = tester.widget<Material>( |
| find.descendant( |
| of: find.byType(BottomSheet), |
| matching: find.byType(Material), |
| ), |
| ); |
| expect(material.elevation, 0); |
| expect(material.color, null); |
| }); |
| |
| testWidgets('Modal bottom sheets respond to theme changes', (WidgetTester tester) async { |
| const double lightElevation = 5.0; |
| const double darkElevation = 3.0; |
| const Color lightBackgroundColor = Colors.green; |
| const Color darkBackgroundColor = Colors.grey; |
| |
| await tester.pumpWidget(MaterialApp( |
| theme: ThemeData.light().copyWith( |
| bottomSheetTheme: const BottomSheetThemeData( |
| elevation: lightElevation, |
| backgroundColor: lightBackgroundColor, |
| ), |
| ), |
| darkTheme: ThemeData.dark().copyWith( |
| bottomSheetTheme: const BottomSheetThemeData( |
| elevation: darkElevation, |
| backgroundColor: darkBackgroundColor, |
| ), |
| ), |
| home: Scaffold( |
| body: Builder( |
| builder: (BuildContext context) { |
| return Column( |
| children: <Widget>[ |
| RawMaterialButton( |
| child: const Text('Show Modal'), |
| onPressed: () { |
| showModalBottomSheet<void>( |
| context: context, |
| builder: (BuildContext context) { |
| return const Text('This is a modal bottom sheet.'); |
| }, |
| ); |
| }, |
| ), |
| ], |
| ); |
| }, |
| ), |
| ), |
| )); |
| await tester.tap(find.text('Show Modal')); |
| await tester.pumpAndSettle(); |
| |
| final Material lightMaterial = tester.widget<Material>( |
| find.descendant( |
| of: find.byType(BottomSheet), |
| matching: find.byType(Material), |
| ), |
| ); |
| expect(lightMaterial.elevation, lightElevation); |
| expect(lightMaterial.color, lightBackgroundColor); |
| |
| // Simulate the user changing to dark theme |
| tester.binding.platformDispatcher.platformBrightnessTestValue = Brightness.dark; |
| await tester.pumpAndSettle(); |
| |
| final Material darkMaterial = tester.widget<Material>( |
| find.descendant( |
| of: find.byType(BottomSheet), |
| matching: find.byType(Material), |
| ), |
| ); |
| expect(darkMaterial.elevation, darkElevation); |
| expect(darkMaterial.color, darkBackgroundColor); |
| }); |
| } |
| |
| Widget bottomSheetWithElevations(BottomSheetThemeData bottomSheetTheme) { |
| return MaterialApp( |
| theme: ThemeData(bottomSheetTheme: bottomSheetTheme), |
| home: Scaffold( |
| body: Builder( |
| builder: (BuildContext context) { |
| return Column( |
| children: <Widget>[ |
| RawMaterialButton( |
| child: const Text('Show Modal'), |
| onPressed: () { |
| showModalBottomSheet<void>( |
| context: context, |
| builder: (BuildContext _) { |
| return const Text( |
| 'This is a modal bottom sheet.', |
| ); |
| }, |
| ); |
| }, |
| ), |
| RawMaterialButton( |
| child: const Text('Show Persistent'), |
| onPressed: () { |
| showBottomSheet<void>( |
| context: context, |
| builder: (BuildContext _) { |
| return const Text( |
| 'This is a persistent bottom sheet.', |
| ); |
| }, |
| ); |
| }, |
| ), |
| ], |
| ); |
| }, |
| ), |
| ), |
| ); |
| } |
| |
| BottomSheetThemeData _bottomSheetTheme() { |
| return const BottomSheetThemeData( |
| backgroundColor: Colors.orange, |
| elevation: 12.0, |
| shape: BeveledRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(12))), |
| clipBehavior: Clip.antiAlias, |
| ); |
| } |