diff --git a/test/accordion_test.dart b/test/accordion_test.dart index 1a8e4067..6709befb 100644 --- a/test/accordion_test.dart +++ b/test/accordion_test.dart @@ -2,54 +2,55 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -enum AccordionItems { first, second } +enum _AccordionItems { first, second } -void main() { - const key = Key("accordion_test"); +const Key _accordionKey = Key("accordionKey"); +const Key _firstAccordionKey = Key("firstAccordionKey"); +const Key _firstAccordionChildKey = Key("firstAccordionChildKey"); +const Key _secondAccordionKey = Key("secondAccordionKey"); +const Key _secondAccordionChildKey = Key("secondAccordionChildKey"); + +const String _accordionLabel = "Label"; +const String _accordionContent = "Content"; +const IconData _accordionTrailingIcon = MoonIcons.other_frame_24_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - Directionality( - textDirection: TextDirection.ltr, - child: MoonAccordion( - key: key, - label: const Text("Title"), - children: [ - Container(), - ], - ), + const _AccordionTestWidget( + accordionKey: _accordionKey, ), ); - expect(find.byKey(key), findsOneWidget); + + expect(find.byKey(_accordionKey), findsOneWidget); }); group('Single accordion', () { - testWidgets("Accordion expands after click", (tester) async { - await tester.pumpWidget( - const SingleAccordionTestWidget(), - ); - final accordion = find.byKey(firstAccordionKey); - final child = find.byKey(firstAccordionChildKey); + testWidgets("Accordion expands when tapped.", (tester) async { + await tester.pumpWidget(const _SingleAccordionTestWidget()); + final accordion = find.byKey(_firstAccordionKey); + final child = find.byKey(_firstAccordionChildKey); expect(accordion, findsOneWidget); expect(child, findsNothing); - expect(find.text(accordionTitle), findsOneWidget); - expect(find.byIcon(accordionIcon), findsOneWidget); + expect(find.text(_accordionLabel), findsOneWidget); + expect(find.byIcon(_accordionTrailingIcon), findsOneWidget); await tester.tap(accordion); await tester.pumpAndSettle(); expect(child, findsOneWidget); - expect(find.text(accordionContent), findsOneWidget); + expect(find.text(_accordionContent), findsOneWidget); }); - testWidgets("Disabled accordion not expands after click", (tester) async { + + testWidgets("Disabled accordion does not expand when tapped.", (tester) async { await tester.pumpWidget( - const SingleAccordionTestWidget( + const _SingleAccordionTestWidget( isDisabled: true, ), ); - final accordion = find.byKey(firstAccordionKey); - final child = find.byKey(firstAccordionChildKey); + final accordion = find.byKey(_firstAccordionKey); + final child = find.byKey(_firstAccordionChildKey); expect(accordion, findsOneWidget); expect(child, findsNothing); @@ -62,30 +63,29 @@ void main() { }); group('Grouped accordion', () { - testWidgets("First accordion hides when second expands", (tester) async { - await tester.pumpWidget( - const GroupedAccordionTestWidget(), - ); - final accordion1 = find.byKey(firstAccordionKey); - final child1 = find.byKey(firstAccordionChildKey); - - final accordion2 = find.byKey(secondAccordionKey); - final child2 = find.byKey(secondAccordionChildKey); - - //Initially first accordion is expanded + testWidgets("First accordion collapses when second accordion expands.", (tester) async { + await tester.pumpWidget(const _GroupedAccordionTestWidget()); + // First accordion. + final accordion1 = find.byKey(_firstAccordionKey); + final child1 = find.byKey(_firstAccordionChildKey); + // Second accordion. + final accordion2 = find.byKey(_secondAccordionKey); + final child2 = find.byKey(_secondAccordionChildKey); + + // Initially, the first accordion is expanded. expect(accordion1, findsOneWidget); expect(accordion2, findsOneWidget); expect(child1, findsOneWidget); expect(child2, findsNothing); - //Tap on second accordion to expand it + // Tap on the second accordion to expand it and collapse the first one. await tester.tap(accordion2); await tester.pumpAndSettle(); expect(child2, findsOneWidget); expect(child1, findsNothing); - //Tap on second accordion again to close it + // Tap on the second accordion again to collapse it. await tester.tap(accordion2); await tester.pumpAndSettle(); @@ -95,41 +95,42 @@ void main() { }); } -const String accordionTitle = "Single MoonAccordion item"; -const String accordionContent = "Accordion content"; -const IconData accordionIcon = MoonIcons.other_frame_24_light; +class _AccordionTestWidget extends StatelessWidget { + final Key? accordionKey; -const firstAccordionKey = Key("first_accordion"); -const firstAccordionChildKey = Key("first_accordion_child"); -const secondAccordionKey = Key("second_accordion"); -const secondAccordionChildKey = Key("second_accordion_child"); + const _AccordionTestWidget({this.accordionKey}); -class SingleAccordionTestWidget extends StatelessWidget { + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: MoonAccordion<_AccordionItems>( + key: accordionKey, + label: const Text(_accordionLabel), + ), + ), + ); + } +} + +class _SingleAccordionTestWidget extends StatelessWidget { final bool isDisabled; - const SingleAccordionTestWidget({super.key, this.isDisabled = false}); + const _SingleAccordionTestWidget({this.isDisabled = false}); + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( - body: MoonAccordion( + body: MoonAccordion<_AccordionItems>( + key: _firstAccordionKey, isDisabled: isDisabled, - key: firstAccordionKey, - accordionSize: MoonAccordionSize.md, - textColor: context.moonColors?.piccolo, - expandedTextColor: Colors.amber, - iconColor: Colors.red, - expandedIconColor: Colors.green, - borderColor: Colors.blue, - backgroundColor: Colors.yellow, - expandedBackgroundColor: Colors.brown, - childrenPadding: const EdgeInsets.all(12), - leading: const Icon(accordionIcon), - label: const Text(accordionTitle), + leading: const Icon(_accordionTrailingIcon), + label: const Text(_accordionLabel), children: const [ Text( - accordionContent, - key: firstAccordionChildKey, + key: _firstAccordionChildKey, + _accordionContent, ), ], ), @@ -138,55 +139,47 @@ class SingleAccordionTestWidget extends StatelessWidget { } } -class GroupedAccordionTestWidget extends StatefulWidget { - const GroupedAccordionTestWidget({ - super.key, - }); +class _GroupedAccordionTestWidget extends StatefulWidget { + const _GroupedAccordionTestWidget(); @override - State createState() => _GroupedAccordionTestWidgetState(); + State<_GroupedAccordionTestWidget> createState() => _GroupedAccordionTestWidgetState(); } -class _GroupedAccordionTestWidgetState extends State { - AccordionItems? _currentlyOpenAccordionItem = AccordionItems.first; +class _GroupedAccordionTestWidgetState extends State<_GroupedAccordionTestWidget> { + _AccordionItems? _currentlyOpenAccordionItem = _AccordionItems.first; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: ListView( - clipBehavior: Clip.none, children: [ - MoonAccordion( - key: firstAccordionKey, - identityValue: AccordionItems.first, + MoonAccordion<_AccordionItems>( + key: _firstAccordionKey, + identityValue: _AccordionItems.first, groupIdentityValue: _currentlyOpenAccordionItem, - onExpansionChanged: (AccordionItems? value) { - setState(() => _currentlyOpenAccordionItem = value); - }, + onExpansionChanged: (_AccordionItems? value) => setState(() => _currentlyOpenAccordionItem = value), leading: const Icon(MoonIcons.other_frame_24_light), label: const Text("Grouped MoonAccordion item #1"), children: const [ Text( - accordionContent, - key: firstAccordionChildKey, + key: _firstAccordionChildKey, + _accordionContent, ), ], ), - const SizedBox(height: 8), - MoonAccordion( - key: secondAccordionKey, - identityValue: AccordionItems.second, + MoonAccordion<_AccordionItems>( + key: _secondAccordionKey, + identityValue: _AccordionItems.second, groupIdentityValue: _currentlyOpenAccordionItem, - onExpansionChanged: (AccordionItems? value) { - setState(() => _currentlyOpenAccordionItem = value); - }, + onExpansionChanged: (_AccordionItems? value) => setState(() => _currentlyOpenAccordionItem = value), leading: const Icon(MoonIcons.other_frame_24_light), label: const Text("Grouped MoonAccordion item #2"), children: const [ Text( - accordionContent, - key: secondAccordionChildKey, + key: _secondAccordionChildKey, + _accordionContent, ), ], ), diff --git a/test/alert_test.dart b/test/alert_test.dart index 02c868a0..81627bb3 100644 --- a/test/alert_test.dart +++ b/test/alert_test.dart @@ -2,82 +2,85 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("alert_test"); +const Key _alertKey = Key("alertKey"); +const Key _closeButtonKey = Key("closeButtonKey"); + +const String _alertLabel = "Label"; +const String _alertBody = "Body"; +const IconData _alertLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _alertTrailingIcon = MoonIcons.controls_close_small_24_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: MoonAlert( - key: key, - label: Text(alertTitle), - ), + const _AlertTestWidget( + alertKey: _alertKey, ), ); - expect(find.byKey(key), findsOneWidget); + + expect(find.byKey(_alertKey), findsOneWidget); }); - testWidgets("Simple alert", (tester) async { - await tester.pumpWidget( - const TestWidget(), - ); + testWidgets("Alert has only label widget and no leading, trailing or body widget.", (tester) async { + await tester.pumpWidget(const _AlertTestWidget()); - expect(find.text(alertTitle), findsOneWidget); + expect(find.text(_alertLabel), findsOneWidget); + expect(find.text(_alertBody), findsNothing); + expect(find.byIcon(_alertTrailingIcon), findsNothing); + expect(find.byIcon(_alertLeadingIcon), findsNothing); }); - testWidgets("Alert with leading, trailing, body", (tester) async { + testWidgets("Alert has a leading, trailing and body widget.", (tester) async { await tester.pumpWidget( - const TestWidget( + const _AlertTestWidget( showLeading: true, showBody: true, showTrailing: true, ), ); - expect(find.text(alertTitle), findsOneWidget); - expect(find.text(alertBody), findsOneWidget); - expect(find.byIcon(trailingIcon), findsOneWidget); - expect(find.byIcon(leadingIcon), findsOneWidget); + + expect(find.text(_alertLabel), findsOneWidget); + expect(find.text(_alertBody), findsOneWidget); + expect(find.byIcon(_alertTrailingIcon), findsOneWidget); + expect(find.byIcon(_alertLeadingIcon), findsOneWidget); }); - testWidgets("Hide alert", (tester) async { + testWidgets("Alert is not visible when the 'close' button is tapped.", (tester) async { await tester.pumpWidget( - const TestWidget( + const _AlertTestWidget( showTrailing: true, ), ); - final trailing = find.byIcon(trailingIcon); + final trailing = find.byKey(_closeButtonKey); - expect(find.text(alertTitle), findsOneWidget); + expect(find.text(_alertLabel), findsOneWidget); expect(trailing, findsOneWidget); - await tester.tap(trailing); + await tester.tap(trailing, warnIfMissed: false); await tester.pumpAndSettle(); - expect(find.text(alertTitle), findsNothing); + + expect(find.text(_alertLabel), findsNothing); }); } -const String alertTitle = "Alert title"; -const String alertBody = "Alert body"; -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; - -class TestWidget extends StatefulWidget { +class _AlertTestWidget extends StatefulWidget { + final Key? alertKey; final bool showLeading; final bool showTrailing; final bool showBody; - const TestWidget({ - super.key, + const _AlertTestWidget({ + this.alertKey, this.showLeading = false, this.showTrailing = false, this.showBody = false, }); + @override - State createState() => _TestWidgetState(); + State<_AlertTestWidget> createState() => _AlertTestWidgetState(); } -class _TestWidgetState extends State { +class _AlertTestWidgetState extends State<_AlertTestWidget> { bool _showAlert = true; @override @@ -85,33 +88,18 @@ class _TestWidgetState extends State { return MaterialApp( home: Scaffold( body: MoonAlert( + key: widget.alertKey, show: _showAlert, - leading: widget.showLeading ? const Icon(leadingIcon) : null, - label: const SizedBox( - height: 24, - child: Align( - alignment: AlignmentDirectional.centerStart, - child: Text(alertTitle), - ), - ), + leading: widget.showLeading ? const Icon(_alertLeadingIcon) : null, + label: const Text(_alertLabel), trailing: widget.showTrailing ? MoonButton.icon( - buttonSize: MoonButtonSize.xs, - disabledOpacityValue: 1, - icon: const Icon(trailingIcon, size: 24), - gap: 0, + key: _closeButtonKey, + icon: const Icon(_alertTrailingIcon), onTap: () => setState(() => _showAlert = !_showAlert), ) : null, - content: widget.showBody - ? const SizedBox( - height: 24, - child: Align( - alignment: AlignmentDirectional.centerStart, - child: Text(alertBody), - ), - ) - : null, + content: widget.showBody ? const Text(_alertBody) : null, ), ), ); diff --git a/test/auth_code_test.dart b/test/auth_code_test.dart index 0c7bb2e5..65a99aeb 100644 --- a/test/auth_code_test.dart +++ b/test/auth_code_test.dart @@ -2,69 +2,65 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("auth_code_test"); +const Key _authCodeKey = Key("authCodeKey"); + +const String _validatorErrorMessage = 'Validator error message.'; +const String _providedErrorMessage = 'Provided error message.'; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - authCodeKey: key, + const _AuthCodeTestWidget( + authCodeKey: _authCodeKey, ), ); - expect(find.byKey(key), findsOneWidget); + + expect(find.byKey(_authCodeKey), findsOneWidget); }); - testWidgets("Enter valid code", (tester) async { - await tester.pumpWidget( - const TestWidget( - authCodeKey: key, - ), - ); + testWidgets("When valid code is entered, error message is not shown.", (tester) async { + await tester.pumpWidget(const _AuthCodeTestWidget()); final widget = find.byType(TextFormField).first; + await tester.enterText(widget, '9921'); - await tester.pump(const Duration(milliseconds: 110)); - expect(find.text(errorMessage), findsNothing); + await tester.pump(); + + expect(find.text(_validatorErrorMessage), findsNothing); }); - testWidgets("Enter invalid code", (tester) async { - await tester.pumpWidget( - const TestWidget( - authCodeKey: key, - ), - ); + + testWidgets("When invalid code is entered, error message is shown.", (tester) async { + await tester.pumpWidget(const _AuthCodeTestWidget()); final widget = find.byType(TextFormField).first; + await tester.enterText(widget, '1111'); - await tester.pump(const Duration(milliseconds: 110)); - expect(find.text(errorMessage), findsOneWidget); + await tester.pump(); + + expect(find.text(_validatorErrorMessage), findsOneWidget); }); - testWidgets("Initial error message", (tester) async { + testWidgets("Validator errors take precedence over the provided errorText.", (tester) async { await tester.pumpWidget( - const TestWidget( - authCodeKey: key, - initialErrorMessage: initialErrorMessage, + const _AuthCodeTestWidget( + providedErrorMessage: _providedErrorMessage, ), ); final widget = find.byType(TextFormField).first; - expect(find.text(initialErrorMessage), findsOneWidget); - await tester.enterText(widget, '1111'); - await tester.pump(const Duration(milliseconds: 110)); - expect(find.text(initialErrorMessage), findsNothing); - expect(find.text(errorMessage), findsOneWidget); - }); -} -const errorMessage = 'Invalid authentication code. Please try again.'; -const initialErrorMessage = 'Initial error message'; + expect(find.text(_providedErrorMessage), findsOneWidget); + + await tester.enterText(widget, '1111'); + await tester.pump(); -class TestWidget extends StatelessWidget { - const TestWidget({ - super.key, - this.authCodeKey, - this.initialErrorMessage, + expect(find.text(_providedErrorMessage), findsNothing); + expect(find.text(_validatorErrorMessage), findsOneWidget); }); +} +class _AuthCodeTestWidget extends StatelessWidget { final Key? authCodeKey; - final String? initialErrorMessage; + final String? providedErrorMessage; + + const _AuthCodeTestWidget({this.authCodeKey, this.providedErrorMessage}); @override Widget build(BuildContext context) { @@ -75,20 +71,9 @@ class TestWidget extends StatelessWidget { child: MoonAuthCode( key: authCodeKey, authInputFieldCount: 4, - autoFocus: true, - enableInputFill: true, - validator: (String? pin) { - return pin?.length == 4 && pin != '9921' ? errorMessage : null; - }, - errorText: initialErrorMessage, - errorBuilder: (BuildContext context, String? errorText) { - return Align( - child: Padding( - padding: const EdgeInsets.only(top: 8), - child: Text(errorText ?? ''), - ), - ); - }, + errorText: providedErrorMessage, + validator: (String? pin) => pin?.length == 4 && pin != '9921' ? _validatorErrorMessage : null, + errorBuilder: (BuildContext context, String? errorText) => Text(errorText ?? ''), ), ), ), diff --git a/test/bottom_sheet_test.dart b/test/bottom_sheet_test.dart index 2c5c176b..386cbaa0 100644 --- a/test/bottom_sheet_test.dart +++ b/test/bottom_sheet_test.dart @@ -2,121 +2,126 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -// Test +const Key _bottomSheetKey = Key("bottomSheetKey"); +const Key _showButtonKey = Key("showButtonKey"); + +const Widget _bottomSheetContent = Text("Content"); + void main() { - const key = Key("bottom_sheet_test"); + testWidgets("Provided key is used.", (tester) async { + await tester.pumpWidget( + const _BottomSheetTestWidget( + key: _bottomSheetKey, + ), + ); + final button = find.byKey(_showButtonKey); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byKey(_bottomSheetKey), findsOneWidget); + }); - testWidgets("Botton sheet is shown after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.byType(MoonFilledButton); + testWidgets("Bottom sheet is displayed when the 'show' button is tapped.", (tester) async { + await tester.pumpWidget(const _BottomSheetTestWidget()); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_bottomSheetContent), findsOneWidget); }); - testWidgets("Botton sheet is hidden after clicking outside content", - (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.byType(MoonFilledButton); + testWidgets("Bottom sheet closes when a tap occurs outside its content, if dismissible.", (tester) async { + await tester.pumpWidget(const _BottomSheetTestWidget()); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_bottomSheetContent), findsOneWidget); await tester.tapAt(const Offset(10, 10)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsNothing); + expect(find.byWidget(_bottomSheetContent), findsNothing); }); - testWidgets( - "Botton sheet is not hidden after clicking outside content if not dismissable", - (tester) async { + testWidgets("Bottom sheet stays visible when a tap occurs outside its content, if not dismissible.", (tester) async { await tester.pumpWidget( - const TestWidget( - key: key, - content: content, + const _BottomSheetTestWidget( isDismissible: false, ), ); - final button = find.byType(MoonFilledButton); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_bottomSheetContent), findsOneWidget); await tester.tapAt(const Offset(10, 10)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_bottomSheetContent), findsOneWidget); }); - testWidgets("Botton sheet is expanded", (tester) async { + + testWidgets("Bottom sheet is expanded.", (tester) async { await tester.pumpWidget( - const TestWidget( - key: key, - content: content, + const _BottomSheetTestWidget( isExpanded: true, ), ); - final button = find.byType(MoonFilledButton); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_bottomSheetContent), findsOneWidget); await tester.tapAt(const Offset(1, 1)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_bottomSheetContent), findsOneWidget); await tester.tapAt(const Offset(100, 1)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_bottomSheetContent), findsOneWidget); }); } -const String bottomSheetText = "Botton sheet content"; -const Widget content = Text(bottomSheetText); - -class TestWidget extends StatelessWidget { - final Widget content; +class _BottomSheetTestWidget extends StatelessWidget { final bool isDismissible; final bool isExpanded; - const TestWidget({ - required this.content, + const _BottomSheetTestWidget({ + super.key, this.isDismissible = true, this.isExpanded = false, - super.key, }); @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( - body: Center( - child: StatefulBuilder( - builder: (context, setState) { - return MoonFilledButton( - label: const Text("Tap me"), - onTap: () => bottomSheetBuilder(context), - ); - }, - ), + body: Builder( + builder: (BuildContext context) { + return MoonFilledButton( + key: _showButtonKey, + onTap: () => bottomSheetBuilder(context), + ); + }, ), ), ); @@ -124,13 +129,10 @@ class TestWidget extends StatelessWidget { Future bottomSheetBuilder(BuildContext context) { return showMoonModalBottomSheet( - isExpanded: isExpanded, context: context, - backgroundColor: Colors.black38, - enableDrag: true, + isExpanded: isExpanded, isDismissible: isDismissible, - height: MediaQuery.of(context).size.height * 0.5, - builder: (BuildContext context) => content, + builder: (BuildContext context) => _bottomSheetContent, ); } } diff --git a/test/breadcrumb_test.dart b/test/breadcrumb_test.dart index 8ffaad31..ca5c30ac 100644 --- a/test/breadcrumb_test.dart +++ b/test/breadcrumb_test.dart @@ -2,118 +2,116 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("breadcrumb_test"); +const Key _breadcrumbKey = Key("breadcrumbKey"); + +const String _showMoreButtonText = '...'; +const String _breadcrumbItem = 'breadcrumb item'; +const IconData _breadcrumbLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _breadcrumbDividerIcon = MoonIcons.arrows_chevron_right_double_16_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _BreadCrumbTestWidget( + breadcrumbKey: _breadcrumbKey, ), ); - expect( - find.byWidgetPredicate( - (widget) => widget is MoonBreadcrumb && widget.key == key, - ), - findsOneWidget, - ); + expect(find.byKey(_breadcrumbKey), findsOneWidget); }); - testWidgets("More items button", (tester) async { - await tester.pumpWidget( - const TestWidget( - widgetKey: key, - ), - ); - final moreButton = find.text('...'); + testWidgets("Tapping on a 'show more' button expands collapsed items, and the button itself becomes hidden.", (tester) async { + await tester.pumpWidget(const _BreadCrumbTestWidget()); + final moreButton = find.text(_showMoreButtonText); expect(moreButton, findsOneWidget); + // Collapsed item with index 1 is not visible. expect(find.textContaining('1'), findsNothing); - await tester.tap(moreButton); + await tester.tap(moreButton, warnIfMissed: false); await tester.pumpAndSettle(); + + // Collapsed item with index 1 is visible. expect(find.textContaining('1'), findsOneWidget); + expect(find.textContaining(_showMoreButtonText), findsNothing); }); - testWidgets("Item with leading, custom divider and label", (tester) async { + testWidgets("Breadcrumb item has a leading, divider and label widget.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _BreadCrumbTestWidget( showLeading: true, ), ); - expect(find.textContaining('p'), findsWidgets); - - expect(find.byIcon(leadingIcon), findsWidgets); - expect(find.byIcon(dividerIcon), findsWidgets); + expect(find.textContaining(_breadcrumbItem), findsWidgets); + expect(find.byIcon(_breadcrumbLeadingIcon), findsWidgets); + expect(find.byIcon(_breadcrumbDividerIcon), findsWidgets); }); - testWidgets("Test max itemsToShow", (tester) async { + testWidgets("Only N items are shown, where N is defined by the value of itemsToShow.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, - itemsToShow: 2, + const _BreadCrumbTestWidget( + itemsToShow: 3, ), ); - final moreButton = find.text('...'); + final moreButton = find.textContaining(_showMoreButtonText); expect(moreButton, findsOneWidget); - expect(find.textContaining('p'), findsNWidgets(2)); + expect(find.textContaining(_breadcrumbItem), findsNWidgets(3)); - await tester.tap(moreButton); + await tester.tap(moreButton, warnIfMissed: false); await tester.pumpAndSettle(); - expect(find.textContaining('p'), findsNWidgets(4)); + + expect(find.textContaining(_breadcrumbItem), findsNWidgets(4)); }); - testWidgets("Press breadcrumb item", (tester) async { - var value = 0; + testWidgets("Breadcrumb item callback works.", (tester) async { + int value = 0; + await tester.pumpWidget( - TestWidget( - widgetKey: key, - onPressed: (index) => value = index, + _BreadCrumbTestWidget( + onTap: (index) => value = index, ), ); + final moreButton = find.text(_showMoreButtonText); - await tester.tap(find.textContaining('2')); + // Find breadcrumb item with index 2 and tap on it. + await tester.tap(find.textContaining('2'), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 2); - await tester.tap(find.textContaining('0')); + // Find breadcrumb item with index 0 and tap on it. + await tester.tap(find.textContaining('0'), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); - - final moreButton = find.text('...'); - expect(moreButton, findsOneWidget); - await tester.tap(moreButton); + + await tester.tap(moreButton, warnIfMissed: false); await tester.pumpAndSettle(); - await tester.tap(find.textContaining('1')); + // Find initially collapsed breadcrumb item with index 1 and tap on it. + await tester.tap(find.textContaining('1'), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 1); + // Tapping on a 'show more' button expands collapsed items, and the button itself becomes hidden. + expect(moreButton, findsNothing); }); } -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData dividerIcon = MoonIcons.arrows_chevron_right_double_16_light; - -class TestWidget extends StatelessWidget { +class _BreadCrumbTestWidget extends StatelessWidget { + final Key? breadcrumbKey; final bool showLeading; final int? itemsToShow; - final void Function(int)? onPressed; - final Key? widgetKey; + final void Function(int)? onTap; - const TestWidget({ - super.key, + const _BreadCrumbTestWidget({ + this.breadcrumbKey, this.showLeading = false, this.itemsToShow, - this.onPressed, - this.widgetKey, + this.onTap, }); @override @@ -123,16 +121,16 @@ class TestWidget extends StatelessWidget { body: SingleChildScrollView( scrollDirection: Axis.horizontal, child: MoonBreadcrumb( - key: widgetKey, + key: breadcrumbKey, visibleItemCount: itemsToShow ?? 3, - divider: const Icon(dividerIcon), + divider: const Icon(_breadcrumbDividerIcon), items: [ ...List.generate(4, (i) => i).map( - (index) { + (int index) { return MoonBreadcrumbItem( - label: Text('p$index'), - leading: showLeading ? const Icon(leadingIcon) : null, - onTap: () => onPressed?.call(index), + label: Text('$_breadcrumbItem $index'), + leading: showLeading ? const Icon(_breadcrumbLeadingIcon) : null, + onTap: () => onTap?.call(index), ); }, ), diff --git a/test/button_test.dart b/test/button_test.dart index e8ab76cb..851ae1b1 100644 --- a/test/button_test.dart +++ b/test/button_test.dart @@ -2,114 +2,98 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("button_test"); +const Key _buttonKey = Key("buttonKey"); + +const String _buttonLabel = "Label"; +const IconData _buttonLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _buttonTrailingIcon = MoonIcons.controls_close_small_24_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - key: key, + const _ButtonTestWidget( + buttonKey: _buttonKey, ), ); - expect(find.byKey(key), findsOneWidget); + + expect(find.byKey(_buttonKey), findsOneWidget); }); - testWidgets("Button with leading, trailing, label", (tester) async { + testWidgets("Button has a leading, label and trailing widget.", (tester) async { await tester.pumpWidget( - const TestWidget( + const _ButtonTestWidget( showLeading: true, showLabel: true, showTrailing: true, ), ); - expect(find.text(buttonLabel), findsOneWidget); - expect(find.byIcon(trailingIcon), findsOneWidget); - expect(find.byIcon(leadingIcon), findsOneWidget); + + expect(find.text(_buttonLabel), findsOneWidget); + expect(find.byIcon(_buttonTrailingIcon), findsOneWidget); + expect(find.byIcon(_buttonLeadingIcon), findsOneWidget); }); - testWidgets("Button tap", (tester) async { + testWidgets("Button onTap callback works.", (tester) async { bool tapped = false; + await tester.pumpWidget( - TestWidget( + _ButtonTestWidget( + buttonKey: _buttonKey, onTap: () => tapped = true, ), ); - await tester.tap(find.byType(MoonButton)); + + await tester.tap(find.byKey(_buttonKey)); await tester.pumpAndSettle(); + expect(tapped, true); }); - testWidgets("Button long press", (tester) async { + testWidgets("Button onLongPress callback works.", (tester) async { bool longPressed = false; - bool tapped = false; + await tester.pumpWidget( - TestWidget( + _ButtonTestWidget( + buttonKey: _buttonKey, onLongPress: () => longPressed = true, - onTap: () => tapped = true, ), ); - await tester.longPress(find.byType(MoonButton)); + + await tester.longPress(find.byKey(_buttonKey)); await tester.pumpAndSettle(); + expect(longPressed, true); - expect(tapped, false); }); } -const String buttonLabel = "Button label"; -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; - -class TestWidget extends StatefulWidget { +class _ButtonTestWidget extends StatelessWidget { + final Key? buttonKey; final bool showLeading; final bool showTrailing; final bool showLabel; final VoidCallback? onTap; final VoidCallback? onLongPress; - final Key? buttonKey; - const TestWidget({ - super.key, + const _ButtonTestWidget({ + this.buttonKey, this.showLeading = false, this.showTrailing = false, this.showLabel = false, - this.buttonKey, this.onTap, this.onLongPress, }); - @override - State createState() => _TestWidgetState(); -} - -class _TestWidgetState extends State { - bool _showAlert = true; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MoonButton( - key: widget.buttonKey, - onLongPress: widget.onLongPress, - onTap: widget.onTap, - leading: widget.showLeading ? const Icon(leadingIcon) : null, - label: widget.showLabel - ? const SizedBox( - height: 24, - child: Align( - alignment: AlignmentDirectional.centerStart, - child: Text(buttonLabel), - ), - ) - : null, - trailing: widget.showTrailing - ? MoonButton.icon( - buttonSize: MoonButtonSize.xs, - disabledOpacityValue: 1, - icon: const Icon(trailingIcon, size: 24), - gap: 0, - onTap: () => setState(() => _showAlert = !_showAlert), - ) - : null, + key: buttonKey, + onLongPress: onLongPress, + onTap: onTap, + leading: showLeading ? const Icon(_buttonLeadingIcon) : null, + label: showLabel ? const Text(_buttonLabel) : null, + trailing: showTrailing ? const Icon(_buttonTrailingIcon) : null, ), ), ); diff --git a/test/carousel_test.dart b/test/carousel_test.dart index c7ba2c2b..8e852416 100644 --- a/test/carousel_test.dart +++ b/test/carousel_test.dart @@ -2,48 +2,41 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; +const Key _carouselKey = Key("carouselKey"); + void main() { - const key = Key("button_test"); + testWidgets("Provided key is used.", (tester) async { + await tester.pumpWidget( + const _CarouselTestWidget( + carouselKey: _carouselKey, + ), + ); - testWidgets( - "Provided key is used", - (tester) async { - await tester.pumpWidget( - const CarouselTestWidget( - widgetKey: key, - ), - ); - expect(find.byKey(key), findsOneWidget); - }, - ); + expect(find.byKey(_carouselKey), findsOneWidget); + }); - testWidgets( - "Test scroll", - (tester) async { - await tester.pumpWidget( - const CarouselTestWidget( - widgetKey: key, - ), - ); - expect(find.text('1'), findsOneWidget); - expect(find.text('2'), findsOneWidget); - expect(find.text('3'), findsNothing); - await tester.drag(find.byKey(key), const Offset(-150, 0)); - await tester.pumpAndSettle(); - expect(find.text('1'), findsNothing); - expect(find.text('2'), findsOneWidget); - expect(find.text('3'), findsOneWidget); - expect(find.text('4'), findsOneWidget); - expect(find.text('5'), findsNothing); + testWidgets("Carousel items visibility changes on scroll.", (tester) async { + await tester.pumpWidget(const _CarouselTestWidget(carouselKey: _carouselKey)); + + expect(find.text('0'), findsOneWidget); + expect(find.text('1'), findsOneWidget); + expect(find.text('2'), findsNothing); + + await tester.drag(find.byKey(_carouselKey), const Offset(-150, 0)); + await tester.pumpAndSettle(); - }, - ); + expect(find.text('0'), findsNothing); + expect(find.text('1'), findsOneWidget); + expect(find.text('2'), findsOneWidget); + expect(find.text('3'), findsOneWidget); + expect(find.text('4'), findsNothing); + }); } -class CarouselTestWidget extends StatelessWidget { - final Key? widgetKey; +class _CarouselTestWidget extends StatelessWidget { + final Key? carouselKey; - const CarouselTestWidget({super.key, this.widgetKey}); + const _CarouselTestWidget({this.carouselKey}); @override Widget build(BuildContext context) { @@ -53,23 +46,11 @@ class CarouselTestWidget extends StatelessWidget { height: 114, width: 200, child: MoonCarousel( - key: widgetKey, + key: carouselKey, gap: 0, itemCount: 10, itemExtent: 100, - itemBuilder: (BuildContext context, int itemIndex, int _) => Container( - height: 100, - width: 100, - decoration: ShapeDecoration( - color: context.moonColors?.goku, - shape: MoonSquircleBorder( - borderRadius: BorderRadius.circular(12).squircleBorderRadius(context), - ), - ), - child: Center( - child: Text("${itemIndex + 1}"), - ), - ), + itemBuilder: (BuildContext _, int itemIndex, int __) => Text("$itemIndex"), ), ), ), diff --git a/test/checkbox_test.dart b/test/checkbox_test.dart index 2925e978..825a8f18 100644 --- a/test/checkbox_test.dart +++ b/test/checkbox_test.dart @@ -2,106 +2,98 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; +const Key _checkboxKey = Key("checkboxKey"); + void main() { - const key = Key("cehckbox_test"); - - testWidgets( - "Provided key is used", - (tester) async { - await tester.pumpWidget( - const TestWidget( - widgetKey: key, - ), - ); - expect(find.byKey(key), findsOneWidget); - }, - ); - - testWidgets( - "Change checkbox value", - (tester) async { - bool? checkboxValue = false; - await tester.pumpWidget( - TestWidget( - widgetKey: key, - onChanged: (newValue) => checkboxValue = newValue, - ), - ); - final checkbox = find.byKey(key); - await tester.tap(checkbox); - await tester.pumpAndSettle(); - expect(checkboxValue, true); - - await tester.tap(checkbox); - await tester.pumpAndSettle(); - expect(checkboxValue, false); - }, - ); - - testWidgets( - "Change tristate checkbox value", - (tester) async { - bool? checkboxValue = false; - await tester.pumpWidget( - TestWidget( - widgetKey: key, - isTristate: true, - onChanged: (newValue) => checkboxValue = newValue, - ), - ); - final checkbox = find.byKey(key); - await tester.tap(checkbox); - await tester.pumpAndSettle(); - expect(checkboxValue, true); - - await tester.tap(checkbox); - await tester.pumpAndSettle(); - expect(checkboxValue, null); - - await tester.tap(checkbox); - await tester.pumpAndSettle(); - expect(checkboxValue, false); - }, - ); + testWidgets("Provided key is used.", (tester) async { + await tester.pumpWidget( + const _CheckboxTestWidget( + checkboxKey: _checkboxKey, + ), + ); + + expect(find.byKey(_checkboxKey), findsOneWidget); + }); + + testWidgets("Checkbox value changes after a tap.", (tester) async { + bool? checkboxValue = false; + + await tester.pumpWidget( + _CheckboxTestWidget( + checkboxKey: _checkboxKey, + onChanged: (bool? newValue) => checkboxValue = newValue, + ), + ); + final checkbox = find.byKey(_checkboxKey); + + await tester.tap(checkbox); + await tester.pumpAndSettle(); + + expect(checkboxValue, true); + + await tester.tap(checkbox); + await tester.pumpAndSettle(); + + expect(checkboxValue, false); + }); + + testWidgets("Tristate checkbox value changes correctly when tapped multiple times.", (tester) async { + bool? checkboxValue = false; + + await tester.pumpWidget( + _CheckboxTestWidget( + checkboxKey: _checkboxKey, + isTristate: true, + onChanged: (newValue) => checkboxValue = newValue, + ), + ); + final checkbox = find.byKey(_checkboxKey); + + await tester.tap(checkbox); + await tester.pumpAndSettle(); + + expect(checkboxValue, true); + + await tester.tap(checkbox); + await tester.pumpAndSettle(); + + expect(checkboxValue, null); + + await tester.tap(checkbox); + await tester.pumpAndSettle(); + + expect(checkboxValue, false); + }); } -class TestWidget extends StatefulWidget { - final Key? widgetKey; - final void Function(bool?)? onChanged; +class _CheckboxTestWidget extends StatefulWidget { + final Key? checkboxKey; final bool isTristate; - final bool initialValue; + final void Function(bool?)? onChanged; - const TestWidget({ - super.key, - this.widgetKey, + const _CheckboxTestWidget({ + this.checkboxKey, this.isTristate = false, this.onChanged, - this.initialValue = false, }); @override - State createState() => _TestWidgetState(); + State<_CheckboxTestWidget> createState() => _CheckboxTestWidgetState(); } -class _TestWidgetState extends State { - bool? checkboxValue; - - @override - void initState() { - super.initState(); - checkboxValue = widget.initialValue; - } +class _CheckboxTestWidgetState extends State<_CheckboxTestWidget> { + bool? _checkboxValue = false; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MoonCheckbox( - key: widget.widgetKey, - value: checkboxValue, + key: widget.checkboxKey, + value: _checkboxValue, tristate: widget.isTristate, onChanged: (bool? newValue) { - setState(() => checkboxValue = newValue); + setState(() => _checkboxValue = newValue); widget.onChanged?.call(newValue); }, ), diff --git a/test/chip_test.dart b/test/chip_test.dart index bfe77be6..01a15451 100644 --- a/test/chip_test.dart +++ b/test/chip_test.dart @@ -2,68 +2,72 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("chip_test"); +const Key _chipKey = Key("chipKey"); + +const String _chipLabel = "Label"; +const IconData _chipLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _chipTrailingIcon = MoonIcons.controls_close_small_24_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _ChipTestWidget( + chipKey: _chipKey, ), ); - expect(find.byKey(key), findsOneWidget); + + expect(find.byKey(_chipKey), findsOneWidget); }); - testWidgets("Simple chip", (tester) async { + testWidgets("Chip has only a label and no leading or trailing widget.", (tester) async { await tester.pumpWidget( - const TestWidget( + const _ChipTestWidget( showLabel: true, ), ); - expect(find.text(label), findsOneWidget); + expect(find.text(_chipLabel), findsOneWidget); + expect(find.byIcon(_chipTrailingIcon), findsNothing); + expect(find.byIcon(_chipLeadingIcon), findsNothing); }); - testWidgets("Chip with leading, trailing, body", (tester) async { + testWidgets("Chip has a leading, label and trailing widget.", (tester) async { await tester.pumpWidget( - const TestWidget( + const _ChipTestWidget( showLeading: true, showLabel: true, showTrailing: true, ), ); - expect(find.text(label), findsOneWidget); - expect(find.byIcon(trailingIcon), findsOneWidget); - expect(find.byIcon(leadingIcon), findsOneWidget); + + expect(find.byIcon(_chipLeadingIcon), findsOneWidget); + expect(find.text(_chipLabel), findsOneWidget); + expect(find.byIcon(_chipTrailingIcon), findsOneWidget); }); } -const String label = "Label"; -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; - -class TestWidget extends StatelessWidget { +class _ChipTestWidget extends StatelessWidget { + final Key? chipKey; final bool showLeading; final bool showTrailing; final bool showLabel; - final Key? widgetKey; - const TestWidget({ - super.key, + const _ChipTestWidget({ + this.chipKey, this.showLeading = false, this.showLabel = false, this.showTrailing = false, - this.widgetKey, }); + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MoonChip( - key: widgetKey, - leading: showLeading ? const Icon(leadingIcon) : null, - label: showLabel ? const Text(label) : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, + key: chipKey, + leading: showLeading ? const Icon(_chipLeadingIcon) : null, + label: showLabel ? const Text(_chipLabel) : null, + trailing: showTrailing ? const Icon(_chipTrailingIcon) : null, ), ), ); diff --git a/test/drawer_test.dart b/test/drawer_test.dart index 5fbb99b4..975fd1ce 100644 --- a/test/drawer_test.dart +++ b/test/drawer_test.dart @@ -2,102 +2,110 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; +const Key _drawerKey = Key("drawerKey"); +const Key _openButtonKey = Key("openButtonKey"); +const Key _closeButtonKey = Key("closeButtonKey"); + +const Widget _drawerContent = Text("Content"); + void main() { - testWidgets("Drawer is shown after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(content: content)); - final button = find.text(openButtonText); + testWidgets("Provided key is used.", (tester) async { + await tester.pumpWidget( + const _DrawerTestWidget( + drawerKey: _drawerKey, + ), + ); + + final button = find.byKey(_openButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byKey(_drawerKey), findsOneWidget); }); - testWidgets("Drawer close after clicking outside", (tester) async { - await tester.pumpWidget(const TestWidget(content: content)); - final button = find.text(openButtonText); + testWidgets("Drawer is displayed when the open button is tapped.", (tester) async { + await tester.pumpWidget(const _DrawerTestWidget()); + + final button = find.byKey(_openButtonKey); + + expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); - await tester.tapAt(const Offset(210, 10)); - await tester.pumpAndSettle(); - expect(find.byWidget(content), findsNothing); + expect(find.byWidget(_drawerContent), findsOneWidget); }); - testWidgets("Drawer close after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(content: content)); - final button = find.text(openButtonText); + testWidgets("Drawer closes when a tap occurs outside its content.", (tester) async { + await tester.pumpWidget(const _DrawerTestWidget()); + + final button = find.byKey(_openButtonKey); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); - await tester.tap(find.text(closeButtonText)); + expect(find.byWidget(_drawerContent), findsOneWidget); + + await tester.tapAt(const Offset(210, 10)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsNothing); + + expect(find.byWidget(_drawerContent), findsNothing); }); -} -const String contentText = "Drawer content"; -const String openButtonText = "Open"; -const String closeButtonText = "Close"; + testWidgets("Drawer closes when the 'close' button is tapped.", (tester) async { + await tester.pumpWidget(const _DrawerTestWidget()); + + final button = find.byKey(_openButtonKey); + + await tester.tap(button); + await tester.pumpAndSettle(); -const Widget content = Text(contentText); + expect(find.byWidget(_drawerContent), findsOneWidget); -class TestWidget extends StatelessWidget { - final Widget content; + await tester.tap(find.byKey(_closeButtonKey)); + await tester.pumpAndSettle(); - const TestWidget({ - required this.content, - super.key, + expect(find.byWidget(_drawerContent), findsNothing); }); +} + +class _DrawerTestWidget extends StatelessWidget { + final Key? drawerKey; + + const _DrawerTestWidget({this.drawerKey}); @override Widget build(BuildContext context) { return MaterialApp( - home: OverflowBox( - maxHeight: MediaQuery.of(context).size.height, - maxWidth: MediaQuery.of(context).size.width, - child: Scaffold( - drawer: MoonDrawer( - width: 200, - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - children: [ - content, - const SizedBox(height: 32), - Builder( - builder: (BuildContext context) { - return MoonFilledButton( - label: const Text(closeButtonText), - onTap: () => Navigator.of(context).pop(), - ); - }, - ), - ], - ), - ), - body: Center( - child: Builder( - builder: (BuildContext context) { - return Padding( - padding: const EdgeInsets.symmetric( - vertical: 64.0, - horizontal: 16.0, - ), - child: MoonFilledButton( - label: const Text(openButtonText), - onTap: () => Scaffold.of(context).openDrawer(), - ), - ); - }, - ), + home: Scaffold( + drawer: MoonDrawer( + key: drawerKey, + width: 200, + child: Column( + children: [ + _drawerContent, + Builder( + builder: (BuildContext context) { + return MoonFilledButton( + key: _closeButtonKey, + onTap: () => Navigator.of(context).pop(), + ); + }, + ), + ], ), ), + body: Builder( + builder: (BuildContext context) { + return MoonFilledButton( + key: _openButtonKey, + onTap: () => Scaffold.of(context).openDrawer(), + ); + }, + ), ), ); } diff --git a/test/dropdown_test.dart b/test/dropdown_test.dart index c796e31d..1de3acc8 100644 --- a/test/dropdown_test.dart +++ b/test/dropdown_test.dart @@ -4,101 +4,122 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/src/widgets/buttons/filled_button.dart'; import 'package:moon_design/src/widgets/dropdown/dropdown.dart'; -// Test +const Key _dropdownKey = Key("dropdownKey"); +const Key _showButtonKey = Key("showButtonKey"); + +const Widget _drawerContent = Text("Content"); + void main() { - const key = Key("dropdown_test"); + testWidgets("Provided key is used.", (tester) async { + await tester.pumpWidget( + const _DropdownTestWidget( + dropdownKey: _dropdownKey, + ), + ); - testWidgets("Provided key is used", (tester) async { - await tester.pumpWidget(MoonDropdown(key: key, show: true, content: Container(), child: Container())); - expect(find.byKey(key), findsOneWidget); + expect(find.byKey(_dropdownKey), findsOneWidget); }); - testWidgets("Dropdown is shown after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.byType(MoonFilledButton); + testWidgets("Dropdown is displayed when the 'show' button is tapped.", (tester) async { + await tester.pumpWidget(const _DropdownTestWidget()); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_drawerContent), findsOneWidget); }); - testWidgets("Dropdown is hidden after clicking outside content", (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.byType(MoonFilledButton); + testWidgets("Dropdown collapses when a tap occurs outside its content, if dismissible.", (tester) async { + await tester.pumpWidget(const _DropdownTestWidget()); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_drawerContent), findsOneWidget); await tester.tapAt(const Offset(10, 10)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsNothing); + expect(find.byWidget(_drawerContent), findsNothing); }); - testWidgets("Provided color is used", (tester) async { + testWidgets("Dropdown stays expanded when a tap occurs outside its content, if not dismissible.", (tester) async { + await tester.pumpWidget(const _DropdownTestWidget(isDismissible: false)); + final button = find.byKey(_showButtonKey); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(_drawerContent), findsOneWidget); + + await tester.tapAt(const Offset(10, 10)); + await tester.pumpAndSettle(); + + expect(find.byWidget(_drawerContent), findsOneWidget); + }); + + testWidgets("Provided background color is used for dropdown.", (tester) async { await tester.pumpWidget( - const TestWidget( - key: key, - content: content, - color: Colors.red, + const _DropdownTestWidget( + color: Colors.blue, ), ); - final button = find.byType(MoonFilledButton); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_drawerContent), findsOneWidget); expect( - find.byWidgetPredicate((widget) => widget is MoonDropdown && widget.backgroundColor == Colors.red), + find.byWidgetPredicate((Widget widget) => widget is MoonDropdown && widget.backgroundColor == Colors.blue), findsOneWidget, ); }); } -const String dropdownText = "Dropdown content"; -const Widget content = Text(dropdownText); - -bool show = false; - -class TestWidget extends StatelessWidget { - final Widget content; +class _DropdownTestWidget extends StatefulWidget { + final Key? dropdownKey; + final bool isDismissible; final Color color; - const TestWidget({ - required this.content, + const _DropdownTestWidget({ + this.dropdownKey, + this.isDismissible = true, this.color = Colors.white, - super.key, }); + @override + State<_DropdownTestWidget> createState() => _DropdownTestWidgetState(); +} + +class _DropdownTestWidgetState extends State<_DropdownTestWidget> { + bool _show = false; + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: Center( - child: StatefulBuilder( - builder: (context, setState) { - return MoonDropdown( - show: show, - backgroundColor: color, - content: content, - onTapOutside: () => setState(() => show = false), - child: MoonFilledButton( - onTap: () { - setState(() => show = true); - }, - ), - ); - }, + child: MoonDropdown( + key: widget.dropdownKey, + show: _show, + backgroundColor: widget.color, + onTapOutside: () => setState(() => _show = !widget.isDismissible), + content: _drawerContent, + child: MoonFilledButton( + key: _showButtonKey, + onTap: () => setState(() => _show = true), + ), ), ), ), diff --git a/test/menu_item_test.dart b/test/menu_item_test.dart index 43f76648..26f3754c 100644 --- a/test/menu_item_test.dart +++ b/test/menu_item_test.dart @@ -2,83 +2,91 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("menu_item_test"); +const Key _menuItemKey = Key("menuItemKey"); + +const String _menuItemLabel = "Label"; +const String _menuItemContent = "Content"; +const IconData _menuItemLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _menuItemTrailingIcon = MoonIcons.controls_close_small_24_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _MenuItemTestWidget( + menuItemKey: _menuItemKey, ), ); - expect(find.byKey(key), findsOneWidget); + + expect(find.byKey(_menuItemKey), findsOneWidget); }); - testWidgets("Simple menu item", (tester) async { - await tester.pumpWidget( - const TestWidget(), - ); + testWidgets("Menu item has only label and no leading, trailing or content widget.", (tester) async { + await tester.pumpWidget(const _MenuItemTestWidget()); - expect(find.text(title), findsOneWidget); + expect(find.text(_menuItemLabel), findsOneWidget); + expect(find.byIcon(_menuItemLeadingIcon), findsNothing); + expect(find.byIcon(_menuItemTrailingIcon), findsNothing); + expect(find.text(_menuItemContent), findsNothing); }); - testWidgets("Menu item with leading, trailing, description", (tester) async { + testWidgets("Menu item has a leading, label, trailing and content widget.", (tester) async { await tester.pumpWidget( - const TestWidget( + const _MenuItemTestWidget( showLeading: true, - showDescription: true, showTrailing: true, + showContent: true, ), ); - expect(find.text(description), findsOneWidget); - expect(find.byIcon(trailingIcon), findsOneWidget); - expect(find.byIcon(leadingIcon), findsOneWidget); + + expect(find.text(_menuItemLabel), findsOneWidget); + expect(find.byIcon(_menuItemLeadingIcon), findsOneWidget); + expect(find.byIcon(_menuItemTrailingIcon), findsOneWidget); + expect(find.text(_menuItemContent), findsOneWidget); }); - testWidgets("Tap menu item", (tester) async { + testWidgets("Menu item onTap callback works.", (tester) async { bool value = false; + await tester.pumpWidget( - TestWidget( + _MenuItemTestWidget( + menuItemKey: _menuItemKey, onTap: () => value = !value, ), ); - await tester.tap(find.byType(MoonMenuItem)); + + await tester.tap(find.byKey(_menuItemKey)); await tester.pumpAndSettle(); + expect(value, true); }); } -const String title = "Title"; -const String description = "Description"; -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; - -class TestWidget extends StatelessWidget { +class _MenuItemTestWidget extends StatelessWidget { + final Key? menuItemKey; final bool showLeading; final bool showTrailing; - final bool showDescription; - final Key? widgetKey; + final bool showContent; final VoidCallback? onTap; - const TestWidget({ - super.key, + const _MenuItemTestWidget({ + this.menuItemKey, this.showLeading = false, - this.showDescription = false, this.showTrailing = false, - this.widgetKey, + this.showContent = false, this.onTap, }); + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MoonMenuItem( - key: widgetKey, - leading: showLeading ? const Icon(leadingIcon) : null, - content: showDescription ? const Text(description) : null, - label: const Text(title), - trailing: showTrailing ? const Icon(trailingIcon) : null, + key: menuItemKey, onTap: onTap, + leading: showLeading ? const Icon(_menuItemLeadingIcon) : null, + label: const Text(_menuItemLabel), + trailing: showTrailing ? const Icon(_menuItemTrailingIcon) : null, + content: showContent ? const Text(_menuItemContent) : null, ), ), ); diff --git a/test/modal_test.dart b/test/modal_test.dart index 5252d50b..ed8d2b63 100644 --- a/test/modal_test.dart +++ b/test/modal_test.dart @@ -2,91 +2,103 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -// Test +const Key _modalKey = Key("modalKey"); +const Key _showButtonKey = Key("showButtonKey"); +const Key _closeButtonKey = Key("closeButtonKey"); + +const Widget _modalContent = Text('Content'); + void main() { - const key = Key("modal_test"); + testWidgets("Provided key is used.", (tester) async { + await tester.pumpWidget( + const _ModalTestWidget( + modalKey: _modalKey, + ), + ); + + final button = find.byKey(_showButtonKey); + + expect(button, findsOneWidget); - testWidgets("Modal is shown after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.text(openButtonText); + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byKey(_modalKey), findsOneWidget); + }); + + testWidgets("Modal is displayed when the 'show' button is tapped.", (tester) async { + await tester.pumpWidget(const _ModalTestWidget()); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_modalContent), findsOneWidget); }); - testWidgets("Modal is hidden after clicking outside content", (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.text(openButtonText); + testWidgets("Modal closes when a tap occurs outside its content, if dismissible.", (tester) async { + await tester.pumpWidget(const _ModalTestWidget()); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_modalContent), findsOneWidget); await tester.tapAt(const Offset(10, 10)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsNothing); + expect(find.byWidget(_modalContent), findsNothing); }); - testWidgets( - "Modal is not hidden after clicking outside content if not dismissable", - (tester) async { + testWidgets("Modal stays visible when a tap occurs outside its content, if not dismissible.", (tester) async { await tester.pumpWidget( - const TestWidget( - key: key, - content: content, + const _ModalTestWidget( isDismissible: false, ), ); - final button = find.text(openButtonText); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_modalContent), findsOneWidget); await tester.tapAt(const Offset(10, 10)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_modalContent), findsOneWidget); }); - testWidgets("Modal close after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(content: content)); - final button = find.text(openButtonText); + testWidgets("Modal closes when the 'close' button is tapped.", (tester) async { + await tester.pumpWidget(const _ModalTestWidget()); + final button = find.byKey(_showButtonKey); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); - await tester.tap(find.text(closeButtonText)); + expect(find.byWidget(_modalContent), findsOneWidget); + + await tester.tap(find.byKey(_closeButtonKey)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsNothing); + + expect(find.byWidget(_modalContent), findsNothing); }); } -const String contentText = "Content"; -const Widget content = Text(contentText); -const String openButtonText = "Open"; -const String closeButtonText = "Close"; - -class TestWidget extends StatelessWidget { - final Widget content; +class _ModalTestWidget extends StatelessWidget { + final Key? modalKey; final bool isDismissible; - const TestWidget({ - required this.content, + const _ModalTestWidget({ + this.modalKey, this.isDismissible = true, - super.key, }); @override @@ -94,10 +106,10 @@ class TestWidget extends StatelessWidget { return MaterialApp( home: Scaffold( body: Center( - child: StatefulBuilder( - builder: (context, setState) { + child: Builder( + builder: (context) { return MoonFilledButton( - label: const Text(openButtonText), + key: _showButtonKey, onTap: () => modalBuilder(context), ); }, @@ -111,21 +123,18 @@ class TestWidget extends StatelessWidget { return showMoonModal( context: context, barrierDismissible: isDismissible, - useRootNavigator: false, - builder: (BuildContext _) { + builder: (BuildContext context) { return Directionality( textDirection: Directionality.of(context), child: MoonModal( + key: modalKey, child: SizedBox( width: 300, child: Column( - mainAxisSize: MainAxisSize.min, - crossAxisAlignment: CrossAxisAlignment.start, children: [ - content, + _modalContent, MoonFilledButton( - label: const Text(closeButtonText), - isFullWidth: true, + key: _closeButtonKey, onTap: () => Navigator.of(context).pop(), ), ], diff --git a/test/popover_test.dart b/test/popover_test.dart index 24e551fd..8435bdbd 100644 --- a/test/popover_test.dart +++ b/test/popover_test.dart @@ -2,86 +2,104 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -// Test -void main() { - const key = Key("popover_test"); +const Key _popoverKey = Key("popoverKey"); +const Key _showButtonKey = Key("showButtonKey"); +const Key _closeButtonKey = Key("closeButtonKey"); + +const Widget _content = Text("Content"); - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, - content: content, + const _PopoverTestWidget( + popoverKey: _popoverKey, ), ); - expect(find.byKey(key), findsOneWidget); + + expect(find.byKey(_popoverKey), findsOneWidget); }); - testWidgets("Popover is shown after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.text(openButtonText); + + testWidgets("Popover is displayed when the 'show' button is tapped.", (tester) async { + await tester.pumpWidget(const _PopoverTestWidget()); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_content), findsOneWidget); }); - testWidgets("Popover is hidden after clicking outside content", - (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.text(openButtonText); + testWidgets("Popover closes when a tap occurs outside its content, if dismissible.", (tester) async { + await tester.pumpWidget(const _PopoverTestWidget()); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_content), findsOneWidget); await tester.tapAt(const Offset(10, 10)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsNothing); + expect(find.byWidget(_content), findsNothing); }); - testWidgets("Popover is hidden after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(content: content)); - final button = find.text(openButtonText); + testWidgets("Popover stays visible when a tap occurs outside its content, if not dismissible.", (tester) async { + await tester.pumpWidget( + const _PopoverTestWidget( + isDismissible: false, + ), + ); + final button = find.byKey(_showButtonKey); + + expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); - await tester.tap(find.text(closeButtonText)); + expect(find.byWidget(_content), findsOneWidget); + + await tester.tapAt(const Offset(10, 10)); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsNothing); + + expect(find.byWidget(_content), findsOneWidget); }); -} -const String contentText = "Content"; -const Widget content = Text(contentText); -const String openButtonText = "Open"; -const String closeButtonText = "Close"; + testWidgets("Popover closes when the 'close' button is tapped.", (tester) async { + await tester.pumpWidget(const _PopoverTestWidget()); + final button = find.byKey(_showButtonKey); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(_content), findsOneWidget); + + await tester.tap(find.byKey(_closeButtonKey)); + await tester.pumpAndSettle(); + + expect(find.byWidget(_content), findsNothing); + }); +} -class TestWidget extends StatefulWidget { - final Widget content; +class _PopoverTestWidget extends StatefulWidget { + final Key? popoverKey; final bool isDismissible; - final Key? widgetKey; - const TestWidget({ - required this.content, + const _PopoverTestWidget({ + this.popoverKey, this.isDismissible = true, - this.widgetKey, - super.key, }); @override - State createState() => _TestWidgetState(); + State<_PopoverTestWidget> createState() => _PopoverTestWidgetState(); } -class _TestWidgetState extends State { - bool show = false; +class _PopoverTestWidgetState extends State<_PopoverTestWidget> { + bool _show = false; @override Widget build(BuildContext context) { @@ -89,30 +107,24 @@ class _TestWidgetState extends State { home: Scaffold( body: Center( child: MoonPopover( - key: widget.widgetKey, - show: show, - onTapOutside: widget.isDismissible - ? () => setState(() => show = false) - : null, + key: widget.popoverKey, + show: _show, + onTapOutside: () => setState(() => _show = !widget.isDismissible), content: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 190), child: Column( - mainAxisSize: MainAxisSize.min, children: [ - widget.content, - const SizedBox(height: 16), + _content, MoonFilledButton( - buttonSize: MoonButtonSize.sm, - isFullWidth: true, - onTap: () => setState(() => show = false), - label: const Text(closeButtonText), + key: _closeButtonKey, + onTap: () => setState(() => _show = false), ), ], ), ), child: MoonFilledButton( - onTap: () => setState(() => show = !show), - label: const Text(openButtonText), + key: _showButtonKey, + onTap: () => setState(() => _show = !_show), ), ), ), diff --git a/test/radio_test.dart b/test/radio_test.dart index bafd00ca..2ea08cbd 100644 --- a/test/radio_test.dart +++ b/test/radio_test.dart @@ -2,146 +2,138 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -enum Choice { first, second } +enum _Choice { first, second } -void main() { - const firstKey = Key("first_radio_test"); - const secondKey = Key("second_radio_test"); +const Key _firstRadioKey = Key("firstRadioKey"); +const Key _secondRadioKey = Key("secondRadioKey"); - Finder findSelecterFirstRadio() { +void main() { + Finder findSelectorFirstRadio() { return find.byWidgetPredicate( - (widget) => + (Widget widget) => widget is MoonRadio && - widget.key == firstKey && - widget.value == Choice.first && - widget.groupValue == Choice.first, + widget.key == _firstRadioKey && + widget.value == _Choice.first && + widget.groupValue == _Choice.first, ); } - Finder findSelecterSecondRadio() { + Finder findSelectorSecondRadio() { return find.byWidgetPredicate( - (widget) => + (Widget widget) => widget is MoonRadio && - widget.key == secondKey && - widget.value == Choice.second && - widget.groupValue == Choice.second, + widget.key == _secondRadioKey && + widget.value == _Choice.second && + widget.groupValue == _Choice.second, ); } - testWidgets("Provided key is used", (tester) async { + testWidgets("Provided keys are used.", (tester) async { await tester.pumpWidget( - const TestRadioWidget( - firstRadioKey: firstKey, + const _RadioTestWidget( + firstRadioKey: _firstRadioKey, + secondRadioKey: _secondRadioKey, ), ); - expect( - find.byWidgetPredicate( - (widget) => widget is MoonRadio && widget.key == firstKey, - ), - findsOneWidget, - ); + expect(find.byKey(_firstRadioKey), findsOneWidget); + expect(find.byKey(_secondRadioKey), findsOneWidget); }); - testWidgets("Test radio switch", (tester) async { + testWidgets("The selection of radio buttons can be changed.", (tester) async { await tester.pumpWidget( - const TestRadioWidget( - firstRadioKey: firstKey, - secondRadioKey: secondKey, + const _RadioTestWidget( + firstRadioKey: _firstRadioKey, + secondRadioKey: _secondRadioKey, ), ); - await tester.tap(find.byKey(firstKey)); + await tester.tap(find.byKey(_firstRadioKey)); await tester.pumpAndSettle(); - expect( - findSelecterFirstRadio(), - findsOneWidget, - ); + expect(findSelectorFirstRadio(), findsOneWidget); - await tester.tap(find.byKey(secondKey)); + await tester.tap(find.byKey(_secondRadioKey)); await tester.pumpAndSettle(); - expect(findSelecterFirstRadio(), findsNothing); - expect(findSelecterSecondRadio(), findsOneWidget); - await tester.tap(find.byKey(secondKey)); + + expect(findSelectorFirstRadio(), findsNothing); + expect(findSelectorSecondRadio(), findsOneWidget); + + await tester.tap(find.byKey(_firstRadioKey)); await tester.pumpAndSettle(); - expect(findSelecterFirstRadio(), findsNothing); - expect(findSelecterSecondRadio(), findsOneWidget); + + expect(findSelectorFirstRadio(), findsOneWidget); + expect(findSelectorSecondRadio(), findsNothing); }); - testWidgets("Test toggable radio switch", (tester) async { + testWidgets("Selected radio button can be unselected.", (tester) async { await tester.pumpWidget( - const TestRadioWidget( - firstRadioKey: firstKey, - secondRadioKey: secondKey, + const _RadioTestWidget( + firstRadioKey: _firstRadioKey, + secondRadioKey: _secondRadioKey, toggleable: true, ), ); - await tester.tap(find.byKey(firstKey)); + await tester.tap(find.byKey(_firstRadioKey)); await tester.pumpAndSettle(); - expect( - findSelecterFirstRadio(), - findsOneWidget, - ); + expect(findSelectorFirstRadio(), findsOneWidget); - await tester.tap(find.byKey(secondKey)); + await tester.tap(find.byKey(_secondRadioKey)); await tester.pumpAndSettle(); - expect(findSelecterFirstRadio(), findsNothing); - expect(findSelecterSecondRadio(), findsOneWidget); - await tester.tap(find.byKey(secondKey)); + + expect(findSelectorFirstRadio(), findsNothing); + expect(findSelectorSecondRadio(), findsOneWidget); + + await tester.tap(find.byKey(_secondRadioKey)); await tester.pumpAndSettle(); - expect(findSelecterFirstRadio(), findsNothing); - expect(findSelecterSecondRadio(), findsNothing); + + expect(findSelectorFirstRadio(), findsNothing); + expect(findSelectorSecondRadio(), findsNothing); }); } -class TestRadioWidget extends StatefulWidget { +class _RadioTestWidget extends StatefulWidget { final bool toggleable; - final Key? firstRadioKey; final Key? secondRadioKey; - const TestRadioWidget({ - super.key, - this.toggleable = false, + + const _RadioTestWidget({ this.firstRadioKey, this.secondRadioKey, + this.toggleable = false, }); + @override - State createState() => _TestRadioWidgetState(); + State<_RadioTestWidget> createState() => _RadioTestWidgetState(); } -class _TestRadioWidgetState extends State { - Choice? value; +class _RadioTestWidgetState extends State<_RadioTestWidget> { + _Choice? _value; + @override Widget build(BuildContext context) { - // TODO: implement build return MaterialApp( home: Scaffold( - body: Center( - child: SingleChildScrollView( - padding: const EdgeInsets.symmetric(vertical: 64.0, horizontal: 16.0), - child: Column( - children: [ - MoonRadio( - key: widget.firstRadioKey, - value: Choice.first, - groupValue: value, - onChanged: (Choice? choice) => setState(() => value = choice), - toggleable: widget.toggleable, - ), - const SizedBox(height: 8), - MoonRadio( - value: Choice.second, - key: widget.secondRadioKey, - groupValue: value, - onChanged: (Choice? choice) => setState(() => value = choice), - toggleable: widget.toggleable, - ), - ], + body: Column( + children: [ + MoonRadio( + key: widget.firstRadioKey, + toggleable: widget.toggleable, + value: _Choice.first, + groupValue: _value, + onChanged: (_Choice? choice) => setState(() => _value = choice), + ), + const SizedBox(height: 8), + MoonRadio( + key: widget.secondRadioKey, + toggleable: widget.toggleable, + value: _Choice.second, + groupValue: _value, + onChanged: (_Choice? choice) => setState(() => _value = choice), ), - ), + ], ), ), ); diff --git a/test/segmented_control_test.dart b/test/segmented_control_test.dart index 47831cf5..475fce74 100644 --- a/test/segmented_control_test.dart +++ b/test/segmented_control_test.dart @@ -2,137 +2,135 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("segment_control_test"); +const Key _segmentedControlKey = Key("segmentControlKey"); + +const String _firstSegmentLabel = "Label 1"; +const String _secondSegmentLabel = "Label 2"; +const String _thirdSegmentLabel = "Label 3"; +const IconData _segmentLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _segmentTrailingIcon = MoonIcons.controls_close_small_24_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _SegmentedControlTestWidget( + segmentedControlKey: _segmentedControlKey, ), ); - expect( - find.byWidgetPredicate( - (widget) => widget is MoonSegmentedControl && widget.key == key, - ), - findsOneWidget, - ); + expect(find.byKey(_segmentedControlKey), findsOneWidget); }); - testWidgets("Segment with leading, trailing, label", (tester) async { + testWidgets("Segment has a leading, label and trailing widget.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _SegmentedControlTestWidget( showLabel: true, showLeading: true, showTrailing: true, ), ); - expect(find.textContaining(label), findsWidgets); - expect(find.byIcon(leadingIcon), findsWidgets); - expect(find.byIcon(trailingIcon), findsWidgets); + expect(find.textContaining(_firstSegmentLabel), findsWidgets); + expect(find.textContaining(_secondSegmentLabel), findsWidgets); + expect(find.textContaining(_thirdSegmentLabel), findsWidgets); + expect(find.byIcon(_segmentLeadingIcon), findsWidgets); + expect(find.byIcon(_segmentTrailingIcon), findsWidgets); }); - testWidgets("Press segment", (tester) async { + testWidgets("Segment onTap callback works.", (tester) async { var value = 0; + await tester.pumpWidget( - TestWidget( - widgetKey: key, + _SegmentedControlTestWidget( showLabel: true, - onTap: (index) => value = index, + onTap: (int index) => value = index, ), ); - await tester.tap(find.text('$label 2')); + await tester.tap(find.text(_secondSegmentLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 1); - await tester.tap(find.text('$label 1')); + await tester.tap(find.text(_firstSegmentLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); - await tester.tap(find.text('$label 3')); + await tester.tap(find.text(_thirdSegmentLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 2); }); - testWidgets("Disabled press segment", (tester) async { + testWidgets("The onTap callbacks of segments are ignored if segmented control is disabled.", (tester) async { var value = 0; + await tester.pumpWidget( - TestWidget( - widgetKey: key, + _SegmentedControlTestWidget( showLabel: true, isDisabled: true, - onTap: (index) => value = index, + onTap: (int index) => value = index, ), ); - await tester.tap(find.text('$label 2')); + await tester.tap(find.text(_secondSegmentLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); - await tester.tap(find.text('$label 1')); + await tester.tap(find.text(_firstSegmentLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); - await tester.tap(find.text('$label 3')); + await tester.tap(find.text(_thirdSegmentLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); }); } -const String label = "Label"; -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; - -class TestWidget extends StatelessWidget { +class _SegmentedControlTestWidget extends StatelessWidget { + final Key? segmentedControlKey; final bool showLeading; - final bool showTrailing; final bool showLabel; - final Key? widgetKey; - final void Function(int)? onTap; + final bool showTrailing; final bool isDisabled; + final void Function(int)? onTap; - const TestWidget({ - super.key, + const _SegmentedControlTestWidget({ + this.segmentedControlKey, this.showLeading = false, this.showLabel = false, this.showTrailing = false, - this.widgetKey, - this.onTap, this.isDisabled = false, + this.onTap, }); + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MoonSegmentedControl( - onSegmentChanged: onTap, - key: widgetKey, + key: segmentedControlKey, isDisabled: isDisabled, + onSegmentChanged: onTap, segments: [ Segment( - leading: showLeading ? const Icon(leadingIcon) : null, - label: showLabel ? const Text('$label 1') : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, + leading: showLeading ? const Icon(_segmentLeadingIcon) : null, + label: showLabel ? const Text(_firstSegmentLabel) : null, + trailing: showTrailing ? const Icon(_segmentTrailingIcon) : null, ), Segment( - leading: showLeading ? const Icon(leadingIcon) : null, - label: showLabel ? const Text('$label 2') : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, + leading: showLeading ? const Icon(_segmentLeadingIcon) : null, + label: showLabel ? const Text(_secondSegmentLabel) : null, + trailing: showTrailing ? const Icon(_segmentTrailingIcon) : null, ), Segment( - leading: showLeading ? const Icon(leadingIcon) : null, - label: showLabel ? const Text('$label 3') : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, + leading: showLeading ? const Icon(_segmentLeadingIcon) : null, + label: showLabel ? const Text(_thirdSegmentLabel) : null, + trailing: showTrailing ? const Icon(_segmentTrailingIcon) : null, ), ], ), diff --git a/test/switch_test.dart b/test/switch_test.dart index 5c64879d..cb3eab84 100644 --- a/test/switch_test.dart +++ b/test/switch_test.dart @@ -2,78 +2,67 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("switch_test"); +const Key _switchKey = Key("switchKey"); - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _SwitchTestWidget( + switchKey: _switchKey, ), ); - expect( - find.byWidgetPredicate( - (widget) => widget is MoonSwitch && widget.key == key, - ), - findsOneWidget, - ); + expect(find.byKey(_switchKey), findsOneWidget); }); - testWidgets("Toggle switch", (tester) async { + testWidgets("Tapping on a switch changes its value.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _SwitchTestWidget( + switchKey: _switchKey, ), ); expect( - find.byWidgetPredicate( - (widget) => widget is MoonSwitch && widget.value == true, - ), + find.byWidgetPredicate((Widget widget) => widget is MoonSwitch && widget.value == true), findsOneWidget, ); - await tester.tap(find.byKey(key)); + await tester.tap(find.byKey(_switchKey)); await tester.pumpAndSettle(); expect( - find.byWidgetPredicate( - (widget) => widget is MoonSwitch && widget.value == false, - ), + find.byWidgetPredicate((Widget widget) => widget is MoonSwitch && widget.value == false), findsOneWidget, ); - await tester.tap(find.byKey(key)); + await tester.tap(find.byKey(_switchKey)); await tester.pumpAndSettle(); expect( - find.byWidgetPredicate( - (widget) => widget is MoonSwitch && widget.value == true, - ), + find.byWidgetPredicate((Widget widget) => widget is MoonSwitch && widget.value == true), findsOneWidget, ); }); } -class TestWidget extends StatefulWidget { - final Key? widgetKey; +class _SwitchTestWidget extends StatefulWidget { + final Key? switchKey; - const TestWidget({super.key, this.widgetKey}); + const _SwitchTestWidget({this.switchKey}); @override - State createState() => _TestWidgetState(); + State<_SwitchTestWidget> createState() => _SwitchTestWidgetState(); } -class _TestWidgetState extends State { - var _switchValue = true; +class _SwitchTestWidgetState extends State<_SwitchTestWidget> { + bool _switchValue = true; @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MoonSwitch( - key: widget.widgetKey, + key: widget.switchKey, value: _switchValue, onChanged: (bool newValue) => setState(() => _switchValue = newValue), ), diff --git a/test/tab_bar_test.dart b/test/tab_bar_test.dart index faace2b3..e505e8c9 100644 --- a/test/tab_bar_test.dart +++ b/test/tab_bar_test.dart @@ -2,145 +2,145 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("tab_bar_test"); +const Key _tabBarKey = Key("tab_bar_test"); + +const String _firstTabLabel = "Label 1"; +const String _secondTabLabel = "Label 2"; +const String _thirdTabLabel = "Label 3"; +const String _fourthTabLabel = "Label 4"; +const IconData _tabLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _tabTrailingIcon = MoonIcons.controls_close_small_24_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TabBarTestWidget( + tabBarKey: _tabBarKey, ), ); - expect( - find.byWidgetPredicate( - (widget) => widget is MoonTabBar && widget.key == key, - ), - findsOneWidget, - ); + expect(find.byKey(_tabBarKey), findsOneWidget); }); - testWidgets("Tab bar with leading, trailing, label", (tester) async { + testWidgets("Tab bar has a leading, label and trailing widget.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TabBarTestWidget( showLabel: true, showLeading: true, showTrailing: true, ), ); - expect(find.textContaining(label), findsWidgets); - expect(find.byIcon(leadingIcon), findsWidgets); - expect(find.byIcon(trailingIcon), findsWidgets); + expect(find.textContaining(_firstTabLabel), findsWidgets); + expect(find.textContaining(_secondTabLabel), findsWidgets); + expect(find.textContaining(_thirdTabLabel), findsWidgets); + expect(find.textContaining(_fourthTabLabel), findsWidgets); + expect(find.byIcon(_tabLeadingIcon), findsWidgets); + expect(find.byIcon(_tabTrailingIcon), findsWidgets); }); - testWidgets("Press tab", (tester) async { + testWidgets("Tab onTap callback works.", (tester) async { var value = 0; + await tester.pumpWidget( - TestWidget( - widgetKey: key, + _TabBarTestWidget( showLabel: true, onTap: (index) => value = index, ), ); - await tester.tap(find.text('$label 2')); + await tester.tap(find.text(_secondTabLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 1); - await tester.tap(find.text('$label 1')); + await tester.tap(find.text(_firstTabLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); - await tester.tap(find.text('$label 3')); + await tester.tap(find.text(_thirdTabLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 2); }); - testWidgets("Disabled press tab", (tester) async { + testWidgets("OnTap callback of a disabled tab is ignored.", (tester) async { var value = 0; + await tester.pumpWidget( - TestWidget( - widgetKey: key, + _TabBarTestWidget( showLabel: true, isDisabled: true, onTap: (index) => value = index, ), ); - await tester.tap(find.text('$label 2')); + await tester.tap(find.text(_secondTabLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); - await tester.tap(find.text('$label 1')); + await tester.tap(find.text(_firstTabLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); - await tester.tap(find.text('$label 3')); + await tester.tap(find.text(_thirdTabLabel), warnIfMissed: false); await tester.pumpAndSettle(); expect(value, 0); }); } -const String label = "Label"; -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; - -class TestWidget extends StatelessWidget { +class _TabBarTestWidget extends StatelessWidget { + final Key? tabBarKey; final bool showLeading; - final bool showTrailing; final bool showLabel; - final Key? widgetKey; - final void Function(int)? onTap; + final bool showTrailing; final bool isDisabled; + final void Function(int)? onTap; - const TestWidget({ - super.key, + const _TabBarTestWidget({ + this.tabBarKey, this.showLeading = false, this.showLabel = false, this.showTrailing = false, - this.widgetKey, - this.onTap, this.isDisabled = false, + this.onTap, }); + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MoonTabBar( - key: widgetKey, + key: tabBarKey, onTabChanged: onTap, tabs: [ MoonTab( - leading: showLeading ? const Icon(leadingIcon) : null, - label: showLabel ? const Text('$label 1') : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, disabled: isDisabled, + leading: showLeading ? const Icon(_tabLeadingIcon) : null, + label: showLabel ? const Text(_firstTabLabel) : null, + trailing: showTrailing ? const Icon(_tabTrailingIcon) : null, ), MoonTab( - leading: showLeading ? const Icon(leadingIcon) : null, - label: showLabel ? const Text('$label 2') : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, disabled: isDisabled, + leading: showLeading ? const Icon(_tabLeadingIcon) : null, + label: showLabel ? const Text(_secondTabLabel) : null, + trailing: showTrailing ? const Icon(_tabTrailingIcon) : null, ), MoonTab( - leading: showLeading ? const Icon(leadingIcon) : null, - label: showLabel ? const Text('$label 3') : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, disabled: isDisabled, + leading: showLeading ? const Icon(_tabLeadingIcon) : null, + label: showLabel ? const Text(_thirdTabLabel) : null, + trailing: showTrailing ? const Icon(_tabTrailingIcon) : null, ), MoonTab( - leading: showLeading ? const Icon(leadingIcon) : null, - label: showLabel ? const Text('$label 4') : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, disabled: isDisabled, + leading: showLeading ? const Icon(_tabLeadingIcon) : null, + label: showLabel ? const Text(_fourthTabLabel) : null, + trailing: showTrailing ? const Icon(_tabTrailingIcon) : null, ), ], ), diff --git a/test/tag_test.dart b/test/tag_test.dart index b80f3edf..531bbdfd 100644 --- a/test/tag_test.dart +++ b/test/tag_test.dart @@ -2,84 +2,110 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("tag_test"); +const Key _tagKey = Key("tagKey"); + +const String _tagLabel = "Label"; +const IconData _tagLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _tagTrailingIcon = MoonIcons.controls_close_small_24_light; - testWidgets("Provided key is used", (tester) async { +void main() { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const Directionality( - textDirection: TextDirection.ltr, - child: MoonTag( - key: key, - label: Text(title), - ), + const _TagTestWidget( + tagKey: _tagKey, ), ); - expect(find.byKey(key), findsOneWidget); + + expect(find.byKey(_tagKey), findsOneWidget); }); - testWidgets("Simple tag", (tester) async { - await tester.pumpWidget( - const TestWidget(), - ); + testWidgets("Default tag has no leading, label or trailing widget.", (tester) async { + await tester.pumpWidget(const _TagTestWidget()); - expect(find.text(title), findsOneWidget); + expect(find.text(_tagLabel), findsNothing); + expect(find.text(_tagLabel), findsNothing); + expect(find.text(_tagLabel), findsNothing); }); - testWidgets("Tag with leading, trailing", (tester) async { + testWidgets("Tag has a leading, label and trailing widget.", (tester) async { await tester.pumpWidget( - const TestWidget( + const _TagTestWidget( showLeading: true, + showLabel: true, showTrailing: true, ), ); - expect(find.text(title), findsOneWidget); - expect(find.byIcon(trailingIcon), findsOneWidget); - expect(find.byIcon(leadingIcon), findsOneWidget); + + expect(find.text(_tagLabel), findsOneWidget); + expect(find.byIcon(_tagTrailingIcon), findsOneWidget); + expect(find.byIcon(_tagLeadingIcon), findsOneWidget); }); - testWidgets("Press tag", (tester) async { - bool isPressed = false; + testWidgets("Tag onTap callback works.", (tester) async { + bool isTapped = false; + await tester.pumpWidget( - TestWidget( + _TagTestWidget( + tagKey: _tagKey, showTrailing: true, - onTap: () { - isPressed = true; - }, + onTap: () => isTapped = true, ), ); - await tester.tap(find.byType(MoonTag)); + await tester.tap(find.byKey(_tagKey)); await tester.pumpAndSettle(); - expect(isPressed, true); + + expect(isTapped, true); }); -} -const String title = "Tag title"; -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; + testWidgets("Tag onLongPress callback works.", (tester) async { + bool longPressed = false; + bool tapped = false; -class TestWidget extends StatelessWidget { + await tester.pumpWidget( + _TagTestWidget( + tagKey: _tagKey, + onLongPress: () => longPressed = true, + onTap: () => tapped = true, + ), + ); + + await tester.longPress(find.byKey(_tagKey)); + await tester.pumpAndSettle(); + + expect(longPressed, true); + expect(tapped, false); + }); +} + +class _TagTestWidget extends StatelessWidget { + final Key? tagKey; final bool showLeading; + final bool showLabel; final bool showTrailing; - final VoidCallback? onTap; + final VoidCallback? onLongPress; - const TestWidget({ - super.key, + const _TagTestWidget({ + this.tagKey, this.showLeading = false, + this.showLabel = false, this.showTrailing = false, this.onTap, + this.onLongPress, }); + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( body: MoonTag( + key: tagKey, onTap: onTap, - leading: showLeading ? const Icon(leadingIcon) : null, - label: const Text(title), - trailing: showTrailing ? const Icon(trailingIcon) : null, + onLongPress: onLongPress, + leading: showLeading ? const Icon(_tagLeadingIcon) : null, + label: showLabel ? const Text(_tagLabel) : null, + trailing: showTrailing ? const Icon(_tagTrailingIcon) : null, ), ), ); diff --git a/test/text_area_test.dart b/test/text_area_test.dart index a83b7d4f..3096d434 100644 --- a/test/text_area_test.dart +++ b/test/text_area_test.dart @@ -2,139 +2,115 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("text_area_test"); +const Key _textAreaKey = Key("textAreaKey"); +const Key _submitButtonKey = Key("submitButtonKey"); + +const String _hintText = 'Hint text'; +const String _errorText = 'Error text'; +const String _helperText = 'Helper text'; +const String _validText = 'Valid text'; +const String _invalidText = 'Invalid text'; +void main() { Future submit(WidgetTester tester) async { - await tester.tap(find.byType(MoonFilledButton)); + await tester.tap(find.byKey(_submitButtonKey)); await tester.pumpAndSettle(); } - testWidgets("Provided key is used", (tester) async { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextAreaTestWidget( + textAreaKey: _textAreaKey, ), ); - expect( - find.byWidgetPredicate( - (widget) => widget is MoonTextArea && widget.key == key, - ), - findsOneWidget, - ); + expect(find.byKey(_textAreaKey), findsOneWidget); }); - testWidgets("Enter valid text", (tester) async { + testWidgets("When valid text is entered and submitted, error is not shown.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextAreaTestWidget( + textAreaKey: _textAreaKey, ), ); + final textArea = find.byKey(_textAreaKey); - final textArea = find.byKey(key); - - await tester.enterText(textArea, validText); + await tester.enterText(textArea, _validText); await tester.pumpAndSettle(); - expect( - find.text(validText), - findsOneWidget, - ); + + expect(find.text(_validText), findsOneWidget); + await submit(tester); - expect( - find.text(error), - findsNothing, - ); + + expect(find.text(_errorText), findsNothing); }); - testWidgets("Enter invalid text", (tester) async { + testWidgets("When invalid text is entered and submitted, error is shown.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextAreaTestWidget( + textAreaKey: _textAreaKey, ), ); + final textArea = find.byKey(_textAreaKey); - final textArea = find.byKey(key); - - await tester.enterText(textArea, invalidText); + await tester.enterText(textArea, _invalidText); await tester.pumpAndSettle(); - expect( - find.text(invalidText), - findsOneWidget, - ); + + expect(find.text(_invalidText), findsOneWidget); + await submit(tester); - expect( - find.text(error), - findsOneWidget, - ); + + expect(find.text(_errorText), findsOneWidget); }); - testWidgets("Check helper text", (tester) async { + testWidgets("Helper text is shown.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextAreaTestWidget( showHelper: true, ), ); - expect( - find.text(helper), - findsOneWidget, - ); + expect(find.text(_helperText), findsOneWidget); }); - testWidgets("Check hint", (tester) async { + testWidgets("Hint text is shown.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextAreaTestWidget( showHelper: true, ), ); - expect( - find.text(hint), - findsOneWidget, - ); + expect(find.text(_hintText), findsOneWidget); }); - testWidgets("Disabled: enter text", (tester) async { + testWidgets("When text area is disabled, input cannot be entered.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextAreaTestWidget( + textAreaKey: _textAreaKey, enabled: false, ), ); - final textArea = find.byKey(key); + final textArea = find.byKey(_textAreaKey); - await tester.enterText(textArea, validText); + await tester.enterText(textArea, _validText); await tester.pumpAndSettle(); - expect( - find.text(validText), - findsNothing, - ); + + expect(find.text(_validText), findsNothing); }); } -const validText = - 'Lorem Ipsum is simply dummy text of the printing and typesetting industry'; -const invalidText = 'Lorem'; - -const hint = 'Hint'; -const error = 'Error'; -const helper = 'Helper'; - -class TestWidget extends StatelessWidget { +class _TextAreaTestWidget extends StatelessWidget { + final Key? textAreaKey; final bool enabled; final bool showHelper; - final Key? widgetKey; - const TestWidget({ - super.key, + const _TextAreaTestWidget({ + this.textAreaKey, this.enabled = true, this.showHelper = false, - this.widgetKey, }); + @override Widget build(BuildContext context) { return MaterialApp( @@ -143,21 +119,16 @@ class TestWidget extends StatelessWidget { child: Builder( builder: (BuildContext context) { return Column( - mainAxisSize: MainAxisSize.min, children: [ MoonTextArea( - key: widgetKey, + key: textAreaKey, enabled: enabled, - hintText: hint, - validator: (String? value) => - value?.length != null && value!.length < 10 - ? error - : null, - helper: showHelper ? const Text(helper) : null, + hintText: _hintText, + validator: (String? value) => value?.length != null && value!.length > 10 ? _errorText : null, + helper: showHelper ? const Text(_helperText) : null, ), - const SizedBox(height: 32), MoonFilledButton( - label: const Text("Submit"), + key: _submitButtonKey, onTap: () => Form.of(context).validate(), ), ], diff --git a/test/text_input_test.dart b/test/text_input_test.dart index c81aed09..5a15be51 100644 --- a/test/text_input_test.dart +++ b/test/text_input_test.dart @@ -2,156 +2,133 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; -void main() { - const key = Key("text_input_test"); +const Key _textInputKey = Key("textInputKey"); +const Key _submitButtonKey = Key("submitButtonKey"); + +const String _hintText = 'Hint text'; +const String _errorText = 'Error text'; +const String _helperText = 'Helper text'; +const String _validText = 'Valid text'; +const String _invalidText = 'Invalid text'; +const IconData _textInputLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _textInputTrailingIcon = MoonIcons.controls_close_small_24_light; +void main() { Future submit(WidgetTester tester) async { - await tester.tap(find.byType(MoonFilledButton)); + await tester.tap(find.byKey(_submitButtonKey)); await tester.pumpAndSettle(); } - testWidgets("Provided key is used", (tester) async { + testWidgets("Provided key is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextInputTestWidget( + textInputKey: _textInputKey, ), ); - expect( - find.byWidgetPredicate( - (widget) => widget is MoonFormTextInput && widget.key == key, - ), - findsOneWidget, - ); + expect(find.byKey(_textInputKey), findsOneWidget); }); - testWidgets("Enter valid text", (tester) async { + testWidgets("When valid text is entered and submitted, error is not shown.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextInputTestWidget( + textInputKey: _textInputKey, ), ); + final textInput = find.byKey(_textInputKey); - final textInput = find.byKey(key); - - await tester.enterText(textInput, validText); + await tester.enterText(textInput, _validText); await tester.pumpAndSettle(); - expect( - find.text(validText), - findsOneWidget, - ); + + expect(find.text(_validText), findsOneWidget); + await submit(tester); - expect( - find.text(error), - findsNothing, - ); + + expect(find.text(_errorText), findsNothing); }); - testWidgets("Enter invalid text", (tester) async { + testWidgets("When invalid text is entered and submitted, error is shown.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextInputTestWidget( + textInputKey: _textInputKey, ), ); + final textInput = find.byKey(_textInputKey); - final textInput = find.byKey(key); - - await tester.enterText(textInput, invalidText); + await tester.enterText(textInput, _invalidText); await tester.pumpAndSettle(); - expect( - find.text(invalidText), - findsOneWidget, - ); + + expect(find.text(_invalidText), findsOneWidget); + await submit(tester); - expect( - find.text(error), - findsOneWidget, - ); + + expect(find.text(_errorText), findsOneWidget); }); - testWidgets("Check helper text", (tester) async { + testWidgets("Helper text is shown.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextInputTestWidget( showHelper: true, ), ); - expect( - find.text(helper), - findsOneWidget, - ); + expect(find.text(_helperText), findsOneWidget); }); - testWidgets("Check hint", (tester) async { + testWidgets("Hint text is shown.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextInputTestWidget( showHelper: true, ), ); - expect( - find.text(hint), - findsOneWidget, - ); + expect(find.text(_hintText), findsOneWidget); }); - testWidgets("Check leading, traling", (tester) async { + + testWidgets("Text input has a leading and trailing widget.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextInputTestWidget( showLeading: true, showTrailing: true, ), ); - expect(find.byIcon(leadingIcon), findsOneWidget); - expect(find.byIcon(trailingIcon), findsOneWidget); + expect(find.byIcon(_textInputLeadingIcon), findsOneWidget); + expect(find.byIcon(_textInputTrailingIcon), findsOneWidget); }); - testWidgets("Disabled: enter text", (tester) async { + testWidgets("When text input is disabled, input cannot be entered.", (tester) async { await tester.pumpWidget( - const TestWidget( - widgetKey: key, + const _TextInputTestWidget( + textInputKey: _textInputKey, enabled: false, ), ); - final textArea = find.byKey(key); + final textArea = find.byKey(_textInputKey); - await tester.enterText(textArea, validText); + await tester.enterText(textArea, _validText); await tester.pumpAndSettle(); - expect( - find.text(validText), - findsNothing, - ); + + expect(find.text(_validText), findsNothing); }); } -const validText = 'Lorem Ipsum is simply dummy text of the printing and typesetting industry'; -const invalidText = 'Lorem'; - -const hint = 'Hint'; -const error = 'Error'; -const helper = 'Helper'; -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; - -class TestWidget extends StatelessWidget { +class _TextInputTestWidget extends StatelessWidget { + final Key? textInputKey; final bool enabled; final bool showHelper; - final Key? widgetKey; final bool showLeading; final bool showTrailing; - const TestWidget({ - super.key, + const _TextInputTestWidget({ + this.textInputKey, this.enabled = true, this.showHelper = false, - this.widgetKey, this.showLeading = false, this.showTrailing = false, }); + @override Widget build(BuildContext context) { return MaterialApp( @@ -160,20 +137,18 @@ class TestWidget extends StatelessWidget { child: Builder( builder: (BuildContext context) { return Column( - mainAxisSize: MainAxisSize.min, children: [ MoonFormTextInput( - key: widgetKey, + key: textInputKey, enabled: enabled, - hintText: hint, - validator: (String? value) => value != null && value.length < 10 ? error : null, - leading: showLeading ? const Icon(leadingIcon) : null, - trailing: showTrailing ? const Icon(trailingIcon) : null, - helper: showHelper ? const Text(helper) : null, + hintText: _hintText, + validator: (String? value) => value != null && value.length > 10 ? _errorText : null, + leading: showLeading ? const Icon(_textInputLeadingIcon) : null, + trailing: showTrailing ? const Icon(_textInputTrailingIcon) : null, + helper: showHelper ? const Text(_helperText) : null, ), - const SizedBox(height: 32), MoonFilledButton( - label: const Text("Submit"), + key: _submitButtonKey, onTap: () => Form.of(context).validate(), ), ], diff --git a/test/toast_test.dart b/test/toast_test.dart index ea93fd8d..5e4da37b 100644 --- a/test/toast_test.dart +++ b/test/toast_test.dart @@ -2,35 +2,31 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/moon_design.dart'; +const Key _showButtonKey = Key('showButtonKey'); + +const String _toastLabel = 'Label'; +const String _toastBody = 'Body'; +const IconData _toastLeadingIcon = MoonIcons.other_frame_24_light; +const IconData _toastTrailingIcon = MoonIcons.controls_close_small_24_light; + void main() { - testWidgets("Open toast", (tester) async { - await tester.pumpWidget( - TestWidget(), - ); - await tester.tap(find.byType(MoonFilledButton)); - await tester.pump(const Duration(milliseconds: 100)); - await tester.pump(const Duration(milliseconds: 100)); + testWidgets("Toast is displayed when the 'show' button is tapped and dismissed after 2 seconds.", (tester) async { + await tester.pumpWidget(_ToastTestWidget()); + await tester.tap(find.byKey(_showButtonKey)); + await tester.pump(const Duration(milliseconds: 200)); - expect(find.text(title), findsOneWidget); - expect(find.text(body), findsOneWidget); - expect(find.byIcon(leadingIcon), findsOneWidget); - expect(find.byIcon(trailingIcon), findsOneWidget); - await tester.pump(const Duration(milliseconds: 100)); - await tester.pump(const Duration(milliseconds: 100)); - await tester.pump(const Duration(milliseconds: 100)); - await tester.pump(const Duration(milliseconds: 100)); - await tester.pump(const Duration(milliseconds: 100)); + expect(find.text(_toastLabel), findsOneWidget); + expect(find.text(_toastBody), findsOneWidget); + expect(find.byIcon(_toastLeadingIcon), findsOneWidget); + expect(find.byIcon(_toastTrailingIcon), findsOneWidget); - expect(find.text(title), findsNothing); + await tester.pump(const Duration(seconds: 2)); + + expect(find.text(_toastLabel), findsNothing); }); } -const IconData leadingIcon = MoonIcons.other_frame_24_light; -const IconData trailingIcon = MoonIcons.controls_close_small_24_light; -const title = 'Title'; -const body = 'Body'; - -class TestWidget extends StatelessWidget { +class _ToastTestWidget extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( @@ -38,16 +34,16 @@ class TestWidget extends StatelessWidget { body: Builder( builder: (context) { return MoonFilledButton( - label: const Text("Tap me"), + key: _showButtonKey, onTap: () { MoonToast.show( context, - displayDuration: const Duration(milliseconds: 500), + displayDuration: const Duration(seconds: 2), transitionDuration: Duration.zero, - leading: const Icon(leadingIcon), - label: const Text(title), - trailing: const Icon(trailingIcon), - content: const Text(body), + leading: const Icon(_toastLeadingIcon), + label: const Text(_toastLabel), + trailing: const Icon(_toastTrailingIcon), + content: const Text(_toastBody), ); }, ); diff --git a/test/tooltip_test.dart b/test/tooltip_test.dart index dc2e52a0..1e745c62 100644 --- a/test/tooltip_test.dart +++ b/test/tooltip_test.dart @@ -4,105 +4,115 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:moon_design/src/widgets/buttons/filled_button.dart'; import 'package:moon_design/src/widgets/tooltip/tooltip.dart'; +const Key _tooltipKey = Key("tooltipKey"); +const Key _showButtonKey = Key("_showButtonKey"); + +const Widget _tooltipContent = Text("Content"); + void main() { - const key = Key("tooltip_test"); + testWidgets("Provided key is used.", (tester) async { + await tester.pumpWidget( + const _ToastTestWidget( + tooltipKey: _tooltipKey, + ), + ); - testWidgets("Provided key is used", (tester) async { - await tester.pumpWidget(MoonTooltip(key: key, show: true, content: Container(), child: Container())); - expect(find.byKey(key), findsOneWidget); + expect(find.byKey(_tooltipKey), findsOneWidget); }); - testWidgets("Tooltip is shown after clicking on button", (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.byType(MoonFilledButton); + testWidgets("Tooltip is displayed when the 'show' button is tapped.", (tester) async { + await tester.pumpWidget( + const _ToastTestWidget( + tooltipKey: _tooltipKey, + ), + ); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_tooltipContent), findsOneWidget); }); - testWidgets("Tooltip is hidden after clicking on it", (tester) async { - await tester.pumpWidget(const TestWidget(key: key, content: content)); - final button = find.byType(MoonFilledButton); + testWidgets("Tooltip closes when tapped.", (tester) async { + await tester.pumpWidget( + const _ToastTestWidget( + tooltipKey: _tooltipKey, + ), + ); + final button = find.byKey(_showButtonKey); + final tooltipContent = find.byWidget(_tooltipContent); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - final tooltipContent = _findTooltipContent(tooltipText); + await tester.tap(tooltipContent); await tester.pumpAndSettle(); expect(tooltipContent, findsNothing); }); - testWidgets("Provided color is used", (tester) async { + testWidgets("Provided background color is used.", (tester) async { await tester.pumpWidget( - const TestWidget( - key: key, - content: content, - color: Colors.red, + const _ToastTestWidget( + tooltipKey: _tooltipKey, + color: Colors.blue, ), ); - final button = find.byType(MoonFilledButton); + final button = find.byKey(_showButtonKey); expect(button, findsOneWidget); await tester.tap(button); await tester.pumpAndSettle(); - expect(find.byWidget(content), findsOneWidget); + expect(find.byWidget(_tooltipContent), findsOneWidget); expect( - find.byWidgetPredicate((widget) => widget is MoonTooltip && widget.backgroundColor == Colors.red), + find.byWidgetPredicate((Widget widget) => widget is MoonTooltip && widget.backgroundColor == Colors.blue), findsOneWidget, ); }); } -const String tooltipText = "Tooltip content"; -const Widget content = Text(tooltipText); - -Finder _findTooltipContent(String tooltipText) { - return find.ancestor( - of: find.text(tooltipText), - matching: find.byType(Container), - ); -} - -bool show = false; - -class TestWidget extends StatelessWidget { - final Widget content; +class _ToastTestWidget extends StatefulWidget { + final Key? tooltipKey; final Color color; - const TestWidget({ - required this.content, + const _ToastTestWidget({ + this.tooltipKey, this.color = Colors.white, - super.key, }); + @override + State<_ToastTestWidget> createState() => _ToastTestWidgetState(); +} + +class _ToastTestWidgetState extends State<_ToastTestWidget> { + bool _show = false; + @override Widget build(BuildContext context) { return MaterialApp( home: Scaffold( - body: Center( - child: StatefulBuilder( - builder: (context, setState) { - return MoonTooltip( - show: show, - backgroundColor: color, - content: content, + body: Builder( + builder: (BuildContext context) { + return Center( + child: MoonTooltip( + key: widget.tooltipKey, + show: _show, + backgroundColor: widget.color, + content: _tooltipContent, child: MoonFilledButton( - onTap: () { - setState(() => show = true); - }, + key: _showButtonKey, + onTap: () => setState(() => _show = true), ), - ); - }, - ), + ), + ); + }, ), ), );