@@ -59,28 +59,30 @@ def get_value(output: Union[Mapping, List], path: str = "*", exclude: List = Non
59
59
if exclude and isinstance (output , Dict ):
60
60
if not isinstance (exclude , list ):
61
61
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 )
64
64
65
65
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 '*'" )
67
67
path = "*"
68
68
69
69
if path == "*" :
70
- return output # return if path is not specified
70
+ # return if path is not specified
71
+ return output
71
72
72
73
values = jmespath .search (jmespath_value_parser (path ), output )
73
74
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 ):
75
77
return values
76
78
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 :
80
81
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 ):
82
84
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 } ".'
84
86
)
85
87
if isinstance (item , list ):
86
88
values = flatten_list (values ) # flatten list and rewrite values
@@ -123,50 +125,55 @@ def evaluate(self, *args, **kwargs) -> Tuple[Dict, bool]:
123
125
tuple: Dictionary representing check result, bool indicating if differences are found.
124
126
"""
125
127
# This method should call before any other logic the validation of the arguments
126
- # self.validate (**kwargs)
128
+ # self._validate (**kwargs)
127
129
128
130
@staticmethod
129
131
@abstractmethod
130
- def validate ( ** kwargs ) -> None :
132
+ def _validate ( * args ) -> None :
131
133
"""Method to validate arguments that raises proper exceptions."""
132
134
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
+
133
140
134
141
class ExactMatchType (CheckType ):
135
142
"""Exact Match class docstring."""
136
143
137
144
@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
141
148
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]
143
150
"""Returns the difference between values and the boolean."""
144
- self .validate (reference_data = reference_data )
145
151
evaluation_result = diff_generator (reference_data , value_to_compare )
146
- return evaluation_result , not evaluation_result
152
+ return self . result ( evaluation_result )
147
153
148
154
149
155
class ToleranceType (CheckType ):
150
156
"""Tolerance class docstring."""
151
157
152
158
@staticmethod
153
- def validate ( ** kwargs ) -> None :
159
+ def _validate ( tolerance ) -> None : # type: ignore[override]
154
160
"""Method to validate arguments."""
155
161
# reference_data = getattr(kwargs, "reference_data")
156
- tolerance = kwargs .get ("tolerance" )
157
162
if not tolerance :
158
163
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 } ." )
161
168
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]
163
170
"""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 )
168
175
169
- def _remove_within_tolerance (self , diff : Dict , tolerance : int ) -> None :
176
+ def _remove_within_tolerance (self , diff : Dict , tolerance : Union [ int , float ] ) -> None :
170
177
"""Recursively look into diff and apply tolerance check, remove reported difference when within tolerance."""
171
178
172
179
def _make_float (value : Any ) -> float :
@@ -197,87 +204,81 @@ class ParameterMatchType(CheckType):
197
204
"""Parameter Match class implementation."""
198
205
199
206
@staticmethod
200
- def validate ( ** kwargs ) -> None :
207
+ def _validate ( params , mode ) -> None : # type: ignore[override]
201
208
"""Method to validate arguments."""
202
209
mode_options = ["match" , "no-match" ]
203
- params = kwargs .get ("params" )
204
210
if not params :
205
211
raise ValueError ("'params' argument is mandatory for ParameterMatch Check Type." )
206
212
if not isinstance (params , dict ):
207
213
raise ValueError (f"'params' argument must be a dict. You have: { type (params )} ." )
208
214
209
- mode = kwargs .get ("mode" )
210
215
if not mode :
211
216
raise ValueError ("'mode' argument is mandatory for ParameterMatch Check Type." )
212
217
if mode not in mode_options :
213
218
raise ValueError (
214
219
f"'mode' argument should be one of the following: { ', ' .join (mode_options )} . You have: { mode } "
215
220
)
216
221
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]
218
223
"""Parameter Match evaluator implementation."""
219
- self .validate (params = params , mode = mode )
224
+ self ._validate (params = params , mode = mode )
220
225
# TODO: we don't use the mode?
221
226
evaluation_result = parameter_evaluator (value_to_compare , params , mode )
222
- return evaluation_result , not evaluation_result
227
+ return self . result ( evaluation_result )
223
228
224
229
225
230
class RegexType (CheckType ):
226
231
"""Regex Match class implementation."""
227
232
228
233
@staticmethod
229
- def validate ( ** kwargs ) -> None :
234
+ def _validate ( regex , mode ) -> None : # type: ignore[override]
230
235
"""Method to validate arguments."""
231
236
mode_options = ["match" , "no-match" ]
232
- regex = kwargs .get ("regex" )
233
237
if not regex :
234
238
raise ValueError ("'regex' argument is mandatory for Regex Check Type." )
235
239
if not isinstance (regex , str ):
236
240
raise ValueError (f"'regex' argument must be a string. You have: { type (regex )} ." )
237
241
238
- mode = kwargs .get ("mode" )
239
242
if not mode :
240
243
raise ValueError ("'mode' argument is mandatory for Regex Check Type." )
241
244
if mode not in mode_options :
242
245
raise ValueError (f"'mode' argument should be { mode_options } . You have: { mode } " )
243
246
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]
245
248
"""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 )
249
252
250
253
251
254
class OperatorType (CheckType ):
252
255
"""Operator class implementation."""
253
256
254
257
@staticmethod
255
- def validate ( ** kwargs ) -> None :
258
+ def _validate ( params ) -> None : # type: ignore[override]
256
259
"""Validate operator parameters."""
257
260
in_operators = ("is-in" , "not-in" , "in-range" , "not-range" )
258
261
bool_operators = ("all-same" ,)
259
262
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")
262
263
string_operators = ("contains" , "not-contains" )
263
264
valid_options = (
264
265
in_operators ,
265
266
bool_operators ,
266
267
number_operators ,
267
268
string_operators ,
268
- # equal_operators,
269
269
)
270
270
271
271
# 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 ]} ." )
274
275
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" )
277
278
278
279
if not params_key or not params_value :
279
280
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 ())} ."
281
282
)
282
283
283
284
# Validate "params" value is legal.
@@ -326,10 +327,18 @@ def validate(**kwargs) -> None:
326
327
f"check option all-same must have value of type bool. You have: { params_value } of type { type (params_value )} "
327
328
)
328
329
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]
330
331
"""Operator evaluator implementation."""
331
- self .validate ( ** params )
332
+ self ._validate ( params )
332
333
# For name consistency.
333
334
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