@@ -59,28 +59,30 @@ def get_value(output: Union[Mapping, List], path: str = "*", exclude: List = Non
5959 if exclude and isinstance (output , Dict ):
6060 if not isinstance (exclude , list ):
6161 raise ValueError (f"Exclude list must be defined as a list. You have { type (exclude )} " )
62-
63- exclude_filter (output , exclude ) # exclude unwanted elements
62+ # exclude unwanted elements
63+ exclude_filter (output , exclude )
6464
6565 if not path :
66- warnings .warn ("JMSPath cannot be of type 'None'. Path argumente reverted to default value '*'" )
66+ warnings .warn ("JMSPath cannot be empty string or type 'None'. Path argument reverted to default value '*'" )
6767 path = "*"
6868
6969 if path == "*" :
70- return output # return if path is not specified
70+ # return if path is not specified
71+ return output
7172
7273 values = jmespath .search (jmespath_value_parser (path ), output )
7374
74- if not any (isinstance (i , list ) for i in values ): # check for multi-nested lists if not found return here
75+ # check for multi-nested lists if not found return here
76+ if not any (isinstance (i , list ) for i in values ):
7577 return values
7678
77- for element in values : # process elements to check is lists should be flatten
78- # TODO: Not sure how this is working because from `jmespath.search` it's supposed to get a flat list
79- # of str or Decimals, not another list...
79+ # process elements to check if lists should be flattened
80+ for element in values :
8081 for item in element :
81- if isinstance (item , dict ): # raise if there is a dict, path must be more specific to extract data
82+ # raise if there is a dict, path must be more specific to extract data
83+ if isinstance (item , dict ):
8284 raise TypeError (
83- f'Must be list of lists i.e. [["Idle", 75759616], ["Idle", 75759620]].' f" You have { values } '."
85+ f'Must be list of lists i.e. [["Idle", 75759616], ["Idle", 75759620]]. You have " { values } ".'
8486 )
8587 if isinstance (item , list ):
8688 values = flatten_list (values ) # flatten list and rewrite values
@@ -123,50 +125,55 @@ def evaluate(self, *args, **kwargs) -> Tuple[Dict, bool]:
123125 tuple: Dictionary representing check result, bool indicating if differences are found.
124126 """
125127 # This method should call before any other logic the validation of the arguments
126- # self.validate (**kwargs)
128+ # self._validate (**kwargs)
127129
128130 @staticmethod
129131 @abstractmethod
130- def validate ( ** kwargs ) -> None :
132+ def _validate ( * args ) -> None :
131133 """Method to validate arguments that raises proper exceptions."""
132134
135+ @staticmethod
136+ def result (evaluation_result ) -> Tuple [Dict , bool ]:
137+ """Result method implementation. Will return diff data and bool for checking failed result."""
138+ return evaluation_result , not evaluation_result
139+
133140
134141class ExactMatchType (CheckType ):
135142 """Exact Match class docstring."""
136143
137144 @staticmethod
138- def validate ( ** kwargs ) -> None :
139- """Method to validate arguments."""
140- # reference_data = getattr(kwargs, "reference_data")
145+ def _validate ( reference_data ) :
146+ # No need for _validate method as exact-match does not take any specific arguments.
147+ pass
141148
142- def evaluate (self , value_to_compare : Any , reference_data : Any ) -> Tuple [Dict , bool ]:
149+ def evaluate (self , value_to_compare : Any , reference_data : Any ) -> Tuple [Dict , bool ]: # type: ignore[override]
143150 """Returns the difference between values and the boolean."""
144- self .validate (reference_data = reference_data )
145151 evaluation_result = diff_generator (reference_data , value_to_compare )
146- return evaluation_result , not evaluation_result
152+ return self . result ( evaluation_result )
147153
148154
149155class ToleranceType (CheckType ):
150156 """Tolerance class docstring."""
151157
152158 @staticmethod
153- def validate ( ** kwargs ) -> None :
159+ def _validate ( tolerance ) -> None : # type: ignore[override]
154160 """Method to validate arguments."""
155161 # reference_data = getattr(kwargs, "reference_data")
156- tolerance = kwargs .get ("tolerance" )
157162 if not tolerance :
158163 raise ValueError ("'tolerance' argument is mandatory for Tolerance Check Type." )
159- if not isinstance (tolerance , int ):
160- raise ValueError (f"Tolerance argument's value must be an integer. You have: { type (tolerance )} ." )
164+ if not isinstance (tolerance , (int , float )):
165+ raise ValueError (f"Tolerance argument's value must be a number. You have: { type (tolerance )} ." )
166+ if tolerance < 0 :
167+ raise ValueError (f"Tolerance value must be greater than 0. You have: { tolerance } ." )
161168
162- def evaluate (self , value_to_compare : Any , reference_data : Any , tolerance : int ) -> Tuple [Dict , bool ]:
169+ def evaluate (self , value_to_compare : Any , reference_data : Any , tolerance : int ) -> Tuple [Dict , bool ]: # type: ignore[override]
163170 """Returns the difference between values and the boolean. Overwrites method in base class."""
164- self .validate ( reference_data = reference_data , tolerance = tolerance )
165- diff = diff_generator (reference_data , value_to_compare )
166- self ._remove_within_tolerance (diff , tolerance )
167- return diff , not diff
171+ self ._validate ( tolerance = tolerance )
172+ evaluation_result = diff_generator (reference_data , value_to_compare )
173+ self ._remove_within_tolerance (evaluation_result , tolerance )
174+ return self . result ( evaluation_result )
168175
169- def _remove_within_tolerance (self , diff : Dict , tolerance : int ) -> None :
176+ def _remove_within_tolerance (self , diff : Dict , tolerance : Union [ int , float ] ) -> None :
170177 """Recursively look into diff and apply tolerance check, remove reported difference when within tolerance."""
171178
172179 def _make_float (value : Any ) -> float :
@@ -197,87 +204,81 @@ class ParameterMatchType(CheckType):
197204 """Parameter Match class implementation."""
198205
199206 @staticmethod
200- def validate ( ** kwargs ) -> None :
207+ def _validate ( params , mode ) -> None : # type: ignore[override]
201208 """Method to validate arguments."""
202209 mode_options = ["match" , "no-match" ]
203- params = kwargs .get ("params" )
204210 if not params :
205211 raise ValueError ("'params' argument is mandatory for ParameterMatch Check Type." )
206212 if not isinstance (params , dict ):
207213 raise ValueError (f"'params' argument must be a dict. You have: { type (params )} ." )
208214
209- mode = kwargs .get ("mode" )
210215 if not mode :
211216 raise ValueError ("'mode' argument is mandatory for ParameterMatch Check Type." )
212217 if mode not in mode_options :
213218 raise ValueError (
214219 f"'mode' argument should be one of the following: { ', ' .join (mode_options )} . You have: { mode } "
215220 )
216221
217- def evaluate (self , value_to_compare : Mapping , params : Dict , mode : str ) -> Tuple [Dict , bool ]:
222+ def evaluate (self , value_to_compare : Mapping , params : Dict , mode : str ) -> Tuple [Dict , bool ]: # type: ignore[override]
218223 """Parameter Match evaluator implementation."""
219- self .validate (params = params , mode = mode )
224+ self ._validate (params = params , mode = mode )
220225 # TODO: we don't use the mode?
221226 evaluation_result = parameter_evaluator (value_to_compare , params , mode )
222- return evaluation_result , not evaluation_result
227+ return self . result ( evaluation_result )
223228
224229
225230class RegexType (CheckType ):
226231 """Regex Match class implementation."""
227232
228233 @staticmethod
229- def validate ( ** kwargs ) -> None :
234+ def _validate ( regex , mode ) -> None : # type: ignore[override]
230235 """Method to validate arguments."""
231236 mode_options = ["match" , "no-match" ]
232- regex = kwargs .get ("regex" )
233237 if not regex :
234238 raise ValueError ("'regex' argument is mandatory for Regex Check Type." )
235239 if not isinstance (regex , str ):
236240 raise ValueError (f"'regex' argument must be a string. You have: { type (regex )} ." )
237241
238- mode = kwargs .get ("mode" )
239242 if not mode :
240243 raise ValueError ("'mode' argument is mandatory for Regex Check Type." )
241244 if mode not in mode_options :
242245 raise ValueError (f"'mode' argument should be { mode_options } . You have: { mode } " )
243246
244- def evaluate (self , value_to_compare : Mapping , regex : str , mode : str ) -> Tuple [Mapping , bool ]:
247+ def evaluate (self , value_to_compare : Mapping , regex : str , mode : str ) -> Tuple [Dict , bool ]: # type: ignore[override]
245248 """Regex Match evaluator implementation."""
246- self .validate (regex = regex , mode = mode )
247- diff = regex_evaluator (value_to_compare , regex , mode )
248- return diff , not diff
249+ self ._validate (regex = regex , mode = mode )
250+ evaluation_result = regex_evaluator (value_to_compare , regex , mode )
251+ return self . result ( evaluation_result )
249252
250253
251254class OperatorType (CheckType ):
252255 """Operator class implementation."""
253256
254257 @staticmethod
255- def validate ( ** kwargs ) -> None :
258+ def _validate ( params ) -> None : # type: ignore[override]
256259 """Validate operator parameters."""
257260 in_operators = ("is-in" , "not-in" , "in-range" , "not-range" )
258261 bool_operators = ("all-same" ,)
259262 number_operators = ("is-gt" , "is-lt" )
260- # "equals" is redundant with check type "exact_match" an "parameter_match"
261- # equal_operators = ("is-equal", "not-equal")
262263 string_operators = ("contains" , "not-contains" )
263264 valid_options = (
264265 in_operators ,
265266 bool_operators ,
266267 number_operators ,
267268 string_operators ,
268- # equal_operators,
269269 )
270270
271271 # Validate "params" argument is not None.
272- if not kwargs or list (kwargs .keys ())[0 ] != "params" :
273- raise ValueError (f"'params' argument must be provided. You have: { list (kwargs .keys ())[0 ]} ." )
272+ # {'params': {'mode': 'all-same', 'operator_data': True}}
273+ if not params or list (params .keys ())[0 ] != "params" :
274+ raise ValueError (f"'params' argument must be provided. You have: { list (params .keys ())[0 ]} ." )
274275
275- params_key = kwargs [ "params" ] .get ("mode" )
276- params_value = kwargs [ "params" ] .get ("operator_data" )
276+ params_key = params . get ( "params" , {}) .get ("mode" )
277+ params_value = params . get ( "params" , {}) .get ("operator_data" )
277278
278279 if not params_key or not params_value :
279280 raise ValueError (
280- f"'mode' and 'operator_data' arguments must be provided. You have: { list (kwargs ['params' ].keys ())} ."
281+ f"'mode' and 'operator_data' arguments must be provided. You have: { list (params ['params' ].keys ())} ."
281282 )
282283
283284 # Validate "params" value is legal.
@@ -326,10 +327,18 @@ def validate(**kwargs) -> None:
326327 f"check option all-same must have value of type bool. You have: { params_value } of type { type (params_value )} "
327328 )
328329
329- def evaluate (self , value_to_compare : Any , params : Any ) -> Tuple [Dict , bool ]:
330+ def evaluate (self , value_to_compare : Any , params : Any ) -> Tuple [Dict , bool ]: # type: ignore[override]
330331 """Operator evaluator implementation."""
331- self .validate ( ** params )
332+ self ._validate ( params )
332333 # For name consistency.
333334 reference_data = params
334- evaluation_result , evaluation_bool = operator_evaluator (reference_data ["params" ], value_to_compare )
335- return evaluation_result , not evaluation_bool
335+ evaluation_result = operator_evaluator (reference_data ["params" ], value_to_compare )
336+ return self .result (evaluation_result )
337+
338+ def result (self , evaluation_result ):
339+ """
340+ Operator result method overwrite.
341+
342+ This is required as Opertor return its own boolean within result.
343+ """
344+ return evaluation_result [0 ], not evaluation_result [1 ]
0 commit comments