From 10c9ce36d0e54e42936f0465428012a0bfdf21c4 Mon Sep 17 00:00:00 2001 From: Stan Persoons <147701137+stan-at-work@users.noreply.github.com> Date: Fri, 6 Dec 2024 18:30:31 +0100 Subject: [PATCH 1/4] Fix unit tests --- demo/pubspec.yaml | 174 +++---- lib/src/helper/pluto_key_manager_event.dart | 448 ++++++++++-------- .../helper/pluto_key_manager_event_test.dart | 433 +++++++++-------- 3 files changed, 572 insertions(+), 483 deletions(-) diff --git a/demo/pubspec.yaml b/demo/pubspec.yaml index 9d24b2f0e..06ae60b00 100644 --- a/demo/pubspec.yaml +++ b/demo/pubspec.yaml @@ -1,86 +1,88 @@ -name: demo -description: PlutoGrid demo app. - -# The following line prevents the package from being accidentally published to -# pub.dev using `pub publish`. This is preferred for private packages. -publish_to: 'none' # Remove this line if you wish to publish to pub.dev - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 1.0.0+1 - -environment: - sdk: ^3.0.0 - -dependencies: - flutter: - sdk: flutter - pluto_grid_plus: 8.4.3 - faker: ^2.1.0 - url_launcher: ^6.2.1 - font_awesome_flutter: ^10.6.0 - rainbow_color: ^2.0.1 - pluto_menu_bar: ^3.0.1 - file_saver: ^0.2.10 - pluto_grid_plus_export: 1.0.5 - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. - cupertino_icons: ^1.0.6 - -dev_dependencies: - flutter_test: - sdk: flutter - flutter_lints: ^5.0.0 - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. -flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. - uses-material-design: true - - # To add assets to your application, add an assets section, like this: - assets: - - assets/images/ - - fonts: - - family: OpenSans - fonts: - - asset: assets/fonts/open_sans/OpenSans-ExtraBold.ttf - weight: 800 - - asset: assets/fonts/open_sans/OpenSans-ExtraBoldItalic.ttf - weight: 800 - style: italic - - asset: assets/fonts/open_sans/OpenSans-Bold.ttf - weight: 700 - - asset: assets/fonts/open_sans/OpenSans-BoldItalic.ttf - weight: 700 - style: italic - - asset: assets/fonts/open_sans/OpenSans-SemiBold.ttf - weight: 600 - - asset: assets/fonts/open_sans/OpenSans-SemiBoldItalic.ttf - weight: 600 - style: italic - - asset: assets/fonts/open_sans/OpenSans-Regular.ttf - weight: 400 - - asset: assets/fonts/open_sans/OpenSans-Italic.ttf - weight: 400 - style: italic - - asset: assets/fonts/open_sans/OpenSans-Light.ttf - weight: 300 - - asset: assets/fonts/open_sans/OpenSans-LightItalic.ttf - weight: 300 - style: italic - +name: demo +description: PlutoGrid demo app. + +# The following line prevents the package from being accidentally published to +# pub.dev using `pub publish`. This is preferred for private packages. +publish_to: 'none' # Remove this line if you wish to publish to pub.dev + +# The following defines the version and build number for your application. +# A version number is three numbers separated by dots, like 1.2.43 +# followed by an optional build number separated by a +. +# Both the version and the builder number may be overridden in flutter +# build by specifying --build-name and --build-number, respectively. +# In Android, build-name is used as versionName while build-number used as versionCode. +# Read more about Android versioning at https://developer.android.com/studio/publish/versioning +# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. +# Read more about iOS versioning at +# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html +version: 1.0.0+1 + +environment: + sdk: ^3.0.0 + +dependency_overrides: + pluto_grid_plus: + path: ../ + +dependencies: + flutter: + sdk: flutter + pluto_grid_plus: 8.4.3 + faker: ^2.1.0 + url_launcher: ^6.2.1 + font_awesome_flutter: ^10.6.0 + rainbow_color: ^2.0.1 + pluto_menu_bar: ^3.0.1 + file_saver: ^0.2.10 + pluto_grid_plus_export: 1.0.5 + # The following adds the Cupertino Icons font to your application. + # Use with the CupertinoIcons class for iOS style icons. + cupertino_icons: ^1.0.6 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +# For information on the generic Dart part of this file, see the +# following page: https://dart.dev/tools/pub/pubspec + +# The following section is specific to Flutter. +flutter: + # The following line ensures that the Material Icons font is + # included with your application, so that you can use the icons in + # the material Icons class. + uses-material-design: true + + # To add assets to your application, add an assets section, like this: + assets: + - assets/images/ + + fonts: + - family: OpenSans + fonts: + - asset: assets/fonts/open_sans/OpenSans-ExtraBold.ttf + weight: 800 + - asset: assets/fonts/open_sans/OpenSans-ExtraBoldItalic.ttf + weight: 800 + style: italic + - asset: assets/fonts/open_sans/OpenSans-Bold.ttf + weight: 700 + - asset: assets/fonts/open_sans/OpenSans-BoldItalic.ttf + weight: 700 + style: italic + - asset: assets/fonts/open_sans/OpenSans-SemiBold.ttf + weight: 600 + - asset: assets/fonts/open_sans/OpenSans-SemiBoldItalic.ttf + weight: 600 + style: italic + - asset: assets/fonts/open_sans/OpenSans-Regular.ttf + weight: 400 + - asset: assets/fonts/open_sans/OpenSans-Italic.ttf + weight: 400 + style: italic + - asset: assets/fonts/open_sans/OpenSans-Light.ttf + weight: 300 + - asset: assets/fonts/open_sans/OpenSans-LightItalic.ttf + weight: 300 + style: italic diff --git a/lib/src/helper/pluto_key_manager_event.dart b/lib/src/helper/pluto_key_manager_event.dart index 13294fcce..855c39e17 100644 --- a/lib/src/helper/pluto_key_manager_event.dart +++ b/lib/src/helper/pluto_key_manager_event.dart @@ -1,207 +1,241 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; - -class PlutoKeyManagerEvent { - FocusNode focusNode; - KeyEvent event; - - PlutoKeyManagerEvent({ - required this.focusNode, - required this.event, - }); - - bool get needsThrottle => isMoving || isTab || isPageUp || isPageDown; - - bool get isKeyDownEvent => event.runtimeType == KeyDownEvent; - - bool get isKeyUpEvent => event.runtimeType == KeyUpEvent; - - bool get isMoving => isHorizontal || isVertical; - - bool get isHorizontal => isLeft || isRight; - - bool get isVertical => isUp || isDown; - - bool get isLeft => - event.logicalKey.keyId == LogicalKeyboardKey.arrowLeft.keyId; - - bool get isRight => - event.logicalKey.keyId == LogicalKeyboardKey.arrowRight.keyId; - - bool get isUp => event.logicalKey.keyId == LogicalKeyboardKey.arrowUp.keyId; - - bool get isDown => - event.logicalKey.keyId == LogicalKeyboardKey.arrowDown.keyId; - - bool get isHome => event.logicalKey.keyId == LogicalKeyboardKey.home.keyId; - - bool get isEnd => event.logicalKey.keyId == LogicalKeyboardKey.end.keyId; - - bool get isPageUp { - // windows 에서 pageUp keyId 가 0x10700000021. - return event.logicalKey.keyId == LogicalKeyboardKey.pageUp.keyId || - event.logicalKey.keyId == 0x10700000021; - } - - bool get isPageDown { - // windows 에서 pageDown keyId 가 0x10700000022. - return event.logicalKey.keyId == LogicalKeyboardKey.pageDown.keyId || - event.logicalKey.keyId == 0x10700000022; - } - - bool get isEsc => event.logicalKey.keyId == LogicalKeyboardKey.escape.keyId; - - bool get isEnter => - event.logicalKey.keyId == LogicalKeyboardKey.enter.keyId || - event.logicalKey.keyId == LogicalKeyboardKey.numpadEnter.keyId; - - bool get isTab => event.logicalKey.keyId == LogicalKeyboardKey.tab.keyId; - - bool get isF2 => event.logicalKey.keyId == LogicalKeyboardKey.f2.keyId; - - bool get isF3 => event.logicalKey.keyId == LogicalKeyboardKey.f3.keyId; - - bool get isF4 => event.logicalKey.keyId == LogicalKeyboardKey.f4.keyId; - - bool get isBackspace => - event.logicalKey.keyId == LogicalKeyboardKey.backspace.keyId; - - bool get isShift => - event.logicalKey.keyId == LogicalKeyboardKey.shift.keyId; - - bool get isControl => - event.logicalKey.keyId == LogicalKeyboardKey.control.keyId; - - bool get isCharacter => _characters.contains(event.logicalKey.keyId); - - bool get isCtrlC { - return isCtrlPressed && - event.logicalKey.keyId == LogicalKeyboardKey.keyC.keyId; - } - - bool get isCtrlV { - return isCtrlPressed && - event.logicalKey.keyId == LogicalKeyboardKey.keyV.keyId; - } - - bool get isCtrlA { - return isCtrlPressed && - event.logicalKey.keyId == LogicalKeyboardKey.keyA.keyId; - } - - bool get isShiftPressed { - return HardwareKeyboard.instance.isShiftPressed; - } - - bool get isCtrlPressed { - return HardwareKeyboard.instance.isMetaPressed || - HardwareKeyboard.instance.isControlPressed; - } - - bool get isAltPressed { - return HardwareKeyboard.instance.isAltPressed; - } - - bool get isModifierPressed { - return isShiftPressed || isCtrlPressed || isAltPressed; - } -} - -const _characters = { - 0x0000000041, // keyA, - 0x0000000042, // keyB, - 0x0000000043, // keyC, - 0x0000000044, // keyD, - 0x0000000045, // keyE, - 0x0000000046, // keyF, - 0x0000000047, // keyG, - 0x0000000048, // keyH, - 0x0000000049, // keyI, - 0x000000004a, // keyJ, - 0x000000004b, // keyK, - 0x000000004c, // keyL, - 0x000000004d, // keyM, - 0x000000004e, // keyN, - 0x000000004f, // keyO, - 0x0000000050, // keyP, - 0x0000000051, // keyQ, - 0x0000000052, // keyR, - 0x0000000053, // keyS, - 0x0000000054, // keyT, - 0x0000000055, // keyU, - 0x0000000056, // keyV, - 0x0000000057, // keyW, - 0x0000000058, // keyX, - 0x0000000059, // keyY, - 0x000000005a, // keyZ, - 0x0000000061, // keyA, - 0x0000000062, // keyB, - 0x0000000063, // keyC, - 0x0000000064, // keyD, - 0x0000000065, // keyE, - 0x0000000066, // keyF, - 0x0000000067, // keyG, - 0x0000000068, // keyH, - 0x0000000069, // keyI, - 0x000000006a, // keyJ, - 0x000000006b, // keyK, - 0x000000006c, // keyL, - 0x000000006d, // keyM, - 0x000000006e, // keyN, - 0x000000006f, // keyO, - 0x0000000070, // keyP, - 0x0000000071, // keyQ, - 0x0000000072, // keyR, - 0x0000000073, // keyS, - 0x0000000074, // keyT, - 0x0000000075, // keyU, - 0x0000000076, // keyV, - 0x0000000077, // keyW, - 0x0000000078, // keyX, - 0x0000000079, // keyY, - 0x000000007a, // keyZ, - 0x0000000031, // digit1, - 0x0000000032, // digit2, - 0x0000000033, // digit3, - 0x0000000034, // digit4, - 0x0000000035, // digit5, - 0x0000000036, // digit6, - 0x0000000037, // digit7, - 0x0000000038, // digit8, - 0x0000000039, // digit9, - 0x0000000030, // digit0, - 0x0000000020, // space, - 0x000000002d, // minus, - 0x000000003d, // equal, - 0x000000005b, // bracketLeft, - 0x000000005d, // bracketRight, - 0x000000005c, // backslash, - 0x000000003b, // semicolon, - 0x0000000027, // quote, - 0x0000000060, // backquote, - 0x000000002c, // comma, - 0x000000002e, // period, - 0x000000002f, // slash, - 0x0100070054, // numpadDivide, - 0x0100070055, // numpadMultiply, - 0x0100070056, // numpadSubtract, - 0x0100070057, // numpadAdd, - 0x0100070059, // numpad1, - 0x010007005a, // numpad2, - 0x010007005b, // numpad3, - 0x010007005c, // numpad4, - 0x010007005d, // numpad5, - 0x010007005e, // numpad6, - 0x010007005f, // numpad7, - 0x0100070060, // numpad8, - 0x0100070061, // numpad9, - 0x0100070062, // numpad0, - 0x0100070063, // numpadDecimal, - 0x0100070064, // intlBackslash, - 0x0100070067, // numpadEqual, - 0x0100070085, // numpadComma, - 0x0100070087, // intlRo, - 0x0100070089, // intlYen, - 0x01000700b6, // numpadParenLeft, - 0x01000700b7, // numpadParenRight, -}; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; + +class PlutoKeyManagerEvent { + FocusNode focusNode; + KeyEvent event; + bool Function(LogicalKeyboardKey key)? isLogicalKeyPressed; + + PlutoKeyManagerEvent({ + required this.focusNode, + required this.event, + this.isLogicalKeyPressed, + }); + + bool get needsThrottle => isMoving || isTab || isPageUp || isPageDown; + + bool get isKeyDownEvent => event.runtimeType == KeyDownEvent; + + bool get isKeyUpEvent => event.runtimeType == KeyUpEvent; + + bool get isMoving => isHorizontal || isVertical; + + bool get isHorizontal => isLeft || isRight; + + bool get isVertical => isUp || isDown; + + bool get isLeft => + event.logicalKey.keyId == LogicalKeyboardKey.arrowLeft.keyId; + + bool get isRight => + event.logicalKey.keyId == LogicalKeyboardKey.arrowRight.keyId; + + bool get isUp => event.logicalKey.keyId == LogicalKeyboardKey.arrowUp.keyId; + + bool get isDown => + event.logicalKey.keyId == LogicalKeyboardKey.arrowDown.keyId; + + bool get isHome => event.logicalKey.keyId == LogicalKeyboardKey.home.keyId; + + bool get isEnd => event.logicalKey.keyId == LogicalKeyboardKey.end.keyId; + + bool get isPageUp { + // windows 에서 pageUp keyId 가 0x10700000021. + return event.logicalKey.keyId == LogicalKeyboardKey.pageUp.keyId || + event.logicalKey.keyId == 0x10700000021; + } + + bool get isPageDown { + // windows 에서 pageDown keyId 가 0x10700000022. + return event.logicalKey.keyId == LogicalKeyboardKey.pageDown.keyId || + event.logicalKey.keyId == 0x10700000022; + } + + bool get isEsc => event.logicalKey.keyId == LogicalKeyboardKey.escape.keyId; + + bool get isEnter => + event.logicalKey.keyId == LogicalKeyboardKey.enter.keyId || + event.logicalKey.keyId == LogicalKeyboardKey.numpadEnter.keyId; + + bool get isTab => event.logicalKey.keyId == LogicalKeyboardKey.tab.keyId; + + bool get isF2 => event.logicalKey.keyId == LogicalKeyboardKey.f2.keyId; + + bool get isF3 => event.logicalKey.keyId == LogicalKeyboardKey.f3.keyId; + + bool get isF4 => event.logicalKey.keyId == LogicalKeyboardKey.f4.keyId; + + bool get isBackspace => + event.logicalKey.keyId == LogicalKeyboardKey.backspace.keyId; + + /// This can be: + /// + /// LogicalKeyboardKey.shift + /// LogicalKeyboardKey.shiftLeft + /// LogicalKeyboardKey.shiftRight + bool get isShift => [ + LogicalKeyboardKey.shift, + LogicalKeyboardKey.shiftLeft, + LogicalKeyboardKey.shiftRight, + ].any((lKey) => lKey.keyId == event.logicalKey.keyId); + + bool get isLeftShift => [ + LogicalKeyboardKey.shiftLeft, + ].any((lKey) => lKey.keyId == event.logicalKey.keyId); + + bool get isRightShift => [ + LogicalKeyboardKey.shiftRight, + ].any((lKey) => lKey.keyId == event.logicalKey.keyId); + + /// This can be: + /// + /// LogicalKeyboardKey.control + /// LogicalKeyboardKey.controlLeft + /// LogicalKeyboardKey.controlRight + bool get isControl => [ + LogicalKeyboardKey.control, + LogicalKeyboardKey.controlLeft, + LogicalKeyboardKey.controlRight, + ].any((lKey) => lKey.keyId == event.logicalKey.keyId); + + bool get isLeftControl => [ + LogicalKeyboardKey.controlLeft, + ].any((lKey) => lKey.keyId == event.logicalKey.keyId); + + bool get isRightControl => [ + LogicalKeyboardKey.controlRight, + ].any((lKey) => lKey.keyId == event.logicalKey.keyId); + + bool get isCharacter => _characters.contains(event.logicalKey.keyId); + + bool get isCtrlC { + return isCtrlPressed && + event.logicalKey.keyId == LogicalKeyboardKey.keyC.keyId; + } + + bool get isCtrlV { + return isCtrlPressed && + event.logicalKey.keyId == LogicalKeyboardKey.keyV.keyId; + } + + bool get isCtrlA { + return isCtrlPressed && + event.logicalKey.keyId == LogicalKeyboardKey.keyA.keyId; + } + + bool get isShiftPressed { + return HardwareKeyboard.instance.isShiftPressed; + } + + bool get isCtrlPressed { + return HardwareKeyboard.instance.isMetaPressed || + HardwareKeyboard.instance.isControlPressed; + } + + bool get isAltPressed { + return HardwareKeyboard.instance.isAltPressed; + } + + bool get isModifierPressed { + return isShiftPressed || isCtrlPressed || isAltPressed; + } +} + +const _characters = { + 0x0000000041, // keyA, + 0x0000000042, // keyB, + 0x0000000043, // keyC, + 0x0000000044, // keyD, + 0x0000000045, // keyE, + 0x0000000046, // keyF, + 0x0000000047, // keyG, + 0x0000000048, // keyH, + 0x0000000049, // keyI, + 0x000000004a, // keyJ, + 0x000000004b, // keyK, + 0x000000004c, // keyL, + 0x000000004d, // keyM, + 0x000000004e, // keyN, + 0x000000004f, // keyO, + 0x0000000050, // keyP, + 0x0000000051, // keyQ, + 0x0000000052, // keyR, + 0x0000000053, // keyS, + 0x0000000054, // keyT, + 0x0000000055, // keyU, + 0x0000000056, // keyV, + 0x0000000057, // keyW, + 0x0000000058, // keyX, + 0x0000000059, // keyY, + 0x000000005a, // keyZ, + 0x0000000061, // keyA, + 0x0000000062, // keyB, + 0x0000000063, // keyC, + 0x0000000064, // keyD, + 0x0000000065, // keyE, + 0x0000000066, // keyF, + 0x0000000067, // keyG, + 0x0000000068, // keyH, + 0x0000000069, // keyI, + 0x000000006a, // keyJ, + 0x000000006b, // keyK, + 0x000000006c, // keyL, + 0x000000006d, // keyM, + 0x000000006e, // keyN, + 0x000000006f, // keyO, + 0x0000000070, // keyP, + 0x0000000071, // keyQ, + 0x0000000072, // keyR, + 0x0000000073, // keyS, + 0x0000000074, // keyT, + 0x0000000075, // keyU, + 0x0000000076, // keyV, + 0x0000000077, // keyW, + 0x0000000078, // keyX, + 0x0000000079, // keyY, + 0x000000007a, // keyZ, + 0x0000000031, // digit1, + 0x0000000032, // digit2, + 0x0000000033, // digit3, + 0x0000000034, // digit4, + 0x0000000035, // digit5, + 0x0000000036, // digit6, + 0x0000000037, // digit7, + 0x0000000038, // digit8, + 0x0000000039, // digit9, + 0x0000000030, // digit0, + 0x0000000020, // space, + 0x000000002d, // minus, + 0x000000003d, // equal, + 0x000000005b, // bracketLeft, + 0x000000005d, // bracketRight, + 0x000000005c, // backslash, + 0x000000003b, // semicolon, + 0x0000000027, // quote, + 0x0000000060, // backquote, + 0x000000002c, // comma, + 0x000000002e, // period, + 0x000000002f, // slash, + 0x0100070054, // numpadDivide, + 0x0100070055, // numpadMultiply, + 0x0100070056, // numpadSubtract, + 0x0100070057, // numpadAdd, + 0x0100070059, // numpad1, + 0x010007005a, // numpad2, + 0x010007005b, // numpad3, + 0x010007005c, // numpad4, + 0x010007005d, // numpad5, + 0x010007005e, // numpad6, + 0x010007005f, // numpad7, + 0x0100070060, // numpad8, + 0x0100070061, // numpad9, + 0x0100070062, // numpad0, + 0x0100070063, // numpadDecimal, + 0x0100070064, // intlBackslash, + 0x0100070067, // numpadEqual, + 0x0100070085, // numpadComma, + 0x0100070087, // intlRo, + 0x0100070089, // intlYen, + 0x01000700b6, // numpadParenLeft, + 0x01000700b7, // numpadParenRight, +}; diff --git a/test/src/helper/pluto_key_manager_event_test.dart b/test/src/helper/pluto_key_manager_event_test.dart index dc20b95b2..c31764414 100644 --- a/test/src/helper/pluto_key_manager_event_test.dart +++ b/test/src/helper/pluto_key_manager_event_test.dart @@ -1,190 +1,243 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:pluto_grid_plus/pluto_grid_plus.dart'; - -void main() { - late FocusNode focusNode; - - late PlutoKeyManagerEvent? keyManagerEvent; - - KeyEventResult callback(FocusNode node, KeyEvent event) { - keyManagerEvent = PlutoKeyManagerEvent( - focusNode: node, - event: event, - ); - - return KeyEventResult.handled; - } - - setUp(() { - focusNode = FocusNode(); - }); - - tearDown(() { - keyManagerEvent = null; - }); - - Future buildWidget({ - required WidgetTester tester, - required KeyEventResult Function(FocusNode, KeyEvent) callback, - }) async { - await tester.pumpWidget(MaterialApp( - home: FocusScope( - autofocus: true, - onKeyEvent: callback, - child: Focus( - focusNode: focusNode, - child: const SizedBox(width: 100, height: 100), - ), - ), - )); - - focusNode.requestFocus(); - } - - testWidgets( - '아무 키나 입력하면 isKeyDownEvent 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.keyE; - await tester.sendKeyDownEvent(key); - expect(keyManagerEvent!.isKeyDownEvent, true); - await tester.sendKeyUpEvent(key); - expect(keyManagerEvent!.isKeyDownEvent, false); - }, - ); - - testWidgets( - 'Home 키를 입력하면 isHome 이 true 여야 한다.', - (tester) async { - late PlutoKeyManagerEvent keyManagerEvent; - - KeyEventResult callback(FocusNode node, KeyEvent event) { - keyManagerEvent = PlutoKeyManagerEvent( - focusNode: node, - event: event, - ); - - return KeyEventResult.handled; - } - - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.home; - await tester.sendKeyDownEvent(key); - expect(keyManagerEvent.isHome, true); - await tester.sendKeyUpEvent(key); - }, - ); - - testWidgets( - 'End 키를 입력하면 isEnd 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.end; - await tester.sendKeyDownEvent(key); - expect(keyManagerEvent!.isEnd, true); - await tester.sendKeyUpEvent(key); - }, - ); - - testWidgets( - 'F4 키를 입력하면 isF4 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.f4; - await tester.sendKeyDownEvent(key); - expect(keyManagerEvent!.isF4, true); - await tester.sendKeyUpEvent(key); - }, - ); - - testWidgets( - 'Backspace 키를 입력하면 isBackspace 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.backspace; - await tester.sendKeyDownEvent(key); - expect(keyManagerEvent!.isBackspace, true); - await tester.sendKeyUpEvent(key); - }, - ); - - testWidgets( - 'Shift 키를 입력하면 isShift 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.shift; - await tester.sendKeyDownEvent(key); - expect(keyManagerEvent!.isShift, true); - await tester.sendKeyUpEvent(key); - }, - ); - - testWidgets( - 'Control 키를 입력하면 isControl 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.control; - await tester.sendKeyDownEvent(key); - expect(keyManagerEvent!.isControl, true); - await tester.sendKeyUpEvent(key); - }, - ); - - // While key combos still work in the real world, these 3 tests are failing due to what I suspect is an - // incomplete deprecation/migration from focusNode `onKey` to `onKeyEvent`. - // Flutter 3.19 does not trigger our event for `sendKeyUpEvent` only, and I prefer not - // to switch these tests to `sendKeyDownEvent` as that may cause unexpected behavior - // such as pasting multiple times due to repeating key presses. It might also be fine. - - // https://github.com/flutter/flutter/issues/136419 - testWidgets( - 'Control + C 키를 입력하면 isCtrlC 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.control; - const key2 = LogicalKeyboardKey.keyC; - await tester.sendKeyDownEvent(key); - await tester.sendKeyUpEvent( - key2); // sendKeyUpEvent is not sending a keyManagerEvent - - expect(keyManagerEvent?.isCtrlC, true); - await tester.sendKeyUpEvent(key); - }, - ); - - testWidgets( - 'Control + V 키를 입력하면 isCtrlV 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.control; - await tester.sendKeyDownEvent(key); - await tester.sendKeyUpEvent(LogicalKeyboardKey.keyV); - expect(keyManagerEvent!.isCtrlV, true); - await tester.sendKeyUpEvent(key); - }, - ); - - testWidgets( - 'Control + A 키를 입력하면 isCtrlA 가 true 여야 한다.', - (tester) async { - await buildWidget(tester: tester, callback: callback); - - const key = LogicalKeyboardKey.control; - await tester.sendKeyDownEvent(key); - await tester.sendKeyUpEvent(LogicalKeyboardKey.keyA); - expect(keyManagerEvent!.isCtrlA, true); - await tester.sendKeyUpEvent(key); - }, - ); -} +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pluto_grid_plus/pluto_grid_plus.dart'; + +void main() { + late FocusNode focusNode; + + late PlutoKeyManagerEvent? keyManagerEvent; + + KeyEventResult callback(FocusNode node, KeyEvent event) { + keyManagerEvent = PlutoKeyManagerEvent( + focusNode: node, + event: event, + isLogicalKeyPressed: HardwareKeyboard.instance.isLogicalKeyPressed, + ); + + return KeyEventResult.handled; + } + + setUp(() { + focusNode = FocusNode(); + }); + + tearDown(() { + keyManagerEvent = null; + }); + + Future buildWidget({ + required WidgetTester tester, + required FocusOnKeyEventCallback callback, + }) async { + await tester.pumpWidget(MaterialApp( + home: FocusScope( + autofocus: true, + onKeyEvent: callback, + child: Focus( + focusNode: focusNode, + child: const SizedBox(width: 100, height: 100), + ), + ), + )); + + focusNode.requestFocus(); + } + + testWidgets( + '아무 키나 입력하면 isKeyDownEvent 가 true 여야 한다.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.keyE; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isKeyDownEvent, true); + await tester.sendKeyUpEvent(key); + expect(keyManagerEvent!.isKeyDownEvent, false); + }, + ); + + testWidgets( + 'Home 키를 입력하면 isHome 이 true 여야 한다.', + (tester) async { + late PlutoKeyManagerEvent keyManagerEvent; + + KeyEventResult callback(FocusNode node, KeyEvent event) { + keyManagerEvent = PlutoKeyManagerEvent( + focusNode: node, + event: event, + ); + + return KeyEventResult.handled; + } + + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.home; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent.isHome, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'End 키를 입력하면 isEnd 가 true 여야 한다.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.end; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isEnd, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'F4 키를 입력하면 isF4 가 true 여야 한다.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.f4; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isF4, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'Backspace 키를 입력하면 isBackspace 가 true 여야 한다.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.backspace; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isBackspace, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'When the Shift key is pressed, isShift must be `true`.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.shift; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isShift, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'When the LeftShift key is pressed, isLeftShift must be `true`.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.shiftLeft; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isLeftShift, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'When the RightShift key is pressed, RightShift must be `true`.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.shiftRight; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isRightShift, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'If the Control key is pressed, isControl should be true.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.control; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isControl, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'If the controlLeft key is pressed, isLeftControl should be true.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.controlLeft; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isLeftControl, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'If the controlRight key is pressed, isRightControl should be true.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.controlRight; + await tester.sendKeyDownEvent(key); + expect(keyManagerEvent!.isRightControl, true); + await tester.sendKeyUpEvent(key); + }, + ); + + testWidgets( + 'If the Control + C keys are pressed, isCtrlC should be true.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.control; + const key2 = LogicalKeyboardKey.keyC; + + await tester.sendKeyDownEvent(key); + await tester.sendKeyDownEvent(key2); + + expect(keyManagerEvent?.isCtrlC, true); + + await tester.sendKeyUpEvent(key); + await tester.sendKeyUpEvent(key2); + }, + ); + + testWidgets( + 'If the Control + V keys are pressed, isCtrlV should be true.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.control; + const key2 = LogicalKeyboardKey.keyV; + + await tester.sendKeyDownEvent(key); + await tester.sendKeyDownEvent(key2); + + expect(keyManagerEvent!.isCtrlV, true); + await tester.sendKeyUpEvent(key); + await tester.sendKeyUpEvent(key2); + }, + ); + + testWidgets( + 'If the Control + A keys are pressed, isCtrlA should be true.', + (tester) async { + await buildWidget(tester: tester, callback: callback); + + const key = LogicalKeyboardKey.control; + const key2 = LogicalKeyboardKey.keyA; + + await tester.sendKeyDownEvent(key); + await tester.sendKeyDownEvent(key2); + + expect(keyManagerEvent!.isCtrlA, true); + + await tester.sendKeyUpEvent(key); + await tester.sendKeyUpEvent(key2); + }, + ); +} From 1c917b8b37f7cb0574443d486fafe638a4f18729 Mon Sep 17 00:00:00 2001 From: Stan Persoons <147701137+stan-at-work@users.noreply.github.com> Date: Fri, 6 Dec 2024 19:33:25 +0100 Subject: [PATCH 2/4] Changed test to english --- .../helper/pluto_key_manager_event_test.dart | 24 +++++++++---------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/test/src/helper/pluto_key_manager_event_test.dart b/test/src/helper/pluto_key_manager_event_test.dart index c31764414..f91afa98f 100644 --- a/test/src/helper/pluto_key_manager_event_test.dart +++ b/test/src/helper/pluto_key_manager_event_test.dart @@ -45,7 +45,7 @@ void main() { } testWidgets( - '아무 키나 입력하면 isKeyDownEvent 가 true 여야 한다.', + 'When any key is pressed, isKeyDownEvent must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -58,7 +58,7 @@ void main() { ); testWidgets( - 'Home 키를 입력하면 isHome 이 true 여야 한다.', + 'When the Home key is pressed, isHome must be `true`.', (tester) async { late PlutoKeyManagerEvent keyManagerEvent; @@ -81,7 +81,7 @@ void main() { ); testWidgets( - 'End 키를 입력하면 isEnd 가 true 여야 한다.', + 'When the End key is pressed, isEnd must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -93,7 +93,7 @@ void main() { ); testWidgets( - 'F4 키를 입력하면 isF4 가 true 여야 한다.', + 'When the F4 key is pressed, isF4 must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -105,7 +105,7 @@ void main() { ); testWidgets( - 'Backspace 키를 입력하면 isBackspace 가 true 여야 한다.', + 'When the Backspace key is pressed, isBackspace must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -141,7 +141,7 @@ void main() { ); testWidgets( - 'When the RightShift key is pressed, RightShift must be `true`.', + 'When the RightShift key is pressed, isRightShift must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -153,7 +153,7 @@ void main() { ); testWidgets( - 'If the Control key is pressed, isControl should be true.', + 'When the Control key is pressed, isControl must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -165,7 +165,7 @@ void main() { ); testWidgets( - 'If the controlLeft key is pressed, isLeftControl should be true.', + 'When the LeftControl key is pressed, isLeftControl must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -177,7 +177,7 @@ void main() { ); testWidgets( - 'If the controlRight key is pressed, isRightControl should be true.', + 'When the RightControl key is pressed, isRightControl must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -189,7 +189,7 @@ void main() { ); testWidgets( - 'If the Control + C keys are pressed, isCtrlC should be true.', + 'When Control + C keys are pressed, isCtrlC must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -207,7 +207,7 @@ void main() { ); testWidgets( - 'If the Control + V keys are pressed, isCtrlV should be true.', + 'When Control + V keys are pressed, isCtrlV must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); @@ -224,7 +224,7 @@ void main() { ); testWidgets( - 'If the Control + A keys are pressed, isCtrlA should be true.', + 'When Control + A keys are pressed, isCtrlA must be `true`.', (tester) async { await buildWidget(tester: tester, callback: callback); From f0179124d8108e186f2ff7a21e4b9952a039bcaa Mon Sep 17 00:00:00 2001 From: Stan Persoons <147701137+stan-at-work@users.noreply.github.com> Date: Fri, 6 Dec 2024 20:04:36 +0100 Subject: [PATCH 3/4] Fixed test --- .../helper/pluto_aggregate_helper_test.dart | 824 +++++++++--------- 1 file changed, 412 insertions(+), 412 deletions(-) diff --git a/test/src/helper/pluto_aggregate_helper_test.dart b/test/src/helper/pluto_aggregate_helper_test.dart index 2bc4111d7..080be252c 100644 --- a/test/src/helper/pluto_aggregate_helper_test.dart +++ b/test/src/helper/pluto_aggregate_helper_test.dart @@ -1,412 +1,412 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:pluto_grid_plus/pluto_grid_plus.dart'; - -void main() { - group('sum', () { - test('숫자 컬럼이 아닌경우 0이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.text(), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), - PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), - PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), - PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), - PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), - ]; - - expect(PlutoAggregateHelper.sum(rows: rows, column: column), 0); - }); - - test('[양수] condition 이 없이 sum 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10)}), - PlutoRow(cells: {'column': PlutoCell(value: 20)}), - PlutoRow(cells: {'column': PlutoCell(value: 30)}), - PlutoRow(cells: {'column': PlutoCell(value: 40)}), - PlutoRow(cells: {'column': PlutoCell(value: 50)}), - ]; - - expect(PlutoAggregateHelper.sum(rows: rows, column: column), 150); - }); - - test('[음수] condition 이 없이 sum 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: -10)}), - PlutoRow(cells: {'column': PlutoCell(value: -20)}), - PlutoRow(cells: {'column': PlutoCell(value: -30)}), - PlutoRow(cells: {'column': PlutoCell(value: -40)}), - PlutoRow(cells: {'column': PlutoCell(value: -50)}), - ]; - - expect(PlutoAggregateHelper.sum(rows: rows, column: column), -150); - }); - - test('[소수] condition 이 없이 sum 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - ]; - - expect(PlutoAggregateHelper.sum(rows: rows, column: column), 50.005); - }); - - test('condition 이 있는 경우 조건에 맞는 아이템의 합계 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - ]; - - expect( - PlutoAggregateHelper.sum( - rows: rows, - column: column, - filter: (PlutoCell cell) => cell.value == 10.001, - ), - 30.003, - ); - }); - - test('condition 이 있는 경우 조건에 맞는 아이템이 없다면 0이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - ]; - - expect( - PlutoAggregateHelper.sum( - rows: rows, - column: column, - filter: (PlutoCell cell) => cell.value == 10.003, - ), - 0, - ); - }); - }); - - group('average', () { - test('[양수] condition 이 없이 average 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10)}), - PlutoRow(cells: {'column': PlutoCell(value: 20)}), - PlutoRow(cells: {'column': PlutoCell(value: 30)}), - PlutoRow(cells: {'column': PlutoCell(value: 40)}), - PlutoRow(cells: {'column': PlutoCell(value: 50)}), - ]; - - expect(PlutoAggregateHelper.average(rows: rows, column: column), 30); - }); - - test('[음수] condition 이 없이 average 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: -10)}), - PlutoRow(cells: {'column': PlutoCell(value: -20)}), - PlutoRow(cells: {'column': PlutoCell(value: -30)}), - PlutoRow(cells: {'column': PlutoCell(value: -40)}), - PlutoRow(cells: {'column': PlutoCell(value: -50)}), - ]; - - expect(PlutoAggregateHelper.average(rows: rows, column: column), -30); - }); - - test('[소수] condition 이 없이 average 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), - ]; - - expect(PlutoAggregateHelper.average(rows: rows, column: column), 10.003); - }); - }); - - group('min', () { - test('[양수] condition 이 없이 min 을 호출 한 경우 최소 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 101)}), - PlutoRow(cells: {'column': PlutoCell(value: 102)}), - PlutoRow(cells: {'column': PlutoCell(value: 103)}), - PlutoRow(cells: {'column': PlutoCell(value: 104)}), - PlutoRow(cells: {'column': PlutoCell(value: 105)}), - ]; - - expect(PlutoAggregateHelper.min(rows: rows, column: column), 101); - }); - - test('[음수] condition 이 없이 min 을 호출 한 경우 최소 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: -101)}), - PlutoRow(cells: {'column': PlutoCell(value: -102)}), - PlutoRow(cells: {'column': PlutoCell(value: -103)}), - PlutoRow(cells: {'column': PlutoCell(value: -104)}), - PlutoRow(cells: {'column': PlutoCell(value: -105)}), - ]; - - expect(PlutoAggregateHelper.min(rows: rows, column: column), -105); - }); - - test('[소수] condition 이 없이 min 을 호출 한 경우 최소 값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), - ]; - - expect(PlutoAggregateHelper.min(rows: rows, column: column), 10.001); - }); - - test('condition 이 있는 경우 조건에 맞는 아이템이 있다면 조건내에서 최소값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), - ]; - - expect( - PlutoAggregateHelper.min( - rows: rows, - column: column, - filter: (PlutoCell cell) => cell.value >= 10.003, - ), - 10.003, - ); - }); - - test('condition 이 있는 경우 조건에 맞는 아이템이 없다면 null 이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - ]; - - expect( - PlutoAggregateHelper.min( - rows: rows, - column: column, - filter: (PlutoCell cell) => cell.value == 10.003, - ), - null, - ); - }); - }); - - group('max', () { - test('condition 이 있는 경우 조건에 맞는 아이템이 있다면 조건내에서 최대값이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), - ]; - - expect( - PlutoAggregateHelper.max( - rows: rows, - column: column, - filter: (PlutoCell cell) => cell.value >= 10.003, - ), - 10.005, - ); - }); - - test('condition 이 있는 경우 조건에 맞는 아이템이 없다면 null 이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), - ]; - - expect( - PlutoAggregateHelper.max( - rows: rows, - column: column, - filter: (PlutoCell cell) => cell.value >= 10.006, - ), - null, - ); - }); - }); - - group('count', () { - test('condition 이 없는 경우 전체 리스트 개수가 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), - ]; - - expect(PlutoAggregateHelper.count(rows: rows, column: column), 5); - }); - - test('condition 이 있는 경우 조건에 맞는 아이템이 있다면 조건에 맞는 아이템 개수가 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), - ]; - - expect( - PlutoAggregateHelper.count( - rows: rows, - column: column, - filter: (PlutoCell cell) => cell.value >= 10.003, - ), - 3, - ); - }); - - test('condition 이 있는 경우 조건에 맞는 아이템이 없다면 0 이 리턴 되어야 한다.', () { - final column = PlutoColumn( - title: 'column', - field: 'column', - type: PlutoColumnType.number(format: '#,###.###'), - ); - - final rows = [ - PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), - PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), - ]; - - expect( - PlutoAggregateHelper.count( - rows: rows, - column: column, - filter: (PlutoCell cell) => cell.value >= 10.006, - ), - 0, - ); - }); - }); -} +import 'package:flutter_test/flutter_test.dart'; +import 'package:pluto_grid_plus/pluto_grid_plus.dart'; + +void main() { + group('sum', () { + test('숫자 컬럼이 아닌경우 0이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.text(), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), + PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), + PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), + PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), + PlutoRow(cells: {'column': PlutoCell(value: '10.001')}), + ]; + + expect(PlutoAggregateHelper.sum(rows: rows, column: column), 0); + }); + + test('[양수] condition 이 없이 sum 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10)}), + PlutoRow(cells: {'column': PlutoCell(value: 20)}), + PlutoRow(cells: {'column': PlutoCell(value: 30)}), + PlutoRow(cells: {'column': PlutoCell(value: 40)}), + PlutoRow(cells: {'column': PlutoCell(value: 50)}), + ]; + + expect(PlutoAggregateHelper.sum(rows: rows, column: column), 150); + }); + + test('[음수] condition 이 없이 sum 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: -10)}), + PlutoRow(cells: {'column': PlutoCell(value: -20)}), + PlutoRow(cells: {'column': PlutoCell(value: -30)}), + PlutoRow(cells: {'column': PlutoCell(value: -40)}), + PlutoRow(cells: {'column': PlutoCell(value: -50)}), + ]; + + expect(PlutoAggregateHelper.sum(rows: rows, column: column), -150); + }); + + test('[소수] condition 이 없이 sum 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + ]; + + expect(PlutoAggregateHelper.sum(rows: rows, column: column), 50.005); + }); + + test('condition 이 있는 경우 조건에 맞는 아이템의 합계 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + ]; + + expect( + PlutoAggregateHelper.sum( + rows: rows, + column: column, + filter: (PlutoCell cell) => cell.value == 10.001, + ), + 30.003, + ); + }); + + test('condition 이 있는 경우 조건에 맞는 아이템이 없다면 0이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + ]; + + expect( + PlutoAggregateHelper.sum( + rows: rows, + column: column, + filter: (PlutoCell cell) => cell.value == 10.003, + ), + null, + ); + }); + }); + + group('average', () { + test('[양수] condition 이 없이 average 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10)}), + PlutoRow(cells: {'column': PlutoCell(value: 20)}), + PlutoRow(cells: {'column': PlutoCell(value: 30)}), + PlutoRow(cells: {'column': PlutoCell(value: 40)}), + PlutoRow(cells: {'column': PlutoCell(value: 50)}), + ]; + + expect(PlutoAggregateHelper.average(rows: rows, column: column), 30); + }); + + test('[음수] condition 이 없이 average 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: -10)}), + PlutoRow(cells: {'column': PlutoCell(value: -20)}), + PlutoRow(cells: {'column': PlutoCell(value: -30)}), + PlutoRow(cells: {'column': PlutoCell(value: -40)}), + PlutoRow(cells: {'column': PlutoCell(value: -50)}), + ]; + + expect(PlutoAggregateHelper.average(rows: rows, column: column), -30); + }); + + test('[소수] condition 이 없이 average 을 호출 한 경우 전체 합계 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), + ]; + + expect(PlutoAggregateHelper.average(rows: rows, column: column), 10.003); + }); + }); + + group('min', () { + test('[양수] condition 이 없이 min 을 호출 한 경우 최소 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 101)}), + PlutoRow(cells: {'column': PlutoCell(value: 102)}), + PlutoRow(cells: {'column': PlutoCell(value: 103)}), + PlutoRow(cells: {'column': PlutoCell(value: 104)}), + PlutoRow(cells: {'column': PlutoCell(value: 105)}), + ]; + + expect(PlutoAggregateHelper.min(rows: rows, column: column), 101); + }); + + test('[음수] condition 이 없이 min 을 호출 한 경우 최소 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: -101)}), + PlutoRow(cells: {'column': PlutoCell(value: -102)}), + PlutoRow(cells: {'column': PlutoCell(value: -103)}), + PlutoRow(cells: {'column': PlutoCell(value: -104)}), + PlutoRow(cells: {'column': PlutoCell(value: -105)}), + ]; + + expect(PlutoAggregateHelper.min(rows: rows, column: column), -105); + }); + + test('[소수] condition 이 없이 min 을 호출 한 경우 최소 값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), + ]; + + expect(PlutoAggregateHelper.min(rows: rows, column: column), 10.001); + }); + + test('condition 이 있는 경우 조건에 맞는 아이템이 있다면 조건내에서 최소값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), + ]; + + expect( + PlutoAggregateHelper.min( + rows: rows, + column: column, + filter: (PlutoCell cell) => cell.value >= 10.003, + ), + 10.003, + ); + }); + + test('condition 이 있는 경우 조건에 맞는 아이템이 없다면 null 이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + ]; + + expect( + PlutoAggregateHelper.min( + rows: rows, + column: column, + filter: (PlutoCell cell) => cell.value == 10.003, + ), + null, + ); + }); + }); + + group('max', () { + test('condition 이 있는 경우 조건에 맞는 아이템이 있다면 조건내에서 최대값이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), + ]; + + expect( + PlutoAggregateHelper.max( + rows: rows, + column: column, + filter: (PlutoCell cell) => cell.value >= 10.003, + ), + 10.005, + ); + }); + + test('condition 이 있는 경우 조건에 맞는 아이템이 없다면 null 이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), + ]; + + expect( + PlutoAggregateHelper.max( + rows: rows, + column: column, + filter: (PlutoCell cell) => cell.value >= 10.006, + ), + null, + ); + }); + }); + + group('count', () { + test('condition 이 없는 경우 전체 리스트 개수가 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), + ]; + + expect(PlutoAggregateHelper.count(rows: rows, column: column), 5); + }); + + test('condition 이 있는 경우 조건에 맞는 아이템이 있다면 조건에 맞는 아이템 개수가 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), + ]; + + expect( + PlutoAggregateHelper.count( + rows: rows, + column: column, + filter: (PlutoCell cell) => cell.value >= 10.003, + ), + 3, + ); + }); + + test('condition 이 있는 경우 조건에 맞는 아이템이 없다면 0 이 리턴 되어야 한다.', () { + final column = PlutoColumn( + title: 'column', + field: 'column', + type: PlutoColumnType.number(format: '#,###.###'), + ); + + final rows = [ + PlutoRow(cells: {'column': PlutoCell(value: 10.001)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.002)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.003)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.004)}), + PlutoRow(cells: {'column': PlutoCell(value: 10.005)}), + ]; + + expect( + PlutoAggregateHelper.count( + rows: rows, + column: column, + filter: (PlutoCell cell) => cell.value >= 10.006, + ), + 0, + ); + }); + }); +} From f0005781eb1a4c83af618468723ceb6754cbaafa Mon Sep 17 00:00:00 2001 From: Stan Persoons <147701137+stan-at-work@users.noreply.github.com> Date: Fri, 6 Dec 2024 20:09:34 +0100 Subject: [PATCH 4/4] Added tests on pull_req --- .github/workflows/tests.yaml | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 .github/workflows/tests.yaml diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml new file mode 100644 index 000000000..f72b9453d --- /dev/null +++ b/.github/workflows/tests.yaml @@ -0,0 +1,13 @@ +name: Tests +on: + pull_request: + branches: + - master +jobs: + tests: + runs-on: ubuntu-latest + steps: + - name: Install Flutter Dependencies + run: flutter pub get + - name: Run Flutter Tests + run: flutter test