Skip to content

Commit

Permalink
fix conformance parsing results and simplify code
Browse files Browse the repository at this point in the history
  • Loading branch information
3nids committed Oct 20, 2023
1 parent 8063ac6 commit 7706eac
Showing 1 changed file with 35 additions and 58 deletions.
93 changes: 35 additions & 58 deletions tests/conformance/parse_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from itertools import islice
from os import path
from sys import argv, exit
from typing import List, NamedTuple, Tuple, Union
from typing import List, NamedTuple

from lxml import etree

Expand All @@ -26,101 +26,78 @@ class Cmp(str, Enum):
WORSE = 2

@classmethod
def tell(cls, x: Union[int, List], y: Union[int, List]) -> "Cmp":
if isinstance(x, List) and isinstance(y, List):
x, y = len(x), len(y)
if x > y:
return cls.BETTER
if x == y:
return cls.EQUAL
return cls.WORSE
def emoji(cls, cmp) -> str:
if cmp == Cmp.EQUAL:
return "🤓"
if cmp == Cmp.BETTER:
return "🍻"
else:
return "☠️"


class Results(NamedTuple):
class Result(NamedTuple):
passed: List[str]
skipped: List[str]
failed: List[str]

@classmethod
def get_latest(cls, path) -> "Results":
with open(path, "r") as fh:
def load(cls, _path) -> "Result":
with open(_path, "r") as fh:
results = json.load(fh)
return cls(**results)

@classmethod
def parse(cls, path) -> "Results":
def parse(cls, _path) -> "Result":
ids = {"0", "1"}
statuses = {"failed", "passed", "skipped"}
xpaths_statuses = {
(f'//tbody[@id="t{id}"]/tr[contains(@class, "{status}")]', status) for id in ids for status in statuses
(f'//tbody[@id="t{_id}"]/tr[contains(@class, "{status}")]', status) for _id in ids for status in statuses
}
results = {k: [] for k in statuses}

parser = etree.HTMLParser()
tree = etree.parse(path, parser)
tree = etree.parse(_path, parser)
root = tree.getroot()
has_dots = lambda x: x is not None and "." in x
relevant_slice = lambda s: s.split(".", 5)[-1]

for xp, status in xpaths_statuses:
trs = root.xpath(xp)
for tr in trs:
children = tr.getchildren()
found = [relevant_slice(e.text) for e in islice(children, 2) if has_dots(e.text)]
found = [e.text.split(".", 5)[-1] for e in islice(children, 2) if e.text is not None and "." in e.text]
results[status] += found
return cls(**results)

@staticmethod
def write(current: "Results"):
current = current._asdict()
def write(self):
with open(baseline_path, "w") as fh:
json.dump(current, fh, indent=2)
json.dump(self._asdict(), fh, indent=2)
fh.write("\n")
print("Results written to disk.")

@staticmethod
def pass_verdict(current: "Results", previous: "Results"):
diff = Diff.compare(current, previous)._asdict()
worse = [f"{v}: {k}!" for k, v in diff.items() if Cmp.WORSE in v]
not_better = all(Cmp.EQUAL in v for v in diff.values())

if worse:
print(
f"{worse}\n\n^ Sorry, job results suggest that you didn't manage to clear the baseline. Scroll up for details. ^"
)
def compare(self, other: "Result") -> Cmp:
"""
Compares the result with another one and returns if it is better, equal or worse than the other one
"""
if len(self.passed) < len(other.passed):
return Cmp.WORSE
elif not_better:
print(f"{current}\n\n^ Results are similar. ^")
return Cmp.EQUAL
else:
Results.write(current)
if len(self.passed) > len(other.passed):
return Cmp.BETTER


class Diff(NamedTuple):
passed: Tuple[int, Cmp]
skipped: Tuple[int, Cmp]
failed: Tuple[int, Cmp]

@classmethod
def compare(cls, last: Results, previous: Results) -> "Diff":
passed = (len(last.passed), Cmp.tell(last.passed, previous.passed))
skipped = (len(last.skipped), Cmp.tell(last.skipped, previous.skipped))
failed = (len(last.failed), Cmp.tell(last.failed, previous.failed))
return cls(passed, skipped, failed)
if len(self.skipped) + len(self.failed) > len(other.skipped) + len(other.failed):
return Cmp.WORSE
if len(self.skipped) + len(self.failed) < len(other.skipped) + len(other.failed):
return Cmp.BETTER
return Cmp.EQUAL


if __name__ == "__main__":
report_path = path.relpath(argv[1])
baseline_path = path.relpath(argv[2])

assert path.exists(report_path)
current = Results.parse(report_path)
_current = Result.load(baseline_path)

if not path.exists(baseline_path):
Results.write(current)
exit(Cmp.BETTER.value)
assert path.exists(report_path)
_new = Result.parse(report_path)
_new.write()

previous = Results.get_latest(baseline_path)
cmp = Results.pass_verdict(current, previous)
exit(int(cmp.value))
_cmp = _new.compare(_current)
print(f"{Cmp.emoji(_cmp)} Conformance is {_cmp.name}")
exit(int(_cmp.value))

0 comments on commit 7706eac

Please sign in to comment.