import argparse
import logging.config
import os
import json
import subprocess
import logging
import sys
import re
from common_output import get_common_output, remove_common_part
def ensure_exists(path):
if not os.path.exists(path):
raise RuntimeError(f'The file {path} cannot be found')
def es2panda_command(es2panda_path, stdlib_path, config_path, file_path):
return [
*str(es2panda_path).split(),
'--stdlib', stdlib_path,
'--arktsconfig', config_path,
file_path
]
def normalize_output_file_paths(text):
if not text:
return text
path_pattern = r'(?:[a-zA-Z]:)?(?:[\\/][^\\/:\s]+)+(?:[\\/][^\\/:\s]+)*'
def replace_absolute_path(match):
path = match.group(0)
filename = os.path.basename(path)
if os.path.isabs(path) or ':' in path:
return f"[ABS_PATH]/{filename}"
return path
normalized = re.sub(path_pattern, replace_absolute_path, text)
return normalized
def normalize_output(actual_output, common_outputs, part_name):
result = normalize_output_file_paths(actual_output)
result = remove_common_part(result, common_outputs, part_name)
return result
def compare_test_output(lhs, rhs, ignore_parts):
if lhs.returncode != rhs.get("returncode", 0):
raise RuntimeError(f"Return code mismatch: expected {rhs.get('returncode', 0)}, got {lhs.returncode}")
if "stdout" in rhs:
normalized_stdout = normalize_output(lhs.stdout, ignore_parts, "stdout")
expected_stdout = rhs["stdout"]
if normalized_stdout != expected_stdout:
message = [
"Stdout mismatch:",
f"Expected: {repr(expected_stdout)}",
f"Got: {repr(normalized_stdout)}",
"",
"Raw stdout for debugging:",
f"{repr(lhs.stdout)}"
]
raise RuntimeError("\n".join(message))
if "stderr" in rhs:
normalized_stderr = normalize_output(lhs.stderr, ignore_parts, "stderr")
if normalized_stderr != rhs["stderr"]:
raise RuntimeError(f"Stderr mismatch\nExpected: {rhs['stderr']}\nGot: {normalized_stderr}")
parser = argparse.ArgumentParser()
parser.add_argument('--es2panda', required=True,
help='Path to es2panda executable, could be prefixed')
parser.add_argument('--config', required=True, help='Path to project config')
parser.add_argument('--stdlib', required=True, help='Path to es2panda stdlib')
parser.add_argument('--filepath', required=True, help='Path to ets file')
args = parser.parse_args()
project_dir = os.path.dirname(args.config)
expected_path = os.path.join(project_dir, 'expected.json')
[ensure_exists(f) for f in [
str(args.es2panda).split()[-1], args.config, expected_path]]
cmd = es2panda_command(args.es2panda, args.stdlib, args.config, args.filepath)
actual = subprocess.run(cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
encoding='utf-8')
with open(expected_path, "r", encoding="utf-8") as expected_file:
expected = json.load(expected_file)
common_parts = get_common_output(expected_path)
compare_test_output(actual, expected, common_parts)