187 lines
6 KiB
Python
Executable file
187 lines
6 KiB
Python
Executable file
#!/usr/bin/env python3
|
||
"""
|
||
run_tests.py - Запуск русских тестов для rusi
|
||
"""
|
||
|
||
import os
|
||
import sys
|
||
import csv
|
||
import subprocess
|
||
from pathlib import Path
|
||
|
||
RUSI = "./rusi.elf"
|
||
TEST_DIR = Path(__file__).parent
|
||
|
||
GREEN = "\033[92m"
|
||
RED = "\033[91m"
|
||
YELLOW = "\033[93m"
|
||
BLUE = "\033[94m"
|
||
RESET = "\033[0m"
|
||
BOLD = "\033[1m"
|
||
|
||
|
||
def print_header(text):
|
||
print(f"\n{BOLD}{BLUE}{'='*60}{RESET}")
|
||
print(f"{BOLD}{BLUE}{text:^60}{RESET}")
|
||
print(f"{BOLD}{BLUE}{'='*60}{RESET}")
|
||
|
||
|
||
def load_tests():
|
||
csv_file = TEST_DIR / "test_ru.csv"
|
||
tests = []
|
||
|
||
if not csv_file.exists():
|
||
for f in sorted(TEST_DIR.glob("*.c")):
|
||
tests.append({
|
||
"номер": f.stem.split('_')[0] if '_' in f.stem else "??",
|
||
"тест": f.stem,
|
||
"описание": "Без описания",
|
||
"ожидаемый_код": None,
|
||
"файл": f
|
||
})
|
||
return tests
|
||
|
||
with open(csv_file, 'r', encoding='utf-8-sig') as f:
|
||
reader = csv.DictReader(f)
|
||
for row in reader:
|
||
test_name = row['Тест'].strip()
|
||
test_file = TEST_DIR / f"{test_name}.c"
|
||
if test_file.exists():
|
||
try:
|
||
expected = int(str(row['Ожидаемый_код']).strip())
|
||
except (ValueError, KeyError):
|
||
expected = None
|
||
|
||
tests.append({
|
||
"номер": row['Номер'].strip(),
|
||
"тест": test_name,
|
||
"описание": row['Описание'].strip(),
|
||
"ожидаемый_код": expected,
|
||
"файл": test_file
|
||
})
|
||
|
||
return tests
|
||
|
||
|
||
def compile_test(test_name, test_file):
|
||
exe_file = TEST_DIR / test_name
|
||
|
||
if not os.path.exists(RUSI):
|
||
return False, f"rusi не найден: {RUSI}"
|
||
|
||
cmd = [RUSI, "-o", str(exe_file), str(test_file)]
|
||
result = subprocess.run(cmd, capture_output=True, text=True)
|
||
|
||
if result.returncode != 0:
|
||
return False, result.stderr
|
||
|
||
return True, str(exe_file)
|
||
|
||
|
||
def run_test(exe_file):
|
||
result = subprocess.run([exe_file], capture_output=True, text=True)
|
||
return result.returncode, result.stdout, result.stderr
|
||
|
||
|
||
def main():
|
||
import argparse
|
||
|
||
parser = argparse.ArgumentParser()
|
||
parser.add_argument("--keep", "-k", action="store_true")
|
||
parser.add_argument("--verbose", "-v", action="store_true")
|
||
parser.add_argument("--test", "-t")
|
||
args = parser.parse_args()
|
||
|
||
print_header("ЗАПУСК РУССКИХ ТЕСТОВ ДЛЯ RUSI")
|
||
|
||
tests = load_tests()
|
||
|
||
if args.test:
|
||
tests = [t for t in tests if t["тест"] == args.test or t["номер"] == args.test]
|
||
if not tests:
|
||
print(f"{RED}ОШИБКА: Тест '{args.test}' не найден{RESET}")
|
||
sys.exit(1)
|
||
|
||
if not tests:
|
||
print(f"{YELLOW}ВНИМАНИЕ: Тесты не найдены{RESET}")
|
||
sys.exit(0)
|
||
|
||
print(f"\nНайдено тестов: {len(tests)}")
|
||
print(f"Компилятор: {RUSI}")
|
||
print(f"Папка тестов: {TEST_DIR}")
|
||
print()
|
||
|
||
passed = 0
|
||
failed = 0
|
||
results = []
|
||
|
||
for test in tests:
|
||
test_name = test["тест"]
|
||
test_file = test["файл"]
|
||
expected = test["ожидаемый_код"]
|
||
exe_file = TEST_DIR / test_name
|
||
|
||
ok, result = compile_test(test_name, test_file)
|
||
|
||
if not ok:
|
||
print(f" {RED}✗{RESET} {test_name:<20} Ошибка компиляции")
|
||
if args.verbose:
|
||
print(f" {result}")
|
||
failed += 1
|
||
results.append((test_name, False, "compile_error", None))
|
||
continue
|
||
|
||
code, stdout, stderr = run_test(str(exe_file))
|
||
|
||
if expected is not None:
|
||
if code == expected:
|
||
print(f" {GREEN}✓{RESET} {test_name:<20} ожидалось {expected}, получено {code}")
|
||
passed += 1
|
||
results.append((test_name, True, "пройден", code))
|
||
else:
|
||
print(f" {RED}✗{RESET} {test_name:<20} ожидалось {expected}, получено {code}")
|
||
if args.verbose:
|
||
if stdout:
|
||
print(f" Вывод: {stdout.strip()}")
|
||
if stderr:
|
||
print(f" Ошибки: {stderr.strip()}")
|
||
failed += 1
|
||
results.append((test_name, False, f"expected_{expected}_got_{code}", code))
|
||
else:
|
||
if code == 0:
|
||
print(f" {GREEN}✓{RESET} {test_name:<20} завершился успешно (код {code})")
|
||
passed += 1
|
||
results.append((test_name, True, "пройден", code))
|
||
else:
|
||
print(f" {RED}✗{RESET} {test_name:<20} завершился с ошибкой (код {code})")
|
||
failed += 1
|
||
results.append((test_name, False, f"failed_with_{code}", code))
|
||
|
||
if not args.keep and exe_file.exists():
|
||
os.remove(exe_file)
|
||
|
||
print_header("РЕЗУЛЬТАТЫ ТЕСТИРОВАНИЯ")
|
||
|
||
for test_name, ok, status, code in results:
|
||
if ok:
|
||
print(f" {GREEN}✓{RESET} {test_name:<20} {status}")
|
||
else:
|
||
print(f" {RED}✗{RESET} {test_name:<20} {status}")
|
||
|
||
print(f"\n{BOLD}Итого:{RESET}")
|
||
print(f" {GREEN}Пройдено:{RESET} {passed}")
|
||
print(f" {RED}Провалено:{RESET} {failed}")
|
||
print(f" {BOLD}Всего:{RESET} {len(tests)}")
|
||
|
||
if args.keep:
|
||
print(f"\n{YELLOW}Бинарники сохранены в {TEST_DIR}{RESET}")
|
||
|
||
if failed > 0:
|
||
sys.exit(1)
|
||
else:
|
||
print(f"\n{GREEN}{BOLD}🎉 Все тесты пройдены!{RESET}")
|
||
sys.exit(0)
|
||
|
||
|
||
if __name__ == "__main__":
|
||
main() |