2021-06-16 04:43:57 +08:00
|
|
|
#!python
|
|
|
|
## Copyright (c) 2020-2021 Thakee Nathees
|
|
|
|
## Distributed Under The MIT License
|
|
|
|
|
|
|
|
import os, sys, platform
|
|
|
|
import subprocess, json, re
|
2021-06-20 08:49:35 +08:00
|
|
|
from os.path import join, abspath, dirname, relpath
|
2021-06-10 07:35:14 +08:00
|
|
|
|
2021-06-23 12:21:58 +08:00
|
|
|
## TODO: Re-write this in doctest (https://github.com/onqtam/doctest)
|
2021-06-10 07:35:14 +08:00
|
|
|
|
2021-06-16 12:41:36 +08:00
|
|
|
## The absolute path of this file, when run as a script.
|
|
|
|
## This file is not intended to be included in other files at the moment.
|
2021-06-20 08:49:35 +08:00
|
|
|
THIS_PATH = abspath(dirname(__file__))
|
2021-06-16 12:41:36 +08:00
|
|
|
|
2021-06-10 07:35:14 +08:00
|
|
|
## All the test files.
|
2021-06-16 04:43:57 +08:00
|
|
|
TEST_SUITE = {
|
|
|
|
"Unit Tests": (
|
|
|
|
"lang/basics.pk",
|
2021-06-20 23:28:31 +08:00
|
|
|
"lang/class.pk",
|
2021-06-16 04:43:57 +08:00
|
|
|
"lang/core.pk",
|
|
|
|
"lang/controlflow.pk",
|
|
|
|
"lang/fibers.pk",
|
|
|
|
"lang/functions.pk",
|
|
|
|
"lang/import.pk",
|
|
|
|
),
|
|
|
|
|
|
|
|
"Examples": (
|
|
|
|
"examples/brainfuck.pk",
|
|
|
|
"examples/fib.pk",
|
|
|
|
"examples/fizzbuzz.pk",
|
|
|
|
"examples/helloworld.pk",
|
|
|
|
"examples/pi.pk",
|
|
|
|
"examples/prime.pk",
|
|
|
|
),
|
2021-06-10 07:35:14 +08:00
|
|
|
}
|
|
|
|
|
2021-06-16 12:41:36 +08:00
|
|
|
## Map from systems to the relative binary path
|
|
|
|
SYSTEM_TO_BINARY_PATH = {
|
|
|
|
"Windows": "..\\build\\debug\\bin\\pocket.exe",
|
|
|
|
"Linux": "../build/debug/pocket",
|
|
|
|
"Darwin": "../build/debug/pocket",
|
|
|
|
}
|
|
|
|
|
2021-06-16 04:43:57 +08:00
|
|
|
## This global variable will be set to true if any test failed.
|
|
|
|
tests_failed = False
|
2021-06-18 12:42:57 +08:00
|
|
|
|
2021-06-10 07:35:14 +08:00
|
|
|
def main():
|
2021-06-16 04:43:57 +08:00
|
|
|
|
2021-06-18 12:42:57 +08:00
|
|
|
## This will enable ANSI codes in windows terminal.
|
2021-06-16 04:43:57 +08:00
|
|
|
os.system('')
|
|
|
|
|
2021-06-10 07:35:14 +08:00
|
|
|
run_all_tests()
|
2021-06-16 04:43:57 +08:00
|
|
|
if tests_failed:
|
|
|
|
sys.exit(1)
|
2021-06-10 07:35:14 +08:00
|
|
|
|
|
|
|
def run_all_tests():
|
2021-06-16 04:43:57 +08:00
|
|
|
## get the interpreter.
|
|
|
|
pocket = get_pocket_binary()
|
2021-06-10 07:35:14 +08:00
|
|
|
|
2021-06-16 04:43:57 +08:00
|
|
|
for suite in TEST_SUITE:
|
|
|
|
print_title(suite)
|
2021-06-16 12:41:36 +08:00
|
|
|
for test in TEST_SUITE[suite]:
|
2021-06-18 12:42:57 +08:00
|
|
|
path = join(THIS_PATH, test)
|
2021-06-16 12:41:36 +08:00
|
|
|
run_test_file(pocket, test, path)
|
2021-06-16 04:43:57 +08:00
|
|
|
|
2021-06-16 12:41:36 +08:00
|
|
|
def run_test_file(pocket, test, path):
|
2021-06-10 07:35:14 +08:00
|
|
|
FMT_PATH = "%-25s"
|
2021-06-16 04:43:57 +08:00
|
|
|
INDENTATION = ' | '
|
2021-06-16 12:41:36 +08:00
|
|
|
print(FMT_PATH % test, end='')
|
2021-06-16 04:43:57 +08:00
|
|
|
|
|
|
|
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')
|
2021-06-10 07:35:14 +08:00
|
|
|
|
2021-06-16 04:43:57 +08:00
|
|
|
## 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()
|
2021-06-16 12:41:36 +08:00
|
|
|
if system not in SYSTEM_TO_BINARY_PATH:
|
2021-06-16 04:43:57 +08:00
|
|
|
error_exit("Unsupported platform %s" % system)
|
2021-06-16 12:41:36 +08:00
|
|
|
|
2021-06-18 12:42:57 +08:00
|
|
|
pocket = abspath(join(THIS_PATH, SYSTEM_TO_BINARY_PATH[system]))
|
2021-06-16 04:43:57 +08:00
|
|
|
if not os.path.exists(pocket):
|
|
|
|
error_exit("Pocket interpreter not found at: '%s'" % pocket)
|
2021-06-16 12:41:36 +08:00
|
|
|
|
2021-06-16 04:43:57 +08:00
|
|
|
return pocket
|
2021-06-10 07:35:14 +08:00
|
|
|
|
|
|
|
def run_command(command):
|
|
|
|
return subprocess.run(command,
|
2021-06-18 12:42:57 +08:00
|
|
|
stdout=subprocess.PIPE,
|
|
|
|
stderr=subprocess.PIPE)
|
2021-06-10 07:35:14 +08:00
|
|
|
|
2021-06-16 04:43:57 +08:00
|
|
|
## ----------------------------------------------------------------------------
|
|
|
|
|
|
|
|
## ANSI color codes to print messages.
|
|
|
|
COLORS = {
|
|
|
|
'GREEN' : '\u001b[32m',
|
|
|
|
'YELLOW' : '\033[93m',
|
|
|
|
'RED' : '\u001b[31m',
|
|
|
|
'UNDERLINE' : '\033[4m' ,
|
|
|
|
'END' : '\033[0m' ,
|
|
|
|
}
|
|
|
|
|
2021-06-23 12:21:58 +08:00
|
|
|
## All tests messages are written to stdout because they're mixed
|
2021-06-16 06:06:02 +08:00
|
|
|
## 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.
|
|
|
|
|
2021-06-16 04:43:57 +08:00
|
|
|
## prints an error to stderr and continue tests.
|
|
|
|
def print_error(msg):
|
|
|
|
global tests_failed
|
|
|
|
tests_failed = True
|
2021-06-16 06:06:02 +08:00
|
|
|
for line in msg.splitlines():
|
|
|
|
print(COLORS['RED'] + line + COLORS['END'])
|
2021-06-16 04:43:57 +08:00
|
|
|
|
|
|
|
## print success message to stdout.
|
|
|
|
def print_success(msg):
|
2021-06-16 06:06:02 +08:00
|
|
|
for line in msg.splitlines():
|
|
|
|
print(COLORS['GREEN'] + line + COLORS['END'])
|
2021-06-16 04:43:57 +08:00
|
|
|
|
|
|
|
## prints an error message to stderr and exit
|
|
|
|
## immediately.
|
|
|
|
def error_exit(msg):
|
|
|
|
print("Error:", msg, file=sys.stderr)
|
|
|
|
sys.exit(1)
|
|
|
|
|
2021-06-10 07:35:14 +08:00
|
|
|
def print_title(title):
|
2021-06-16 04:43:57 +08:00
|
|
|
print("----------------------------------")
|
2021-06-10 07:35:14 +08:00
|
|
|
print(" %s " % title)
|
2021-06-16 04:43:57 +08:00
|
|
|
print("----------------------------------")
|
2021-06-10 07:35:14 +08:00
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
main()
|