import re import sys from io import StringIO from typing import Any
class Capturing(list): def enter(self): self._stdout = sys.stdout sys.stdout = self._stringio = StringIO() return self
def __exit__(self, *args):
self.extend(self._stringio.getvalue().splitlines())
del self._stringio # free up some memory
sys.stdout = self._stdout
class Test: def init(self, name: str, code: str, error_should_raise: list[Exception], should_print: list[str]): self.name = name self.code = code self.error_should_raise = error_should_raise self.should_print: list[re.Pattern] = [re.compile(p) for p in should_print]
def check_print(self, print_lines: list[str]):
return any(p.match(l) for p in self.should_print for l in print_lines)
def run(self,
test_globals: dict[str, Any],
test_locals: dict[str, Any]):
with Capturing() as output:
try:
exec(self.code, test_globals, test_locals)
return self.check_print(output)
except self.error_should_raise:
return self.check_print(output)
except:
return False
test
tests = [ Test ]