diff --git a/test/combobox_test.dart b/test/combobox_test.dart new file mode 100644 index 000000000..94b1e230c --- /dev/null +++ b/test/combobox_test.dart @@ -0,0 +1,93 @@ +import 'package:fluent_ui/fluent_ui.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'app_test.dart'; + +void main() { + group('ComboBox', () { + testWidgets('is displayed correctly', (tester) async { + var selectedValue = 0; + + await tester.pumpWidget( + wrapApp( + child: ComboBox( + value: selectedValue, + items: [1, 2, 3].map((e) { + return ComboBoxItem( + value: e, + child: Text('$e'), + ); + }).toList(), + onChanged: (_) {}, + ), + ), + ); + + expect(find.byType(ComboBox), findsOneWidget); + }); + + testWidgets('is selected correctly', (tester) async { + var selectedValue = -1; + final comboBoxKey = LabeledGlobalKey('combo_box'); + + await tester.pumpWidget( + wrapApp( + child: StatefulBuilder( + builder: (context, setState) { + return ComboBox( + value: selectedValue, + key: comboBoxKey, + items: [0, 1, 2].map((e) { + return ComboBoxItem( + key: ValueKey('$e'), + value: e, + child: Text('${e + 1}'), + ); + }).toList(), + onChanged: (value) { + if (value == null) return; + setState(() { + selectedValue = value; + }); + }, + ); + }, + ), + ), + ); + + // Find ComboBox widget + final comboBox = find.byKey(comboBoxKey); + + expect(comboBox, findsOneWidget); + + // The ComboBoxItems are not visible yet + expect(find.byType(ComboBoxItem), findsNothing); + + // Tap the ComboBox + await tester.tap(find.byKey(comboBoxKey)); + await tester.pumpAndSettle(); + + // ComboBoxItems are visible + final comboBoxItems = find.byType(ComboBoxItem); + expect(comboBoxItems, findsNWidgets(3)); + + final comboBoxItem1 = find.byKey(const ValueKey('0')); + final comboBoxItem2 = find.byKey(const ValueKey('1')); + final comboBoxItem3 = find.byKey(const ValueKey('2')); + + expect(comboBoxItem1, findsOneWidget); + expect(comboBoxItem2, findsOneWidget); + expect(comboBoxItem3, findsOneWidget); + + // Select a ComboBoxItem + await tester.tap(comboBoxItem1); + await tester.pumpAndSettle(); + + // The selected ComboBoxItem is founds and the rest are not found + expect(find.byKey(const ValueKey('0')), findsOneWidget); + expect(find.byKey(const ValueKey('1')), findsNothing); + expect(find.byKey(const ValueKey('2')), findsNothing); + }); + }); +} diff --git a/test/flyout_test.dart b/test/flyout_test.dart index fb926830c..b3b5a746f 100644 --- a/test/flyout_test.dart +++ b/test/flyout_test.dart @@ -4,11 +4,70 @@ import 'package:flutter_test/flutter_test.dart'; import 'app_test.dart'; void main() { - testWidgets('FlyoutListTile can be used outside of a Flyout', (tester) async { - await tester.pumpWidget( - wrapApp( - child: const FlyoutListTile(text: Text('Copy')), - ), - ); + group('FlyoutListTile', () { + testWidgets('is displayed correctly', (tester) async { + await tester.pumpWidget( + wrapApp( + child: const FlyoutListTile( + text: Text('Copy'), + ), + ), + ); + + expect(find.byType(FlyoutListTile), findsOneWidget); + }); + + testWidgets('is rendered via controller', (tester) async { + final controller = FlyoutController(); + + await tester.pumpWidget( + wrapApp( + child: FlyoutTarget( + controller: controller, + child: Button( + child: const Text('Clear cart'), + onPressed: () { + controller.showFlyout( + autoModeConfiguration: FlyoutAutoConfiguration( + preferredMode: FlyoutPlacementMode.topCenter, + ), + barrierDismissible: true, + dismissOnPointerMoveAway: false, + dismissWithEsc: true, + builder: (context) { + return FlyoutContent( + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + const Text( + 'All items will be removed. Do you want to continue?', + style: TextStyle(fontWeight: FontWeight.bold), + ), + const SizedBox(height: 12.0), + Button( + onPressed: Flyout.of(context).close, + child: const Text('Yes, empty my cart'), + ), + ], + ), + ); + }, + ); + }, + ), + ), + ), + ); + + // Before tapping button FlyoutContent is not shown + expect(find.byType(FlyoutContent), findsNothing); + + await tester.tap(find.byType(Button)); + await tester.pumpAndSettle(); + + // After tapping button FlyoutContent is displayed + expect(find.byType(FlyoutContent), findsOneWidget); + }); }); } diff --git a/test/number_box_test.dart b/test/number_box_test.dart new file mode 100644 index 000000000..5af3ef144 --- /dev/null +++ b/test/number_box_test.dart @@ -0,0 +1,151 @@ +import 'package:fluent_ui/fluent_ui.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; + +import 'app_test.dart'; + +void main() { + group('NumberBox Test', () { + testWidgets('is displayed correctly', (tester) async { + await tester.pumpWidget( + wrapApp( + child: NumberBox( + value: 0, + onChanged: (_) {}, + ), + ), + ); + + expect(find.byType(NumberBox), findsOneWidget); + }); + + testWidgets('is increased and decreased by suffix icon button taps', + (tester) async { + final numberBoxKey = LabeledGlobalKey('number_box_key'); + var value = 0; + + await tester.pumpWidget( + wrapApp( + child: StatefulBuilder( + builder: (context, setState) { + return NumberBox( + key: numberBoxKey, + value: value, + mode: SpinButtonPlacementMode.inline, + onChanged: (newValue) { + if (newValue == null) return; + setState(() { + value = newValue; + }); + }, + ); + }, + ), + ), + ); + + expect(find.byType(NumberBox), findsOneWidget); + var numberBox = numberBoxKey.currentWidget as NumberBox; + + // Default value should be 0 + expect(numberBox.value, 0); + + final incrementWidget = find.byIcon(FluentIcons.chevron_up); + expect(incrementWidget, findsOneWidget); + + await tester.tap(incrementWidget); + await tester.pumpAndSettle(); + + // NumberBox value should increase + numberBox = numberBoxKey.currentWidget as NumberBox; + expect(numberBox.value, 1); + expect(value, 1); + + final decrementWidget = find.byIcon(FluentIcons.chevron_down); + expect(decrementWidget, findsOneWidget); + + await tester.tap(decrementWidget); + await tester.pumpAndSettle(); + + // NumberBox value should decrease + numberBox = numberBoxKey.currentWidget as NumberBox; + expect(numberBox.value, 0); + expect(value, 0); + }); + + testWidgets( + 'is increased and decreased by keyboard keys', + (tester) async { + final numberBoxKey = LabeledGlobalKey('number_box_key'); + var value = 0; + + await tester.pumpWidget( + wrapApp( + child: StatefulBuilder( + builder: (context, setState) { + return NumberBox( + key: numberBoxKey, + value: value, + mode: SpinButtonPlacementMode.inline, + onChanged: (newValue) { + if (newValue == null) return; + setState(() { + value = newValue; + }); + }, + ); + }, + ), + ), + ); + + expect(find.byType(NumberBox), findsOneWidget); + + await tester.showKeyboard(find.byType(NumberBox)); + await tester.sendKeyEvent(LogicalKeyboardKey.arrowUp); + await tester.pumpAndSettle(); + + // On LogicalKeyboardKey.arrowUp, NumberBox should get incremented + // by `min` which is 1 in our case + var numberBox = numberBoxKey.currentWidget as NumberBox; + expect(numberBox.value, 1); + expect(value, 1); + + await tester.sendKeyEvent(LogicalKeyboardKey.arrowDown); + await tester.pumpAndSettle(); + + // On LogicalKeyboardKey.arrowDown, NumberBox should get decremented + // by `min` which is 1 in our case + numberBox = numberBoxKey.currentWidget as NumberBox; + expect(numberBox.value, 0); + expect(value, 0); + + await tester.sendKeyEvent(LogicalKeyboardKey.pageUp); + await tester.pumpAndSettle(); + + // On LogicalKeyboardKey.pageUp, NumberBox should get incremented + // by `max` which is 10 in our case + numberBox = numberBoxKey.currentWidget as NumberBox; + expect(numberBox.value, 10); + expect(value, 10); + + await tester.sendKeyEvent(LogicalKeyboardKey.pageDown); + await tester.pumpAndSettle(); + + // On LogicalKeyboardKey.pageDown, NumberBox should get decremented + // by `max` which is 10 in our case + numberBox = numberBoxKey.currentWidget as NumberBox; + expect(numberBox.value, 0); + expect(value, 0); + + await tester.sendKeyEvent(LogicalKeyboardKey.keyA); + await tester.pumpAndSettle(); + + // NumberBox should ignore alphabetic key events + numberBox = numberBoxKey.currentWidget as NumberBox; + expect(numberBox.value, 0); + expect(value, 0); + }, + ); + }); +} diff --git a/test/radio_button_test.dart b/test/radio_button_test.dart index ba9055a33..7ba7d918e 100644 --- a/test/radio_button_test.dart +++ b/test/radio_button_test.dart @@ -4,35 +4,90 @@ import 'package:flutter_test/flutter_test.dart'; import 'app_test.dart'; void main() { - testWidgets('RadioButton change state accordingly', - (WidgetTester tester) async { - var radioButtonValue = false; - - await tester.pumpWidget( - StatefulBuilder( - builder: (BuildContext context, StateSetter setState) { - return wrapApp( - child: RadioButton( - checked: radioButtonValue, - onChanged: (bool value) { - setState(() { - radioButtonValue = value; - }); - }, - ), - ); - }, - ), - ); - - expect(tester.widget(find.byType(RadioButton)).checked, false); - - await tester.tap(find.byType(RadioButton)); - await tester.pumpAndSettle(); - expect(radioButtonValue, true); - - await tester.tap(find.byType(RadioButton)); - await tester.pumpAndSettle(); - expect(radioButtonValue, false); + group('RadioButton Test', () { + testWidgets('RadioButton is displayed correctly', + (WidgetTester tester) async { + await tester.pumpWidget( + wrapApp( + child: RadioButton(checked: true, onChanged: (_) {}), + ), + ); + + final radioFinder = find.byType(RadioButton); + expect(radioFinder, findsOneWidget); + }); + + testWidgets('RadioButton is selectable', (WidgetTester tester) async { + var selectedIndex = -1; + + final firstKey = LabeledGlobalKey('0'); + final secondKey = LabeledGlobalKey('1'); + final thirdKey = LabeledGlobalKey('2'); + + final keys = [firstKey, secondKey, thirdKey]; + + await tester.pumpWidget( + wrapApp( + child: StatefulBuilder( + builder: (BuildContext context, StateSetter setState) { + return Column( + children: List.generate(3, (index) { + return RadioButton( + key: keys[index], + checked: index == selectedIndex, + onChanged: (bool value) { + setState(() { + selectedIndex = index; + }); + }, + ); + }), + ); + }, + ), + ), + ); + + // Check for 3 RadioButton widgets + final radioFinder = find.byType(RadioButton); + expect(radioFinder, findsNWidgets(3)); + + var firstRadio = firstKey.currentWidget as RadioButton; + var secondRadio = secondKey.currentWidget as RadioButton; + var thirdRadio = thirdKey.currentWidget as RadioButton; + + // Check for initial states + expect(firstRadio.checked, false); + expect(secondRadio.checked, false); + expect(thirdRadio.checked, false); + + // Update state by tapping on the first RadioButton + await tester.tap(find.byKey(firstKey)); + await tester.pumpAndSettle(); + expect(selectedIndex, 0); + + firstRadio = firstKey.currentWidget as RadioButton; + secondRadio = secondKey.currentWidget as RadioButton; + thirdRadio = thirdKey.currentWidget as RadioButton; + + // Check checked state for all RadioButton widgets + expect(firstRadio.checked, true); + expect(secondRadio.checked, false); + expect(thirdRadio.checked, false); + + // Tap on third RadioButton + await tester.tap(find.byKey(thirdKey)); + await tester.pumpAndSettle(); + expect(selectedIndex, 2); + + firstRadio = firstKey.currentWidget as RadioButton; + secondRadio = secondKey.currentWidget as RadioButton; + thirdRadio = thirdKey.currentWidget as RadioButton; + + // Check state of all RadioButton widgets + expect(firstRadio.checked, false); + expect(secondRadio.checked, false); + expect(thirdRadio.checked, true); + }); }); }