diff --git a/.flake8 b/.flake8 index e58c084..0b39587 100644 --- a/.flake8 +++ b/.flake8 @@ -2,4 +2,5 @@ [flake8] max-line-length = 110 -max-doc-length = 200 \ No newline at end of file +max-doc-length = 200 +per-file-ignores = conftest.py:F401 \ No newline at end of file diff --git a/src/richchk/mpq/stormlib/dlls/windows/Storm.dll b/src/richchk/mpq/stormlib/dlls/windows/Storm.dll deleted file mode 100644 index c708306..0000000 Binary files a/src/richchk/mpq/stormlib/dlls/windows/Storm.dll and /dev/null differ diff --git a/src/richchk/mpq/stormlib/dlls/windows/StormLib.dll b/src/richchk/mpq/stormlib/dlls/windows/StormLib.dll new file mode 100644 index 0000000..e69de29 diff --git a/src/richchk/mpq/stormlib/stormlib_finder.py b/src/richchk/mpq/stormlib/stormlib_finder.py index 4c0c847..bcb5c60 100644 --- a/src/richchk/mpq/stormlib/stormlib_finder.py +++ b/src/richchk/mpq/stormlib/stormlib_finder.py @@ -17,7 +17,7 @@ class StormLibFinder: _SCRIPT_PATH = os.path.dirname(__file__) _MAC_STORM_INTEL = os.path.join(_SCRIPT_PATH, "dlls/macos/libStorm.dylib") _MAC_STORM_M1 = os.path.join(_SCRIPT_PATH, "dlls/macos/libstorm.9.22.0.dylib") - _WINDOWS_STORM = os.path.join(_SCRIPT_PATH, "dlls/windows/Storm.dll") + _WINDOWS_STORM = os.path.join(_SCRIPT_PATH, "dlls\\windows\\StormLib.dll") _LINUX_STORM_X86_64 = os.path.join(_SCRIPT_PATH, "dlls/linux/libstorm.so.9.22.0") @classmethod diff --git a/test/chk_resources.py b/test/chk_resources.py index 47a67ba..9f7ba42 100644 --- a/test/chk_resources.py +++ b/test/chk_resources.py @@ -66,7 +66,6 @@ def _extract_chk_section_name_from_file_path(file_path: str) -> str: MACOS_STORMLIB_M1 = Path( Path.joinpath(_RESOURCES_DIR_PATH, "stormlib/macos/libstorm.9.22.0.dylib") ).absolute() - LINUX_STORMLIB_X86_64 = Path( Path.joinpath(_RESOURCES_DIR_PATH, "stormlib/linux/libstorm.so.9.22.0") ).absolute() diff --git a/test/conftest.py b/test/conftest.py new file mode 100644 index 0000000..454b97a --- /dev/null +++ b/test/conftest.py @@ -0,0 +1,7 @@ +"""Makes all pytest fixtures available to use across any unit test. + +See: https://gist.github.com/peterhurford/09f7dcda0ab04b95c026c60fa49c2a68 +""" +import pytest + +from .helpers.stormlib_test_helper import embedded_stormlib, embedded_stormlib_path diff --git a/test/helpers/stormlib_helper.py b/test/helpers/stormlib_helper.py deleted file mode 100644 index 965ca00..0000000 --- a/test/helpers/stormlib_helper.py +++ /dev/null @@ -1,13 +0,0 @@ -import platform - - -def run_test_if_mac_m1() -> bool: - return ( - platform.system().lower() == "darwin" and platform.machine().lower() == "arm64" - ) - - -def run_test_if_linux_x86_64() -> bool: - return ( - platform.system().lower() == "linux" and platform.machine().lower() == "x86_64" - ) diff --git a/test/helpers/stormlib_test_helper.py b/test/helpers/stormlib_test_helper.py new file mode 100644 index 0000000..64d6d19 --- /dev/null +++ b/test/helpers/stormlib_test_helper.py @@ -0,0 +1,60 @@ +import platform +from test.chk_resources import LINUX_STORMLIB_X86_64, MACOS_STORMLIB_M1 +from typing import Optional + +import pytest + +from richchk.model.mpq.stormlib.stormlib_file_path import StormLibFilePath +from richchk.mpq.stormlib.stormlib_loader import StormLibLoader +from richchk.mpq.stormlib.stormlib_wrapper import StormLibWrapper + + +def run_test_if_mac_m1() -> bool: + return ( + platform.system().lower() == "darwin" and platform.machine().lower() == "arm64" + ) + + +def run_test_if_linux_x86_64() -> bool: + return ( + platform.system().lower() == "linux" and platform.machine().lower() == "x86_64" + ) + + +def run_test_if_supported_os() -> bool: + return any([run_test_if_mac_m1(), run_test_if_linux_x86_64()]) + + +def _first_true(iterable, default=False, predicate=None): + """Returns the first true value or the *default* if there is no true value.""" + return next(filter(predicate, iterable), default) + + +def _get_embedded_stormlib_path() -> Optional[str]: + possible_stormlibs: tuple[tuple[bool, str], ...] = ( + (run_test_if_mac_m1(), str(MACOS_STORMLIB_M1)), + (run_test_if_linux_x86_64(), str(LINUX_STORMLIB_X86_64)), + ) + maybe_embedded_stormlib = _first_true( + possible_stormlibs, default=None, predicate=lambda x: x[0] is True + ) + if maybe_embedded_stormlib: + return maybe_embedded_stormlib[1] + + +@pytest.fixture(scope="function") +def embedded_stormlib_path() -> Optional[str]: + return _get_embedded_stormlib_path() + + +@pytest.fixture(scope="function") +def embedded_stormlib() -> Optional[StormLibWrapper]: + embedded_stormlib_path = _get_embedded_stormlib_path() + if embedded_stormlib_path: + return StormLibWrapper( + StormLibLoader.load_stormlib( + path_to_stormlib=StormLibFilePath( + _path_to_stormlib_dll=embedded_stormlib_path + ) + ) + ) diff --git a/test/io/mpq/stacraft_wav_io_test.py b/test/io/mpq/stacraft_wav_io_test.py index 9e6406f..ea69df4 100644 --- a/test/io/mpq/stacraft_wav_io_test.py +++ b/test/io/mpq/stacraft_wav_io_test.py @@ -21,7 +21,7 @@ EXAMPLE_WAV_FILE, MACOS_STORMLIB_M1, ) -from ...helpers.stormlib_helper import run_test_if_mac_m1 +from ...helpers.stormlib_test_helper import run_test_if_mac_m1 # the canonical place the CHK is stored in a SCX/SCM map file _CHK_MPQ_PATH = "staredit\\scenario.chk" diff --git a/test/io/mpq/starcraft_mpq_io_test.py b/test/io/mpq/starcraft_mpq_io_test.py index 6b84140..0734fb4 100644 --- a/test/io/mpq/starcraft_mpq_io_test.py +++ b/test/io/mpq/starcraft_mpq_io_test.py @@ -24,7 +24,7 @@ EXAMPLE_STARCRAFT_SCX_MAP, MACOS_STORMLIB_M1, ) -from ...helpers.stormlib_helper import run_test_if_mac_m1 +from ...helpers.stormlib_test_helper import run_test_if_mac_m1 # the canonical place the CHK is stored in a SCX/SCM map file _CHK_MPQ_PATH = "staredit\\scenario.chk" diff --git a/test/io/mpq/starcraft_wav_metadata_io_test.py b/test/io/mpq/starcraft_wav_metadata_io_test.py index 34006c4..e16cd8e 100644 --- a/test/io/mpq/starcraft_wav_metadata_io_test.py +++ b/test/io/mpq/starcraft_wav_metadata_io_test.py @@ -15,7 +15,7 @@ EXAMPLE_STARCRAFT_SCM_MAP, MACOS_STORMLIB_M1, ) -from ...helpers.stormlib_helper import run_test_if_mac_m1 +from ...helpers.stormlib_test_helper import run_test_if_mac_m1 # these are the 3 WAV files in COMPLEX_STARCRAFT_SCX_MAP # these are the paths each WAV file is stored inside the MPQ archive diff --git a/test/mpq/stormlib/search/stormlib_file_searcher_test.py b/test/mpq/stormlib/search/stormlib_file_searcher_test.py index 58473c9..4da9c82 100644 --- a/test/mpq/stormlib/search/stormlib_file_searcher_test.py +++ b/test/mpq/stormlib/search/stormlib_file_searcher_test.py @@ -14,7 +14,10 @@ LINUX_STORMLIB_X86_64, MACOS_STORMLIB_M1, ) -from ....helpers.stormlib_helper import run_test_if_linux_x86_64, run_test_if_mac_m1 +from ....helpers.stormlib_test_helper import ( + run_test_if_linux_x86_64, + run_test_if_mac_m1, +) # the canonical place the CHK is stored in a SCX/SCM map file _CHK_MPQ_PATH = "staredit\\scenario.chk" diff --git a/test/mpq/stormlib/stormlib_helper_test.py b/test/mpq/stormlib/stormlib_helper_test.py index 69ec29b..237740a 100644 --- a/test/mpq/stormlib/stormlib_helper_test.py +++ b/test/mpq/stormlib/stormlib_helper_test.py @@ -1,9 +1,11 @@ import os import platform +import pytest + from richchk.mpq.stormlib.stormlib_helper import StormLibHelper -from ...chk_resources import MACOS_STORMLIB_M1 +from ...helpers.stormlib_test_helper import run_test_if_supported_os def _run_test_if_mac_m1() -> bool: @@ -13,12 +15,17 @@ def _run_test_if_mac_m1() -> bool: def test_it_create_stormlib_wrapper_from_embedded_dll(): - if _run_test_if_mac_m1(): + if run_test_if_supported_os(): stormlib = StormLibHelper.load_stormlib(path_to_stormlib_dll=None) assert os.path.exists(stormlib.stormlib.path_to_stormlib.path_to_stormlib_dll) -def test_it_create_stormlib_wrapper_from_provided_dll(): - if _run_test_if_mac_m1(): - stormlib = StormLibHelper.load_stormlib(path_to_stormlib_dll=MACOS_STORMLIB_M1) +@pytest.mark.usefixtures("embedded_stormlib_path") +def test_it_creates_stormlib_wrapper_from_provided_dll( + embedded_stormlib_path, +): + if embedded_stormlib_path: + stormlib = StormLibHelper.load_stormlib( + path_to_stormlib_dll=embedded_stormlib_path + ) assert os.path.exists(stormlib.stormlib.path_to_stormlib.path_to_stormlib_dll) diff --git a/test/mpq/stormlib/stormlib_wrapper_test.py b/test/mpq/stormlib/stormlib_wrapper_test.py index 409ef4e..9e1d1e9 100644 --- a/test/mpq/stormlib/stormlib_wrapper_test.py +++ b/test/mpq/stormlib/stormlib_wrapper_test.py @@ -6,121 +6,99 @@ import pytest from richchk.model.mpq.stormlib.stormlib_archive_mode import StormLibArchiveMode -from richchk.model.mpq.stormlib.stormlib_file_path import StormLibFilePath from richchk.model.mpq.stormlib.stormlib_mpq_handle import StormLibMpqHandle from richchk.model.mpq.stormlib.stormlib_operation_result import StormLibOperationResult -from richchk.mpq.stormlib.stormlib_loader import StormLibLoader -from richchk.mpq.stormlib.stormlib_wrapper import StormLibWrapper -from ...chk_resources import ( - EXAMPLE_STARCRAFT_SCX_MAP, - LINUX_STORMLIB_X86_64, - MACOS_STORMLIB_M1, -) -from ...helpers.stormlib_helper import run_test_if_linux_x86_64, run_test_if_mac_m1 +from ...chk_resources import EXAMPLE_STARCRAFT_SCX_MAP # the canonical place the CHK is stored in a SCX/SCM map file _CHK_MPQ_PATH = "staredit\\scenario.chk" -@pytest.fixture(scope="function") -def stormlib_wrapper(): - if run_test_if_mac_m1(): - return StormLibWrapper( - StormLibLoader.load_stormlib( - path_to_stormlib=StormLibFilePath( - _path_to_stormlib_dll=MACOS_STORMLIB_M1 - ) - ) - ) - elif run_test_if_linux_x86_64(): - return StormLibWrapper( - StormLibLoader.load_stormlib( - path_to_stormlib=StormLibFilePath( - _path_to_stormlib_dll=LINUX_STORMLIB_X86_64 - ) - ) - ) - - def _read_file_as_bytes(infile: str) -> bytes: with open(infile, "rb") as f: return f.read() -def test_it_opens_and_closes_scx_map_unchanged_in_read_mode(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_opens_and_closes_scx_map_unchanged_in_read_mode(embedded_stormlib): + if embedded_stormlib: with tempfile.NamedTemporaryFile() as temp_scx_file: shutil.copyfile(EXAMPLE_STARCRAFT_SCX_MAP, temp_scx_file.name) map_bytes_before_open = _read_file_as_bytes(temp_scx_file.name) - open_result = stormlib_wrapper.open_archive( + open_result = embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_READ_ONLY, ) - stormlib_wrapper.close_archive(open_result) + embedded_stormlib.close_archive(open_result) assert map_bytes_before_open == _read_file_as_bytes(temp_scx_file.name) -def test_it_opens_and_closes_scx_map_unchanged_in_write_mode(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_opens_and_closes_scx_map_unchanged_in_write_mode(embedded_stormlib): + if embedded_stormlib: with tempfile.NamedTemporaryFile() as temp_scx_file: shutil.copyfile(EXAMPLE_STARCRAFT_SCX_MAP, temp_scx_file.name) map_bytes_before_open = _read_file_as_bytes(temp_scx_file.name) - open_result = stormlib_wrapper.open_archive( + open_result = embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_WRITE_ONLY, ) - stormlib_wrapper.close_archive(open_result) + embedded_stormlib.close_archive(open_result) assert map_bytes_before_open == _read_file_as_bytes(temp_scx_file.name) -def test_it_throws_if_input_file_is_not_mpq(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_throws_if_input_file_is_not_mpq(embedded_stormlib): + if embedded_stormlib: with tempfile.NamedTemporaryFile() as temp_scx_file: with pytest.raises(ValueError): - stormlib_wrapper.open_archive( + embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_READ_ONLY, ) -def test_it_throws_if_input_file_does_not_exist(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_throws_if_input_file_does_not_exist(embedded_stormlib): + if embedded_stormlib: not_a_real_file = str(uuid.uuid4()) with pytest.raises(AssertionError): - stormlib_wrapper.open_archive( + embedded_stormlib.open_archive( not_a_real_file, archive_mode=StormLibArchiveMode.STORMLIB_READ_ONLY, ) -def test_it_throws_if_closing_an_archive_never_opened(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_throws_if_closing_an_archive_never_opened(embedded_stormlib): + if embedded_stormlib: with pytest.raises(ValueError): - stormlib_wrapper.close_archive( + embedded_stormlib.close_archive( StormLibOperationResult(StormLibMpqHandle(), _result=1) ) -def test_it_extracts_chk_from_scx_file(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_extracts_chk_from_scx_file(embedded_stormlib): + if embedded_stormlib: with ( tempfile.NamedTemporaryFile() as temp_scx_file, tempfile.NamedTemporaryFile() as temp_chk_file, ): shutil.copyfile(EXAMPLE_STARCRAFT_SCX_MAP, temp_scx_file.name) temp_chk_file_bytes_before_extract = _read_file_as_bytes(temp_scx_file.name) - open_result = stormlib_wrapper.open_archive( + open_result = embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_WRITE_ONLY, ) - stormlib_wrapper.extract_file( + embedded_stormlib.extract_file( open_result, path_to_file_in_archive=_CHK_MPQ_PATH, outfile=temp_chk_file.name, overwrite_existing=True, ) - stormlib_wrapper.close_archive(open_result) + embedded_stormlib.close_archive(open_result) assert os.path.exists(temp_chk_file.name) assert ( _read_file_as_bytes(temp_chk_file.name) @@ -128,8 +106,9 @@ def test_it_extracts_chk_from_scx_file(stormlib_wrapper): ) -def test_it_ovewrites_existing_file_when_extracting(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_ovewrites_existing_file_when_extracting(embedded_stormlib): + if embedded_stormlib: with ( tempfile.NamedTemporaryFile() as temp_scx_file, tempfile.NamedTemporaryFile() as temp_chk_file, @@ -138,34 +117,35 @@ def test_it_ovewrites_existing_file_when_extracting(stormlib_wrapper): bytes_before_overwrite = b"123456" with open(temp_chk_file.name, "wb") as f: f.write(bytes_before_overwrite) - open_result = stormlib_wrapper.open_archive( + open_result = embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_WRITE_ONLY, ) - stormlib_wrapper.extract_file( + embedded_stormlib.extract_file( open_result, path_to_file_in_archive=_CHK_MPQ_PATH, outfile=temp_chk_file.name, overwrite_existing=True, ) - stormlib_wrapper.close_archive(open_result) + embedded_stormlib.close_archive(open_result) assert os.path.exists(temp_chk_file.name) assert _read_file_as_bytes(temp_chk_file.name) != bytes_before_overwrite -def test_it_throws_if_ovewriting_existing_file_when_extracting(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_throws_if_ovewriting_existing_file_when_extracting(embedded_stormlib): + if embedded_stormlib: with ( tempfile.NamedTemporaryFile() as temp_scx_file, tempfile.NamedTemporaryFile() as temp_chk_file, ): shutil.copyfile(EXAMPLE_STARCRAFT_SCX_MAP, temp_scx_file.name) - open_result = stormlib_wrapper.open_archive( + open_result = embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_WRITE_ONLY, ) with pytest.raises(FileExistsError): - stormlib_wrapper.extract_file( + embedded_stormlib.extract_file( open_result, path_to_file_in_archive=_CHK_MPQ_PATH, outfile=temp_chk_file.name, @@ -173,8 +153,9 @@ def test_it_throws_if_ovewriting_existing_file_when_extracting(stormlib_wrapper) ) -def test_it_adds_file_to_archive(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_adds_file_to_archive(embedded_stormlib): + if embedded_stormlib: with ( tempfile.NamedTemporaryFile() as temp_scx_file, tempfile.NamedTemporaryFile() as temp_madeup_file, @@ -184,18 +165,18 @@ def test_it_adds_file_to_archive(stormlib_wrapper): madeup_file_content = b"123456" with open(temp_madeup_file.name, "wb") as f: f.write(madeup_file_content) - open_result = stormlib_wrapper.open_archive( + open_result = embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_WRITE_ONLY, ) - stormlib_wrapper.add_file( + embedded_stormlib.add_file( open_result, temp_madeup_file.name, temp_madeup_file.name ) - stormlib_wrapper.compact_archive(open_result) - stormlib_wrapper.close_archive(open_result) - stormlib_wrapper.close_archive( - stormlib_wrapper.extract_file( - stormlib_wrapper.open_archive( + embedded_stormlib.compact_archive(open_result) + embedded_stormlib.close_archive(open_result) + embedded_stormlib.close_archive( + embedded_stormlib.extract_file( + embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_READ_ONLY, ), @@ -209,20 +190,21 @@ def test_it_adds_file_to_archive(stormlib_wrapper): ) -def test_it_compacts_archive(stormlib_wrapper): - if stormlib_wrapper: +@pytest.mark.usefixtures("embedded_stormlib") +def test_it_compacts_archive(embedded_stormlib): + if embedded_stormlib: with tempfile.NamedTemporaryFile() as temp_scx_file: shutil.copyfile(EXAMPLE_STARCRAFT_SCX_MAP, temp_scx_file.name) - open_result = stormlib_wrapper.open_archive( + open_result = embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_WRITE_ONLY, ) - stormlib_wrapper.compact_archive(open_result) - stormlib_wrapper.close_archive(open_result) + embedded_stormlib.compact_archive(open_result) + embedded_stormlib.close_archive(open_result) compacted_bytes = _read_file_as_bytes(temp_scx_file.name) - stormlib_wrapper.close_archive( - stormlib_wrapper.compact_archive( - stormlib_wrapper.open_archive( + embedded_stormlib.close_archive( + embedded_stormlib.compact_archive( + embedded_stormlib.open_archive( temp_scx_file.name, archive_mode=StormLibArchiveMode.STORMLIB_WRITE_ONLY, )