From 2a1bda246d9404b5df5950ea0f64320c4ccba5e1 Mon Sep 17 00:00:00 2001 From: Kolya Paradiuk Date: Thu, 28 Dec 2023 08:22:16 +0200 Subject: [PATCH 1/2] add tests for auth_code, bottom_sheet, button, carousel, checkbox, chip, drawer, menu_item, modal, popover --- test/auth_code_test.dart | 97 +++++++++++++++++++++++++ test/bottom_sheet_test.dart | 136 ++++++++++++++++++++++++++++++++++ test/button_test.dart | 117 ++++++++++++++++++++++++++++++ test/carousel_test.dart | 74 +++++++++++++++++++ test/checkbox_test.dart | 141 ++++++++++++++++++++++++++++++++++++ test/chip_test.dart | 71 ++++++++++++++++++ test/drawer_test.dart | 104 ++++++++++++++++++++++++++ test/menu_item_test.dart | 86 ++++++++++++++++++++++ test/modal_test.dart | 139 +++++++++++++++++++++++++++++++++++ test/popover_test.dart | 122 +++++++++++++++++++++++++++++++ 10 files changed, 1087 insertions(+) create mode 100644 test/auth_code_test.dart create mode 100644 test/bottom_sheet_test.dart create mode 100644 test/button_test.dart create mode 100644 test/carousel_test.dart create mode 100644 test/checkbox_test.dart create mode 100644 test/chip_test.dart create mode 100644 test/drawer_test.dart create mode 100644 test/menu_item_test.dart create mode 100644 test/modal_test.dart create mode 100644 test/popover_test.dart diff --git a/test/auth_code_test.dart b/test/auth_code_test.dart new file mode 100644 index 00000000..0c7bb2e5 --- /dev/null +++ b/test/auth_code_test.dart @@ -0,0 +1,97 @@ +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"); + + testWidgets("Provided key is used", (tester) async { + await tester.pumpWidget( + const TestWidget( + authCodeKey: key, + ), + ); + expect(find.byKey(key), findsOneWidget); + }); + + testWidgets("Enter valid code", (tester) async { + await tester.pumpWidget( + const TestWidget( + authCodeKey: key, + ), + ); + final widget = find.byType(TextFormField).first; + await tester.enterText(widget, '9921'); + await tester.pump(const Duration(milliseconds: 110)); + expect(find.text(errorMessage), findsNothing); + }); + testWidgets("Enter invalid code", (tester) async { + await tester.pumpWidget( + const TestWidget( + authCodeKey: key, + ), + ); + final widget = find.byType(TextFormField).first; + await tester.enterText(widget, '1111'); + await tester.pump(const Duration(milliseconds: 110)); + expect(find.text(errorMessage), findsOneWidget); + }); + + testWidgets("Initial error message", (tester) async { + await tester.pumpWidget( + const TestWidget( + authCodeKey: key, + initialErrorMessage: initialErrorMessage, + ), + ); + 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'; + +class TestWidget extends StatelessWidget { + const TestWidget({ + super.key, + this.authCodeKey, + this.initialErrorMessage, + }); + + final Key? authCodeKey; + final String? initialErrorMessage; + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: Directionality( + textDirection: TextDirection.ltr, + 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 ?? ''), + ), + ); + }, + ), + ), + ), + ); + } +} diff --git a/test/bottom_sheet_test.dart b/test/bottom_sheet_test.dart new file mode 100644 index 00000000..2c5c176b --- /dev/null +++ b/test/bottom_sheet_test.dart @@ -0,0 +1,136 @@ +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("bottom_sheet_test"); + + 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); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), 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); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + + await tester.tapAt(const Offset(10, 10)); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsNothing); + }); + + testWidgets( + "Botton sheet is not hidden after clicking outside content if not dismissable", + (tester) async { + await tester.pumpWidget( + const TestWidget( + key: key, + content: content, + isDismissible: false, + ), + ); + final button = find.byType(MoonFilledButton); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + + await tester.tapAt(const Offset(10, 10)); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + }); + testWidgets("Botton sheet is expanded", (tester) async { + await tester.pumpWidget( + const TestWidget( + key: key, + content: content, + isExpanded: true, + ), + ); + final button = find.byType(MoonFilledButton); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + + await tester.tapAt(const Offset(1, 1)); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + + await tester.tapAt(const Offset(100, 1)); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + }); +} + +const String bottomSheetText = "Botton sheet content"; +const Widget content = Text(bottomSheetText); + +class TestWidget extends StatelessWidget { + final Widget content; + final bool isDismissible; + final bool isExpanded; + + const TestWidget({ + required this.content, + 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), + ); + }, + ), + ), + ), + ); + } + + Future bottomSheetBuilder(BuildContext context) { + return showMoonModalBottomSheet( + isExpanded: isExpanded, + context: context, + backgroundColor: Colors.black38, + enableDrag: true, + isDismissible: isDismissible, + height: MediaQuery.of(context).size.height * 0.5, + builder: (BuildContext context) => content, + ); + } +} diff --git a/test/button_test.dart b/test/button_test.dart new file mode 100644 index 00000000..0ef50b95 --- /dev/null +++ b/test/button_test.dart @@ -0,0 +1,117 @@ +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"); + + testWidgets("Provided key is used", (tester) async { + await tester.pumpWidget( + const TestWidget( + key: key, + ), + ); + expect(find.byKey(key), findsOneWidget); + }); + + testWidgets("Button with leading, trailing, label", (tester) async { + await tester.pumpWidget( + const TestWidget( + showLeading: true, + showLabel: true, + showTrailing: true, + ), + ); + expect(find.text(buttonLabel), findsOneWidget); + expect(find.byIcon(trailingIcon), findsOneWidget); + expect(find.byIcon(leadinIcon), findsOneWidget); + }); + + testWidgets("Button tap", (tester) async { + bool tapped = false; + await tester.pumpWidget( + TestWidget( + onTap: () => tapped = true, + ), + ); + await tester.tap(find.byType(MoonButton)); + await tester.pumpAndSettle(); + expect(tapped, true); + }); + + testWidgets("Button long press", (tester) async { + bool longPressed = false; + bool tapped = false; + await tester.pumpWidget( + TestWidget( + onLongPress: () => longPressed = true, + onTap: () => tapped = true, + ), + ); + await tester.longPress(find.byType(MoonButton)); + await tester.pumpAndSettle(); + expect(longPressed, true); + expect(tapped, false); + }); +} + +const String buttonLabel = "Button label"; +const IconData leadinIcon = MoonIcons.other_frame_24_light; +const IconData trailingIcon = MoonIcons.controls_close_small_24_light; + +class TestWidget extends StatefulWidget { + final bool showLeading; + final bool showTrailing; + final bool showLabel; + final VoidCallback? onTap; + final VoidCallback? onLongPress; + final Key? buttonKey; + + const TestWidget({ + super.key, + 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(leadinIcon) : 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, + ), + ), + ); + } +} diff --git a/test/carousel_test.dart b/test/carousel_test.dart new file mode 100644 index 00000000..bab80ee4 --- /dev/null +++ b/test/carousel_test.dart @@ -0,0 +1,74 @@ +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"); + + testWidgets( + "Provided key is used", + (tester) async { + await tester.pumpWidget( + const CarouselTestWidget( + widgetKey: key, + ), + ); + expect(find.byKey(key), 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('3'), findsOneWidget); + }, + ); +} + +class CarouselTestWidget extends StatelessWidget { + final Key? widgetKey; + + const CarouselTestWidget({super.key, this.widgetKey}); + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: SizedBox( + height: 114, + width: 200, + child: MoonCarousel( + key: widgetKey, + gap: 8, + itemCount: 10, + itemExtent: 100, + itemBuilder: (BuildContext context, int itemIndex, int realIndex) => + 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}"), + ), + ), + ), + ), + )); + } +} diff --git a/test/checkbox_test.dart b/test/checkbox_test.dart new file mode 100644 index 00000000..bb8aeb35 --- /dev/null +++ b/test/checkbox_test.dart @@ -0,0 +1,141 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:moon_design/moon_design.dart'; + +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( + "Check checkbox label", + (tester) async { + const label = 'Checkbox label'; + + await tester.pumpWidget( + const TestWidget( + widgetKey: key, + label: label, + ), + ); + + expect(find.text(label), findsOneWidget); + }, + ); +} + +class TestWidget extends StatefulWidget { + final Key? widgetKey; + final void Function(bool?)? onChanged; + final bool isTristate; + final bool initialValue; + final String? label; + + const TestWidget({ + super.key, + this.widgetKey, + this.isTristate = false, + this.onChanged, + this.initialValue = false, + this.label, + }); + + @override + State createState() => _TestWidgetState(); +} + +class _TestWidgetState extends State { + bool? checkboxValue; + + @override + void initState() { + super.initState(); + checkboxValue = widget.initialValue; + } + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: widget.label != null + ? MoonCheckbox.withLabel( + context, + key: widget.widgetKey, + value: checkboxValue, + tristate: widget.isTristate, + onChanged: (bool? newValue) { + setState(() => checkboxValue = newValue); + widget.onChanged?.call(newValue); + }, + label: widget.label!, + ) + : MoonCheckbox( + key: widget.widgetKey, + value: checkboxValue, + tristate: widget.isTristate, + onChanged: (bool? newValue) { + setState(() => checkboxValue = newValue); + widget.onChanged?.call(newValue); + }, + ), + ), + ); + } +} diff --git a/test/chip_test.dart b/test/chip_test.dart new file mode 100644 index 00000000..5ba6f8fc --- /dev/null +++ b/test/chip_test.dart @@ -0,0 +1,71 @@ +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"); + + testWidgets("Provided key is used", (tester) async { + await tester.pumpWidget( + const TestWidget( + widgetKey: key, + ), + ); + expect(find.byKey(key), findsOneWidget); + }); + + testWidgets("Simple chip", (tester) async { + await tester.pumpWidget( + const TestWidget( + showLabel: true, + ), + ); + + expect(find.text(label), findsOneWidget); + }); + + testWidgets("Chip with leading, trailing, body", (tester) async { + await tester.pumpWidget( + const TestWidget( + showLeading: true, + showLabel: true, + showTrailing: true, + ), + ); + expect(find.text(label), findsOneWidget); + expect(find.byIcon(trailingIcon), findsOneWidget); + expect(find.byIcon(leadinIcon), findsOneWidget); + }); +} + +const String label = "Label"; +const IconData leadinIcon = MoonIcons.other_frame_24_light; +const IconData trailingIcon = MoonIcons.controls_close_small_24_light; + +class TestWidget extends StatelessWidget { + final bool showLeading; + final bool showTrailing; + final bool showLabel; + final Key? widgetKey; + + const TestWidget({ + super.key, + 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(leadinIcon) : null, + label: showLabel ? const Text(label) : null, + trailing: showTrailing ? const Icon(trailingIcon) : null, + ), + ), + ); + } +} diff --git a/test/drawer_test.dart b/test/drawer_test.dart new file mode 100644 index 00000000..5fbb99b4 --- /dev/null +++ b/test/drawer_test.dart @@ -0,0 +1,104 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:moon_design/moon_design.dart'; + +void main() { + testWidgets("Drawer is shown after clicking on button", (tester) async { + await tester.pumpWidget(const TestWidget(content: content)); + final button = find.text(openButtonText); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + }); + + testWidgets("Drawer close after clicking outside", (tester) async { + await tester.pumpWidget(const TestWidget(content: content)); + final button = find.text(openButtonText); + + 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); + }); + + testWidgets("Drawer close after clicking on button", (tester) async { + await tester.pumpWidget(const TestWidget(content: content)); + final button = find.text(openButtonText); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + await tester.tap(find.text(closeButtonText)); + await tester.pumpAndSettle(); + expect(find.byWidget(content), findsNothing); + }); +} + +const String contentText = "Drawer content"; +const String openButtonText = "Open"; +const String closeButtonText = "Close"; + +const Widget content = Text(contentText); + +class TestWidget extends StatelessWidget { + final Widget content; + + const TestWidget({ + required this.content, + super.key, + }); + + @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(), + ), + ); + }, + ), + ), + ), + ), + ); + } +} diff --git a/test/menu_item_test.dart b/test/menu_item_test.dart new file mode 100644 index 00000000..fb7af6d2 --- /dev/null +++ b/test/menu_item_test.dart @@ -0,0 +1,86 @@ +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"); + + testWidgets("Provided key is used", (tester) async { + await tester.pumpWidget( + const TestWidget( + widgetKey: key, + ), + ); + expect(find.byKey(key), findsOneWidget); + }); + + testWidgets("Simple menu item", (tester) async { + await tester.pumpWidget( + const TestWidget(), + ); + + expect(find.text(title), findsOneWidget); + }); + + testWidgets("Menu item with leading, trailing, description", (tester) async { + await tester.pumpWidget( + const TestWidget( + showLeading: true, + showDiscription: true, + showTrailing: true, + ), + ); + expect(find.text(description), findsOneWidget); + expect(find.byIcon(trailingIcon), findsOneWidget); + expect(find.byIcon(leadinIcon), findsOneWidget); + }); + + testWidgets("Tap menu item", (tester) async { + bool value = false; + await tester.pumpWidget( + TestWidget( + onTap: () => value = !value, + ), + ); + await tester.tap(find.byType(MoonMenuItem)); + await tester.pumpAndSettle(); + expect(value, true); + }); +} + +const String title = "Title"; +const String description = "Description"; +const IconData leadinIcon = MoonIcons.other_frame_24_light; +const IconData trailingIcon = MoonIcons.controls_close_small_24_light; + +class TestWidget extends StatelessWidget { + final bool showLeading; + final bool showTrailing; + final bool showDiscription; + final Key? widgetKey; + final VoidCallback? onTap; + + const TestWidget({ + super.key, + this.showLeading = false, + this.showDiscription = false, + this.showTrailing = false, + this.widgetKey, + this.onTap, + }); + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: MoonMenuItem( + key: widgetKey, + leading: showLeading ? const Icon(leadinIcon) : null, + description: showDiscription ? const Text(description) : null, + title: const Text(title), + trailing: showTrailing ? const Icon(trailingIcon) : null, + onTap: onTap, + ), + ), + ); + } +} diff --git a/test/modal_test.dart b/test/modal_test.dart new file mode 100644 index 00000000..5252d50b --- /dev/null +++ b/test/modal_test.dart @@ -0,0 +1,139 @@ +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("modal_test"); + + testWidgets("Modal is shown after clicking on button", (tester) async { + await tester.pumpWidget(const TestWidget(key: key, content: content)); + final button = find.text(openButtonText); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), 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); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + + await tester.tapAt(const Offset(10, 10)); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsNothing); + }); + + testWidgets( + "Modal is not hidden after clicking outside content if not dismissable", + (tester) async { + await tester.pumpWidget( + const TestWidget( + key: key, + content: content, + isDismissible: false, + ), + ); + final button = find.text(openButtonText); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + + await tester.tapAt(const Offset(10, 10)); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + }); + + testWidgets("Modal close after clicking on button", (tester) async { + await tester.pumpWidget(const TestWidget(content: content)); + final button = find.text(openButtonText); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + await tester.tap(find.text(closeButtonText)); + await tester.pumpAndSettle(); + expect(find.byWidget(content), 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; + final bool isDismissible; + + const TestWidget({ + required this.content, + this.isDismissible = true, + super.key, + }); + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: Center( + child: StatefulBuilder( + builder: (context, setState) { + return MoonFilledButton( + label: const Text(openButtonText), + onTap: () => modalBuilder(context), + ); + }, + ), + ), + ), + ); + } + + Future modalBuilder(BuildContext context) { + return showMoonModal( + context: context, + barrierDismissible: isDismissible, + useRootNavigator: false, + builder: (BuildContext _) { + return Directionality( + textDirection: Directionality.of(context), + child: MoonModal( + child: SizedBox( + width: 300, + child: Column( + mainAxisSize: MainAxisSize.min, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + content, + MoonFilledButton( + label: const Text(closeButtonText), + isFullWidth: true, + onTap: () => Navigator.of(context).pop(), + ), + ], + ), + ), + ), + ); + }, + ); + } +} diff --git a/test/popover_test.dart b/test/popover_test.dart new file mode 100644 index 00000000..24e551fd --- /dev/null +++ b/test/popover_test.dart @@ -0,0 +1,122 @@ +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"); + + testWidgets("Provided key is used", (tester) async { + await tester.pumpWidget( + const TestWidget( + widgetKey: key, + content: content, + ), + ); + expect(find.byKey(key), 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); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + 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); + + expect(button, findsOneWidget); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + + await tester.tapAt(const Offset(10, 10)); + await tester.pumpAndSettle(); + + 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); + + await tester.tap(button); + await tester.pumpAndSettle(); + + expect(find.byWidget(content), findsOneWidget); + await tester.tap(find.text(closeButtonText)); + await tester.pumpAndSettle(); + expect(find.byWidget(content), findsNothing); + }); +} + +const String contentText = "Content"; +const Widget content = Text(contentText); +const String openButtonText = "Open"; +const String closeButtonText = "Close"; + +class TestWidget extends StatefulWidget { + final Widget content; + final bool isDismissible; + final Key? widgetKey; + + const TestWidget({ + required this.content, + this.isDismissible = true, + this.widgetKey, + super.key, + }); + + @override + State createState() => _TestWidgetState(); +} + +class _TestWidgetState extends State { + bool show = false; + + @override + Widget build(BuildContext context) { + return MaterialApp( + home: Scaffold( + body: Center( + child: MoonPopover( + key: widget.widgetKey, + show: show, + onTapOutside: widget.isDismissible + ? () => setState(() => show = false) + : null, + content: ConstrainedBox( + constraints: const BoxConstraints(maxWidth: 190), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + widget.content, + const SizedBox(height: 16), + MoonFilledButton( + buttonSize: MoonButtonSize.sm, + isFullWidth: true, + onTap: () => setState(() => show = false), + label: const Text(closeButtonText), + ), + ], + ), + ), + child: MoonFilledButton( + onTap: () => setState(() => show = !show), + label: const Text(openButtonText), + ), + ), + ), + ), + ); + } +} From e8e7283eb996c11f979310a7593146651634c04d Mon Sep 17 00:00:00 2001 From: Kolya Paradiuk Date: Thu, 28 Dec 2023 11:19:45 +0200 Subject: [PATCH 2/2] fix analyze issue --- test/carousel_test.dart | 45 +++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 22 deletions(-) diff --git a/test/carousel_test.dart b/test/carousel_test.dart index bab80ee4..064cbd15 100644 --- a/test/carousel_test.dart +++ b/test/carousel_test.dart @@ -43,32 +43,33 @@ class CarouselTestWidget extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp( - home: Scaffold( - body: SizedBox( - height: 114, - width: 200, - child: MoonCarousel( - key: widgetKey, - gap: 8, - itemCount: 10, - itemExtent: 100, - itemBuilder: (BuildContext context, int itemIndex, int realIndex) => - Container( - height: 100, - width: 100, - decoration: ShapeDecoration( - color: context.moonColors?.goku, - shape: MoonSquircleBorder( - borderRadius: - BorderRadius.circular(12).squircleBorderRadius(context), + home: Scaffold( + body: SizedBox( + height: 114, + width: 200, + child: MoonCarousel( + key: widgetKey, + gap: 8, + itemCount: 10, + itemExtent: 100, + itemBuilder: (BuildContext context, int itemIndex, int realIndex) => + 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}"), ), - ), - child: Center( - child: Text("${itemIndex + 1}"), ), ), ), ), - )); + ); } }