advanced example

This commit is contained in:
Vysyr committed 2026-10-31 20:16:32 +01:00
1 parent 8c0a639fba
commit 6fe57915e8
99 files changed
+1329 -56

No files matched your search

+81
View File
@@ -0,0 +1,81 @@
"""Automatic folder discovery, explicit selection and the manual reimport switch."""
import importlib.util
from pathlib import Path
import sys
import tempfile
import unittest
from unittest.mock import MagicMock, patch
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "Content/Python"))
from ue_workshop.characters import _clips
class Mesh:
def get_editor_property(self, name):
return "Skeleton"
class Clip:
def get_name(self):
return "EmbeddedTake"
class DiscoveryTests(unittest.TestCase):
def setUp(self):
self.folder = tempfile.TemporaryDirectory()
self.addCleanup(self.folder.cleanup)
self.model = Path(self.folder.name) / "Hero.fbx"
self.walk = self.model.with_name("great sword walk.fbx")
self.attack = self.model.with_name("great sword attack (2).fbx")
for path in (self.model, self.walk, self.attack):
path.touch()
unreal = MagicMock()
unreal.SkeletalMesh, unreal.AnimSequence = Mesh, Clip
name = "ue_workshop._skeletal_discovery_test"
path = Path(__file__).resolve().parents[1] / "Content/Python/ue_workshop/skeletal.py"
spec = importlib.util.spec_from_file_location(name, path)
self.module = importlib.util.module_from_spec(spec)
with patch.dict(sys.modules, {"unreal": unreal, name: self.module}):
spec.loader.exec_module(self.module)
self.cache = patch.object(self.module, "_cached", return_value=[Mesh()]).start()
self.importer = patch.object(self.module, "_import", return_value=[Mesh()]).start()
self.animation = patch.object(self.module, "import_animation", side_effect=lambda *a, **kw: Clip()).start()
self.addCleanup(patch.stopall)
def test_discovery_excludes_model_and_derives_names_without_aliases(self):
self.assertEqual(_clips(self.model), {
"great_sword_attack_2": self.attack,
"great_sword_walk": self.walk,
})
def test_omitted_animations_loads_every_neighbor_and_reuses_model(self):
result = self.module.import_model(self.model, name="Hero")
self.assertEqual(set(result.animations), {"great_sword_attack_2", "great_sword_walk"})
self.importer.assert_not_called()
self.assertEqual(self.animation.call_count, 2)
for call in self.animation.call_args_list:
self.assertFalse(call.kwargs["reimport"])
def test_empty_dictionary_disables_discovery_and_keeps_embedded_name(self):
self.cache.return_value = [Mesh(), Clip()]
result = self.module.import_model(self.model, name="Hero", animations={})
self.assertEqual(set(result.animations), {"EmbeddedTake"})
self.animation.assert_not_called()
def test_explicit_selection_ignores_other_files(self):
result = self.module.import_model(self.model, name="Hero", animations={"selected": self.walk})
self.assertEqual(set(result.animations), {"selected"})
self.animation.assert_called_once()
self.assertEqual(self.animation.call_args.args[0], self.walk)
def test_reimport_true_reimports_model_and_discovered_clips(self):
self.module.import_model(self.model, name="Hero", reimport=True)
self.cache.assert_not_called()
self.importer.assert_called_once()
self.assertTrue(self.importer.call_args.kwargs["reimport"])
self.assertTrue(all(call.kwargs["reimport"] for call in self.animation.call_args_list))
def test_colliding_normalized_names_are_rejected(self):
self.model.with_name("great-sword-walk.fbx").touch()
with self.assertRaises(ValueError):
_clips(self.model)