6 Commits
Author SHA1 Message Date
Oliver Hamlet d356ac2445 Set version number to 4.0.2 2019-03-25 09:47:46 +00:00
Oliver Hamlet fe4c3ab6b5 Update libloot to v0.14.5 2019-03-25 09:47:03 +00:00
Oliver Hamlet b17b531073 Fix get_plugin_cleanliness never returning dirty 2019-03-25 09:01:29 +00:00
Oliver Hamlet 06a6d9ceb6 Use CTest to run Python tests
Avoid having to copy the test script by modifying PYTHONPATH at runtime,
and move the test script into the test directory.
2019-03-25 08:38:34 +00:00
Oliver Hamlet a35abab104 Add a test masterlist
It'll be extended with more test metadata in future.
2019-03-25 08:20:03 +00:00
Oliver Hamlet 646a8d02e0 Add .vscode/ to .gitignore 2019-03-25 08:06:31 +00:00
7 changed files with 129 additions and 50 deletions
+2
View File
@@ -50,3 +50,5 @@ $RECYCLE.BIN/
# Windows shortcuts # Windows shortcuts
*.lnk *.lnk
.vscode/
+8 -26
View File
@@ -55,12 +55,12 @@ add_subdirectory(${PYBIND11_EXTRACTED_PATH})
if (CMAKE_SYSTEM_NAME MATCHES "Windows") if (CMAKE_SYSTEM_NAME MATCHES "Windows")
if (NOT "${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)") if (NOT "${CMAKE_GENERATOR}" MATCHES "(Win64|IA64)")
set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.14.3/libloot-0.14.3-0-g56d8f78_dev-win32.7z") set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.14.5/libloot-0.14.5-0-g68ecc02_dev-win32.7z")
else() else()
set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.14.3/libloot-0.14.3-0-g56d8f78_dev-win64.7z") set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.14.5/libloot-0.14.5-0-g68ecc02_dev-win64.7z")
endif() endif()
else() else()
set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.14.3/libloot.tar.xz") set(LIBLOOT_URL "https://github.com/loot/libloot/releases/download/0.14.5/libloot.tar.xz")
endif() endif()
ExternalProject_Add(libloot ExternalProject_Add(libloot
@@ -78,17 +78,6 @@ link_directories(${LIBLOOT_EXTRACTED_PATH})
set(LIBLOOT_STATIC_LIBRARY "${CMAKE_STATIC_LIBRARY_PREFIX}loot${CMAKE_STATIC_LIBRARY_SUFFIX}") 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}") set(LIBLOOT_SHARED_LIBRARY "${CMAKE_SHARED_LIBRARY_PREFIX}loot${CMAKE_SHARED_LIBRARY_SUFFIX}")
#######################################
# Test Masterlist
#######################################
ExternalProject_Add(test-masterlist
PREFIX "external"
URL "https://github.com/loot/oblivion/archive/7f125ae4464224ff785111c7667c2cff85c896ec.zip"
CONFIGURE_COMMAND ""
BUILD_COMMAND ""
INSTALL_COMMAND "")
####################################### #######################################
# Python Module # Python Module
####################################### #######################################
@@ -97,7 +86,7 @@ pybind11_add_module(loot_api "${CMAKE_SOURCE_DIR}/src/main.cpp"
"${CMAKE_SOURCE_DIR}/src/convenience.cpp" "${CMAKE_SOURCE_DIR}/src/convenience.cpp"
"${CMAKE_BINARY_DIR}/generated/wrapper_version.cpp") "${CMAKE_BINARY_DIR}/generated/wrapper_version.cpp")
add_dependencies(loot_api libloot test-masterlist) add_dependencies(loot_api libloot)
if (CMAKE_SYSTEM_NAME MATCHES "Windows") if (CMAKE_SYSTEM_NAME MATCHES "Windows")
target_link_libraries(loot_api PRIVATE ${LIBLOOT_STATIC_LIBRARY}) target_link_libraries(loot_api PRIVATE ${LIBLOOT_STATIC_LIBRARY})
@@ -117,18 +106,11 @@ add_custom_command(TARGET loot_api POST_BUILD
"${LIBLOOT_EXTRACTED_PATH}/${LIBLOOT_SHARED_LIBRARY}" "${LIBLOOT_EXTRACTED_PATH}/${LIBLOOT_SHARED_LIBRARY}"
"$<TARGET_FILE_DIR:loot_api>/${LIBLOOT_SHARED_LIBRARY}") "$<TARGET_FILE_DIR:loot_api>/${LIBLOOT_SHARED_LIBRARY}")
# Copy the test masterlist to the build directory. enable_testing()
ExternalProject_Get_Property(test-masterlist SOURCE_DIR)
add_custom_command(TARGET loot_api POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"${SOURCE_DIR}/masterlist.yaml"
"$<TARGET_FILE_DIR:loot_api>/masterlist.yaml")
# Also copy the test Python script to the build directory. add_test(NAME python
add_custom_command(TARGET loot_api POST_BUILD WORKING_DIRECTORY $<TARGET_FILE_DIR:loot_api>
COMMAND ${CMAKE_COMMAND} -E copy_if_different COMMAND "${PYTHON_EXECUTABLE}" ${CMAKE_SOURCE_DIR}/test/test.py)
"${CMAKE_SOURCE_DIR}/src/test.py"
"$<TARGET_FILE_DIR:loot_api>/test.py")
######################################## ########################################
# Install # Install
+1 -1
View File
@@ -346,5 +346,5 @@ texinfo_documents = [
# Example configuration for intersphinx: refer to the Python standard library. # Example configuration for intersphinx: refer to the Python standard library.
intersphinx_mapping = { intersphinx_mapping = {
'loot_api': ('http://loot.readthedocs.io/en/0.14.3/', None), 'loot_api': ('http://loot.readthedocs.io/en/0.14.5/', None),
} }
+18 -17
View File
@@ -57,26 +57,27 @@ PluginTags GetPluginTags(const std::shared_ptr<DatabaseInterface> db, const std:
PluginCleanliness GetPluginCleanliness(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin, bool evaluateConditions) { PluginCleanliness GetPluginCleanliness(const std::shared_ptr<DatabaseInterface> db, const std::string& plugin, bool evaluateConditions) {
auto metadata = db->GetPluginMetadata(plugin, true, evaluateConditions); auto metadata = db->GetPluginMetadata(plugin, true, evaluateConditions);
if (metadata.has_value()) { if (!metadata.has_value()) {
if (metadata.value().GetDirtyInfo().empty()) { return PluginCleanliness::unknown;
if (metadata.value().GetCleanInfo().empty()) { }
return PluginCleanliness::unknown;
}
else {
return PluginCleanliness::clean;
}
}
else if (!metadata.value().GetCleanInfo().empty()) {
return PluginCleanliness::unknown;
}
for (const auto& info : metadata.value().GetDirtyInfo()) { auto dirtyInfo = metadata.value().GetDirtyInfo();
if (info.ChooseInfo("en").GetText().find("Do not clean") != std::string::npos) { auto cleanInfo = metadata.value().GetCleanInfo();
return PluginCleanliness::do_not_clean;
} if (dirtyInfo.empty() == cleanInfo.empty()) {
return PluginCleanliness::unknown;
}
if (!cleanInfo.empty()) {
return PluginCleanliness::clean;
}
for (const auto& info : dirtyInfo) {
if (info.ChooseInfo("en").GetText().find("Do not clean") != std::string::npos) {
return PluginCleanliness::do_not_clean;
} }
} }
return PluginCleanliness::unknown; return PluginCleanliness::dirty;
} }
} }
+1 -1
View File
@@ -27,7 +27,7 @@
namespace loot { namespace loot {
const unsigned int WrapperVersion::major = 4; const unsigned int WrapperVersion::major = 4;
const unsigned int WrapperVersion::minor = 0; const unsigned int WrapperVersion::minor = 0;
const unsigned int WrapperVersion::patch = 1; const unsigned int WrapperVersion::patch = 2;
const std::string WrapperVersion::revision = "@GIT_COMMIT_STRING@"; const std::string WrapperVersion::revision = "@GIT_COMMIT_STRING@";
std::string WrapperVersion::string() { std::string WrapperVersion::string() {
+54
View File
@@ -0,0 +1,54 @@
plugins:
- name: Oblivion.esm
msg:
- type: error
content: 'This must not be activated. However, it can be useful when porting Oblivion mods to Nehrim.'
- name: Unofficial Oblivion Patch.esp
tag:
- Actors.ACBS
- Actors.AIData
- Actors.AIPackages
- Actors.CombatStyle
- Actors.DeathItem
- Actors.Stats
- C.Climate
- C.Light
- C.Music
- C.Name
- C.Owner
- Creatures.Blood
- Delev
- Factions
- Invent
- Names
- NPC.Class
- Relations
- Relev
- Scripts
- Stats
- -C.Water
- name: clean_and_dirty.esp
dirty:
- crc: 0xDEADBEEF
util: '[TES4Edit v4.0.0](https://www.nexusmods.com/oblivion/mods/11536)'
clean:
- crc: 0xFEEDFACE
util: 'TES4Edit v4.0.0'
- name: clean.esp
clean:
- crc: 0xFEEDFACE
util: 'TES4Edit v4.0.0'
- name: dirty.esp
dirty:
- crc: 0xDEADBEEF
util: '[TES4Edit v4.0.0](https://www.nexusmods.com/oblivion/mods/11536)'
- name: do_not_clean.esp
dirty:
- crc: 0xDEADBEEF
util: '[TES4Edit v4.0.0](https://www.nexusmods.com/oblivion/mods/11536)'
info: 'Do not clean. This plugin is intentionally left dirty.'
+45 -5
View File
@@ -1,14 +1,20 @@
#!/usr/bin/env python #!/usr/bin/env python
import cProfile import cProfile
import os
import os.path import os.path
import shutil import shutil
import sys
import unittest import unittest
sys.path.append(os.getcwd())
from loot_api import Version from loot_api import Version
from loot_api import WrapperVersion from loot_api import WrapperVersion
from loot_api import GameType from loot_api import GameType
from loot_api import SimpleMessage from loot_api import SimpleMessage
from loot_api import MessageType from loot_api import MessageType
from loot_api import PluginCleanliness
from loot_api import create_game_handle from loot_api import create_game_handle
from loot_api import is_compatible from loot_api import is_compatible
from loot_api import set_logging_callback from loot_api import set_logging_callback
@@ -45,17 +51,17 @@ class TestLootApi(GameFixture):
def test_version(self): def test_version(self):
self.assertEqual(Version.major, 0) self.assertEqual(Version.major, 0)
self.assertEqual(Version.minor, 14) self.assertEqual(Version.minor, 14)
self.assertEqual(Version.patch, 3) self.assertEqual(Version.patch, 5)
self.assertNotEqual(Version.revision, u'') self.assertNotEqual(Version.revision, u'')
self.assertEqual(Version.string(), "0.14.3") self.assertEqual(Version.string(), "0.14.5")
def test_wrapper_version(self): def test_wrapper_version(self):
self.assertEqual(WrapperVersion.major, 4) self.assertEqual(WrapperVersion.major, 4)
self.assertEqual(WrapperVersion.minor, 0) self.assertEqual(WrapperVersion.minor, 0)
self.assertEqual(WrapperVersion.patch, 1) self.assertEqual(WrapperVersion.patch, 2)
self.assertNotEqual(WrapperVersion.revision, u'') self.assertNotEqual(WrapperVersion.revision, u'')
self.assertNotEqual(WrapperVersion.revision, Version.revision) self.assertNotEqual(WrapperVersion.revision, Version.revision)
self.assertEqual(WrapperVersion.string(), "4.0.1") self.assertEqual(WrapperVersion.string(), "4.0.2")
def test_create_db(self): def test_create_db(self):
game = create_game_handle(GameType.tes4, self.game_path, self.local_path) game = create_game_handle(GameType.tes4, self.game_path, self.local_path)
@@ -63,7 +69,7 @@ class TestLootApi(GameFixture):
self.assertNotEqual(db, None) self.assertNotEqual(db, None)
class TestDatabaseInterface(GameFixture): class TestDatabaseInterface(GameFixture):
masterlist_path = u'masterlist.yaml' masterlist_path = os.path.join(os.path.dirname(__file__), u'masterlist.yaml')
def setUp(self): def setUp(self):
super(TestDatabaseInterface, self).setUp() super(TestDatabaseInterface, self).setUp()
@@ -116,6 +122,40 @@ class TestDatabaseInterface(GameFixture):
self.assertEqual(messages[0].type, MessageType.error) self.assertEqual(messages[0].type, MessageType.error)
self.assertEqual(messages[0].text, u'This must not be activated. However, it can be useful when porting Oblivion mods to Nehrim.') self.assertEqual(messages[0].text, u'This must not be activated. However, it can be useful when porting Oblivion mods to Nehrim.')
def test_get_plugin_cleanliness_should_be_unknown_if_no_dirty_or_clean_metadata_exists(self):
self.db.load_lists(self.masterlist_path, u'')
cleanliness = self.db.get_plugin_cleanliness(u'unknown.esp')
self.assertEqual(cleanliness, PluginCleanliness.unknown)
def test_get_plugin_cleanliness_should_be_unknown_if_dirty_and_clean_metadata_exists(self):
self.db.load_lists(self.masterlist_path, u'')
cleanliness = self.db.get_plugin_cleanliness(u'clean_and_dirty.esp')
self.assertEqual(cleanliness, PluginCleanliness.unknown)
def test_get_plugin_cleanliness_should_be_clean_if_only_clean_metadata_exists(self):
self.db.load_lists(self.masterlist_path, u'')
cleanliness = self.db.get_plugin_cleanliness(u'clean.esp')
self.assertEqual(cleanliness, PluginCleanliness.clean)
def test_get_plugin_cleanliness_should_be_dirty_if_only_dirty_metadata_exists(self):
self.db.load_lists(self.masterlist_path, u'')
cleanliness = self.db.get_plugin_cleanliness(u'dirty.esp')
self.assertEqual(cleanliness, PluginCleanliness.dirty)
def test_get_plugin_cleanliness_should_be_do_not_clean_if_dirty_do_not_clean_info_exists(self):
self.db.load_lists(self.masterlist_path, u'')
cleanliness = self.db.get_plugin_cleanliness(u'do_not_clean.esp')
self.assertEqual(cleanliness, PluginCleanliness.do_not_clean)
if __name__ == '__main__': if __name__ == '__main__':
unittest.main() unittest.main()