68 lines
2.5 KiB
Python
68 lines
2.5 KiB
Python
|
import argparse
|
||
|
from pathlib import Path
|
||
|
from difflib import unified_diff
|
||
|
|
||
|
import subprocess as sp
|
||
|
import yaml
|
||
|
|
||
|
from dataclasses import dataclass
|
||
|
|
||
|
@dataclass
|
||
|
class TestCase:
|
||
|
def __init__(self, name, input = None, file = None):
|
||
|
self.name = name
|
||
|
self.input = input
|
||
|
self.file = file
|
||
|
|
||
|
def diff(expected: str, actual: str) -> str:
|
||
|
expected_lines = expected.splitlines(keepends=True)
|
||
|
actual_lines = actual.splitlines(keepends=True)
|
||
|
return ''.join(unified_diff(actual_lines, expected_lines, fromfile='actual', tofile='expected'))
|
||
|
|
||
|
def run_shell(shell: str, stdin: str) -> sp.CompletedProcess:
|
||
|
return sp.run([shell], input=stdin, capture_output=True, text=True, env={})
|
||
|
|
||
|
def perform_check(expected: sp.CompletedProcess, actual: sp.CompletedProcess):
|
||
|
assert expected.returncode == actual.returncode, f"EXIT_CODE_ERR: expected {expected.returncode}, got {actual.returncode}"
|
||
|
assert expected.stdout == actual.stdout, f"STDOUT_ERR\n{diff(expected.stdout, actual.stdout)}"
|
||
|
assert len(expected.stderr) == len(actual.stderr) or (len(expected.stderr) != 0 and len(actual.stderr) != 0), f"STDERR_EMPTY"
|
||
|
|
||
|
if __name__ == '__main__':
|
||
|
parser = argparse.ArgumentParser("bshTestSuite")
|
||
|
parser.add_argument('--binary', required=True, type=Path)
|
||
|
parser.add_argument('--tests', required=True, nargs='+', default=[])
|
||
|
args = parser.parse_args()
|
||
|
|
||
|
binary_path = args.binary.absolute()
|
||
|
|
||
|
tests=0
|
||
|
errors=0
|
||
|
|
||
|
for test in args.tests:
|
||
|
with open(test, 'r') as file:
|
||
|
testsuite = [TestCase(**testcase) for testcase in yaml.safe_load(file)]
|
||
|
print(f"\033[6m## \033[0m\033[34m{test}\033[97m")
|
||
|
for testcase in testsuite:
|
||
|
tests += 1
|
||
|
input = testcase.input
|
||
|
if (testcase.file):
|
||
|
with open(testcase.file, 'r') as file:
|
||
|
input = file.read()
|
||
|
actual = run_shell(binary_path, input)
|
||
|
expected = run_shell("dash", input)
|
||
|
try:
|
||
|
perform_check(expected, actual)
|
||
|
except AssertionError as e:
|
||
|
print(f"\033[1m[ \033[31mKO\033[97m ] \033[0m{testcase.name}\n{e}")
|
||
|
errors += 1
|
||
|
else:
|
||
|
print(f"\033[1m[ \033[92mOK\033[97m ] \033[0m{testcase.name}")
|
||
|
print("")
|
||
|
|
||
|
if (errors > 1):
|
||
|
s = 's'
|
||
|
else:
|
||
|
s = ''
|
||
|
print(f"\n\033[33m✗ \033[34m{tests}\033[97m tests performed, \033[31m{errors}\033[97m error{s}\033[0m")
|
||
|
exit(errors)
|