mirror of
https://github.com/panda3d/panda3d.git
synced 2025-09-29 08:15:18 -04:00
tests: add unit tests for Python loader file types
This commit is contained in:
parent
f63b3a86b9
commit
b23561d863
211
tests/pgraph/test_loader_types.py
Normal file
211
tests/pgraph/test_loader_types.py
Normal file
@ -0,0 +1,211 @@
|
|||||||
|
from panda3d.core import LoaderFileTypeRegistry, ModelRoot, Loader, LoaderOptions
|
||||||
|
import pytest
|
||||||
|
import tempfile
|
||||||
|
import os
|
||||||
|
from contextlib import contextmanager
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_filename():
|
||||||
|
"""Fixture returning a filename to an existent .test file."""
|
||||||
|
fp = tempfile.NamedTemporaryFile(suffix='.test', delete=False)
|
||||||
|
fp.write(b"test")
|
||||||
|
fp.close()
|
||||||
|
yield fp.name
|
||||||
|
os.unlink(fp.name)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def test_pz_filename():
|
||||||
|
"""Fixture returning a filename to an existent .test.pz file."""
|
||||||
|
fp = tempfile.NamedTemporaryFile(suffix='.test.pz', delete=False)
|
||||||
|
fp.write(b"test")
|
||||||
|
fp.close()
|
||||||
|
yield fp.name
|
||||||
|
os.unlink(fp.name)
|
||||||
|
|
||||||
|
|
||||||
|
@contextmanager
|
||||||
|
def registered_type(type):
|
||||||
|
"""Convenience method allowing use of register_type in a with block."""
|
||||||
|
registry = LoaderFileTypeRegistry.get_global_ptr()
|
||||||
|
registry.register_type(type)
|
||||||
|
yield
|
||||||
|
registry.unregister_type(type)
|
||||||
|
|
||||||
|
|
||||||
|
class DummyLoader:
|
||||||
|
"""The simplest possible successful LoaderFileType."""
|
||||||
|
|
||||||
|
extensions = ["test"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load_file(path, options, record=None):
|
||||||
|
return ModelRoot("loaded")
|
||||||
|
|
||||||
|
|
||||||
|
def test_loader_invalid():
|
||||||
|
"""Tests that registering a malformed loader fails."""
|
||||||
|
|
||||||
|
class MissingExtensionsLoader:
|
||||||
|
pass
|
||||||
|
|
||||||
|
class InvalidTypeExtensionsLoader:
|
||||||
|
extensions = "abc"
|
||||||
|
|
||||||
|
class EmptyExtensionsLoader:
|
||||||
|
extensions = []
|
||||||
|
|
||||||
|
class InvalidExtensionsLoader:
|
||||||
|
extensions = [123, None]
|
||||||
|
|
||||||
|
registry = LoaderFileTypeRegistry.get_global_ptr()
|
||||||
|
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
registry.register_type("invalid")
|
||||||
|
|
||||||
|
with pytest.raises(Exception):
|
||||||
|
registry.register_type(MissingExtensionsLoader)
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
registry.register_type(InvalidTypeExtensionsLoader)
|
||||||
|
|
||||||
|
with pytest.raises(ValueError):
|
||||||
|
registry.register_type(EmptyExtensionsLoader)
|
||||||
|
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
registry.register_type(InvalidExtensionsLoader)
|
||||||
|
|
||||||
|
|
||||||
|
def test_loader_success(test_filename):
|
||||||
|
"""Tests that a normal dummy loader successfully loads."""
|
||||||
|
|
||||||
|
with registered_type(DummyLoader):
|
||||||
|
model = Loader.get_global_ptr().load_sync(test_filename, LoaderOptions(LoaderOptions.LF_no_cache))
|
||||||
|
assert model is not None
|
||||||
|
assert model.name == "loaded"
|
||||||
|
|
||||||
|
|
||||||
|
def test_loader_extensions(test_filename):
|
||||||
|
"""Tests multi-extension loaders."""
|
||||||
|
|
||||||
|
class MultiExtensionLoader:
|
||||||
|
extensions = ["test1", "teSt2"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load_file(path, options, record=None):
|
||||||
|
return ModelRoot("loaded")
|
||||||
|
|
||||||
|
fp1 = tempfile.NamedTemporaryFile(suffix='.test1', delete=False)
|
||||||
|
fp1.write(b"test1")
|
||||||
|
fp1.close()
|
||||||
|
fp2 = tempfile.NamedTemporaryFile(suffix='.TEST2', delete=False)
|
||||||
|
fp2.write(b"test2")
|
||||||
|
fp2.close()
|
||||||
|
|
||||||
|
try:
|
||||||
|
with registered_type(MultiExtensionLoader):
|
||||||
|
model1 = Loader.get_global_ptr().load_sync(fp1.name, LoaderOptions(LoaderOptions.LF_no_cache))
|
||||||
|
assert model1 is not None
|
||||||
|
assert model1.name == "loaded"
|
||||||
|
|
||||||
|
model2 = Loader.get_global_ptr().load_sync(fp2.name, LoaderOptions(LoaderOptions.LF_no_cache))
|
||||||
|
assert model2 is not None
|
||||||
|
assert model2.name == "loaded"
|
||||||
|
finally:
|
||||||
|
os.unlink(fp1.name)
|
||||||
|
os.unlink(fp2.name)
|
||||||
|
|
||||||
|
# Ensure that both were unregistered.
|
||||||
|
registry = LoaderFileTypeRegistry.get_global_ptr()
|
||||||
|
assert not registry.get_type_from_extension("test1")
|
||||||
|
assert not registry.get_type_from_extension("test2")
|
||||||
|
|
||||||
|
|
||||||
|
def test_loader_nonexistent():
|
||||||
|
"""Verifies that non-existent files fail before calling load_file."""
|
||||||
|
flag = [False]
|
||||||
|
|
||||||
|
class AssertiveLoader:
|
||||||
|
extensions = ["test"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load_file(path, options, record=None):
|
||||||
|
flag[0] = True
|
||||||
|
assert False, "should never get here"
|
||||||
|
|
||||||
|
with registered_type(AssertiveLoader):
|
||||||
|
model = Loader.get_global_ptr().load_sync("/non-existent", LoaderOptions(LoaderOptions.LF_no_cache))
|
||||||
|
assert model is None
|
||||||
|
assert not flag[0]
|
||||||
|
|
||||||
|
|
||||||
|
def test_loader_exception(test_filename):
|
||||||
|
"""Tests for a loader that raises an exception."""
|
||||||
|
|
||||||
|
class FailingLoader:
|
||||||
|
extensions = ["test"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load_file(path, options, record=None):
|
||||||
|
raise Exception("test error")
|
||||||
|
|
||||||
|
with registered_type(FailingLoader):
|
||||||
|
model = Loader.get_global_ptr().load_sync(test_filename, LoaderOptions(LoaderOptions.LF_no_cache))
|
||||||
|
assert model is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_loader_compressed(test_pz_filename):
|
||||||
|
"""Tests for loading .pz files and the supports_compressed flag."""
|
||||||
|
|
||||||
|
class TestLoader:
|
||||||
|
extensions = ["test"]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def load_file(path, options, record=None):
|
||||||
|
return ModelRoot("loaded")
|
||||||
|
|
||||||
|
# Test with property absent
|
||||||
|
with registered_type(TestLoader):
|
||||||
|
model = Loader.get_global_ptr().load_sync(test_pz_filename, LoaderOptions(LoaderOptions.LF_no_cache))
|
||||||
|
assert model is None
|
||||||
|
|
||||||
|
# Test with property False, should give same result
|
||||||
|
TestLoader.supports_compressed = False
|
||||||
|
with registered_type(TestLoader):
|
||||||
|
model = Loader.get_global_ptr().load_sync(test_pz_filename, LoaderOptions(LoaderOptions.LF_no_cache))
|
||||||
|
assert model is None
|
||||||
|
|
||||||
|
# Test with property True, should work
|
||||||
|
TestLoader.supports_compressed = True
|
||||||
|
with registered_type(TestLoader):
|
||||||
|
model = Loader.get_global_ptr().load_sync(test_pz_filename, LoaderOptions(LoaderOptions.LF_no_cache))
|
||||||
|
assert model is not None
|
||||||
|
assert model.name == "loaded"
|
||||||
|
|
||||||
|
# Test with property invalid type, should not register
|
||||||
|
TestLoader.supports_compressed = None
|
||||||
|
with pytest.raises(TypeError):
|
||||||
|
LoaderFileTypeRegistry.get_global_ptr().register_type(TestLoader)
|
||||||
|
|
||||||
|
|
||||||
|
def test_loader_ram_cache(test_filename):
|
||||||
|
"""Tests that the Python loader plug-ins write to the RAM cache."""
|
||||||
|
|
||||||
|
# Ensure a clean slate.
|
||||||
|
from panda3d.core import ModelPool
|
||||||
|
ModelPool.release_all_models()
|
||||||
|
|
||||||
|
with registered_type(DummyLoader):
|
||||||
|
model1 = Loader.get_global_ptr().load_sync(test_filename, LoaderOptions(LoaderOptions.LF_no_disk_cache | LoaderOptions.LF_allow_instance))
|
||||||
|
assert model1 is not None
|
||||||
|
assert model1.name == "loaded"
|
||||||
|
|
||||||
|
assert ModelPool.has_model(test_filename)
|
||||||
|
assert ModelPool.get_model(test_filename, True) == model1
|
||||||
|
|
||||||
|
model2 = Loader.get_global_ptr().load_sync(test_filename, LoaderOptions(LoaderOptions.LF_cache_only | LoaderOptions.LF_allow_instance))
|
||||||
|
assert model2 is not None
|
||||||
|
assert model1 == model2
|
||||||
|
|
||||||
|
ModelPool.release_model(model2)
|
Loading…
x
Reference in New Issue
Block a user