From d628f669857f937ab5824c14a7d183afc9fd538b Mon Sep 17 00:00:00 2001 From: Minyewoo Date: Wed, 11 Oct 2023 13:12:26 +0300 Subject: [PATCH 1/5] Increased Dart SDK version constraints --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index d7b82b5..0d3359a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,7 +4,7 @@ version: 0.0.5 homepage: https://github.com/a-givertzman/hmi_core environment: - sdk: '>=2.18.2 <3.0.0' + sdk: '>=3.0.0 <4.0.0' flutter: ">=1.17.0" dependencies: From b9d82fdb7a87011238571a952bd97cb47a95f5a0 Mon Sep 17 00:00:00 2001 From: Minyewoo Date: Wed, 11 Oct 2023 13:13:36 +0300 Subject: [PATCH 2/5] Option | Refactored, updated tests --- lib/src/core/option/none.dart | 18 --------- lib/src/core/option/option.dart | 40 +++++++------------ lib/src/core/option/some.dart | 20 ---------- test/unit/core/option/option_fold_test.dart | 17 ++++---- .../unit/core/option/option_is_none_test.dart | 6 +-- .../unit/core/option/option_is_some_test.dart | 6 +-- .../option/option_none_constructor_test.dart | 18 +++++++++ .../core/option/option_none_factory_test.dart | 11 ----- .../option/option_some_constructor_test.dart | 21 ++++++++++ .../core/option/option_some_factory_test.dart | 13 ------ 10 files changed, 69 insertions(+), 101 deletions(-) delete mode 100644 lib/src/core/option/none.dart delete mode 100644 lib/src/core/option/some.dart create mode 100644 test/unit/core/option/option_none_constructor_test.dart delete mode 100644 test/unit/core/option/option_none_factory_test.dart create mode 100644 test/unit/core/option/option_some_constructor_test.dart delete mode 100644 test/unit/core/option/option_some_factory_test.dart diff --git a/lib/src/core/option/none.dart b/lib/src/core/option/none.dart deleted file mode 100644 index c631467..0000000 --- a/lib/src/core/option/none.dart +++ /dev/null @@ -1,18 +0,0 @@ -part of 'option.dart'; -/// [Option] that holds nothing. -class None implements Option { - /// Create [Option] object that holds nothing. - const None(); - // - @override - R fold({ - required R Function(T v) onSome, - required R Function() onNone, - }) => onNone(); - // - @override - bool get isNone => true; - // - @override - bool get isSome => false; -} \ No newline at end of file diff --git a/lib/src/core/option/option.dart b/lib/src/core/option/option.dart index 521ab04..7036be3 100644 --- a/lib/src/core/option/option.dart +++ b/lib/src/core/option/option.dart @@ -1,28 +1,18 @@ -part 'some.dart'; -part 'none.dart'; /// /// Holds either value or nothing. -abstract class Option { - /// - /// Creates object that holds some [value]. - const factory Option.some(T value) = Some; - /// - /// Creates object that holds nothing. - const factory Option.none() = None; - /// - /// Computes value of type [R] from provided functions - /// based on condition that object is holding some value. - /// - /// Example interpetations of provided functions: - /// - [onSome] - transforms holded value to another of type [R], - /// - [onNone] - returns any default of type [R]. - R fold({ - required R Function(T v) onSome, - required R Function() onNone, - }); +sealed class Option {} +/// +/// [Option] that holds value. +final class Some implements Option { + final T value; /// - /// Is object holding some value? - bool get isSome; - /// Is object holding nothing? - bool get isNone; -} \ No newline at end of file + /// Create [Option] object that holds [value]. + const Some(this.value); +} +/// +/// [Option] that holds nothing. +final class None implements Option { + /// + /// Create [Option] object that holds nothing. + const None(); +} diff --git a/lib/src/core/option/some.dart b/lib/src/core/option/some.dart deleted file mode 100644 index 314f56b..0000000 --- a/lib/src/core/option/some.dart +++ /dev/null @@ -1,20 +0,0 @@ -part of 'option.dart'; -/// [Option] that holds some value. -class Some implements Option { - final T _value; - /// - /// Create [Option] object that holds some [value]. - const Some(T value) : _value = value; - // - @override - R fold({ - required R Function(T v) onSome, - required R Function() onNone, - }) => onSome(_value); - // - @override - bool get isNone => false; - // - @override - bool get isSome => true; -} \ No newline at end of file diff --git a/test/unit/core/option/option_fold_test.dart b/test/unit/core/option/option_fold_test.dart index 8c2326d..2c0c30c 100644 --- a/test/unit/core/option/option_fold_test.dart +++ b/test/unit/core/option/option_fold_test.dart @@ -1,24 +1,25 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; + void main() { group('Option fold', () { test('calls onSome function if it is instance of Some', () { for(int i=-50; i<=50; i++) { final Option option = Some(i); - final foldResult = option.fold( - onSome: (v) => '$v', - onNone: () => 'None', - ); + final foldResult = switch(option) { + Some(:final value) => '$value', + None() => 'None', + }; expect(foldResult, equals('$i')); } }); test('calls onNone function if it is instance of None', () { const Option option = None(); - final foldResult = option.fold( - onSome: (v) => '$v', - onNone: () => 'None', - ); + final foldResult = switch(option) { + Some(:final value) => '$value', + None() => 'None', + }; expect(foldResult, equals('None')); }); }); diff --git a/test/unit/core/option/option_is_none_test.dart b/test/unit/core/option/option_is_none_test.dart index 4d5fa39..55664cb 100644 --- a/test/unit/core/option/option_is_none_test.dart +++ b/test/unit/core/option/option_is_none_test.dart @@ -2,16 +2,16 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; void main() { - group('Option isNone', () { + group('Option is None', () { test('returns false if it is instance of Some', () { for(int i=-50; i<=50; i++) { final Option option = Some(i); - expect(option.isNone, equals(false)); + expect(option is None, equals(false)); } }); test('returns true if it is instance of None', () { const Option option = None(); - expect(option.isNone, equals(true)); + expect(option is None, equals(true)); }); }); } \ No newline at end of file diff --git a/test/unit/core/option/option_is_some_test.dart b/test/unit/core/option/option_is_some_test.dart index 9d366dc..6bd71e2 100644 --- a/test/unit/core/option/option_is_some_test.dart +++ b/test/unit/core/option/option_is_some_test.dart @@ -2,16 +2,16 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; void main() { - group('Option isSome', () { + group('Option is Some', () { test('returns true if it is instance of Some', () { for(int i=-50; i<=50; i++) { final Option option = Some(i); - expect(option.isSome, equals(true)); + expect(option is Some, equals(true)); } }); test('returns false if it is instance of None', () { const Option option = None(); - expect(option.isSome, equals(false)); + expect(option is Some, equals(false)); }); }); } \ No newline at end of file diff --git a/test/unit/core/option/option_none_constructor_test.dart b/test/unit/core/option/option_none_constructor_test.dart new file mode 100644 index 0000000..97cecf9 --- /dev/null +++ b/test/unit/core/option/option_none_constructor_test.dart @@ -0,0 +1,18 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:hmi_core/hmi_core_option.dart'; + +void main() { + group('Option None constructor', () { + test('creates instance of None', () { + const Option option = None(); + expect(option, isA()); + }); + test('creates instance of Option of any type', () { + const none = None(); + expect(none, isA>()); + expect(none, isA>()); + expect(none, isA>()); + expect(none, isA>()); + }); + }); +} \ No newline at end of file diff --git a/test/unit/core/option/option_none_factory_test.dart b/test/unit/core/option/option_none_factory_test.dart deleted file mode 100644 index d924a27..0000000 --- a/test/unit/core/option/option_none_factory_test.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:hmi_core/hmi_core_option.dart'; - -void main() { - group('Option none factory', () { - test('creates instance of None', () { - const option = Option.none(); - expect(option, isA>()); - }); - }); -} \ No newline at end of file diff --git a/test/unit/core/option/option_some_constructor_test.dart b/test/unit/core/option/option_some_constructor_test.dart new file mode 100644 index 0000000..db52c73 --- /dev/null +++ b/test/unit/core/option/option_some_constructor_test.dart @@ -0,0 +1,21 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:hmi_core/hmi_core_option.dart'; + +void main() { + group('Option Some constructor', () { + test('creates instance of Some', () { + for(int i=-50; i<=50; i++) { + final option = Some(i); + expect(option, isA>()); + } + for(int i=-50; i<=50; i++) { + final option = Some(i % 2 == 0); + expect(option, isA>()); + } + for(int i=-50; i<=50; i++) { + final option = Some('$i'); + expect(option, isA>()); + } + }); + }); +} \ No newline at end of file diff --git a/test/unit/core/option/option_some_factory_test.dart b/test/unit/core/option/option_some_factory_test.dart deleted file mode 100644 index f3e5648..0000000 --- a/test/unit/core/option/option_some_factory_test.dart +++ /dev/null @@ -1,13 +0,0 @@ -import 'package:flutter_test/flutter_test.dart'; -import 'package:hmi_core/hmi_core_option.dart'; - -void main() { - group('Option some factory', () { - test('creates instance of Some', () { - for(int i=-50; i<=50; i++) { - final option = Option.some(i); - expect(option, isA>()); - } - }); - }); -} \ No newline at end of file From 6fd2b5eedad44987acec1aa6efd6edb0b18fb982 Mon Sep 17 00:00:00 2001 From: Minyewoo Date: Wed, 11 Oct 2023 13:38:57 +0300 Subject: [PATCH 3/5] Github workflows | Raised Flutter version --- .github/workflows/analyze.yml | 2 +- .github/workflows/coverage.yaml | 2 +- .github/workflows/release.yml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/analyze.yml b/.github/workflows/analyze.yml index be37ae7..ef82b17 100644 --- a/.github/workflows/analyze.yml +++ b/.github/workflows/analyze.yml @@ -20,7 +20,7 @@ jobs: # - uses: subosito/flutter-action@v2 with: channel: 'stable' - version: 3.3.10 + version: 3.13.6 # - run: | # sudo apt-get update -y # sudo apt-get install -y ninja-build libgtk-3-dev diff --git a/.github/workflows/coverage.yaml b/.github/workflows/coverage.yaml index 3927510..fa5a446 100644 --- a/.github/workflows/coverage.yaml +++ b/.github/workflows/coverage.yaml @@ -24,7 +24,7 @@ jobs: # - uses: subosito/flutter-action@v2 with: channel: 'stable' - version: 3.3.10 + version: 3.13.6 # - run: | # sudo apt-get update -y # sudo apt-get install -y ninja-build libgtk-3-dev diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9b2722d..966ba60 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -23,7 +23,7 @@ jobs: uses: flutter-actions/setup-flutter@v2 with: channel: 'stable' - version: 3.3.10 + version: 3.13.6 - name: Clearing project run: flutter clean From 4491b60dfe2b56bff7e9b5201c4c656b05d9d2f3 Mon Sep 17 00:00:00 2001 From: a-givertzman Date: Mon, 20 Nov 2023 14:45:46 +0300 Subject: [PATCH 4/5] option tests fixes --- test/unit/core/option/option_fold_test.dart | 42 ++++++++++++++++++++- 1 file changed, 40 insertions(+), 2 deletions(-) diff --git a/test/unit/core/option/option_fold_test.dart b/test/unit/core/option/option_fold_test.dart index 2c0c30c..10e559a 100644 --- a/test/unit/core/option/option_fold_test.dart +++ b/test/unit/core/option/option_fold_test.dart @@ -1,9 +1,13 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; +class ForTestOptionOnly { + final String value; + ForTestOptionOnly(this.value); +} void main() { - group('Option fold', () { + group('Option fold strong typed', () { test('calls onSome function if it is instance of Some', () { for(int i=-50; i<=50; i++) { final Option option = Some(i); @@ -23,4 +27,38 @@ void main() { expect(foldResult, equals('None')); }); }); -} \ No newline at end of file + group('Option fold different types', () { + final testData = [ + 0x7FFFFFFFFFFFFFFF, + -0x8000000000000000, + ForTestOptionOnly("value"), + true, + false, + double.maxFinite, + double.minPositive + -double.maxFinite, + ]; + test('calls onSome function if it is instance of Some', () { + for(final value in testData) { + final Option option = Some(value); + final foldResult = switch(option) { + Some(:final value) => value, + None() => None, + }; + expect(foldResult, equals(value)); + } + }); + test('calls onNone function if it is instance of None', () { + const Option option = None(); + final foldResult = switch(option) { + Some(:final value) => value, + None() => None, + }; + expect(foldResult, equals(None)); + }); + }); +} + + + + From 77daacfb68344351c812de4b71916edffd20b249 Mon Sep 17 00:00:00 2001 From: Minyewoo Date: Tue, 21 Nov 2023 16:27:13 +0300 Subject: [PATCH 5/5] Added more test data for Option --- test/unit/core/option/option_fold_test.dart | 38 +++++-------------- .../unit/core/option/option_is_none_test.dart | 7 ++-- .../unit/core/option/option_is_some_test.dart | 7 ++-- .../option/option_none_constructor_test.dart | 2 + .../option/option_some_constructor_test.dart | 18 ++++----- test/unit/core/option/test_data.dart | 27 +++++++++++++ 6 files changed, 55 insertions(+), 44 deletions(-) create mode 100644 test/unit/core/option/test_data.dart diff --git a/test/unit/core/option/option_fold_test.dart b/test/unit/core/option/option_fold_test.dart index 10e559a..b826d76 100644 --- a/test/unit/core/option/option_fold_test.dart +++ b/test/unit/core/option/option_fold_test.dart @@ -1,10 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; - -class ForTestOptionOnly { - final String value; - ForTestOptionOnly(this.value); -} +import 'test_data.dart'; void main() { group('Option fold strong typed', () { @@ -12,38 +8,28 @@ void main() { for(int i=-50; i<=50; i++) { final Option option = Some(i); final foldResult = switch(option) { - Some(:final value) => '$value', - None() => 'None', + Some(:final value) => value, + None() => null, }; - expect(foldResult, equals('$i')); + expect(foldResult, equals(i)); } }); test('calls onNone function if it is instance of None', () { const Option option = None(); final foldResult = switch(option) { - Some(:final value) => '$value', - None() => 'None', + Some(:final value) => value, + None() => null, }; - expect(foldResult, equals('None')); + expect(foldResult, equals(null)); }); }); group('Option fold different types', () { - final testData = [ - 0x7FFFFFFFFFFFFFFF, - -0x8000000000000000, - ForTestOptionOnly("value"), - true, - false, - double.maxFinite, - double.minPositive - -double.maxFinite, - ]; test('calls onSome function if it is instance of Some', () { for(final value in testData) { final Option option = Some(value); final foldResult = switch(option) { Some(:final value) => value, - None() => None, + None() => null, }; expect(foldResult, equals(value)); } @@ -52,13 +38,9 @@ void main() { const Option option = None(); final foldResult = switch(option) { Some(:final value) => value, - None() => None, + None() => null, }; - expect(foldResult, equals(None)); + expect(foldResult, equals(null)); }); }); } - - - - diff --git a/test/unit/core/option/option_is_none_test.dart b/test/unit/core/option/option_is_none_test.dart index 55664cb..820779e 100644 --- a/test/unit/core/option/option_is_none_test.dart +++ b/test/unit/core/option/option_is_none_test.dart @@ -1,16 +1,17 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; +import 'test_data.dart'; void main() { group('Option is None', () { test('returns false if it is instance of Some', () { - for(int i=-50; i<=50; i++) { - final Option option = Some(i); + for(final value in testData) { + final Option option = Some(value); expect(option is None, equals(false)); } }); test('returns true if it is instance of None', () { - const Option option = None(); + const Option option = None(); expect(option is None, equals(true)); }); }); diff --git a/test/unit/core/option/option_is_some_test.dart b/test/unit/core/option/option_is_some_test.dart index 6bd71e2..58c7de0 100644 --- a/test/unit/core/option/option_is_some_test.dart +++ b/test/unit/core/option/option_is_some_test.dart @@ -1,16 +1,17 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; +import 'test_data.dart'; void main() { group('Option is Some', () { test('returns true if it is instance of Some', () { - for(int i=-50; i<=50; i++) { - final Option option = Some(i); + for(final value in testData) { + final Option option = Some(value); expect(option is Some, equals(true)); } }); test('returns false if it is instance of None', () { - const Option option = None(); + const Option option = None(); expect(option is Some, equals(false)); }); }); diff --git a/test/unit/core/option/option_none_constructor_test.dart b/test/unit/core/option/option_none_constructor_test.dart index 97cecf9..87d82bb 100644 --- a/test/unit/core/option/option_none_constructor_test.dart +++ b/test/unit/core/option/option_none_constructor_test.dart @@ -1,5 +1,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; +import 'test_data.dart'; void main() { group('Option None constructor', () { @@ -13,6 +14,7 @@ void main() { expect(none, isA>()); expect(none, isA>()); expect(none, isA>()); + expect(none, isA>()); }); }); } \ No newline at end of file diff --git a/test/unit/core/option/option_some_constructor_test.dart b/test/unit/core/option/option_some_constructor_test.dart index db52c73..584addd 100644 --- a/test/unit/core/option/option_some_constructor_test.dart +++ b/test/unit/core/option/option_some_constructor_test.dart @@ -1,21 +1,19 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:hmi_core/hmi_core_option.dart'; +import 'test_data.dart'; void main() { group('Option Some constructor', () { test('creates instance of Some', () { for(int i=-50; i<=50; i++) { - final option = Some(i); - expect(option, isA>()); - } - for(int i=-50; i<=50; i++) { - final option = Some(i % 2 == 0); - expect(option, isA>()); - } - for(int i=-50; i<=50; i++) { - final option = Some('$i'); - expect(option, isA>()); + expect(Some(i), isA>()); + expect(Some(i / 2.0), isA>()); + expect(Some(i % 2 == 0), isA>()); + expect(Some('$i'), isA>()); + expect(Some(ForTestOptionOnly('$i')), isA>()); } + const userClassOption = Some(ForTestOptionOnly('')); + expect(userClassOption, isA>()); }); }); } \ No newline at end of file diff --git a/test/unit/core/option/test_data.dart b/test/unit/core/option/test_data.dart new file mode 100644 index 0000000..3819bbd --- /dev/null +++ b/test/unit/core/option/test_data.dart @@ -0,0 +1,27 @@ +final class ForTestOptionOnly { + final String value; + const ForTestOptionOnly(this.value); +} +const _maxInt64 = 0x7FFFFFFFFFFFFFFF; +const _minInt64 = -0x8000000000000000; +const testData = [ + _maxInt64, + _minInt64, + 0, + 353465, + 45, + -3456, + ForTestOptionOnly('value'), + ForTestOptionOnly(''), + ForTestOptionOnly('123'), + true, + false, + double.maxFinite, + double.minPositive + -double.maxFinite, + 0.0, + 1.234, + 234.4, + -0.45676, + -346.786, +]; \ No newline at end of file