| // Copyright 2015 The Chromium 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/rendering.dart'; |
| import 'package:flutter/material.dart'; |
| import 'package:flutter/widgets.dart'; |
| import 'package:flutter_test/flutter_test.dart'; |
| |
| import '../rendering/mock_canvas.dart'; |
| import '../widgets/semantics_tester.dart'; |
| |
| void main() { |
| setUp(() { |
| debugResetSemanticsIdCounter(); |
| }); |
| |
| testWidgets('MaterialButton defaults', (WidgetTester tester) async { |
| final Finder rawButtonMaterial = find.descendant( |
| of: find.byType(MaterialButton), |
| matching: find.byType(Material), |
| ); |
| |
| // Enabled MaterialButton |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: MaterialButton( |
| onPressed: () { }, |
| child: const Text('button'), |
| ), |
| ), |
| ); |
| Material material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, null); |
| expect(material.elevation, 2.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0xdd000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.transparency); |
| |
| final Offset center = tester.getCenter(find.byType(MaterialButton)); |
| await tester.startGesture(center); |
| await tester.pumpAndSettle(); |
| |
| // Only elevation changes when enabled and pressed. |
| material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, null); |
| expect(material.elevation, 8.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0xdd000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.transparency); |
| |
| |
| // Disabled MaterialButton |
| await tester.pumpWidget( |
| const Directionality( |
| textDirection: TextDirection.ltr, |
| child: MaterialButton( |
| onPressed: null, |
| child: Text('button'), |
| ), |
| ), |
| ); |
| material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, null); |
| expect(material.elevation, 0.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0x61000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.transparency); |
| }); |
| |
| testWidgets('FlatButton defaults', (WidgetTester tester) async { |
| final Finder rawButtonMaterial = find.descendant( |
| of: find.byType(FlatButton), |
| matching: find.byType(Material), |
| ); |
| |
| // Enabled FlatButton |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: FlatButton( |
| onPressed: () { }, |
| child: const Text('button'), |
| ), |
| ), |
| ); |
| Material material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, null); |
| expect(material.elevation, 0.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0xdd000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.transparency); |
| |
| final Offset center = tester.getCenter(find.byType(FlatButton)); |
| await tester.startGesture(center); |
| await tester.pumpAndSettle(); |
| |
| material = tester.widget<Material>(rawButtonMaterial); |
| // No change vs enabled and not pressed. |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, null); |
| expect(material.elevation, 0.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0xdd000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.transparency); |
| |
| // Disabled FlatButton |
| await tester.pumpWidget( |
| const Directionality( |
| textDirection: TextDirection.ltr, |
| child: FlatButton( |
| onPressed: null, |
| child: Text('button'), |
| ), |
| ), |
| ); |
| material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, null); |
| expect(material.elevation, 0.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0x61000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.transparency); |
| }); |
| |
| testWidgets('RaisedButton defaults', (WidgetTester tester) async { |
| final Finder rawButtonMaterial = find.descendant( |
| of: find.byType(RaisedButton), |
| matching: find.byType(Material), |
| ); |
| |
| // Enabled RaisedButton |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: RaisedButton( |
| onPressed: () { }, |
| child: const Text('button'), |
| ), |
| ), |
| ); |
| Material material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, const Color(0xffe0e0e0)); |
| expect(material.elevation, 2.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0xdd000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.button); |
| |
| final Offset center = tester.getCenter(find.byType(RaisedButton)); |
| await tester.startGesture(center); |
| await tester.pumpAndSettle(); |
| |
| // Only elevation changes when enabled and pressed. |
| material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, const Color(0xffe0e0e0)); |
| expect(material.elevation, 8.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0xdd000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.button); |
| |
| // Disabled RaisedButton |
| await tester.pumpWidget( |
| const Directionality( |
| textDirection: TextDirection.ltr, |
| child: RaisedButton( |
| onPressed: null, |
| child: Text('button'), |
| ), |
| ), |
| ); |
| material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 200)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, const Color(0x61000000)); |
| expect(material.elevation, 0.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.shape, RoundedRectangleBorder(borderRadius: BorderRadius.circular(2.0))); |
| expect(material.textStyle.color, const Color(0x61000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.button); |
| }); |
| |
| testWidgets('OutlineButton defaults', (WidgetTester tester) async { |
| final Finder rawButtonMaterial = find.descendant( |
| of: find.byType(OutlineButton), |
| matching: find.byType(Material), |
| ); |
| |
| // Enabled OutlineButton |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: OutlineButton( |
| onPressed: () { }, |
| child: const Text('button'), |
| ), |
| ), |
| ); |
| Material material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 75)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, const Color(0x00000000)); |
| expect(material.elevation, 0.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.textStyle.color, const Color(0xdd000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.button); |
| |
| final Offset center = tester.getCenter(find.byType(OutlineButton)); |
| await tester.startGesture(center); |
| await tester.pumpAndSettle(); |
| |
| // No change vs enabled and not pressed. |
| material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 75)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, const Color(0x00000000)); |
| expect(material.elevation, 0.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.textStyle.color, const Color(0xdd000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.button); |
| |
| // Disabled OutlineButton |
| await tester.pumpWidget( |
| const Directionality( |
| textDirection: TextDirection.ltr, |
| child: OutlineButton( |
| onPressed: null, |
| child: Text('button'), |
| ), |
| ), |
| ); |
| material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.animationDuration, const Duration(milliseconds: 75)); |
| expect(material.borderOnForeground, true); |
| expect(material.borderRadius, null); |
| expect(material.clipBehavior, Clip.none); |
| expect(material.color, const Color(0x00000000)); |
| expect(material.elevation, 0.0); |
| expect(material.shadowColor, const Color(0xff000000)); |
| expect(material.textStyle.color, const Color(0x61000000)); |
| expect(material.textStyle.fontFamily, 'Roboto'); |
| expect(material.textStyle.fontSize, 14); |
| expect(material.textStyle.fontWeight, FontWeight.w500); |
| expect(material.type, MaterialType.button); |
| }); |
| |
| testWidgets('Does FlatButton contribute semantics', (WidgetTester tester) async { |
| final SemanticsTester semantics = SemanticsTester(tester); |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: FlatButton( |
| onPressed: () { }, |
| child: const Text('ABC'), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(semantics, hasSemantics( |
| TestSemantics.root( |
| children: <TestSemantics>[ |
| TestSemantics.rootChild( |
| actions: <SemanticsAction>[ |
| SemanticsAction.tap, |
| ], |
| label: 'ABC', |
| rect: Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), |
| transform: Matrix4.translationValues(356.0, 276.0, 0.0), |
| flags: <SemanticsFlag>[ |
| SemanticsFlag.isButton, |
| SemanticsFlag.hasEnabledState, |
| SemanticsFlag.isEnabled, |
| ], |
| ), |
| ], |
| ), |
| ignoreId: true, |
| )); |
| |
| semantics.dispose(); |
| }); |
| |
| testWidgets('Does RaisedButton contribute semantics', (WidgetTester tester) async { |
| final SemanticsTester semantics = SemanticsTester(tester); |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: RaisedButton( |
| onPressed: () { }, |
| child: const Text('ABC'), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(semantics, hasSemantics( |
| TestSemantics.root( |
| children: <TestSemantics>[ |
| TestSemantics.rootChild( |
| actions: <SemanticsAction>[ |
| SemanticsAction.tap, |
| ], |
| label: 'ABC', |
| rect: Rect.fromLTRB(0.0, 0.0, 88.0, 48.0), |
| transform: Matrix4.translationValues(356.0, 276.0, 0.0), |
| flags: <SemanticsFlag>[ |
| SemanticsFlag.isButton, |
| SemanticsFlag.hasEnabledState, |
| SemanticsFlag.isEnabled, |
| ], |
| ), |
| ] |
| ), |
| ignoreId: true, |
| )); |
| |
| semantics.dispose(); |
| }); |
| |
| testWidgets('Does FlatButton scale with font scale changes', (WidgetTester tester) async { |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: MediaQuery( |
| data: const MediaQueryData(textScaleFactor: 1.0), |
| child: Center( |
| child: FlatButton( |
| onPressed: () { }, |
| child: const Text('ABC'), |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getSize(find.byType(FlatButton)), equals(const Size(88.0, 48.0))); |
| expect(tester.getSize(find.byType(Text)), equals(const Size(42.0, 14.0))); |
| |
| // textScaleFactor expands text, but not button. |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: MediaQuery( |
| data: const MediaQueryData(textScaleFactor: 1.3), |
| child: Center( |
| child: FlatButton( |
| onPressed: () { }, |
| child: const Text('ABC'), |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getSize(find.byType(FlatButton)), equals(const Size(88.0, 48.0))); |
| // Scaled text rendering is different on Linux and Mac by one pixel. |
| // TODO(gspencergoog): Figure out why this is, and fix it. https://github.com/flutter/flutter/issues/12357 |
| expect(tester.getSize(find.byType(Text)).width, isIn(<double>[54.0, 55.0])); |
| expect(tester.getSize(find.byType(Text)).height, isIn(<double>[18.0, 19.0])); |
| |
| // Set text scale large enough to expand text and button. |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: MediaQuery( |
| data: const MediaQueryData(textScaleFactor: 3.0), |
| child: Center( |
| child: FlatButton( |
| onPressed: () { }, |
| child: const Text('ABC'), |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| // Scaled text rendering is different on Linux and Mac by one pixel. |
| // TODO(gspencergoog): Figure out why this is, and fix it. https://github.com/flutter/flutter/issues/12357 |
| expect(tester.getSize(find.byType(FlatButton)).width, isIn(<double>[158.0, 159.0])); |
| expect(tester.getSize(find.byType(FlatButton)).height, equals(48.0)); |
| expect(tester.getSize(find.byType(Text)).width, isIn(<double>[126.0, 127.0])); |
| expect(tester.getSize(find.byType(Text)).height, equals(42.0)); |
| }); |
| |
| // This test is very similar to the '...explicit splashColor and highlightColor' test |
| // in icon_button_test.dart. If you change this one, you may want to also change that one. |
| testWidgets('MaterialButton with explicit splashColor and highlightColor', (WidgetTester tester) async { |
| const Color directSplashColor = Color(0xFF000011); |
| const Color directHighlightColor = Color(0xFF000011); |
| |
| Widget buttonWidget = Material( |
| child: Center( |
| child: MaterialButton( |
| splashColor: directSplashColor, |
| highlightColor: directHighlightColor, |
| onPressed: () { /* to make sure the button is enabled */ }, |
| clipBehavior: Clip.antiAlias, |
| ), |
| ), |
| ); |
| |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Theme( |
| data: ThemeData( |
| materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
| ), |
| child: buttonWidget, |
| ), |
| ), |
| ); |
| |
| final Offset center = tester.getCenter(find.byType(MaterialButton)); |
| final TestGesture gesture = await tester.startGesture(center); |
| await tester.pump(); // start gesture |
| await tester.pump(const Duration(milliseconds: 200)); // wait for splash to be well under way |
| |
| final Rect expectedClipRect = Rect.fromLTRB(356.0, 282.0, 444.0, 318.0); |
| final Path expectedClipPath = Path() |
| ..addRRect(RRect.fromRectAndRadius( |
| expectedClipRect, |
| const Radius.circular(2.0), |
| )); |
| expect( |
| Material.of(tester.element(find.byType(MaterialButton))), |
| paints |
| ..clipPath(pathMatcher: coversSameAreaAs( |
| expectedClipPath, |
| areaToCompare: expectedClipRect.inflate(10.0), |
| )) |
| ..circle(color: directSplashColor) |
| ..rect(color: directHighlightColor), |
| ); |
| |
| const Color themeSplashColor1 = Color(0xFF001100); |
| const Color themeHighlightColor1 = Color(0xFF001100); |
| |
| buttonWidget = Material( |
| child: Center( |
| child: MaterialButton( |
| onPressed: () { /* to make sure the button is enabled */ }, |
| clipBehavior: Clip.antiAlias, |
| ), |
| ), |
| ); |
| |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Theme( |
| data: ThemeData( |
| highlightColor: themeHighlightColor1, |
| splashColor: themeSplashColor1, |
| materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
| ), |
| child: buttonWidget, |
| ), |
| ), |
| ); |
| |
| expect( |
| Material.of(tester.element(find.byType(MaterialButton))), |
| paints |
| ..clipPath(pathMatcher: coversSameAreaAs( |
| expectedClipPath, |
| areaToCompare: expectedClipRect.inflate(10.0), |
| )) |
| ..circle(color: themeSplashColor1) |
| ..rect(color: themeHighlightColor1), |
| ); |
| |
| const Color themeSplashColor2 = Color(0xFF002200); |
| const Color themeHighlightColor2 = Color(0xFF002200); |
| |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Theme( |
| data: ThemeData( |
| highlightColor: themeHighlightColor2, |
| splashColor: themeSplashColor2, |
| materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
| ), |
| child: buttonWidget, // same widget, so does not get updated because of us |
| ), |
| ), |
| ); |
| |
| expect( |
| Material.of(tester.element(find.byType(MaterialButton))), |
| paints |
| ..circle(color: themeSplashColor2) |
| ..rect(color: themeHighlightColor2), |
| ); |
| |
| await gesture.up(); |
| }); |
| |
| testWidgets('MaterialButton has no clip by default', (WidgetTester tester) async { |
| final GlobalKey buttonKey = GlobalKey(); |
| final Widget buttonWidget = Material( |
| child: Center( |
| child: MaterialButton( |
| key: buttonKey, |
| onPressed: () { /* to make sure the button is enabled */ }, |
| ), |
| ), |
| ); |
| |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Theme( |
| data: ThemeData( |
| materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
| ), |
| child: buttonWidget, |
| ), |
| ), |
| ); |
| |
| expect( |
| tester.renderObject(find.byKey(buttonKey)), |
| paintsExactlyCountTimes(#clipPath, 0), |
| ); |
| }); |
| |
| testWidgets('Disabled MaterialButton has correct default text color', (WidgetTester tester) async { |
| const String testText = 'Disabled'; |
| const Widget buttonWidget = Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: MaterialButton( |
| onPressed: null, |
| child: Text(testText), // button is disabled |
| ), |
| ), |
| ), |
| ); |
| |
| await tester.pumpWidget(buttonWidget); |
| |
| final RichText text = tester.widget<RichText>(find.byType(RichText)); |
| expect(text.text.style.color, Colors.black38); |
| }); |
| |
| testWidgets('Disabled MaterialButton has same semantic size as enabled and exposes disabled semantics', (WidgetTester tester) async { |
| final SemanticsTester semantics = SemanticsTester(tester); |
| |
| final Rect expectedButtonSize = Rect.fromLTRB(0.0, 0.0, 116.0, 48.0); |
| // Button is in center of screen |
| final Matrix4 expectedButtonTransform = Matrix4.identity() |
| ..translate( |
| TestSemantics.fullScreen.width / 2 - expectedButtonSize.width /2, |
| TestSemantics.fullScreen.height / 2 - expectedButtonSize.height /2, |
| ); |
| |
| // enabled button |
| await tester.pumpWidget(Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: MaterialButton( |
| child: const Text('Button'), |
| onPressed: () { /* to make sure the button is enabled */ }, |
| ), |
| ), |
| ), |
| )); |
| |
| expect(semantics, hasSemantics( |
| TestSemantics.root( |
| children: <TestSemantics>[ |
| TestSemantics.rootChild( |
| id: 1, |
| rect: expectedButtonSize, |
| transform: expectedButtonTransform, |
| label: 'Button', |
| actions: <SemanticsAction>[ |
| SemanticsAction.tap, |
| ], |
| flags: <SemanticsFlag>[ |
| SemanticsFlag.isButton, |
| SemanticsFlag.hasEnabledState, |
| SemanticsFlag.isEnabled, |
| ], |
| ), |
| ], |
| ), |
| )); |
| |
| // disabled button |
| await tester.pumpWidget(const Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: MaterialButton( |
| child: Text('Button'), |
| onPressed: null, // button is disabled |
| ), |
| ), |
| ), |
| )); |
| |
| expect(semantics, hasSemantics( |
| TestSemantics.root( |
| children: <TestSemantics>[ |
| TestSemantics.rootChild( |
| id: 1, |
| rect: expectedButtonSize, |
| transform: expectedButtonTransform, |
| label: 'Button', |
| flags: <SemanticsFlag>[ |
| SemanticsFlag.isButton, |
| SemanticsFlag.hasEnabledState, |
| ], |
| ), |
| ], |
| ), |
| )); |
| |
| |
| semantics.dispose(); |
| }); |
| |
| testWidgets('MaterialButton minWidth and height parameters', (WidgetTester tester) async { |
| Widget buildFrame({ double minWidth, double height, EdgeInsets padding = EdgeInsets.zero, Widget child }) { |
| return Directionality( |
| textDirection: TextDirection.ltr, |
| child: Center( |
| child: MaterialButton( |
| padding: padding, |
| minWidth: minWidth, |
| height: height, |
| onPressed: null, |
| materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, |
| child: child, |
| ), |
| ), |
| ); |
| } |
| |
| await tester.pumpWidget(buildFrame(minWidth: 8.0, height: 24.0)); |
| expect(tester.getSize(find.byType(MaterialButton)), const Size(8.0, 24.0)); |
| |
| await tester.pumpWidget(buildFrame(minWidth: 8.0)); |
| // Default minHeight constraint is 36, see RawMaterialButton. |
| expect(tester.getSize(find.byType(MaterialButton)), const Size(8.0, 36.0)); |
| |
| await tester.pumpWidget(buildFrame(height: 8.0)); |
| // Default minWidth constraint is 88, see RawMaterialButton. |
| expect(tester.getSize(find.byType(MaterialButton)), const Size(88.0, 8.0)); |
| |
| await tester.pumpWidget(buildFrame()); |
| expect(tester.getSize(find.byType(MaterialButton)), const Size(88.0, 36.0)); |
| |
| await tester.pumpWidget(buildFrame(padding: const EdgeInsets.all(4.0))); |
| expect(tester.getSize(find.byType(MaterialButton)), const Size(88.0, 36.0)); |
| |
| // Size is defined by the padding. |
| await tester.pumpWidget( |
| buildFrame( |
| minWidth: 0.0, |
| height: 0.0, |
| padding: const EdgeInsets.all(4.0), |
| ), |
| ); |
| expect(tester.getSize(find.byType(MaterialButton)), const Size(8.0, 8.0)); |
| |
| // Size is defined by the padded child. |
| await tester.pumpWidget( |
| buildFrame( |
| minWidth: 0.0, |
| height: 0.0, |
| padding: const EdgeInsets.all(4.0), |
| child: const SizedBox(width: 8.0, height: 8.0), |
| ), |
| ); |
| expect(tester.getSize(find.byType(MaterialButton)), const Size(16.0, 16.0)); |
| |
| // Size is defined by the minWidth, height constraints. |
| await tester.pumpWidget( |
| buildFrame( |
| minWidth: 18.0, |
| height: 18.0, |
| padding: const EdgeInsets.all(4.0), |
| child: const SizedBox(width: 8.0, height: 8.0), |
| ), |
| ); |
| expect(tester.getSize(find.byType(MaterialButton)), const Size(18.0, 18.0)); |
| }); |
| |
| testWidgets('MaterialButton size is configurable by ThemeData.materialTapTargetSize', (WidgetTester tester) async { |
| final Key key1 = UniqueKey(); |
| await tester.pumpWidget( |
| Theme( |
| data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded), |
| child: Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: MaterialButton( |
| key: key1, |
| child: const SizedBox(width: 50.0, height: 8.0), |
| onPressed: () { }, |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getSize(find.byKey(key1)), const Size(88.0, 48.0)); |
| |
| final Key key2 = UniqueKey(); |
| await tester.pumpWidget( |
| Theme( |
| data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap), |
| child: Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: MaterialButton( |
| key: key2, |
| child: const SizedBox(width: 50.0, height: 8.0), |
| onPressed: () { }, |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getSize(find.byKey(key2)), const Size(88.0, 36.0)); |
| }); |
| |
| testWidgets('FlatButton size is configurable by ThemeData.materialTapTargetSize', (WidgetTester tester) async { |
| final Key key1 = UniqueKey(); |
| await tester.pumpWidget( |
| Theme( |
| data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded), |
| child: Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: FlatButton( |
| key: key1, |
| child: const SizedBox(width: 50.0, height: 8.0), |
| onPressed: () { }, |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getSize(find.byKey(key1)), const Size(88.0, 48.0)); |
| |
| final Key key2 = UniqueKey(); |
| await tester.pumpWidget( |
| Theme( |
| data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap), |
| child: Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: FlatButton( |
| key: key2, |
| child: const SizedBox(width: 50.0, height: 8.0), |
| onPressed: () { }, |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getSize(find.byKey(key2)), const Size(88.0, 36.0)); |
| }); |
| |
| testWidgets('RaisedButton size is configurable by ThemeData.materialTapTargetSize', (WidgetTester tester) async { |
| final Key key1 = UniqueKey(); |
| await tester.pumpWidget( |
| Theme( |
| data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.padded), |
| child: Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: RaisedButton( |
| key: key1, |
| child: const SizedBox(width: 50.0, height: 8.0), |
| onPressed: () { }, |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getSize(find.byKey(key1)), const Size(88.0, 48.0)); |
| |
| final Key key2 = UniqueKey(); |
| await tester.pumpWidget( |
| Theme( |
| data: ThemeData(materialTapTargetSize: MaterialTapTargetSize.shrinkWrap), |
| child: Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: Center( |
| child: RaisedButton( |
| key: key2, |
| child: const SizedBox(width: 50.0, height: 8.0), |
| onPressed: () { }, |
| ), |
| ), |
| ), |
| ), |
| ), |
| ); |
| |
| expect(tester.getSize(find.byKey(key2)), const Size(88.0, 36.0)); |
| }); |
| |
| testWidgets('RaisedButton has no clip by default', (WidgetTester tester) async { |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: Material( |
| child: RaisedButton( |
| onPressed: () { /* to make sure the button is enabled */ }, |
| ), |
| ), |
| ), |
| ); |
| |
| expect( |
| tester.renderObject(find.byType(RaisedButton)), |
| paintsExactlyCountTimes(#clipPath, 0), |
| ); |
| }); |
| |
| testWidgets('MaterialButton shape overrides ButtonTheme shape', (WidgetTester tester) async { |
| // Regression test for https://github.com/flutter/flutter/issues/29146 |
| await tester.pumpWidget( |
| Directionality( |
| textDirection: TextDirection.ltr, |
| child: MaterialButton( |
| onPressed: () { }, |
| shape: const StadiumBorder(), |
| child: const Text('button'), |
| ), |
| ), |
| ); |
| |
| final Finder rawButtonMaterial = find.descendant( |
| of: find.byType(MaterialButton), |
| matching: find.byType(Material), |
| ); |
| expect(tester.widget<Material>(rawButtonMaterial).shape, const StadiumBorder()); |
| }); |
| |
| testWidgets('MaterialButton defaults', (WidgetTester tester) async { |
| // Regression test for https://github.com/flutter/flutter/issues/30012. |
| |
| final Finder rawButtonMaterial = find.descendant( |
| of: find.byType(MaterialButton), |
| matching: find.byType(Material), |
| ); |
| |
| await tester.pumpWidget( |
| const Directionality( |
| textDirection: TextDirection.ltr, |
| child: MaterialButton( |
| disabledColor: Color(0xff00ff00), |
| onPressed: null, |
| child: Text('button'), |
| ), |
| ), |
| ); |
| |
| final Material material = tester.widget<Material>(rawButtonMaterial); |
| expect(material.color, const Color(0xff00ff00)); |
| }); |
| } |