From 1e5438452a878beab3fcefd42671f3a69731fe03 Mon Sep 17 00:00:00 2001 From: Mateusz Masiarz Date: Thu, 12 Dec 2024 18:37:06 +0100 Subject: [PATCH] Add oicompare like comparing --- src/sinol_make/helpers/oicompare.py | 58 ++++++++++++++++++++++++++++ src/sinol_make/task_type/__init__.py | 2 +- src/sinol_make/util.py | 9 ----- tests/helpers/test_oicompare.py | 31 +++++++++++++++ tests/test_util.py | 28 -------------- 5 files changed, 90 insertions(+), 38 deletions(-) create mode 100644 tests/helpers/test_oicompare.py diff --git a/src/sinol_make/helpers/oicompare.py b/src/sinol_make/helpers/oicompare.py index aaea3d72..eec098cf 100644 --- a/src/sinol_make/helpers/oicompare.py +++ b/src/sinol_make/helpers/oicompare.py @@ -1,4 +1,5 @@ import os +import re import requests import subprocess @@ -57,3 +58,60 @@ def check_and_download(): download_oicomapare() if not check_installed(): util.exit_with_error("Couldn't download oicompare. Please try again later or download it manually.") + + +def _strip(s: str) -> str: + """ + Replace all longest sequences of spaces with a single space. + """ + return re.sub(r'[\s\0]+', ' ', s).strip() + + +def compare(file1_path: str, file2_path: str) -> bool: + """ + Compare two files in the same way as oicompare does. Returns True if the files are the same, False otherwise. + """ + print("start") + with open(file1_path, "r") as file1, open(file2_path, "r") as file2: + eof1 = False + eof2 = False + while True: + try: + line1 = _strip(next(file1)) + except StopIteration: + eof1 = True + try: + line2 = _strip(next(file2)) + except StopIteration: + eof2 = True + + print(eof1, eof2) + if eof1 and eof2: + return True + if eof1: + while line2 == "": + try: + line2 = _strip(next(file2)) + except StopIteration: + eof2 = True + print("xd") + break + elif eof2: + while line1 == "": + try: + line1 = _strip(next(file1)) + except StopIteration: + eof1 = True + break + if line1 != "": + break + + if eof1 and eof2: + return True + # print(f'"{line1}" "{line2}" {eof1=} {eof2=}') + if (eof1 and line2 == "") or (eof2 and line1 == ""): + continue + if (eof1 and line2 != "") or (eof2 and line1 != ""): + return False + if line1 != line2: + return False diff --git a/src/sinol_make/task_type/__init__.py b/src/sinol_make/task_type/__init__.py index ca02a86c..428be58c 100644 --- a/src/sinol_make/task_type/__init__.py +++ b/src/sinol_make/task_type/__init__.py @@ -156,7 +156,7 @@ def _run_checker(self, input_file_path, output_file_path, answer_file_path) -> T return self._parse_checker_output(output.decode('utf-8').split('\n')) def _run_diff(self, output_file_path, answer_file_path) -> Tuple[bool, Fraction, str]: - same = util.file_diff(output_file_path, answer_file_path) + same = oicompare.compare(output_file_path, answer_file_path) if same: return True, Fraction(100, 1), "" else: diff --git a/src/sinol_make/util.py b/src/sinol_make/util.py index 6f330a45..3bc2cf90 100644 --- a/src/sinol_make/util.py +++ b/src/sinol_make/util.py @@ -246,15 +246,6 @@ def lines_diff(lines1, lines2): return True -def file_diff(file1_path, file2_path): - """ - Function to compare two files. - Returns True if they are the same, False otherwise. - """ - with open(file1_path) as file1, open(file2_path) as file2: - return lines_diff(file1.readlines(), file2.readlines()) - - def get_terminal_size(): """ Function to get the size of the terminal. diff --git a/tests/helpers/test_oicompare.py b/tests/helpers/test_oicompare.py new file mode 100644 index 00000000..7171551d --- /dev/null +++ b/tests/helpers/test_oicompare.py @@ -0,0 +1,31 @@ +import tempfile + +from sinol_make.helpers import oicompare + + +def test_oicompare(): + with tempfile.TemporaryDirectory() as tmpdir: + tests = [ + ("", "", True), + ("ABC", "ABC", True), + ("ABC\nDEF\n", "ABC\nDEF\n", True), + ("A B C D E", "A B\tC\0D\tE", True), + ("A B", "\0\tA \0 \0B\t\t", True), + ("A\nB\nC", "A\nB\nC\n\n\n\n\n\n\n", True), + ("A\n\n\n\n", "A\n\n\n\n\n\n\n\n\n\n", True), + ("", "ABC", False), + ("YES", "NO", False), + ("A B", "A\nB", False), + ] + + for i, (file1, file2, expected) in enumerate(tests): + with open(tmpdir + f"/file1_{i}.txt", "w") as f1, open(tmpdir + f"/file2_{i}.txt", "w") as f2: + f1.write(file1) + f2.write(file2) + assert oicompare.compare(tmpdir + f"/file1_{i}.txt", tmpdir + f"/file2_{i}.txt") == expected, f"Test {i} failed" + + for i, (file2, file1, expected) in enumerate(tests): + with open(tmpdir + f"/file1_{i}.txt", "w") as f1, open(tmpdir + f"/file2_{i}.txt", "w") as f2: + f1.write(file1) + f2.write(file2) + assert oicompare.compare(tmpdir + f"/file1_{i}.txt", tmpdir + f"/file2_{i}.txt") == expected, f"Swapped test {i} failed" diff --git a/tests/test_util.py b/tests/test_util.py index 3d259fab..f871d92e 100644 --- a/tests/test_util.py +++ b/tests/test_util.py @@ -14,34 +14,6 @@ from sinol_make.helpers import paths from tests import util as test_util from tests.fixtures import create_package -from tests.commands.run import util as run_util - - -def test_file_diff(): - with tempfile.TemporaryDirectory() as tmpdir: - a_file = os.path.join(tmpdir, 'a') - b_file = os.path.join(tmpdir, 'b') - - open(a_file, 'w').write("1" - "2" - "3") - - open(b_file, 'w').write("1" - "2" - "3" - "4") - - assert util.file_diff(a_file, b_file) is False - - open(a_file, 'w').write("1\n") - open(b_file, 'w').write("1 ") - - assert util.file_diff(a_file, b_file) is True - - open(a_file, 'w').write("1\n") - open(b_file, 'w').write("1\n\n") - - assert util.file_diff(a_file, b_file) is False @requests_mock.Mocker(kw="mocker")