Skip to content

Commit

Permalink
Merge pull request #5 from Marcus-Software/mde/feature/containsKeys
Browse files Browse the repository at this point in the history
doIfContains implemented
  • Loading branch information
marcusedu authored Aug 2, 2020
2 parents b064f96 + 8d06c27 commit d4a0de7
Show file tree
Hide file tree
Showing 9 changed files with 167 additions and 79 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -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

Expand Down
18 changes: 18 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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<List<String>>(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).
5 changes: 5 additions & 0 deletions example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,9 @@ Future<void> main(List<String> 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'),
);
}
15 changes: 15 additions & 0 deletions lib/functions/do_if_contains.dart
Original file line number Diff line number Diff line change
@@ -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<T>(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;
}
6 changes: 3 additions & 3 deletions lib/functions/put_if_absent_async.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ 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<V>(
Map map, String key, Future<V> Function() ifAbsent) async {
Future<V> putIfAbsentAsync<V>(
Map<dynamic, V> map, String key, Future<V> Function() ifAbsent) async {
if (map.containsKey(key)) {
return map[key];
} else {
var value = await ifAbsent();
map[key] = value;
return value;
}
}
}
34 changes: 21 additions & 13 deletions lib/ms_map_utils.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,30 +4,32 @@ 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;

extension MapUtils<K, V> on Map<K, V> {
/// 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<Tp>(ReduceFunction<Tp> reduceFunction) =>
_reduce<Tp>(this, reduceFunction) as Tp;
_reduce<Tp>(this, reduceFunction);

/// Remove all values that matches in list of keys
///
Expand All @@ -45,11 +47,17 @@ extension MapUtils<K, V> on Map<K, V> {

/// Return a value if it exists in map or call [ifAbsent] that's return a new value
/// and insert him on map
Future putIfAbsentAsync<V>(String key, Future<V> Function() ifAbsent) async =>
_putIfAbsentAsync(this, key, ifAbsent);
Future<V> putIfAbsentAsync(String key, Future<V> Function() ifAbsent) async =>
_putIfAbsentAsync<V>(this, key, ifAbsent);

/// Return true if map contains all keys in list of keys
bool containsKeys(List<Object> 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<X>(Object key,
{X Function(Object key, Object value) doWork, X Function() elseIf}) =>
_doIfContains<X>(this, key, doWork: doWork, elseIf: elseIf);
}
2 changes: 1 addition & 1 deletion pubspec.yaml
Original file line number Diff line number Diff line change
@@ -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:
Expand Down
38 changes: 38 additions & 0 deletions test/do_if_contains_test.dart
Original file line number Diff line number Diff line change
@@ -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<List<String>>(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<List<String>>(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<List<String>>(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<List<String>>(testMap, 'key3'),
throwsA(TypeMatcher<AssertionError>()));
});
}
122 changes: 61 additions & 61 deletions test/ms_map_utils_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
]
};
Expand All @@ -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'},
]
});
});
Expand All @@ -125,7 +125,7 @@ void main() {
};
var value = mapNumbers
.reduce<int>((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 = <String, int>{
Expand All @@ -137,7 +137,7 @@ void main() {
};
var value = mapNumbers
.reduce<int>((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 = <String, int>{
Expand All @@ -150,7 +150,7 @@ void main() {
var value = mapNumbers
.reduce<String>((String acc, key, _) => (acc ?? '') + key.toString());
expect(value, 'key1key2key3key4key5',
reason: "Value reduced must be 'key1key2key3key4key5'");
reason: 'Value reduced must be "key1key2key3key4key5"');
});
});

Expand Down

0 comments on commit d4a0de7

Please sign in to comment.