Skip to content

Commit

Permalink
Merge pull request #6 from Marcus-Software/mde/maintenance/improve-doc
Browse files Browse the repository at this point in the history
Improved documentation and refactored tests
  • Loading branch information
marcusedu authored Aug 3, 2020
2 parents d4a0de7 + c84cc81 commit 1bd34a2
Show file tree
Hide file tree
Showing 15 changed files with 513 additions and 328 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [0.6.0+1] - 08/03/2020

* improved documentation and refactored tests

## [0.6.0] - 08/02/2020

* doIfExists: do something if exists a key and return something
Expand Down
215 changes: 188 additions & 27 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,50 +1,211 @@
# Overview [![Pub](https://img.shields.io/pub/v/ms_map_utils.svg)](https://pub.dartlang.org/packages/ms_map_utils) ![GitHub stars](https://img.shields.io/github/stars/Marcus-Software/ms_map_utils?style=social)
# Overview [![Pub](https://img.shields.io/pub/v/ms_map_utils.svg)](https://pub.dartlang.org/packages/ms_map_utils)

![GitHub stars](https://img.shields.io/github/stars/Marcus-Software/ms_map_utils?style=social)

A simple lib to incremease Map with usefull functions

## Whats MS_Map_Utils do

Add usefull functions to map:

- `trim` trim all Strings in a map _it's recursive_
- `compact` remove all MapEntries thats values is `null` _it's recursive too_
- `reduce` iterate all items in `Map` for reduce to a unique value returned from callback `ReduceFunction`.
- `removeKeys` remove all entries that contains a key in list.
- `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.
* `trim` trim all Strings in a map _it's recursive_.
* `compact` remove all MapEntries thats values is `null` _it's recursive too_.
* `reduce` iterate all items in `Map` for reduce to a unique value returned from callback `ReduceFunction` .
* `removeKeys` remove all entries that contains a key in list.
* `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

Just import lib and use [extensions](https://dart.dev/guides/language/extension-methods), call the functions to starts work:

```dart
``` dart
// Don't forget to import
import 'package:ms_map_utils/ms_map_utils.dart';
Map itsAMap = {'key1':null,'key2':' just a String withs extras spaces en start and end '};
itsAMap.compact(); // Output: {'key2':' just a String withs extras spaces en start and end '}
itsAMap.trim(); // Output: {'key2':'just a String withs extras spaces en start and end'}
Map mapNumbers = {'key1':50,'key2':7,'key3':71,'key4':45,'key5':5};
// In reduceFunction you must check if `accumulated` is null and set a initial value for it
mapNumbers.reduce<int>((int accumulated, _, value) => (accumulated ?? 0) + (value as int)); // Output 178
mapNumbers.removeKeys(['key1','key5']); //{'key2':7,'key3':71,'key4':45}
mapNumbers.removeKeysExcept(['key3']); //{'key3':71}
var item = await anyMap.putIfAbsentAsync('randomKey', () async {
await Future.delayed(Duration(milliseconds: 1500));
return 'Random Value';
Map itsAMap = {'key1' : null, 'key2' : 'just a String'};
compact(itsAMap); // Output: {'key2':'just a String'}
// or using extensions.
itsAMap.compact(); // Output: {'key2':'just a String'}
```

## trim

The function `trim` all Strings in a map _it's recursive_.

``` dart
test('Most trim any Strings values', () {
const mapToTrim = {
'key1': ' random string ',
'key2': ' another random string ',
'key3': 321
};
expect(mapToTrim.trim(true), {
'key1': 'random string',
'key2': 'another random string',
'key3': 321
});
if (mapNumbers.containsKeys(['key1','key2'])) {
print('The map contians all keys [key1, key2]');
}
});
```

see more in [test file](./test/trim_test.dart).

## compact

The function `compact` remove all MapEntries thats values is `null` _it's recursive_.

``` dart
test('Must return a new empty HashMap without null values', () {
var mapWithNullValues = {
'k1': null,
'k2': null,
'k3': null,
'map': {
'k1': null,
'k2': null,
'k3': null,
},
'list': [
{
'k1': null,
'k2': null,
'k3': null,
},
{
'k1': null,
'k2': null,
'k3': null,
},
]
};
var mapWithoutNull = compact(mapWithNullValues);
expect(mapWithoutNull, {
'map': {},
'list': [{}, {}]
});
});
```

see more in [test file](./test/compact_test.dart).

## reduce

The function `reduce` iterate all items in `Map` for reduce to a unique value returned from callback `ReduceFunction` .

``` dart
test('Multiplies all int values to 120', () {
Map mapNumbers = <String, int>{
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
};
var value = mapNumbers
.reduce<int>((int acc, _, value) => (acc ?? 1) * (value as int));
expect(value, 120, reason: 'Value reduced must be 120');
});
```

see more in [test file](./test/reduce_test.dart).

## removeKeys

The function `removeKeys` remove all entries that contains a key in list.

``` dart
test('Remove all entries that has a key in list with recursive', () {
Map mapNumbers = {
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
'map': {
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
}
};
mapNumbers.removeKeys(['key1', 'key2'], true);
expect(mapNumbers.length, 4);
expect(mapNumbers['map'].length, 3);
});
```

### doIfContains
see more in [test file](./test/remove_keys_test.dart).

## removeKeysExcept

The function `removeKeysExcept` remove all entries that NOT contains a key in list.

``` dart
test('Remove all entries that has a key NOT in list with recursive', () {
Map mapNumbers = {
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
'map': {
'key1': 1,
'key2': 2,
'key3': 3,
'key4': 4,
'key5': 5,
}
};
mapNumbers.removeKeysExcept(['key1', 'key2', 'map'], true);
expect(mapNumbers.length, 3);
expect(mapNumbers['map'].length, 2);
});
```

see more in [test file](./test/remove_keys_except_test.dart).

## putIfAbsentAsync

The function `putIfAbsentAsync` put a item if absent or return existent value async.

``` dart
test('Call async function for empty map', () async {
var emptyMap = <String, String>{};
expect(emptyMap.containsKey('test'), isFalse);
var item = await emptyMap.putIfAbsentAsync('test', () async {
await Future.delayed(Duration(milliseconds: 1500));
return 'Random String';
});
expect(emptyMap, isNotEmpty);
expect(emptyMap.containsKey('test'), isTrue);
expect(item, 'Random String');
});
```

see more in [test file](./test/put_if_absent_async_test.dart).

## containsKeys

The function `containsKeys` check if map contains all keys of list.

``` dart
test('Must return true if contains a list of keys', () {
var listOfKeyToCheck = ['key1', 'key2'];
var mapToCheck = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'};
expect(mapToCheck.containsKeys(listOfKeyToCheck), isTrue);
});
```

see more in [test file](./test/contains_keys_test.dart).

## 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
``` dart
test('must return a object if contains a key', () {
final testMap = {'key1': 'value1', 'key2': 'value2'};
final newThing = doIfContains<List<String>>(testMap, 'key2',
Expand Down
4 changes: 2 additions & 2 deletions example/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ Future<void> main(List<String> args) async {
// Trim all strings values
print({'key1': ' Imagine random string here '}.trim());

Map justMap = {
var justMap = {
'key1': null,
'key2':
' just a String withs extras spaces en start and end '
Expand All @@ -21,7 +21,7 @@ Future<void> main(List<String> args) async {
// {key2: just a String withs extras spaces en start and end}
print(justMap.trim());

Map mapNumbers = {'key1': 50, 'key2': 7, 'key3': 71, 'key4': 45, 'key5': 5};
var mapNumbers = {'key1': 50, 'key2': 7, 'key3': 71, 'key4': 45, 'key5': 5};
// In reduceFunction you must check is acc is null and set a initial value for it
var sumValues = mapNumbers.reduce<int>((int accumulated, _, value) =>
(accumulated ?? 0) + (value as int)); // Output 178
Expand Down
2 changes: 1 addition & 1 deletion lib/functions/do_if_contains.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ 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}) {
{@required 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) {
Expand Down
2 changes: 2 additions & 0 deletions lib/ms_map_utils.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'package:meta/meta.dart';

part './functions/compact.dart';
part './functions/contains_keys.dart';
part './functions/put_if_absent_async.dart';
Expand Down
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.6.0
version: 0.6.0+1
homepage: https://github.com/Marcus-Software/ms_map_utils

environment:
Expand Down
56 changes: 56 additions & 0 deletions test/compact_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import 'package:ms_map_utils/ms_map_utils.dart';
import 'package:test/test.dart';

void main() {
test('Must return a new empty HashMap without null values', () {
var mapWithNullValues = {
'k1': null,
'k2': null,
'k3': null,
'map': {
'k1': null,
'k2': null,
'k3': null,
},
'list': [
{
'k1': null,
'k2': null,
'k3': null,
},
{
'k1': null,
'k2': null,
'k3': null,
},
]
};
var mapWithoutNull = compact(mapWithNullValues);
expect(mapWithoutNull, {
'map': {},
'list': [{}, {}]
});
});
test('Must return a new HashMap without null values', () {
var mapWithNullValues = {
'k1': null,
'k2': null,
'k3': null,
'k4': 'any value'
};
var mapWithoutNull = compact(mapWithNullValues);
expect(mapWithoutNull.length, 1);
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'
};
var mapWithoutNull = mapWithNullValues.compact(true);
expect(mapWithoutNull.length, 1);
expect(mapWithoutNull, {'k4': 'any value'});
});
}
31 changes: 31 additions & 0 deletions test/contains_keys_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import 'package:ms_map_utils/ms_map_utils.dart';
import 'package:test/test.dart';

void main() {
test('Must return true if contains a list of keys', () {
var listOfKeyToCheck = ['key1', 'key2'];
var mapToCheck = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'};
expect(mapToCheck.containsKeys(listOfKeyToCheck), isTrue);
});
test('Must return false if not contains a key in list', () {
var listOfKeyToCheck = ['key1', 'key4'];
var mapToCheck = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'};
expect(mapToCheck.containsKeys(listOfKeyToCheck), isFalse);
});

test('Must return true if contains only keys in list', () {
var listOfKeyToCheck = ['key1', 'key2'];
var mapToCheck = {'key1': 'value1', 'key2': 'value2'};
expect(
mapToCheck.containsKeys(listOfKeyToCheck, rule: ContainsKeysRules.only),
isTrue);
});

test('Must return false if contains only keys in list', () {
var listOfKeyToCheck = ['key1', 'key2'];
var mapToCheck = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'};
expect(
mapToCheck.containsKeys(listOfKeyToCheck, rule: ContainsKeysRules.only),
isFalse);
});
}
1 change: 1 addition & 0 deletions test/do_if_contains_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ void main() {

test('must return throw assertion error if doWork is null', () {
final testMap = {'key1': 'value1', 'key2': 'value2'};
// ignore: missing_required_param
expect(() => doIfContains<List<String>>(testMap, 'key3'),
throwsA(TypeMatcher<AssertionError>()));
});
Expand Down
Loading

0 comments on commit 1bd34a2

Please sign in to comment.