Skip to content

Commit a8d83d9

Browse files
committed
Refactor __run_get_check_result() to return a list of checkResults; Adjust validation result message format
1 parent a762987 commit a8d83d9

2 files changed

Lines changed: 81 additions & 51 deletions

File tree

esdlvalidator/validation/validator.py

Lines changed: 69 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,9 @@ def __constructDatasets(self, selects, esdl):
7070
return datasets
7171

7272
def __run_select(self, select, datasets):
73-
select = FunctionFactory.create(FunctionType.SELECT, select["function"], alias=select["alias"],
74-
datasets=datasets, args=select["args"])
73+
select = FunctionFactory.create(
74+
FunctionType.SELECT, select["function"], alias=select["alias"], datasets=datasets, args=select["args"]
75+
)
7576
return select
7677

7778
def __run_check(self, check, datasets):
@@ -86,61 +87,81 @@ def __run_check(self, check, datasets):
8687

8788
for entry in dataset:
8889
cleanCheck = copy.deepcopy(check)
89-
checkResult = self.__run_get_check_result(cleanCheck, datasets, entry)
90-
checkResults.append(checkResult)
91-
logger.debug("check done, result: {0}".format(checkResult.result.ok))
90+
check_results = self.__run_get_check_result(cleanCheck, datasets, entry)
91+
checkResults.extend(check_results)
92+
logger.debug("check done")
9293
logger.debug("-------------------------")
9394

9495
return checkResults
9596

9697
def __run_get_check_result(self, check, datasets, entry):
98+
"""
99+
Return a list of checkResult(s) for the given check function.
100+
101+
Rules:
102+
- If the check passes and no AND/OR → return [checkResult].
103+
- If AND conditions fail and no OR → return failed AND results.
104+
- If OR condition rescues → return [successful OR checkResult].
105+
- If overall failure → return failed results (including base check, failed ANDs, failed ORs).
106+
"""
97107
functionName = check["function"]
98108
args = check["args"]
99109
logger.debug(
100-
"check entry: {0}, function: '{1}', args: {2}".format(entry.__class__.__name__, functionName, args))
101-
102-
checkResult = FunctionFactory.create(FunctionType.CHECK, functionName, datasets=datasets, value=entry,
103-
args=args)
104-
andList = check["and"] if "and" in check else None
105-
orList = check["or"] if "or" in check else None
106-
107-
# result is ok and no 'and' found
108-
if checkResult.result.ok == True and andList is None:
109-
logger.debug("result == True, and no 'and' options found")
110-
return checkResult
111-
112-
# result is not ok and there is no or
113-
if checkResult.result.ok == False and orList is None:
114-
logger.debug("result == False, no 'or' options found, returning result")
115-
return checkResult
116-
117-
# result is ok but there are more and's defined
118-
if checkResult.result.ok == True and andList is not None:
119-
logger.debug("result == True 'and' options found")
120-
andFailed = False
121-
for a in andList:
122-
checkResult = self.__run_get_check_result(a, datasets, entry)
123-
if checkResult.result.ok == False:
124-
andFailed = True
125-
break
126-
127-
# and resulted in ok == false and there is no or
128-
if andFailed == True and orList is None:
129-
logger.debug("and is not ok, no 'or' options found, returning result")
130-
return checkResult
131-
132-
# result is not ok but there are or's defined
133-
if checkResult.result.ok == False and orList is not None:
134-
logger.debug("executing 'or' function")
135-
orSuccess = False
110+
"check entry: {0}, function: '{1}', args: {2}".format(entry.__class__.__name__, functionName, args)
111+
)
112+
113+
checkResult = FunctionFactory.create(
114+
FunctionType.CHECK, functionName, datasets=datasets, value=entry, args=args
115+
)
116+
andList = check.get("and", [])
117+
orList = check.get("or", [])
118+
119+
# -----------------------
120+
# Helper: evaluate OR
121+
# -----------------------
122+
def evaluate_or():
123+
failed, success = [], None
136124
for o in orList:
137-
checkResult = self.__run_get_check_result(o, datasets, entry)
138-
if checkResult.result.ok == True:
139-
orSuccess = True
125+
subResults = self.__run_get_check_result(o, datasets, entry)
126+
for sr in subResults:
127+
if sr.result.ok:
128+
success = sr
129+
break
130+
if success:
140131
break
132+
failed.extend(subResults)
133+
return success, failed
141134

142-
if orSuccess == True:
143-
logger.debug("result == True, returning result")
144-
return checkResult
135+
if checkResult.result.ok:
136+
# Check ANDs
137+
failed_and = []
138+
for a in andList:
139+
subResults = self.__run_get_check_result(a, datasets, entry)
140+
failed_and.extend([sr for sr in subResults if not sr.result.ok])
141+
142+
if not failed_and and not orList:
143+
return [checkResult] # All good, no AND/OR
144+
if failed_and and not orList:
145+
return failed_and # AND failed, no OR to rescue
146+
147+
# OR evaluation
148+
or_success, failed_or = evaluate_or()
149+
if or_success:
150+
return [or_success] # Rescued by OR
151+
return failed_and + failed_or
152+
153+
else: # checkResult failed
154+
failed_results = [checkResult]
155+
156+
# OR evaluation
157+
or_success, failed_or = evaluate_or()
158+
if or_success:
159+
return [or_success] # Rescued by OR
160+
failed_results.extend(failed_or)
161+
162+
# Check ANDs
163+
for a in andList:
164+
subResults = self.__run_get_check_result(a, datasets, entry)
165+
failed_results.extend([sr for sr in subResults if not sr.result.ok])
145166

146-
return checkResult
167+
return failed_results

esdlvalidator/validation/validator_validation_result.py

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,19 @@ def __getResults(self, checks: list, message: str):
2323
for check in checks:
2424
if not check.result.ok:
2525
if isinstance(check.result.message, dict):
26-
if check.result.message.get("message") and message not in check.result.message["message"]:
27-
check.result.message["message"] = "[ {0} ] {1}".format(message, check.result.message["message"])
26+
if check.result.message.get("message"):
27+
check_msg = (
28+
check.result.message["message"]
29+
if type(check.result.message["message"]) == list
30+
else [check.result.message["message"]]
31+
)
32+
33+
check.result.message["message"] = {
34+
"validation_message": message,
35+
"check_result_message": check_msg,
36+
}
2837
results.append(check.result.message)
2938
else:
30-
results.append("{0}: {1}".format(message, check.result.message))
39+
results.append("{0}: {1}".format(message, str(check.result.message)))
3140

3241
return results

0 commit comments

Comments
 (0)