From ad31d9a979acbaeccd3a0200997ba9180706d9b9 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Sat, 15 May 2021 13:40:11 +0200 Subject: [PATCH] Started tests for skeleton module --- Makefile | 2 +- app/skeleton.py | 30 ++++++++------ renovate.json | 9 +--- tests/test_dict_merge.py | 69 +++++++++++++++++++++++++++++++ tests/test_skeleton.py | 88 ++++++++++++---------------------------- 5 files changed, 116 insertions(+), 82 deletions(-) create mode 100644 tests/test_dict_merge.py diff --git a/Makefile b/Makefile index e6e77ec..ab0f16e 100644 --- a/Makefile +++ b/Makefile @@ -14,7 +14,7 @@ venv: $(VENV)/bin/activate # Format the codebase using Black format: venv - @ '$(VENV)/bin/black' setup.py app/*.py app/**/*.py + @ '$(VENV)/bin/black' setup.py app .PHONY: format # Remove any temporary files diff --git a/app/skeleton.py b/app/skeleton.py index b6e871a..76d9774 100644 --- a/app/skeleton.py +++ b/app/skeleton.py @@ -1,33 +1,39 @@ """Handles merging with the skeleton config.""" -from typing import Dict +from typing import Dict, Union, List class InvalidKeyError(Exception): """Thrown when a config file contains an invalid key.""" - def __init__(self, key: str): + def __init__(self, keys: Union[str, List[str]]): """Create a new InvalidKeyError object with the given key. Args: - key: the invalid key + keys: the invalid key(s) """ - self.message = "Invalid key: {}".format(key) + if type(keys) == str: + keys = [keys] - super().__init__(key) + self.message = "Invalid key(s): {}".format(", ".join(keys)) + + super().__init__() class MissingKeyError(Exception): """Thrown when a required key is missing from a config.""" - def __init__(self, key: str): + def __init__(self, keys: Union[str, List[str]]): """Create a new MissingKeyError object with the given key. Args: - key: the invalid key + keys: the invalid key(s) """ - self.message = "Missing key: {}".format(key) + if type(keys) == str: + keys = [keys] - super().__init__(key) + self.message = "Missing key(s): {}".format(", ".join(keys)) + + super().__init__() def merge(*dicts: [Dict]) -> Dict: @@ -93,10 +99,10 @@ def merge_with_skeleton(data: Dict, skel: Dict) -> Dict: * Split info less complex functions """ # First, check for illegal keys - key = next(key not in skel for key in data) + invalid_keys = list(filter(lambda k: k not in skel, data)) - if key: - raise InvalidKeyError(key) + if invalid_keys: + raise InvalidKeyError(invalid_keys) # Then, check the default values for key, value in skel.items(): diff --git a/renovate.json b/renovate.json index dca187a..9775346 100644 --- a/renovate.json +++ b/renovate.json @@ -1,10 +1,3 @@ { - "$schema": "https://docs.renovatebot.com/renovate-schema.json", - "packageRules": [ - { - "matchUpdateTypes": ["minor", "patch", "pin", "digest"], - "automerge": true, - "automergeType": "branch" - } - ] + "$schema": "https://docs.renovatebot.com/renovate-schema.json" } diff --git a/tests/test_dict_merge.py b/tests/test_dict_merge.py new file mode 100644 index 0000000..2da81bf --- /dev/null +++ b/tests/test_dict_merge.py @@ -0,0 +1,69 @@ +"""Tests for the skeleton module.""" +from app.skeleton import merge + + +def test_merge_empty(): + """Test correct response for an empty merge.""" + assert merge() == {} + + +def test_merge_single(): + """Test merge command with a single input.""" + assert merge({}) == {} + + dic = {"test": "value", "test2": "value2"} + + assert merge(dic) == dic + + +def test_merge_double_no_overlap(): + """Test merge command with two non-overlapping inputs.""" + d1 = {"test": "value", "test2": "value2"} + d2 = {"test3": "value3"} + d_res = {"test": "value", "test2": "value2", "test3": "value3"} + + assert merge(d1, d2) == d_res + + +def test_merge_double_overlap(): + """Test merge command with two overlapping inputs.""" + d1 = {"test": "value", "test2": "value2"} + d2 = {"test2": "value3"} + d_res = {"test": "value", "test2": "value3"} + + assert merge(d1, d2) == d_res + + +def test_merge_triple_no_overlap(): + """Test merge command with three non-overlapping inputs. + + This test tells us that the recursion works. + """ + d1 = {"test": "value", "test2": "value2"} + d2 = {"test3": "value3"} + d3 = {"test4": "value4"} + d_res = { + "test": "value", + "test2": "value2", + "test3": "value3", + "test4": "value4", + } + + assert merge(d1, d2, d3) == d_res + + +def test_merge_triple_overlap(): + """Test merge command with three overlapping inputs. + + This test tells us that the recursion works. + """ + d1 = {"test": "value", "test2": "value2"} + d2 = {"test3": "value3"} + d3 = {"test2": "value4"} + d_res = { + "test": "value", + "test2": "value4", + "test3": "value3", + } + + assert merge(d1, d2, d3) == d_res diff --git a/tests/test_skeleton.py b/tests/test_skeleton.py index 2da81bf..c14fa0c 100644 --- a/tests/test_skeleton.py +++ b/tests/test_skeleton.py @@ -1,69 +1,35 @@ -"""Tests for the skeleton module.""" -from app.skeleton import merge +"""Tests wether the skeleton merge works.""" +from app.skeleton import merge_with_skeleton, MissingKeyError, InvalidKeyError +import pytest -def test_merge_empty(): - """Test correct response for an empty merge.""" - assert merge() == {} - - -def test_merge_single(): - """Test merge command with a single input.""" - assert merge({}) == {} - - dic = {"test": "value", "test2": "value2"} - - assert merge(dic) == dic - - -def test_merge_double_no_overlap(): - """Test merge command with two non-overlapping inputs.""" - d1 = {"test": "value", "test2": "value2"} - d2 = {"test3": "value3"} - d_res = {"test": "value", "test2": "value2", "test3": "value3"} - - assert merge(d1, d2) == d_res - - -def test_merge_double_overlap(): - """Test merge command with two overlapping inputs.""" - d1 = {"test": "value", "test2": "value2"} - d2 = {"test2": "value3"} - d_res = {"test": "value", "test2": "value3"} - - assert merge(d1, d2) == d_res - - -def test_merge_triple_no_overlap(): - """Test merge command with three non-overlapping inputs. - - This test tells us that the recursion works. - """ - d1 = {"test": "value", "test2": "value2"} - d2 = {"test3": "value3"} - d3 = {"test4": "value4"} - d_res = { - "test": "value", - "test2": "value2", - "test3": "value3", - "test4": "value4", +def test_single_invalid_key(): + """Tests wether an InvalidKeyError is correctly thrown for a single key.""" + data = { + "test": 1, + "test2": "test" + } + skel = { + "test": None, } - assert merge(d1, d2, d3) == d_res + with pytest.raises(InvalidKeyError) as e_info: + merge_with_skeleton(data, skel) + + assert e_info.value.message == "Invalid key(s): test2" -def test_merge_triple_overlap(): - """Test merge command with three overlapping inputs. - - This test tells us that the recursion works. - """ - d1 = {"test": "value", "test2": "value2"} - d2 = {"test3": "value3"} - d3 = {"test2": "value4"} - d_res = { - "test": "value", - "test2": "value4", - "test3": "value3", +def test_single_missing_key(): + """Tests wether a MissingKeyError is correctly thrown for a single key.""" + data = { + "test": 1, + } + skel = { + "test": None, + "test2": None, } - assert merge(d1, d2, d3) == d_res + with pytest.raises(MissingKeyError) as e_info: + merge_with_skeleton(data, skel) + + assert e_info.value.message == "Missing key(s): test2"