diff --git a/.github/workflows/coverage.yml b/.github/workflows/coverage.yml deleted file mode 100644 index d4212fb89..000000000 --- a/.github/workflows/coverage.yml +++ /dev/null @@ -1,27 +0,0 @@ -name: Coverage - -on: - push: - branches: - - 'master' - -jobs: - build: - runs-on: ubuntu-latest - env: - CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} - steps: - # Without this, there are no files in the directory. - - uses: actions/checkout@v3 - # using flutter - - uses: subosito/flutter-action@v2.4.0 - with: - channel: 'stable' - - run: dart --version - - run: flutter --version - - run: flutter pub get - - run: flutter test --coverage - # codecov.io - - uses: codecov/codecov-action@v3 - with: - file: ./coverage/lcov.info \ No newline at end of file diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index f72b9453d..f5a15d61f 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -1,13 +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 +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 diff --git a/.vscode/settings.json b/.vscode/settings.json index 8d4d525e8..a2f214196 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,5 @@ { "dart.lineLength": 80, -} \ No newline at end of file + "files.eol": "auto", + "prettier.endOfLine": "auto" +} diff --git a/demo/pubspec.yaml b/demo/pubspec.yaml index 06ae60b00..ddb9e4087 100644 --- a/demo/pubspec.yaml +++ b/demo/pubspec.yaml @@ -1,88 +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 - -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 +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/example/lib/main.dart b/example/lib/main.dart index dad9d280d..78c17d30a 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -170,29 +170,28 @@ class _PlutoGridExamplePageState extends State { body: Container( padding: const EdgeInsets.all(15), child: PlutoGrid( - columns: columns, - rows: rows, - columnGroups: columnGroups, - onLoaded: (PlutoGridOnLoadedEvent event) { - stateManager = event.stateManager; - stateManager.setShowColumnFilter(true); - }, - onChanged: (PlutoGridOnChangedEvent event) { - print(event); - }, - configuration: const PlutoGridConfiguration(), - selectDateCallback: (PlutoCell cell, PlutoColumn column) async { - return showDatePicker( - context: context, - initialDate: PlutoDateTimeHelper.parseOrNullWithFormat( - cell.value, - column.type.date.format, - ) ?? DateTime.now(), - firstDate: column.type.date.startDate ?? DateTime(0), - lastDate: column.type.date.endDate ?? DateTime(9999) - ); - } - ), + columns: columns, + rows: rows, + columnGroups: columnGroups, + onLoaded: (PlutoGridOnLoadedEvent event) { + stateManager = event.stateManager; + stateManager.setShowColumnFilter(true); + }, + onChanged: (PlutoGridOnChangedEvent event) { + print(event); + }, + configuration: const PlutoGridConfiguration(), + selectDateCallback: (PlutoCell cell, PlutoColumn column) async { + return showDatePicker( + context: context, + initialDate: PlutoDateTimeHelper.parseOrNullWithFormat( + cell.value, + column.type.date.format, + ) ?? + DateTime.now(), + firstDate: column.type.date.startDate ?? DateTime(0), + lastDate: column.type.date.endDate ?? DateTime(9999)); + }), ), ); } diff --git a/lib/src/helper/pluto_key_manager_event.dart b/lib/src/helper/pluto_key_manager_event.dart index 855c39e17..a8dd300c5 100644 --- a/lib/src/helper/pluto_key_manager_event.dart +++ b/lib/src/helper/pluto_key_manager_event.dart @@ -1,241 +1,241 @@ -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, -}; +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/lib/src/manager/event/pluto_grid_row_hover_event.dart b/lib/src/manager/event/pluto_grid_row_hover_event.dart index 4987d459f..6f9abbd75 100644 --- a/lib/src/manager/event/pluto_grid_row_hover_event.dart +++ b/lib/src/manager/event/pluto_grid_row_hover_event.dart @@ -12,7 +12,8 @@ class PlutoGridRowHoverEvent extends PlutoGridEvent { @override void handler(PlutoGridStateManager stateManager) { - bool enableRowHoverColor = stateManager.configuration.style.enableRowHoverColor; + bool enableRowHoverColor = + stateManager.configuration.style.enableRowHoverColor; // only change current hovered row index // if row hover color effect is enabled diff --git a/lib/src/manager/state/hovering_state.dart b/lib/src/manager/state/hovering_state.dart index 59b30b646..21abfe000 100644 --- a/lib/src/manager/state/hovering_state.dart +++ b/lib/src/manager/state/hovering_state.dart @@ -1,13 +1,9 @@ import 'package:pluto_grid_plus/pluto_grid_plus.dart'; abstract class IHoveringState { - int? get hoveredRowIdx; - void setHoveredRowIdx( - int? rowIdx, - {bool notify = true} - ); + void setHoveredRowIdx(int? rowIdx, {bool notify = true}); bool isRowIdxHovered(int rowIdx); } @@ -24,9 +20,9 @@ mixin HoveringState implements IPlutoGridState { @override void setHoveredRowIdx( - int? rowIdx, - {bool notify = true,} - ) { + int? rowIdx, { + bool notify = true, + }) { if (hoveredRowIdx == rowIdx) { return; } diff --git a/lib/src/manager/state/layout_state.dart b/lib/src/manager/state/layout_state.dart index 339dd710a..f9946e7c9 100644 --- a/lib/src/manager/state/layout_state.dart +++ b/lib/src/manager/state/layout_state.dart @@ -386,10 +386,8 @@ mixin LayoutState implements IPlutoGridState { double offset = 0; if (showFrozenColumn) { - offset += - leftFrozenColumnsWidth > 0 ? gridBorderWidth: 0; - offset += - rightFrozenColumnsWidth > 0 ? gridBorderWidth : 0; + offset += leftFrozenColumnsWidth > 0 ? gridBorderWidth : 0; + offset += rightFrozenColumnsWidth > 0 ? gridBorderWidth : 0; } return offset; diff --git a/lib/src/plugin/pluto_infinity_scroll_rows.dart b/lib/src/plugin/pluto_infinity_scroll_rows.dart index 756d0232f..13f340582 100644 --- a/lib/src/plugin/pluto_infinity_scroll_rows.dart +++ b/lib/src/plugin/pluto_infinity_scroll_rows.dart @@ -203,7 +203,8 @@ class _PlutoInfinityScrollRowsState extends State { if (!_isLast) { WidgetsBinding.instance.addPostFrameCallback((_) { if (scroll.hasClients && scroll.position.maxScrollExtent == 0) { - var lastRow = stateManager.rows.isNotEmpty ? stateManager.rows.last : null; + var lastRow = + stateManager.rows.isNotEmpty ? stateManager.rows.last : null; _update(lastRow); } }); diff --git a/lib/src/plugin/pluto_lazy_pagination.dart b/lib/src/plugin/pluto_lazy_pagination.dart index 6126c8cc4..4dd915d0d 100644 --- a/lib/src/plugin/pluto_lazy_pagination.dart +++ b/lib/src/plugin/pluto_lazy_pagination.dart @@ -180,7 +180,7 @@ class _PlutoLazyPaginationState extends State { ), ) .then((data) { - if(!mounted)return; + if (!mounted) return; stateManager.scroll.bodyRowsVertical!.jumpTo(0); stateManager.refRows.clearFromOriginal(); diff --git a/lib/src/pluto_grid_configuration.dart b/lib/src/pluto_grid_configuration.dart index c3bed1f8b..0c932002c 100644 --- a/lib/src/pluto_grid_configuration.dart +++ b/lib/src/pluto_grid_configuration.dart @@ -642,7 +642,8 @@ class PlutoGridStyleConfig { defaultColumnFilterPadding ?? this.defaultColumnFilterPadding, defaultCellPadding: defaultCellPadding ?? this.defaultCellPadding, columnTextStyle: columnTextStyle ?? this.columnTextStyle, - columnUnselectedColor: columnUnselectedColor ?? this.columnUnselectedColor, + columnUnselectedColor: + columnUnselectedColor ?? this.columnUnselectedColor, columnActiveColor: columnActiveColor ?? this.columnActiveColor, cellUnselectedColor: cellUnselectedColor ?? this.cellUnselectedColor, cellActiveColor: cellActiveColor ?? this.cellActiveColor, @@ -1784,12 +1785,16 @@ class PlutoGridLocaleText { enum PlutoGridRowSelectionCheckBoxBehavior { /// Selecting a row does nothing to its checkbox none, + /// Automatically enables the checkbox of the selected rows checkRow, + /// Automatically toggles the checkbox of the selected rows toggleCheckRow, + /// Automatically enabels the checkbox of a selected row (if another row is checked via select, the previous one is unchecked) singleRowCheck, + /// Automatically toggles the checkbox of a selected row (if another row is checked via select, the previous one is unchecked) toggleSingleRowCheck, } diff --git a/lib/src/ui/cells/pluto_date_cell.dart b/lib/src/ui/cells/pluto_date_cell.dart index cf8d3d628..1d197096b 100644 --- a/lib/src/ui/cells/pluto_date_cell.dart +++ b/lib/src/ui/cells/pluto_date_cell.dart @@ -52,7 +52,8 @@ class PlutoDateCellState extends State final date = await sm.selectDateCallback!(widget.cell, widget.column); isOpenedPopup = false; if (date != null) { - handleSelected(widget.column.type.date.dateFormat.format(date)); // Consider call onSelected + handleSelected(widget.column.type.date.dateFormat + .format(date)); // Consider call onSelected } } else { PlutoGridDatePicker( diff --git a/test/src/helper/pluto_aggregate_helper_test.dart b/test/src/helper/pluto_aggregate_helper_test.dart index 080be252c..38b84d96a 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, - ), - 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, - ); - }); - }); -} +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, + ); + }); + }); +} diff --git a/test/src/helper/pluto_key_manager_event_test.dart b/test/src/helper/pluto_key_manager_event_test.dart index f91afa98f..37bbd5046 100644 --- a/test/src/helper/pluto_key_manager_event_test.dart +++ b/test/src/helper/pluto_key_manager_event_test.dart @@ -1,243 +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, - 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( - 'When any key is pressed, isKeyDownEvent must be `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( - 'When the Home key is pressed, isHome must be `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( - 'When the End key is pressed, isEnd must be `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( - 'When the F4 key is pressed, isF4 must be `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( - 'When the Backspace key is pressed, isBackspace must be `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, isRightShift 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( - 'When the Control key is pressed, isControl must 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( - 'When the LeftControl key is pressed, isLeftControl must 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( - 'When the RightControl key is pressed, isRightControl must 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( - 'When Control + C keys are pressed, isCtrlC must 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( - 'When Control + V keys are pressed, isCtrlV must 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( - 'When Control + A keys are pressed, isCtrlA must 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); - }, - ); -} +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( + 'When any key is pressed, isKeyDownEvent must be `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( + 'When the Home key is pressed, isHome must be `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( + 'When the End key is pressed, isEnd must be `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( + 'When the F4 key is pressed, isF4 must be `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( + 'When the Backspace key is pressed, isBackspace must be `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, isRightShift 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( + 'When the Control key is pressed, isControl must 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( + 'When the LeftControl key is pressed, isLeftControl must 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( + 'When the RightControl key is pressed, isRightControl must 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( + 'When Control + C keys are pressed, isCtrlC must 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( + 'When Control + V keys are pressed, isCtrlV must 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( + 'When Control + A keys are pressed, isCtrlA must 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); + }, + ); +} diff --git a/test/src/manager/state/hovering_row_state_test.dart b/test/src/manager/state/hovering_row_state_test.dart index da52c2540..e5a7ee6ab 100644 --- a/test/src/manager/state/hovering_row_state_test.dart +++ b/test/src/manager/state/hovering_row_state_test.dart @@ -38,7 +38,7 @@ void main() { group('setHoveredRowIdx', () { test( 'If the rowIdx passed as an argument is the same as' - 'hoveredRowIdx, then notifyListeners should not be called.', + 'hoveredRowIdx, then notifyListeners should not be called.', () { // given stateManager.setHoveredRowIdx(1); @@ -55,7 +55,7 @@ void main() { test( 'If the rowIdx passed as an argument is different from ' - 'hoveredRowIdx, notifyListeners should be called.', + 'hoveredRowIdx, notifyListeners should be called.', () { // given stateManager.setHoveredRowIdx(1); @@ -73,8 +73,8 @@ void main() { test( 'If the rowIdx passed as an argument is different from ' - 'hoveredRowIdx, but notify is false,' - 'notifyListeners should not be called.', + 'hoveredRowIdx, but notify is false,' + 'notifyListeners should not be called.', () { // given stateManager.setHoveredRowIdx(1);