From 8d06c270c6967e14039af2a75cd55293eb8484ba Mon Sep 17 00:00:00 2001 From: Marcus Duarte Date: Sun, 2 Aug 2020 12:31:32 -0300 Subject: [PATCH] doIfContains implemented --- CHANGELOG.md | 6 +- README.md | 18 ++++ example/main.dart | 5 + lib/functions/do_if_contains.dart | 15 +++ lib/functions/put_if_absent_async.dart | 6 +- lib/ms_map_utils.dart | 34 ++++--- pubspec.yaml | 2 +- test/do_if_contains_test.dart | 38 ++++++++ test/ms_map_utils_test.dart | 122 ++++++++++++------------- 9 files changed, 167 insertions(+), 79 deletions(-) create mode 100644 lib/functions/do_if_contains.dart create mode 100644 test/do_if_contains_test.dart diff --git a/CHANGELOG.md b/CHANGELOG.md index e962e52..3894f3d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,12 @@ # Changelog +## [0.6.0] - 08/02/2020 + +* doIfExists: do something if exists a key and return something + ## [0.5.0] - 04/16/2020 -* constainsKeys: is like containsKey but support a list of keys e diferente rules +* containsKeys: is like containsKey but support a list of keys e diferente rules ## [0.4.0] - 03/02/2020 diff --git a/README.md b/README.md index 2878686..e6f785f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Add usefull functions to map: - `removeKeysExcept` remove all entries that NOT contains a key in list. - `putIfAbsentAsync` put a item if absent or return existent value async. - `containsKeys` check if map contains all keys of list. +- `doIfContains` do some work if map contains a key. ## Usage @@ -38,3 +39,20 @@ if (mapNumbers.containsKeys(['key1','key2'])) { print('The map contians all keys [key1, key2]'); } ``` + +### doIfContains + +The function `doIfContains` will be call a callback function if the map contains a key ou else it will be a callback function `elseIf` if `elseIf` is null, null will returned. + +```dart + test('must return a object if contains a key', () { + final testMap = {'key1': 'value1', 'key2': 'value2'}; + final newThing = doIfContains>(testMap, 'key2', + doWork: (key, value) => + [value.toString(), 'new awesome thing', key.toString()], + elseIf: () => ['nothing']); + expect(newThing, ['value2', 'new awesome thing', 'key2']); + }); +``` + +see more in [test file](./test/do_if_contains_test.dart). diff --git a/example/main.dart b/example/main.dart index a1deeb8..03cfad4 100644 --- a/example/main.dart +++ b/example/main.dart @@ -41,4 +41,9 @@ Future main(List args) async { if (mapNumbers.containsKeys(['key1', 'key2'])) { print('The map contians all keys [key1, key2]'); } + + mapNumbers.doIfContains( + 'key1', + doWork: (key, value) => print('Has key1 and i will return void'), + ); } diff --git a/lib/functions/do_if_contains.dart b/lib/functions/do_if_contains.dart new file mode 100644 index 0000000..8ec66c8 --- /dev/null +++ b/lib/functions/do_if_contains.dart @@ -0,0 +1,15 @@ +part of '../ms_map_utils.dart'; + +/// Return a result of [doWork] if a map contains a key or return +/// a result of [elseIf] if non null else will return null +T doIfContains(Map map, Object key, + {T Function(Object key, Object value) doWork, T Function() elseIf}) { + assert(doWork != null, 'doWork should not be non null'); + assert(map != null, 'map should not be non null'); + if (map?.containsKey(key) == true) { + return doWork(key, map[key]); + } else if (elseIf != null) { + return elseIf(); + } + return null; +} diff --git a/lib/functions/put_if_absent_async.dart b/lib/functions/put_if_absent_async.dart index 14f60b0..e48a566 100644 --- a/lib/functions/put_if_absent_async.dart +++ b/lib/functions/put_if_absent_async.dart @@ -2,8 +2,8 @@ part of '../ms_map_utils.dart'; /// Return a value if it exists in map or call [ifAbsent] that's return a new value /// and insert him on map -Future putIfAbsentAsync( - Map map, String key, Future Function() ifAbsent) async { +Future putIfAbsentAsync( + Map map, String key, Future Function() ifAbsent) async { if (map.containsKey(key)) { return map[key]; } else { @@ -11,4 +11,4 @@ Future putIfAbsentAsync( map[key] = value; return value; } -} \ No newline at end of file +} diff --git a/lib/ms_map_utils.dart b/lib/ms_map_utils.dart index 0dc82d6..09fbb0f 100644 --- a/lib/ms_map_utils.dart +++ b/lib/ms_map_utils.dart @@ -4,13 +4,15 @@ part './functions/put_if_absent_async.dart'; part './functions/reduce.dart'; part './functions/remove_keys.dart'; part './functions/trim.dart'; - -Function _compact = compact; -Function _trim = trim; -Function _reduce = reduce; -Function _removeKeys = removeKeys; -Function _removeKeysExcept = removeKeysExcept; -Function _putIfAbsentAsync = putIfAbsentAsync; +part './functions/do_if_contains.dart'; + +final _compact = compact; +final _trim = trim; +final _reduce = reduce; +final _removeKeys = removeKeys; +final _removeKeysExcept = removeKeysExcept; +final _putIfAbsentAsync = putIfAbsentAsync; +final _doIfContains = doIfContains; bool Function(Map map, List keys, {ContainsKeysRules rule}) _containsKeys = containsKeys; @@ -18,16 +20,16 @@ extension MapUtils on Map { /// Remove all entries that value is null /// /// [newMap] if true return a new map modifield - Map compact([bool newMap = false]) => _compact(this, newMap) as Map; + Map compact([bool newMap = false]) => _compact(this, newMap); /// Apply trim in all String values on tree /// - /// [newMap] if true return a new map modifield - Map trim([bool newMap = false]) => _trim(this, newMap) as Map; + /// [newMap] if true return a new map modifield' + Map trim([bool newMap = false]) => _trim(this, newMap); /// Reduce Tp reduce(ReduceFunction reduceFunction) => - _reduce(this, reduceFunction) as Tp; + _reduce(this, reduceFunction); /// Remove all values that matches in list of keys /// @@ -45,11 +47,17 @@ extension MapUtils on Map { /// Return a value if it exists in map or call [ifAbsent] that's return a new value /// and insert him on map - Future putIfAbsentAsync(String key, Future Function() ifAbsent) async => - _putIfAbsentAsync(this, key, ifAbsent); + Future putIfAbsentAsync(String key, Future Function() ifAbsent) async => + _putIfAbsentAsync(this, key, ifAbsent); /// Return true if map contains all keys in list of keys bool containsKeys(List keys, {ContainsKeysRules rule = ContainsKeysRules.none}) => _containsKeys(this, keys, rule: rule); + + /// Return a result of [doWork] if a map contains a key or return + /// a result of [elseIf] if non null else will return null + X doIfContains(Object key, + {X Function(Object key, Object value) doWork, X Function() elseIf}) => + _doIfContains(this, key, doWork: doWork, elseIf: elseIf); } diff --git a/pubspec.yaml b/pubspec.yaml index abd2ca0..8fa101c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: ms_map_utils description: A dart package that implement a lot of util functions for a Map -version: 0.5.0 +version: 0.6.0 homepage: https://github.com/Marcus-Software/ms_map_utils environment: diff --git a/test/do_if_contains_test.dart b/test/do_if_contains_test.dart new file mode 100644 index 0000000..03ada3c --- /dev/null +++ b/test/do_if_contains_test.dart @@ -0,0 +1,38 @@ +import 'package:ms_map_utils/ms_map_utils.dart'; +import 'package:test/test.dart'; + +void main() { + test('must return a object if contains a key', () { + final testMap = {'key1': 'value1', 'key2': 'value2'}; + final newThing = doIfContains>(testMap, 'key2', + doWork: (key, value) => + [value.toString(), 'new awesome thing', key.toString()], + elseIf: () => ['nothing']); + expect(newThing, ['value2', 'new awesome thing', 'key2']); + }); + + test('must return a default object if not contains a key', () { + final testMap = {'key1': 'value1', 'key2': 'value2'}; + final newThing = doIfContains>(testMap, 'key3', + doWork: (key, value) => + [value.toString(), 'new awesome thing', key.toString()], + elseIf: () => ['nothing']); + expect(newThing, ['nothing']); + }); + + test( + 'must return a null if not contains a key and not pass callback to elseIf', + () { + final testMap = {'key1': 'value1', 'key2': 'value2'}; + final newThing = doIfContains>(testMap, 'key3', + doWork: (key, value) => + [value.toString(), 'new awesome thing', key.toString()]); + expect(newThing, null); + }); + + test('must return throw assertion error if doWork is null', () { + final testMap = {'key1': 'value1', 'key2': 'value2'}; + expect(() => doIfContains>(testMap, 'key3'), + throwsA(TypeMatcher())); + }); +} diff --git a/test/ms_map_utils_test.dart b/test/ms_map_utils_test.dart index 6080531..3266037 100644 --- a/test/ms_map_utils_test.dart +++ b/test/ms_map_utils_test.dart @@ -2,27 +2,27 @@ import 'package:ms_map_utils/ms_map_utils.dart'; import 'package:test/test.dart'; void main() { - group("Compact Map", () { + group('Compact Map', () { test('Must return a new empty HashMap without null values', () { var mapWithNullValues = { - "k1": null, - "k2": null, - "k3": null, + 'k1': null, + 'k2': null, + 'k3': null, 'map': { - "k1": null, - "k2": null, - "k3": null, + 'k1': null, + 'k2': null, + 'k3': null, }, 'list': [ { - "k1": null, - "k2": null, - "k3": null, + 'k1': null, + 'k2': null, + 'k3': null, }, { - "k1": null, - "k2": null, - "k3": null, + 'k1': null, + 'k2': null, + 'k3': null, }, ] }; @@ -34,81 +34,81 @@ void main() { }); test('Must return a new HashMap without null values', () { var mapWithNullValues = { - "k1": null, - "k2": null, - "k3": null, - "k4": "any value" + 'k1': null, + 'k2': null, + 'k3': null, + 'k4': 'any value' }; var mapWithoutNull = compact(mapWithNullValues); expect(mapWithoutNull.length, 1); - expect(mapWithoutNull, {"k4": "any value"}); + expect(mapWithoutNull, {'k4': 'any value'}); }); test('Must return a new HashMap without null values', () { var mapWithNullValues = { - "k1": null, - "k2": null, - "k3": null, - "k4": "any value" + 'k1': null, + 'k2': null, + 'k3': null, + 'k4': 'any value' }; var mapWithoutNull = mapWithNullValues.compact(true); expect(mapWithoutNull.length, 1); - expect(mapWithoutNull, {"k4": "any value"}); + expect(mapWithoutNull, {'k4': 'any value'}); }); }); - group("Trim Strings on map", () { - test("Most trim any Strings values", () { + group('Trim Strings on map', () { + test('Most trim any Strings values', () { const mapToTrim = { - "key1": " random string ", - "key2": " another random string ", - "key3": 321 + 'key1': ' random string ', + 'key2': ' another random string ', + 'key3': 321 }; expect(mapToTrim.trim(true), { - "key1": "random string", - "key2": "another random string", - "key3": 321 + 'key1': 'random string', + 'key2': 'another random string', + 'key3': 321 }); }); - test("Most trim any Strings values and map enhered", () { + test('Most trim any Strings values and map enhered', () { const mapToTrim = { - "key1": " random string ", - "key2": " another random string ", - "map": { - "key1": " random string ", - "key2": " another random string ", - "map": { - "key1": " random string ", - "key2": " another random string ", + 'key1': ' random string ', + 'key2': ' another random string ', + 'map': { + 'key1': ' random string ', + 'key2': ' another random string ', + 'map': { + 'key1': ' random string ', + 'key2': ' another random string ', } } }; expect(mapToTrim.trim(true), { - "key1": "random string", - "key2": "another random string", - "map": { - "key1": "random string", - "key2": "another random string", - "map": { - "key1": "random string", - "key2": "another random string", + 'key1': 'random string', + 'key2': 'another random string', + 'map': { + 'key1': 'random string', + 'key2': 'another random string', + 'map': { + 'key1': 'random string', + 'key2': 'another random string', } } }); }); }); - group("Must trim list with maps", () { - test("Trim a map with a list of maps", () { + group('Must trim list with maps', () { + test('Trim a map with a list of maps', () { var mapToTrim = { - "key": [ - {"key": " random string "}, - {"key": " another random string "}, - {"key": " last random string "}, + 'key': [ + {'key': ' random string '}, + {'key': ' another random string '}, + {'key': ' last random string '}, ] }; expect(mapToTrim.trim(true), { - "key": [ - {"key": "random string"}, - {"key": "another random string"}, - {"key": "last random string"}, + 'key': [ + {'key': 'random string'}, + {'key': 'another random string'}, + {'key': 'last random string'}, ] }); }); @@ -125,7 +125,7 @@ void main() { }; var value = mapNumbers .reduce((int acc, _, value) => (acc ?? 0) + (value as int)); - expect(value, 178, reason: "Value reduced must be 178"); + expect(value, 178, reason: 'Value reduced must be 178'); }); test('Multiplies all int values to 120', () { Map mapNumbers = { @@ -137,7 +137,7 @@ void main() { }; var value = mapNumbers .reduce((int acc, _, value) => (acc ?? 1) * (value as int)); - expect(value, 120, reason: "Value reduced must be 120"); + expect(value, 120, reason: 'Value reduced must be 120'); }); test('Concat all keys to "key1key2key3key4key5"', () { Map mapNumbers = { @@ -150,7 +150,7 @@ void main() { var value = mapNumbers .reduce((String acc, key, _) => (acc ?? '') + key.toString()); expect(value, 'key1key2key3key4key5', - reason: "Value reduced must be 'key1key2key3key4key5'"); + reason: 'Value reduced must be "key1key2key3key4key5"'); }); });