Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions netcompare/check_types.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""CheckType Implementation."""
import re
from typing import Mapping, Tuple, List, Dict, Any, Union
from abc import ABC, abstractmethod
import jmespath


Expand All @@ -17,11 +18,11 @@
# pylint: disable=arguments-differ


class CheckType:
"""Check Type Class."""
class CheckType(ABC):
"""Check Type Base Abstract Class."""

@staticmethod
def init(check_type):
def init(check_type: str):
"""Factory pattern to get the appropriate CheckType implementation.

Args:
Expand Down Expand Up @@ -68,7 +69,7 @@ def get_value(output: Union[Mapping, List], path: str, exclude: List = None) ->
return values

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

return values

def evaluate(self, value_to_compare: Any, **kwargs) -> Tuple[Dict, bool]:
@abstractmethod
def evaluate(self, *args, **kwargs) -> Tuple[Dict, bool]:
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed that to be more generic, so code validation doesn't highlight it as method signature discrepancy in child classes.

"""Return the result of the evaluation and a boolean True if it passes it or False otherwise.

This method is the one that each CheckType has to implement.

Args:
value_to_compare: Similar value as above to perform comparison.
*args: arguments specific to child class implementation
**kwargs: named arguments

Returns:
tuple: Dictionary representing check result, bool indicating if differences are found.
"""
# This method should call before any other logic the validation of the arguments
# self.validate(**kwargs)
raise NotImplementedError

@staticmethod
def validate(**kwargs):
@abstractmethod
def validate(**kwargs) -> None:
"""Method to validate arguments that raises proper exceptions."""
raise NotImplementedError


class ExactMatchType(CheckType):
Expand Down
43 changes: 40 additions & 3 deletions tests/test_type_checks.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,49 @@
"Check Type unit tests."
"""Check Type unit tests."""
import pytest
from netcompare.check_types import CheckType, ExactMatchType, ToleranceType
from netcompare.check_types import CheckType, ExactMatchType, ToleranceType, ParameterMatchType, RegexType
from .utility import load_json_file, load_mocks, ASSERT_FAIL_MESSAGE


def test_child_class_raises_exception():
"""Tests that exception is raised for child class when abstract methods are not implemented."""

class CheckTypeChild(CheckType):
"""Test Class."""

with pytest.raises(TypeError) as error:
CheckTypeChild() # pylint: disable=E0110

assert (
"Can't instantiate abstract class CheckTypeChild"
" with abstract methods evaluate, validate" in error.value.__str__()
)


def test_child_class_proper_implementation():
"""Test properly implemented child class can be instantiated."""

class CheckTypeChild(CheckType):
"""Test Class."""

@staticmethod
def validate(**kwargs):
return None

def evaluate(self, *args, **kwargs):
return {}, True

check = CheckTypeChild()
assert isinstance(check, CheckTypeChild) and check.validate() is None and check.evaluate() == ({}, True)


@pytest.mark.parametrize(
"check_type_str, expected_class",
[("exact_match", ExactMatchType), ("tolerance", ToleranceType)],
[
("exact_match", ExactMatchType),
("tolerance", ToleranceType),
("parameter_match", ParameterMatchType),
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parameter and regex were missing here.

("regex", RegexType),
],
)
def test_check_init(check_type_str, expected_class):
"""Validate that the returned class is the expected one."""
Expand Down