pocketlang/scripts/run_tests.py
2022-05-01 14:12:27 +05:30

148 lines
3.8 KiB
Python

#!python
## Copyright (c) 2020-2021 Thakee Nathees
## Copyright (c) 2021-2022 Pocketlang Contributors
## Distributed Under The MIT License
import os, sys, platform
import subprocess, json, re
from os.path import (join, abspath, dirname,
relpath, exists)
## TODO: Re-write this in doctest (https://github.com/onqtam/doctest)
## Pocket lang root directory.
ROOT_PATH = abspath(join(dirname(__file__), ".."))
## Output debug cli executable path relative to root.
POCKET_BINARY = "build/Debug/bin/pocket"
## All the test files, relative to root/tests/ directory.
TEST_SUITE = {
"Unit Tests": (
"lang/basics.pk",
"lang/builtin_fn.pk",
"lang/class.pk",
"lang/closure.pk",
"lang/core.pk",
"lang/controlflow.pk",
"lang/fibers.pk",
"lang/functions.pk",
"lang/import.pk",
),
"Modules Test" : (
"modules/dummy.pk",
"modules/math.pk",
),
"Random Scripts" : (
"random/linked_list.pk",
"random/lisp_eval.pk",
"random/string_algo.pk",
),
"Examples": (
"examples/brainfuck.pk",
"examples/fib.pk",
"examples/fizzbuzz.pk",
"examples/helloworld.pk",
"examples/matrix.pk",
"examples/pi.pk",
"examples/prime.pk",
),
}
## This global variable will be set to true if any test failed.
tests_failed = False
def main():
run_all_tests()
if tests_failed:
sys.exit(1)
def run_all_tests():
## get the interpreter.
pocket = get_pocket_binary()
for suite in TEST_SUITE:
print_title(suite)
for test in TEST_SUITE[suite]:
path = join(ROOT_PATH, "tests", test)
run_test_file(pocket, test, path)
def run_test_file(pocket, test, path):
FMT_PATH = "%-25s"
INDENTATION = ' | '
print(FMT_PATH % test, end='')
sys.stdout.flush()
result = run_command([pocket, path])
if result.returncode != 0:
print_error('-- Failed')
err = INDENTATION + result.stderr \
.decode('utf8') \
.replace('\n', '\n' + INDENTATION)
print_error(err)
else:
print_success('-- PASSED')
## This will return the path of the pocket binary (on different platforms).
## The debug version of it for enabling the assertions.
def get_pocket_binary():
system = platform.system()
if system not in ("Windows", "Linux", "Darwin"):
error_exit("Unsupported platform")
binary = join(ROOT_PATH, POCKET_BINARY)
if system == "Windows": binary += ".exe"
if not exists(binary):
error_exit(f"Pocket interpreter not found at: '{binary}'")
return binary
def run_command(command):
return subprocess.run(command,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
## ----------------------------------------------------------------------------
## ANSI color codes to print messages.
COLORS = {
'GREEN' : '\u001b[32m',
'YELLOW' : '\033[93m',
'RED' : '\u001b[31m',
'UNDERLINE' : '\033[4m' ,
'END' : '\033[0m' ,
}
## All tests messages are written to stdout because they're mixed
## and github actions io calls seems asynchronous. And ANSI colors
## not seems to working with multiline in github actions, so
## printing the message line by line.
## prints an error to stderr and continue tests.
def print_error(msg):
global tests_failed
tests_failed = True
for line in msg.splitlines():
print(COLORS['RED'] + line + COLORS['END'])
## print success message to stdout.
def print_success(msg):
for line in msg.splitlines():
print(COLORS['GREEN'] + line + COLORS['END'])
## prints an error message to stderr and exit immediately.
def error_exit(msg):
print("Error:", msg, file=sys.stderr)
sys.exit(1)
def print_title(title):
print("----------------------------------")
print(" %s " % title)
print("----------------------------------")
if __name__ == '__main__':
## This will enable ANSI codes in windows terminal.
os.system('')
main()