import os
import subprocess
import sys
+import shlex
-# TODO: Harcoded
-COMPILER="/home/momoyon/Programming/python/lang/lang"
-TESTS_DIR="./tests/"
-SUFFIX=".momo"
+# TODO: Use Colored logging
+## Substitutable values; These values are substituted with the following values if found in BUILD_CMD or RUN_CMD
-# TODO: Use Colored logging
+# - {test_name} - name of the test.
+# - {src_suffix} - suffix of the source files. (excluding the .)
+
+# BUILD_CMD will be the command run when the `build` subcommand is ran.
+BUILD_CMD="NOT SET"
+# Same as the BUILD_CMD but run when the `run` command is ran.
+RUN_CMD="NOT SET"
+# The name of the directory all the tests live in. (Will chdir to this)
+TESTS_DIR="NOT SET"
+# Suffix of the source files the build command iw (if there is a . prefix, it will be removed
+SRC_SUFFIX="NOT SET"
+
+def get_env_variables():
+ global BUILD_CMD, RUN_CMD, TESTS_DIR, SRC_SUFFIX
+ BUILD_CMD = os.environ["BUILD_CMD"] if "BUILD_CMD" in os.environ else "NOT SET"
+ RUN_CMD = os.environ["RUN_CMD"] if "RUN_CMD" in os.environ else "NOT SET"
+ TESTS_DIR = os.environ["TESTS_DIR"] if "TESTS_DIR" in os.environ else "NOT SET"
+ SRC_SUFFIX = os.environ["SRC_SUFFIX"] if "SRC_SUFFIX" in os.environ else "NOT SET"
+ SRC_SUFFIX = SRC_SUFFIX.removeprefix(".")
+ # SRC_SUFFIX = os.environ["SRC_SUFFIX"] if "SRC_SUFFIXsuffix" in os.environ else "NOT SET"
+
+
+def get_cmd_substituted(cmd, tests, current_test):
+ assert current_test in tests, "The test that you passed is not in the tests map!"
+ cmd = cmd.replace("{test_name}", tests[current_test].name)
+ cmd = cmd.replace("{src_suffix}", SRC_SUFFIX)
+
+ return cmd
+
+def check_crucial_envvar(var, var_name):
+ if var == "NOT SET":
+ print(f"[ERROR] `{var_name}` environment variable not set! please provide a value and run again!", file=sys.stderr)
+ exit(1)
class Test:
stdin = ''
f = self.get_expected_filename(name)
if not os.path.exists(f):
with open(f, "w") as file:
- print(f"[INFO] Created empty {self.name}.{name}.expected")
+ pass
+ # NOTE: Why do we need to log this?
+ # print(f"[INFO] Created empty {self.name}.{name}.expected")
return ""
else:
with open(f, "r") as file:
build_input_array.pop(i)
return build_input_array
+ def get_stdin_list(self):
+ input_array = self.stdin.split(sep=' ')
+ for i in range(len(input_array)-1, -1, -1):
+ if len(input_array[i]) <= 0:
+ input_array.pop(i)
+ return input_array
+
def usage(program: str):
print(f"Usage: {program} <subcmd> [flags]")
hhelp()
exit(1)
+ get_env_variables()
+
+ check_crucial_envvar(TESTS_DIR, "TESTS_DIR")
+ check_crucial_envvar(SRC_SUFFIX, "SRC_SUFFIX")
+
os.chdir(TESTS_DIR)
+ vlog(verbose_output, f"[INFO] Changed cwd to {os.getcwd()}")
tests = {}
for e in sorted(os.listdir(os.getcwd())):
- if not e.endswith(SUFFIX): continue
- base_name = e.removesuffix(SUFFIX)
+ if not e.endswith("." + SRC_SUFFIX): continue
+ base_name = e.removesuffix("." + SRC_SUFFIX)
if not tests.get(base_name):
tests[base_name] = Test(base_name)
+ # print(f"BUILD_CMD: {BUILD_CMD}")
+ # print(f"RUN_CMD: {RUN_CMD}")
+ # print(f"TESTS_DIR: {TESTS_DIR}")
+ # print(f"SRC_SUFFIX: {SRC_SUFFIX}")
+
for subcmd in subcmds:
total_tests_count = len(tests)
current_test_id = 0
hhelp()
exit(0)
elif subcmd == "build":
+ check_crucial_envvar(BUILD_CMD, "BUILD_CMD")
print(f'----- [BUILD] -----')
for test_name in tests:
print(f'+ Building {test_name} [{current_test_id+1}/{total_tests_count}]...')
if stop_on_error: exit(1)
continue
- cmd = [COMPILER, f"{test_name}{SUFFIX}"]
+ cmd = shlex.split(get_cmd_substituted(BUILD_CMD, tests, test_name))
build_stdin_list = test.get_build_stdin_list()
if len(build_stdin_list) > 0: cmd.extend(build_stdin_list)
vlog(verbose_output, f"[CMD] {cmd}")
print(f"Build {passing_tests_count}/{total_tests_count} tests")
elif subcmd == "run":
- assert False, "'run' Subcommand is not fully tested!"
+ check_crucial_envvar(RUN_CMD, "RUN_CMD")
print(f'----- [RUN] -----')
for test_name in tests:
print(f'+ Running {test_name} [{current_test_id+1}/{total_tests_count}]...')
res = None
try:
- cmd = [f"./{test_name}"]
+ cmd = shlex.split(get_cmd_substituted(RUN_CMD, tests, test_name))
vlog(verbose_output, f"[CMD] {cmd}")
res = subprocess.run(cmd, capture_output = True, text = True)
except Exception as e:
print(f"PASSED {passing_tests_count}/{total_tests_count}")
elif subcmd == "record":
- assert False, "'record' Subcommand is not fully tested!"
+ check_crucial_envvar(RUN_CMD, "RUN_CMD")
print(f'----- [RECORD] -----')
for test_name in tests:
print(f"+ Recording expected behaviour for '{test_name}'...")
test = tests[test_name]
+ cmd = shlex.split(get_cmd_substituted(RUN_CMD, tests, test_name))
+ stdin_list = test.get_stdin_list()
+ if len(stdin_list) > 0: cmd.extend(stdin_list)
+ vlog(verbose_output, f"[CMD] {cmd}")
res = subprocess.run([f"./{test_name}"], capture_output = True, text = True)
print(f"stdout: {res.stdout}")
else:
print('[SKIP]')
elif subcmd == "record_build":
+ check_crucial_envvar(BUILD_CMD, "BUILD_CMD")
print(f'----- [RECORD_BUILD] -----')
for test_name in tests:
print(f"+ Recording expected build behaviour for '{test_name}'...")
ans = input("Do you want to change the build_input? [y/N]")
if ans.lower() == 'y':
test.build_stdin = input("What is the input passed? ")
+ else:
+ print("[SKIPPING]...")
+ continue
else:
test.build_stdin = input("What is the input passed? ")
-
- cmd = [COMPILER, f"{test_name}{SUFFIX}"]
+ cmd = shlex.split(get_cmd_substituted(BUILD_CMD, tests, test_name))
build_stdin_list = test.get_build_stdin_list()
if len(build_stdin_list) > 0: cmd.extend(build_stdin_list)
vlog(verbose_output, f"[CMD] {cmd}")