161 lines
4.1 KiB
Python
Executable file
161 lines
4.1 KiB
Python
Executable file
#!/usr/bin/env python3
|
|
|
|
import time;
|
|
import subprocess
|
|
import shlex as sl;
|
|
import argparse
|
|
import json;
|
|
|
|
class colors:
|
|
red = "\033[38;2;200;20;0m";
|
|
orange = "\033[38;2;200;150;0m";
|
|
yellow = "\033[38;2;200;200;0m";
|
|
green = "\033[38;2;0;200;0m";
|
|
reset = "\033[0m";
|
|
|
|
def parse_args():
|
|
parser = argparse.ArgumentParser(prog='ProgramName', description='What the program does', epilog='Text at the bottom of help')
|
|
|
|
parser.add_argument('-n', '--new', "-t", "--touch")
|
|
parser.add_argument('-s', '--save')
|
|
parser.add_argument('-c', '--correct', action='store_true')
|
|
parser.add_argument('-d', '--delete')
|
|
|
|
parser.add_argument('--config', default="tests.json")
|
|
|
|
return parser.parse_args();
|
|
|
|
def load_database(path):
|
|
try:
|
|
with open(path) as stream:
|
|
return json.load(stream);
|
|
except FileNotFoundError:
|
|
return dict();
|
|
|
|
def save_database(path, tests):
|
|
with open(path, "w") as stream:
|
|
json.dump(tests, stream, sort_keys=True, indent=2);
|
|
|
|
def new_test(new_input, database):
|
|
if new_input in database:
|
|
line = colors.orange + \
|
|
f"test.py: " + \
|
|
f"{sl.quote(new_input)} already in database. " + \
|
|
f"It has been moved to the front of the line. " + \
|
|
colors.reset;
|
|
|
|
print(line);
|
|
|
|
database[new_input]['ftime'] = time.time();
|
|
else:
|
|
database[new_input] = {
|
|
'output': "???",
|
|
'exit': 0,
|
|
};
|
|
|
|
def save_test(input_, database):
|
|
result = subprocess.run(["./bin/qc", "-c", input_],
|
|
text = True, check = False, capture_output = True);
|
|
|
|
line = colors.orange + \
|
|
f"test.py: " + \
|
|
f"re-ran and saved result of {sl.quote(input_)}" + \
|
|
colors.reset;
|
|
|
|
print(line);
|
|
|
|
database[input_] = {
|
|
'output': result.stdout,
|
|
'exit': result.returncode,
|
|
}
|
|
|
|
def correct_test(database):
|
|
input_ = max(database.items(), key = lambda kv: kv[1]['ftime'])[0];
|
|
|
|
save_test(input_, database);
|
|
|
|
def delete_test(input_, database):
|
|
if input_ in database:
|
|
line = colors.orange + \
|
|
f"test.py: " + \
|
|
f"deleted test {sl.quote(input_)}" + \
|
|
colors.reset;
|
|
|
|
print(line);
|
|
|
|
del database[input_];
|
|
else:
|
|
line = colors.red + \
|
|
f"test.py: " + \
|
|
f"no test found for {sl.quote(input_)}" + \
|
|
colors.reset;
|
|
|
|
print(line);
|
|
|
|
def run_tests(tests):
|
|
for _, test in sorted(tests.items()):
|
|
if 'ftime' not in test:
|
|
test['ftime'] = time.time();
|
|
|
|
tests = sorted(tests.items(), key = lambda kv: kv[1]['ftime'], reverse = True);
|
|
|
|
all_passed = True;
|
|
|
|
for i, (input_, test) in enumerate(tests):
|
|
line = f"[{i:2}/{len(tests)}] "
|
|
|
|
line += colors.yellow + f"$ ./bin/qc -c {sl.quote(input_)}" + colors.reset;
|
|
|
|
print(line);
|
|
|
|
result = subprocess.run(["./bin/qc", "-c", input_],
|
|
text = True, check = False, capture_output = True);
|
|
|
|
passed = True;
|
|
|
|
if test['output'] != result.stdout:
|
|
print("incorrect output");
|
|
print(f"expected: {test['output']}");
|
|
print(f"received:")
|
|
print(f"{result.stdout.strip()}");
|
|
print(f"received:");
|
|
print(f"{result.stderr.strip()}");
|
|
passed = False;
|
|
|
|
if result.returncode != test.get('exit', 0):
|
|
print("incorrect exit code");
|
|
passed = False;
|
|
|
|
if not passed:
|
|
test['ftime'] = time.time();
|
|
all_passed = False;
|
|
break;
|
|
|
|
if all_passed:
|
|
print(colors.green + f"all tests pass!" + colors.reset);
|
|
return 0;
|
|
else:
|
|
return 1;
|
|
|
|
def main(args):
|
|
retval = 0
|
|
|
|
database = load_database(args.config);
|
|
|
|
if (args.new):
|
|
new_test(args.new, database);
|
|
elif (args.save):
|
|
save_test(args.save, database);
|
|
elif (args.correct):
|
|
correct_test(database);
|
|
elif (args.delete):
|
|
delete_test(args.delete, database);
|
|
else:
|
|
retval = run_tests(database);
|
|
|
|
save_database(args.config, database);
|
|
|
|
return retval;
|
|
|
|
exit(main(parse_args()));
|
|
|