added testing

This commit is contained in:
Zander Thannhauser 2025-08-17 22:22:09 -05:00
parent 2ae1f3e967
commit aeb52829d0
3 changed files with 1788 additions and 3 deletions

13
main.c
View file

@ -3205,11 +3205,24 @@ int main(int argc, char* const* argv)
struct expression* expression = parse(line);
if (expression->kind == ek_syntax_error)
{
printf("syntax error!\n");
printf("%s\n", line);
syntax_error_print(expression);
retval = 1;
}
else
{
struct value* value = evaluate(expression, scope);
print(value);
free_value(value);
}
free_expression(expression);
}

145
test.py Executable file
View file

@ -0,0 +1,145 @@
#!/usr/bin/env python3
import time;
import subprocess
import shlex as sl;
import argparse
import json;
class colors:
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('--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(args, database):
assert(not "TODO");
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):
assert(not "TODO");
else:
retval = run_tests(database);
save_database(args.config, database);
return retval;
exit(main(parse_args()));

1627
tests.json Normal file

File diff suppressed because it is too large Load diff