// 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/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; void main() { test('DropdownMenuThemeData copyWith, ==, hashCode basics', () { expect(const DropdownMenuThemeData(), const DropdownMenuThemeData().copyWith()); expect(const DropdownMenuThemeData().hashCode, const DropdownMenuThemeData().copyWith().hashCode); const DropdownMenuThemeData custom = DropdownMenuThemeData( menuStyle: MenuStyle(backgroundColor: MaterialStatePropertyAll<Color>(Colors.green)), inputDecorationTheme: InputDecorationTheme(filled: true), textStyle: TextStyle(fontSize: 25.0), ); final DropdownMenuThemeData copy = const DropdownMenuThemeData().copyWith( menuStyle: custom.menuStyle, inputDecorationTheme: custom.inputDecorationTheme, textStyle: custom.textStyle, ); expect(copy, custom); }); testWidgets('Default DropdownMenuThemeData debugFillProperties', (WidgetTester tester) async { final DiagnosticPropertiesBuilder builder = DiagnosticPropertiesBuilder(); const DropdownMenuThemeData().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('With no other configuration, defaults are used', (WidgetTester tester) async { final ThemeData themeData = ThemeData(); await tester.pumpWidget( MaterialApp( theme: themeData, home: const Scaffold( body: Center( child: DropdownMenu<int>( dropdownMenuEntries: <DropdownMenuEntry<int>>[ DropdownMenuEntry<int>(value: 0, label: 'Item 0'), DropdownMenuEntry<int>(value: 1, label: 'Item 1'), DropdownMenuEntry<int>(value: 2, label: 'Item 2'), ], ), ), ), ) ); final EditableText editableText = tester.widget(find.byType(EditableText)); expect(editableText.style.color, themeData.textTheme.labelLarge!.color); expect(editableText.style.background, themeData.textTheme.labelLarge!.background); expect(editableText.style.shadows, themeData.textTheme.labelLarge!.shadows); expect(editableText.style.decoration, themeData.textTheme.labelLarge!.decoration); expect(editableText.style.locale, themeData.textTheme.labelLarge!.locale); expect(editableText.style.wordSpacing, themeData.textTheme.labelLarge!.wordSpacing); final TextField textField = tester.widget(find.byType(TextField)); expect(textField.decoration?.border, const OutlineInputBorder()); await tester.tap(find.widgetWithIcon(IconButton, Icons.arrow_drop_down).first); await tester.pump(); expect(find.byType(MenuAnchor), findsOneWidget); final Finder menuMaterial = find.ancestor( of: find.widgetWithText(TextButton, 'Item 0'), matching: find.byType(Material), ).last; Material material = tester.widget<Material>(menuMaterial); expect(material.color, themeData.colorScheme.surface); expect(material.shadowColor, themeData.colorScheme.shadow); expect(material.surfaceTintColor, themeData.colorScheme.surfaceTint); expect(material.elevation, 3.0); expect(material.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(4.0)))); final Finder buttonMaterial = find.descendant( of: find.widgetWithText(TextButton, 'Item 0'), matching: find.byType(Material), ).last; material = tester.widget<Material>(buttonMaterial); expect(material.color, Colors.transparent); expect(material.elevation, 0.0); expect(material.shape, const RoundedRectangleBorder()); expect(material.textStyle?.color, themeData.colorScheme.onSurface); }); testWidgets('ThemeData.dropdownMenuTheme overrides defaults', (WidgetTester tester) async { final ThemeData theme = ThemeData( dropdownMenuTheme: DropdownMenuThemeData( textStyle: TextStyle( color: Colors.orange, backgroundColor: Colors.indigo, fontSize: 30.0, shadows: kElevationToShadow[1], decoration: TextDecoration.underline, wordSpacing: 2.0, ), menuStyle: const MenuStyle( backgroundColor: MaterialStatePropertyAll<Color>(Colors.grey), shadowColor: MaterialStatePropertyAll<Color>(Colors.brown), surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.amberAccent), elevation: MaterialStatePropertyAll<double>(10.0), shape: MaterialStatePropertyAll<OutlinedBorder>( RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))), ), ), inputDecorationTheme: const InputDecorationTheme(filled: true, fillColor: Colors.lightGreen), ) ); await tester.pumpWidget( MaterialApp( theme: theme, home: const Scaffold( body: Center( child: DropdownMenu<int>( dropdownMenuEntries: <DropdownMenuEntry<int>>[ DropdownMenuEntry<int>(value: 0, label: 'Item 0'), DropdownMenuEntry<int>(value: 1, label: 'Item 1'), DropdownMenuEntry<int>(value: 2, label: 'Item 2'), ], ), ), ) ) ); final EditableText editableText = tester.widget(find.byType(EditableText)); expect(editableText.style.color, Colors.orange); expect(editableText.style.backgroundColor, Colors.indigo); expect(editableText.style.shadows, kElevationToShadow[1]); expect(editableText.style.decoration, TextDecoration.underline); expect(editableText.style.wordSpacing, 2.0); final TextField textField = tester.widget(find.byType(TextField)); expect(textField.decoration?.filled, isTrue); expect(textField.decoration?.fillColor, Colors.lightGreen); await tester.tap(find.widgetWithIcon(IconButton, Icons.arrow_drop_down).first); await tester.pump(); expect(find.byType(MenuAnchor), findsOneWidget); final Finder menuMaterial = find.ancestor( of: find.widgetWithText(TextButton, 'Item 0'), matching: find.byType(Material), ).last; Material material = tester.widget<Material>(menuMaterial); expect(material.color, Colors.grey); expect(material.shadowColor, Colors.brown); expect(material.surfaceTintColor, Colors.amberAccent); expect(material.elevation, 10.0); expect(material.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0)))); final Finder buttonMaterial = find.descendant( of: find.widgetWithText(TextButton, 'Item 0'), matching: find.byType(Material), ).last; material = tester.widget<Material>(buttonMaterial); expect(material.color, Colors.transparent); expect(material.elevation, 0.0); expect(material.shape, const RoundedRectangleBorder()); expect(material.textStyle?.color, theme.colorScheme.onSurface); }); testWidgets('DropdownMenuTheme overrides ThemeData and defaults', (WidgetTester tester) async { final DropdownMenuThemeData global = DropdownMenuThemeData( textStyle: TextStyle( color: Colors.orange, backgroundColor: Colors.indigo, fontSize: 30.0, shadows: kElevationToShadow[1], decoration: TextDecoration.underline, wordSpacing: 2.0, ), menuStyle: const MenuStyle( backgroundColor: MaterialStatePropertyAll<Color>(Colors.grey), shadowColor: MaterialStatePropertyAll<Color>(Colors.brown), surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.amberAccent), elevation: MaterialStatePropertyAll<double>(10.0), shape: MaterialStatePropertyAll<OutlinedBorder>( RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))), ), ), inputDecorationTheme: const InputDecorationTheme(filled: true, fillColor: Colors.lightGreen), ); final DropdownMenuThemeData dropdownMenuTheme = DropdownMenuThemeData( textStyle: TextStyle( color: Colors.red, backgroundColor: Colors.orange, fontSize: 27.0, shadows: kElevationToShadow[2], decoration: TextDecoration.lineThrough, wordSpacing: 5.0, ), menuStyle: const MenuStyle( backgroundColor: MaterialStatePropertyAll<Color>(Colors.yellow), shadowColor: MaterialStatePropertyAll<Color>(Colors.green), surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.teal), elevation: MaterialStatePropertyAll<double>(15.0), shape: MaterialStatePropertyAll<OutlinedBorder>( RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))), ), ), inputDecorationTheme: const InputDecorationTheme(filled: true, fillColor: Colors.blue), ); final ThemeData theme = ThemeData(dropdownMenuTheme: global); await tester.pumpWidget( MaterialApp( theme: theme, home: DropdownMenuTheme( data: dropdownMenuTheme, child: const Scaffold( body: Center( child: DropdownMenu<int>( dropdownMenuEntries: <DropdownMenuEntry<int>>[ DropdownMenuEntry<int>(value: 0, label: 'Item 0'), DropdownMenuEntry<int>(value: 1, label: 'Item 1'), DropdownMenuEntry<int>(value: 2, label: 'Item 2'), ], ), ), ), ) ) ); final EditableText editableText = tester.widget(find.byType(EditableText)); expect(editableText.style.color, Colors.red); expect(editableText.style.backgroundColor, Colors.orange); expect(editableText.style.fontSize, 27.0); expect(editableText.style.shadows, kElevationToShadow[2]); expect(editableText.style.decoration, TextDecoration.lineThrough); expect(editableText.style.wordSpacing, 5.0); final TextField textField = tester.widget(find.byType(TextField)); expect(textField.decoration?.filled, isTrue); expect(textField.decoration?.fillColor, Colors.blue); await tester.tap(find.widgetWithIcon(IconButton, Icons.arrow_drop_down).first); await tester.pump(); expect(find.byType(MenuAnchor), findsOneWidget); final Finder menuMaterial = find.ancestor( of: find.widgetWithText(TextButton, 'Item 0'), matching: find.byType(Material), ).last; Material material = tester.widget<Material>(menuMaterial); expect(material.color, Colors.yellow); expect(material.shadowColor, Colors.green); expect(material.surfaceTintColor, Colors.teal); expect(material.elevation, 15.0); expect(material.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0)))); final Finder buttonMaterial = find.descendant( of: find.widgetWithText(TextButton, 'Item 0'), matching: find.byType(Material), ).last; material = tester.widget<Material>(buttonMaterial); expect(material.color, Colors.transparent); expect(material.elevation, 0.0); expect(material.shape, const RoundedRectangleBorder()); expect(material.textStyle?.color, theme.colorScheme.onSurface); }); testWidgets('Widget parameters overrides DropdownMenuTheme, ThemeData and defaults', (WidgetTester tester) async { final DropdownMenuThemeData global = DropdownMenuThemeData( textStyle: TextStyle( color: Colors.orange, backgroundColor: Colors.indigo, fontSize: 30.0, shadows: kElevationToShadow[1], decoration: TextDecoration.underline, wordSpacing: 2.0, ), menuStyle: const MenuStyle( backgroundColor: MaterialStatePropertyAll<Color>(Colors.grey), shadowColor: MaterialStatePropertyAll<Color>(Colors.brown), surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.amberAccent), elevation: MaterialStatePropertyAll<double>(10.0), shape: MaterialStatePropertyAll<OutlinedBorder>( RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(10.0))), ), ), inputDecorationTheme: const InputDecorationTheme(filled: true, fillColor: Colors.lightGreen), ); final DropdownMenuThemeData dropdownMenuTheme = DropdownMenuThemeData( textStyle: TextStyle( color: Colors.red, backgroundColor: Colors.orange, fontSize: 27.0, shadows: kElevationToShadow[2], decoration: TextDecoration.lineThrough, wordSpacing: 5.0, ), menuStyle: const MenuStyle( backgroundColor: MaterialStatePropertyAll<Color>(Colors.yellow), shadowColor: MaterialStatePropertyAll<Color>(Colors.green), surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.teal), elevation: MaterialStatePropertyAll<double>(15.0), shape: MaterialStatePropertyAll<OutlinedBorder>( RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(8.0))), ), ), inputDecorationTheme: const InputDecorationTheme(filled: true, fillColor: Colors.blue), ); final ThemeData theme = ThemeData(dropdownMenuTheme: global); await tester.pumpWidget( MaterialApp( theme: theme, home: DropdownMenuTheme( data: dropdownMenuTheme, child: Scaffold( body: Center( child: DropdownMenu<int>( textStyle: TextStyle( color: Colors.pink, backgroundColor: Colors.cyan, fontSize: 32.0, shadows: kElevationToShadow[3], decoration: TextDecoration.overline, wordSpacing: 3.0, ), menuStyle: const MenuStyle( backgroundColor: MaterialStatePropertyAll<Color>(Colors.limeAccent), shadowColor: MaterialStatePropertyAll<Color>(Colors.deepOrangeAccent), surfaceTintColor: MaterialStatePropertyAll<Color>(Colors.lightBlue), elevation: MaterialStatePropertyAll<double>(21.0), shape: MaterialStatePropertyAll<OutlinedBorder>( RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(15.0))), ), ), inputDecorationTheme: const InputDecorationTheme(filled: true, fillColor: Colors.deepPurple), dropdownMenuEntries: const <DropdownMenuEntry<int>>[ DropdownMenuEntry<int>(value: 0, label: 'Item 0'), DropdownMenuEntry<int>(value: 1, label: 'Item 1'), DropdownMenuEntry<int>(value: 2, label: 'Item 2'), ], ), ), ), ) ) ); final EditableText editableText = tester.widget(find.byType(EditableText)); expect(editableText.style.color, Colors.pink); expect(editableText.style.backgroundColor, Colors.cyan); expect(editableText.style.fontSize, 32.0); expect(editableText.style.shadows, kElevationToShadow[3]); expect(editableText.style.decoration, TextDecoration.overline); expect(editableText.style.wordSpacing, 3.0); final TextField textField = tester.widget(find.byType(TextField)); expect(textField.decoration?.filled, isTrue); expect(textField.decoration?.fillColor, Colors.deepPurple); await tester.tap(find.widgetWithIcon(IconButton, Icons.arrow_drop_down).first); await tester.pump(); expect(find.byType(MenuAnchor), findsOneWidget); final Finder menuMaterial = find.ancestor( of: find.widgetWithText(TextButton, 'Item 0'), matching: find.byType(Material), ).last; Material material = tester.widget<Material>(menuMaterial); expect(material.color, Colors.limeAccent); expect(material.shadowColor, Colors.deepOrangeAccent); expect(material.surfaceTintColor, Colors.lightBlue); expect(material.elevation, 21.0); expect(material.shape, const RoundedRectangleBorder(borderRadius: BorderRadius.all(Radius.circular(15.0)))); final Finder buttonMaterial = find.descendant( of: find.widgetWithText(TextButton, 'Item 0'), matching: find.byType(Material), ).last; material = tester.widget<Material>(buttonMaterial); expect(material.color, Colors.transparent); expect(material.elevation, 0.0); expect(material.shape, const RoundedRectangleBorder()); expect(material.textStyle?.color, theme.colorScheme.onSurface); }); }