| 567 | return failed == 0 |
| 568 | |
| 569 | def check_match(self, expected, actual): |
| 570 | if expected == actual: |
| 571 | return True |
| 572 | |
| 573 | escaped = re.escape(expected) |
| 574 | # Replace escaped ellipsis (\.\.\.) with regex wildcard (.*) |
| 575 | # We use .* to match across lines (DOTALL) |
| 576 | # Newlines before and after ellipsis are discarded (optional) |
| 577 | # Note: re.escape escapes \n as backslash + newline, so we match that |
| 578 | escaped_newline = '\\' + '\n' |
| 579 | pattern = escaped.replace(escaped_newline + '\\.\\.\\.' + escaped_newline, '.*') |
| 580 | pattern = pattern.replace('\\.\\.\\.' + escaped_newline, '.*') |
| 581 | pattern = pattern.replace(escaped_newline + '\\.\\.\\.', '.*') |
| 582 | pattern = pattern.replace('\\.\\.\\.', '.*') |
| 583 | regex = f"^{pattern}$" |
| 584 | |
| 585 | return bool(re.match(regex, actual, re.DOTALL)) |
| 586 | |
| 587 | if __name__ == "__main__": |
| 588 | arg_parser = argparse.ArgumentParser(description="Execute shell commands found in code snippets of markdown files and validate their output.") |