From a047295c613419051b3791107b6e1b58817d04a0 Mon Sep 17 00:00:00 2001 From: GitBib <15717621+GitBib@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:01:43 +0300 Subject: [PATCH 1/7] Add new test cases to test_actions_track.py This commit introduces multiple test cases in test_actions_track.py which cover muxing functionality, track handling, and handling of title in MKV files. Each introduced test function validates a specific boundary case or functionality and asserts the expected behavior. --- tests/test_actions_track.py | 99 +++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) diff --git a/tests/test_actions_track.py b/tests/test_actions_track.py index b21da67..5bf5156 100644 --- a/tests/test_actions_track.py +++ b/tests/test_actions_track.py @@ -66,3 +66,102 @@ def test_move_track_front_and_mux(get_base_path: Path, get_path_test_file: Path) assert len(mkv.tracks) == 2 # noqa: PLR2004 assert mkv.tracks[0].track_type == "audio" assert mkv.tracks[1].track_type == "video" + + +def test_mux_and_test_title(get_base_path: Path, get_path_test_file: Path) -> None: + output_file = get_base_path / "file-test.mkv" + + mkv = MKVFile(get_path_test_file) + mkv.title = "Test title in mkv file" + mkv.mux(output_file) + + mkv = MKVFile(output_file) + + assert mkv.title == "Test title in mkv file" + + +def test_mux_and_test_track_name(get_base_path: Path, get_path_test_file: Path) -> None: + output_file = get_base_path / "file-test.mkv" + + mkv = MKVFile(get_path_test_file) + mkv.tracks[0].track_name = "Test track name" + mkv.mux(output_file) + + mkv = MKVFile(output_file) + + assert mkv.tracks[0].track_name == "Test track name" + + +def test_move_track_end_raises(get_path_test_file: Path) -> None: + mkv = MKVFile(get_path_test_file) + + with pytest.raises(IndexError): + mkv.move_track_end(-1) + + with pytest.raises(IndexError): + mkv.move_track_end(2) + + +def test_move_track_end_and_mux(get_base_path: Path, get_path_test_file: Path) -> None: + output_file = get_base_path / "file-test.mkv" + + mkv = MKVFile(get_path_test_file) + mkv.move_track_end(0) + mkv.mux(output_file) + + mkv = MKVFile(output_file) + + assert len(mkv.tracks) == 2 # noqa: PLR2004 + assert mkv.tracks[0].track_type == "audio" + assert mkv.tracks[1].track_type == "video" + + +def test_move_track_forward_raises(get_path_test_file: Path) -> None: + mkv = MKVFile(get_path_test_file) + + with pytest.raises(IndexError): + mkv.move_track_forward(-1) + + with pytest.raises(IndexError): + mkv.move_track_forward(2) + + with pytest.raises(IndexError): + mkv.move_track_forward(1) + + +def test_move_track_forward_and_mux(get_base_path: Path, get_path_test_file: Path) -> None: + output_file = get_base_path / "file-test.mkv" + + mkv = MKVFile(get_path_test_file) + mkv.move_track_forward(0) + mkv.mux(output_file) + + mkv = MKVFile(output_file) + + assert len(mkv.tracks) == 2 # noqa: PLR2004 + assert mkv.tracks[0].track_type == "audio" + assert mkv.tracks[1].track_type == "video" + + +def test_move_track_backward_raises(get_path_test_file: Path) -> None: + mkv = MKVFile(get_path_test_file) + + with pytest.raises(IndexError): + mkv.move_track_backward(-1) + + with pytest.raises(IndexError): + mkv.move_track_backward(2) + + +def test_move_track_backward_and_mux(get_base_path: Path, get_path_test_file: Path) -> None: + output_file = get_base_path / "file-test.mkv" + + mkv = MKVFile(get_path_test_file) + mkv.move_track_backward(1) + mkv.mux(output_file) + + mkv = MKVFile(output_file) + + assert len(mkv.tracks) == 2 # noqa: PLR2004 + assert mkv.tracks[0].track_type == "audio" + assert mkv.tracks[1].track_type == "video" From e7d1f6c9b6ee8e4965fdd71f319ef252ab4a7a8d Mon Sep 17 00:00:00 2001 From: GitBib <15717621+GitBib@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:01:53 +0300 Subject: [PATCH 2/7] Add unit tests for file and track IDs in test_add_file.py This commit introduces new unit tests within the test_add_file.py script. The tests validate that the file_id and track_id are correctly attributed within the MKV tracks. The file ID is expected to change every two tracks, while the track ID should alternate between 0 and 1. --- tests/test_add_file.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/test_add_file.py b/tests/test_add_file.py index b976858..9168139 100644 --- a/tests/test_add_file.py +++ b/tests/test_add_file.py @@ -12,6 +12,12 @@ def test_add_file(get_base_path: Path, get_path_test_file: Path, get_path_test_f mkv_two = MKVFile(get_path_test_file_two) mkv.add_file(mkv_two) + for i, track in enumerate(mkv.tracks): + expected_file_id = i // 2 # the file_id should change every two tracks + expected_track_id = i % 2 # the track_id should alternate between 0 and 1 + assert track.file_id == expected_file_id + assert track.track_id == expected_track_id + assert len(mkv.tracks) == 4 # noqa: PLR2004 mkv.mux(output_file) From f7045dfe65204dbbd30db055da359b79e66b0650 Mon Sep 17 00:00:00 2001 From: GitBib <15717621+GitBib@users.noreply.github.com> Date: Wed, 12 Jun 2024 12:02:37 +0300 Subject: [PATCH 3/7] Add new tests and assertion in test_open_files A new assert condition has been added to the test_open_file function to check if the mkv.title is None. Moreover, a new test case, test_verify_mkvmerge_in_mkv_file, has been introduced to verify the mkvmerge path and raise a FileNotFoundError if the path is incorrect. --- tests/test_open_files.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_open_files.py b/tests/test_open_files.py index 9ed99d7..7475dbc 100644 --- a/tests/test_open_files.py +++ b/tests/test_open_files.py @@ -8,6 +8,7 @@ def test_open_file(get_path_test_file: Path) -> None: mkv = MKVFile(get_path_test_file) + assert mkv.title is None assert len(mkv.tracks) == 2 # noqa: PLR2004 @@ -45,3 +46,11 @@ def test_empty_mkv_file() -> None: assert mkv.title == "test" assert len(mkv.tracks) == 0 + + +def test_verify_mkvmerge_in_mkv_file() -> None: + with pytest.raises( + FileNotFoundError, + match="mkvmerge is not at the specified path, add it there or changed mkvmerge_path property", + ): + MKVFile(title="test", mkvmerge_path="mkvmerge_test") From 3c139c11ec80dbce72242b4609ee12ec527eb675 Mon Sep 17 00:00:00 2001 From: GitBib <15717621+GitBib@users.noreply.github.com> Date: Wed, 12 Jun 2024 16:50:14 +0300 Subject: [PATCH 4/7] Add more tests for get_track function This update introduces additional tests for the 'get_track' function in the 'test_actions_track.py' file. It specifically addresses two new scenarios: when the function retrieves a specific track and when the function raises an error due to an invalid track number. The type hint for the 'get_track' function in the 'MKVFile.py' file has also been updated to reflect that it can return a list of tracks. --- pymkv/MKVFile.py | 2 +- tests/test_actions_track.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/pymkv/MKVFile.py b/pymkv/MKVFile.py index 8de3221..fd1bd20 100644 --- a/pymkv/MKVFile.py +++ b/pymkv/MKVFile.py @@ -435,7 +435,7 @@ def add_attachment(self, attachment: str | MKVAttachment) -> None: msg = "Attachment is not str of MKVAttachment" raise TypeError(msg) - def get_track(self, track_num: int | None = None) -> MKVTrack: + def get_track(self, track_num: int | None = None) -> MKVTrack | list[MKVTrack]: """Get a :class:`~pymkv.MKVTrack` from the :class:`~pymkv.MKVFile` object. Parameters diff --git a/tests/test_actions_track.py b/tests/test_actions_track.py index 5bf5156..cec296f 100644 --- a/tests/test_actions_track.py +++ b/tests/test_actions_track.py @@ -165,3 +165,21 @@ def test_move_track_backward_and_mux(get_base_path: Path, get_path_test_file: Pa assert len(mkv.tracks) == 2 # noqa: PLR2004 assert mkv.tracks[0].track_type == "audio" assert mkv.tracks[1].track_type == "video" + + +def test_get_track(get_path_test_file: Path) -> None: + mkv = MKVFile(get_path_test_file) + track = mkv.get_track(1) + + assert track.track_type == "audio" + + tracks = mkv.get_track() + + assert isinstance(tracks, list) + assert len(tracks) == 2 # noqa: PLR2004 + + +def test_get_track_error(get_path_test_file: Path) -> None: + mkv = MKVFile(get_path_test_file) + with pytest.raises(IndexError): + mkv.get_track(2) From f1e5378070f1e9039a55575c9ee3175d5833d9b5 Mon Sep 17 00:00:00 2001 From: GitBib <15717621+GitBib@users.noreply.github.com> Date: Thu, 20 Jun 2024 21:12:01 +0300 Subject: [PATCH 5/7] Add tests and tweak Timestamp class in pymkv This update introduces comprehensive tests in 'test_timestamp.py' for the 'Timestamp' class in the 'pymkv' module. The code also refactors the usage of regular expressions in 'Timestamp.py', replacing direct 'match' calls with 're.match' and refining the 'verify' method to exclusively handle string inputs. --- pymkv/Timestamp.py | 12 +++--- tests/test_timestamp.py | 91 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 6 deletions(-) create mode 100644 tests/test_timestamp.py diff --git a/pymkv/Timestamp.py b/pymkv/Timestamp.py index 96a0af5..bf9dedd 100644 --- a/pymkv/Timestamp.py +++ b/pymkv/Timestamp.py @@ -1,6 +1,6 @@ from __future__ import annotations -from re import match +import re class Timestamp: @@ -175,7 +175,7 @@ def __getitem__(self, index: int) -> int: def ts(self) -> str: """Generates the timestamp specified in the object.""" # parse timestamp format - format_groups = match(r"^(([Hh]{1,2}):)?([Mm]{1,2}):([Ss]{1,2})(\.([Nn]{1,9}))?$", self.form).groups() + format_groups = re.match(r"^(([Hh]{1,2}):)?([Mm]{1,2}):([Ss]{1,2})(\.([Nn]{1,9}))?$", self.form).groups() timestamp_format = [format_groups[i] is not None for i in (1, 2, 3, 5)] # create timestamp string @@ -248,16 +248,16 @@ def form(self, form: str) -> None: self._form = form @staticmethod - def verify(timestamp: str | int) -> bool: + def verify(timestamp: str) -> bool: """Verify a timestamp has the proper form to be used in mkvmerge. - timestamp (str, int): + timestamp (str): The timestamp to be verified. """ if not isinstance(timestamp, str): msg = f'"{type(timestamp)}" is not str type' raise TypeError(msg) - elif match(r"^[0-9]{1,2}(:[0-9]{1,2}){1,2}(\.[0-9]{1,9})?$", timestamp): # noqa: RET506 + elif re.match(r"^[0-9]{1,2}(:[0-9]{1,2}){1,2}(\.[0-9]{1,9})?$", timestamp): # noqa: RET506 return True return False @@ -305,7 +305,7 @@ def splitting_timestamp(self, timestamp: str) -> None: The seconds (self.ss) will be set to 56. The nanoseconds (self.nn) will be set to 789012345. """ - timestamp_groups = match(r"^(([0-9]{1,2}):)?([0-9]{1,2}):([0-9]{1,2})(\.([0-9]{1,9}))?$", timestamp).groups() + timestamp_groups = re.match(r"^(([0-9]{1,2}):)?([0-9]{1,2}):([0-9]{1,2})(\.([0-9]{1,9}))?$", timestamp).groups() timestamp = [timestamp_groups[i] for i in (1, 2, 3, 4)] timestamp_clean = [] diff --git a/tests/test_timestamp.py b/tests/test_timestamp.py new file mode 100644 index 0000000..0be9a87 --- /dev/null +++ b/tests/test_timestamp.py @@ -0,0 +1,91 @@ +import pytest + +from pymkv.Timestamp import Timestamp + + +def test_init() -> None: + ts1 = Timestamp("01:23:45.678") + assert str(ts1) == "01:23:45.678" + + ts2 = Timestamp(3661) # 1 hour, 1 minute, 1 second + assert str(ts2) == "01:01:01" + + ts3 = Timestamp(hh=2, mm=30, ss=15, nn=500000000) + assert str(ts3) == "02:30:15.5" + + +def test_comparison() -> None: + ts1 = Timestamp("01:00:00") + ts2 = Timestamp("02:00:00") + ts3 = Timestamp("01:00:00") + + assert ts1 < ts2 + assert ts2 > ts1 + assert ts1 <= ts3 + assert ts1 >= ts3 + assert ts1 == ts3 + assert ts1 != ts2 + + +def test_properties() -> None: + ts = Timestamp("12:34:56.789") + assert ts.hh == 12 # noqa: PLR2004 + assert ts.mm == 34 # noqa: PLR2004 + assert ts.ss == 56 # noqa: PLR2004 + assert ts.nn == 789000000 # noqa: PLR2004 + + +def test_setters() -> None: + ts = Timestamp() + ts.hh = 10 + ts.mm = 20 + ts.ss = 30 + ts.nn = 400000000 + assert str(ts) == "10:20:30.4" + + # Test overflow handling + ts.mm = 70 + assert ts.mm == 0 + + +def test_verify() -> None: + assert Timestamp.verify("01:23:45") + assert Timestamp.verify("01:23:45.678") + assert not Timestamp.verify("25.00:00") + + +def test_extract() -> None: + ts = Timestamp() + ts.extract(3661) # 1 hour, 1 minute, 1 second + + assert ts.hh == 1 + assert ts.mm == 1 + assert ts.ss == 1 + assert ts.nn == 0 + + +def test_getitem() -> None: + ts = Timestamp("01:23:45.678") + assert ts[0] == 1 # hours + assert ts[1] == 23 # minutes # noqa: PLR2004 + assert ts[2] == 45 # seconds # noqa: PLR2004 + assert ts[3] == 45 # seconds (again, as per the implementation) # noqa: PLR2004 + + +def test_invalid_input() -> None: + with pytest.raises(TypeError): + Timestamp([]) # Invalid type + + with pytest.raises(ValueError): # noqa: PT011 + Timestamp("invalid_timestamp") + + +def test_ts_property() -> None: + ts = Timestamp("01:23:45.678") + assert ts.ts == "01:23:45.678" + + ts.ts = "02:30:00" + assert ts.ts == "02:30:00" + + with pytest.raises(TypeError): + ts.ts = [] # Invalid type From bf1195b37f72ce54cefe3da4b487950112e273be Mon Sep 17 00:00:00 2001 From: GitBib <15717621+GitBib@users.noreply.github.com> Date: Thu, 20 Jun 2024 21:33:32 +0300 Subject: [PATCH 6/7] Add MKVAttachment tests and temp_file fixture New unit tests for the MKVAttachment class have been added in `tests/test_mkv_attachment.py` to increase overall test coverage. Additionally, added a pytest fixture in `tests/conftest.py` for a temporary text file used in tests. Clean-up routines have also been updated to account for the creation of temporary `.txt` files. --- tests/conftest.py | 9 ++++- tests/test_mkv_attachment.py | 76 ++++++++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 tests/test_mkv_attachment.py diff --git a/tests/conftest.py b/tests/conftest.py index 7bbb098..70b6aa7 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -21,7 +21,14 @@ def get_path_test_file_two(get_base_path: Path) -> Path: @pytest.fixture(autouse=True) def cleanup_mkv_files(get_base_path: Path, get_path_test_file: Path, get_path_test_file_two: Path) -> None: # noqa: PT004 yield - for ext in ["*.mkv", "*.mp4", "*.ogg"]: + for ext in ["*.mkv", "*.mp4", "*.ogg", "*.txt"]: for file_path in get_base_path.glob(ext): if file_path not in (get_path_test_file, get_path_test_file_two): file_path.unlink() + + +@pytest.fixture() +def temp_file(tmp_path: Path) -> str: + file = tmp_path / "test_attachment.txt" + file.write_text("Test content") + return str(file) diff --git a/tests/test_mkv_attachment.py b/tests/test_mkv_attachment.py new file mode 100644 index 0000000..1c095cc --- /dev/null +++ b/tests/test_mkv_attachment.py @@ -0,0 +1,76 @@ +from pathlib import Path + +import pytest + +from pymkv.MKVAttachment import MKVAttachment + + +def test_init(temp_file: str) -> None: + attachment = MKVAttachment(temp_file) + assert attachment.file_path == temp_file + assert attachment.mime_type == "text/plain" + assert attachment.name is None + assert attachment.description is None + assert attachment.attach_once is False + + +def test_init_with_options(temp_file: str) -> None: + attachment = MKVAttachment(temp_file, name="Test", description="Test Description", attach_once=True) + assert attachment.file_path == temp_file + assert attachment.name == "Test" + assert attachment.description == "Test Description" + assert attachment.attach_once is True + + +def test_file_path_setter_valid(temp_file: str) -> None: + attachment = MKVAttachment(temp_file) + new_file = Path(temp_file).parent / "new_file.txt" + new_file.write_text("New content") + attachment.file_path = str(new_file) + assert attachment.file_path == str(new_file) + assert attachment.mime_type == "text/plain" + assert attachment.name is None + + +def test_file_path_setter_invalid() -> None: + with pytest.raises(FileNotFoundError): + MKVAttachment("non_existent_file.txt") + + +def test_repr(temp_file: str) -> None: + attachment = MKVAttachment(temp_file, name="Test", description="Test Description") + repr_str = repr(attachment) + assert "file_path" in repr_str + assert "name" in repr_str + assert "description" in repr_str + assert "mime_type" in repr_str + + +def test_mime_type_guess(tmp_path: Path) -> None: + # Test different file types + file_types = { + "test.txt": "text/plain", + "test.jpg": "image/jpeg", + "test.png": "image/png", + "test.mp3": "audio/mpeg", + } + + for file_name, expected_mime in file_types.items(): + file_path = tmp_path / file_name + file_path.write_text("Test content") + attachment = MKVAttachment(str(file_path)) + assert attachment.mime_type == expected_mime + + +def test_file_path_expansion(tmp_path: Path, monkeypatch) -> None: # noqa: ANN001 + fake_home = tmp_path / "fake_home" + fake_home.mkdir() + monkeypatch.setenv("HOME", str(fake_home)) + + # Создаем файл в поддельной домашней директории + test_file = fake_home / "test_file.txt" + test_file.write_text("Test content") + + # Используем ~ в пути к файлу + attachment = MKVAttachment("~/test_file.txt") + assert attachment.file_path == str(test_file) From 8b7fab90847125dd76047f5397610a703a1bcae0 Mon Sep 17 00:00:00 2001 From: GitBib <15717621+GitBib@users.noreply.github.com> Date: Thu, 20 Jun 2024 21:34:14 +0300 Subject: [PATCH 7/7] Refactor mkv_attachment test code --- tests/test_mkv_attachment.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_mkv_attachment.py b/tests/test_mkv_attachment.py index 1c095cc..465c2f3 100644 --- a/tests/test_mkv_attachment.py +++ b/tests/test_mkv_attachment.py @@ -67,10 +67,8 @@ def test_file_path_expansion(tmp_path: Path, monkeypatch) -> None: # noqa: ANN0 fake_home.mkdir() monkeypatch.setenv("HOME", str(fake_home)) - # Создаем файл в поддельной домашней директории test_file = fake_home / "test_file.txt" test_file.write_text("Test content") - # Используем ~ в пути к файлу attachment = MKVAttachment("~/test_file.txt") assert attachment.file_path == str(test_file)