Skip to content

Commit 1631a6d

Browse files
pszulczewskiPatryk Szulczewski
andauthored
Base class CheckType implemented as abstract class (#35)
Co-authored-by: Patryk Szulczewski <patryk.szulczewski@networktocode.com>
1 parent d5929c7 commit 1631a6d

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

netcompare/check_types.py

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
"""CheckType Implementation."""
22
import re
33
from typing import Mapping, Tuple, List, Dict, Any, Union
4+
from abc import ABC, abstractmethod
45
import jmespath
56

67

@@ -17,11 +18,11 @@
1718
# pylint: disable=arguments-differ
1819

1920

20-
class CheckType:
21-
"""Check Type Class."""
21+
class CheckType(ABC):
22+
"""Check Type Base Abstract Class."""
2223

2324
@staticmethod
24-
def init(check_type):
25+
def init(check_type: str):
2526
"""Factory pattern to get the appropriate CheckType implementation.
2627
2728
Args:
@@ -68,7 +69,7 @@ def get_value(output: Union[Mapping, List], path: str, exclude: List = None) ->
6869
return values
6970

7071
for element in values: # process elements to check is lists should be flatten
71-
# TODO: Not sure how this is working becasyse from `jmespath.search` it's supposed to get a flat list
72+
# TODO: Not sure how this is working because from `jmespath.search` it's supposed to get a flat list
7273
# of str or Decimals, not another list...
7374
for item in element:
7475
if isinstance(item, dict): # raise if there is a dict, path must be more specific to extract data
@@ -88,25 +89,26 @@ def get_value(output: Union[Mapping, List], path: str, exclude: List = None) ->
8889

8990
return values
9091

91-
def evaluate(self, value_to_compare: Any, **kwargs) -> Tuple[Dict, bool]:
92+
@abstractmethod
93+
def evaluate(self, *args, **kwargs) -> Tuple[Dict, bool]:
9294
"""Return the result of the evaluation and a boolean True if it passes it or False otherwise.
9395
9496
This method is the one that each CheckType has to implement.
9597
9698
Args:
97-
value_to_compare: Similar value as above to perform comparison.
99+
*args: arguments specific to child class implementation
100+
**kwargs: named arguments
98101
99102
Returns:
100103
tuple: Dictionary representing check result, bool indicating if differences are found.
101104
"""
102105
# This method should call before any other logic the validation of the arguments
103106
# self.validate(**kwargs)
104-
raise NotImplementedError
105107

106108
@staticmethod
107-
def validate(**kwargs):
109+
@abstractmethod
110+
def validate(**kwargs) -> None:
108111
"""Method to validate arguments that raises proper exceptions."""
109-
raise NotImplementedError
110112

111113

112114
class ExactMatchType(CheckType):

tests/test_type_checks.py

Lines changed: 40 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,49 @@
1-
"Check Type unit tests."
1+
"""Check Type unit tests."""
22
import pytest
3-
from netcompare.check_types import CheckType, ExactMatchType, ToleranceType
3+
from netcompare.check_types import CheckType, ExactMatchType, ToleranceType, ParameterMatchType, RegexType
44
from .utility import load_json_file, load_mocks, ASSERT_FAIL_MESSAGE
55

66

7+
def test_child_class_raises_exception():
8+
"""Tests that exception is raised for child class when abstract methods are not implemented."""
9+
10+
class CheckTypeChild(CheckType):
11+
"""Test Class."""
12+
13+
with pytest.raises(TypeError) as error:
14+
CheckTypeChild() # pylint: disable=E0110
15+
16+
assert (
17+
"Can't instantiate abstract class CheckTypeChild"
18+
" with abstract methods evaluate, validate" in error.value.__str__()
19+
)
20+
21+
22+
def test_child_class_proper_implementation():
23+
"""Test properly implemented child class can be instantiated."""
24+
25+
class CheckTypeChild(CheckType):
26+
"""Test Class."""
27+
28+
@staticmethod
29+
def validate(**kwargs):
30+
return None
31+
32+
def evaluate(self, *args, **kwargs):
33+
return {}, True
34+
35+
check = CheckTypeChild()
36+
assert isinstance(check, CheckTypeChild) and check.validate() is None and check.evaluate() == ({}, True)
37+
38+
739
@pytest.mark.parametrize(
840
"check_type_str, expected_class",
9-
[("exact_match", ExactMatchType), ("tolerance", ToleranceType)],
41+
[
42+
("exact_match", ExactMatchType),
43+
("tolerance", ToleranceType),
44+
("parameter_match", ParameterMatchType),
45+
("regex", RegexType),
46+
],
1047
)
1148
def test_check_init(check_type_str, expected_class):
1249
"""Validate that the returned class is the expected one."""

0 commit comments

Comments
 (0)