diff --git a/CMakeLists.txt b/CMakeLists.txt index ae3213e..3383844 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -84,6 +84,20 @@ link_directories(${LIBLOOT_EXTRACTED_PATH}) set(LIBLOOT_STATIC_LIBRARY "${CMAKE_STATIC_LIBRARY_PREFIX}loot${CMAKE_STATIC_LIBRARY_SUFFIX}") set(LIBLOOT_SHARED_LIBRARY "${CMAKE_SHARED_LIBRARY_PREFIX}loot${CMAKE_SHARED_LIBRARY_SUFFIX}") +####################################### +# testing-plugins +####################################### + +# This is a bit messy because the testing-plugins aren't actually required to +# build libloot-python, but having them as a dependency is the easiest way to +# manage downloading and moving them to the expected location. +ExternalProject_Add(testing-plugins + PREFIX "external" + URL "https://github.com/Ortham/testing-plugins/archive/1.4.1.tar.gz" + CONFIGURE_COMMAND "" + BUILD_COMMAND "" + INSTALL_COMMAND "") + ####################################### # Python Module ####################################### @@ -96,7 +110,7 @@ pybind11_add_module(libloot-python "${CMAKE_SOURCE_DIR}/src/main.cpp" # conventions (no lib, no -python). set_target_properties(libloot-python PROPERTIES OUTPUT_NAME loot) -add_dependencies(libloot-python libloot) +add_dependencies(libloot-python libloot testing-plugins) if (CMAKE_SYSTEM_NAME MATCHES "Windows") target_link_libraries(libloot-python PRIVATE ${LIBLOOT_STATIC_LIBRARY}) @@ -116,6 +130,13 @@ add_custom_command(TARGET libloot-python POST_BUILD "${LIBLOOT_EXTRACTED_PATH}/${LIBLOOT_SHARED_LIBRARY}" "$/${LIBLOOT_SHARED_LIBRARY}") +# Copy testing plugins +ExternalProject_Get_Property(testing-plugins SOURCE_DIR) +add_custom_command(TARGET libloot-python POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_directory + ${SOURCE_DIR} + $) + enable_testing() add_test(NAME python diff --git a/appveyor.yml b/appveyor.yml index a43fd2e..255da04 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -20,6 +20,9 @@ environment: install: - ps: (New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/Ortham/ci-scripts/2.0.0/delete_old_bintray_versions.py', "$env:APPVEYOR_BUILD_FOLDER\delete_old_bintray_versions.py") + - ps: (New-Object Net.WebClient).DownloadFile('https://github.com/WrinklyNinja/testing-plugins/archive/1.4.1.zip', "$PWD/1.4.1.zip") + - 7z x 1.4.1.zip + - mv testing-plugins-1.4.1 testing-plugins before_build: - ps: $env:PYTHON_DIRECTORY_VERSION=$env:PYTHON_VERSION.Replace(".", "") diff --git a/src/main.cpp b/src/main.cpp index c8559e7..6645215 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -149,6 +149,12 @@ void bindInterfaceClasses(pybind11::module& module) { pybind11::call_guard()) .def("get_database", &GameInterface::GetDatabase, + pybind11::call_guard()) + .def("load_plugins", + &GameInterface::LoadPlugins, + pybind11::call_guard()) + .def("get_plugin", + &GameInterface::GetPlugin, pybind11::call_guard()); class_>(module, "DatabaseInterface") @@ -182,6 +188,20 @@ void bindInterfaceClasses(pybind11::module& module) { .def("write_minimal_list", &py::WriteMinimalList, pybind11::call_guard()); + + class_>(module, "PluginInterface") + .def_property_readonly("name", + &PluginInterface::GetName, + pybind11::call_guard()) + .def("is_master", + &PluginInterface::IsMaster, + pybind11::call_guard()) + .def("is_light_master", + &PluginInterface::IsLightMaster, + pybind11::call_guard()) + .def("is_valid_as_light_master", + &PluginInterface::IsValidAsLightMaster, + pybind11::call_guard()); } void bindClasses(pybind11::module& module) { diff --git a/test/test.py b/test/test.py index be8d614..aba2b25 100644 --- a/test/test.py +++ b/test/test.py @@ -27,22 +27,21 @@ set_logging_callback(logging_callback) class GameFixture(unittest.TestCase): game_path = os.path.join(u'.', u'Oblivion') local_path = os.path.join(u'.', u'local') + master_filename = u'Oblivion.esm' def setUp(self): - data_path = os.path.join(self.game_path, 'Data') - master_file = os.path.join(data_path, 'Oblivion.esm') - - if not os.path.exists(data_path): - os.makedirs(data_path) - open(master_file, 'a').close() + open(self.master_file_path(), 'a').close() if not os.path.exists(self.local_path): os.makedirs(self.local_path) def tearDown(self): - shutil.rmtree(self.game_path) + os.remove(self.master_file_path()) shutil.rmtree(self.local_path) + def master_file_path(self): + return os.path.join(self.game_path, 'Data', self.master_filename) + class TestLootApi(GameFixture): def test_is_compatible(self): self.assertFalse(is_compatible(0, 9, 0)) @@ -68,6 +67,61 @@ class TestLootApi(GameFixture): db = game.get_database() self.assertNotEqual(db, None) +class TestGameInterface(GameFixture): + def setUp(self): + super(TestGameInterface, self).setUp() + + self.game = create_game_handle(GameType.tes4, self.game_path, self.local_path) + + def test_load_plugins(self): + self.game.load_plugins([u'Blank.esm'], True) + self.game.load_plugins([u'Blank.esm'], False) + + def test_get_plugin(self): + self.game.load_plugins([u'Blank.esm'], True) + plugin = self.game.get_plugin(u'Blank.esm') + + self.assertNotEqual(plugin, None) + +class TestPluginInterface(GameFixture): + game_path = os.path.join(u'.', u'SkyrimSE') + master_filename = u'Skyrim.esm' + + def setUp(self): + super(TestPluginInterface, self).setUp() + + self.game = create_game_handle(GameType.tes5se, self.game_path, self.local_path) + self.game.load_plugins([u'Blank.esm', u'Blank.esl'], False) + + def test_name(self): + plugin = self.game.get_plugin(u'Blank.esm') + + self.assertNotEqual(plugin, None) + self.assertEqual(plugin.name, u'Blank.esm') + + def test_is_master(self): + plugin = self.game.get_plugin(u'Blank.esm') + + self.assertNotEqual(plugin, None) + self.assertTrue(plugin.is_master()) + + def test_is_light_master(self): + plugin = self.game.get_plugin(u'Blank.esm') + + self.assertNotEqual(plugin, None) + self.assertFalse(plugin.is_light_master()) + + plugin = self.game.get_plugin(u'Blank.esl') + + self.assertNotEqual(plugin, None) + self.assertTrue(plugin.is_light_master()) + + def test_is_valid_as_light_master(self): + plugin = self.game.get_plugin(u'Blank.esm') + + self.assertNotEqual(plugin, None) + self.assertTrue(plugin.is_valid_as_light_master()) + class TestDatabaseInterface(GameFixture): masterlist_path = os.path.join(os.path.dirname(__file__), u'masterlist.yaml')