Files
blender-se-palette/tests/blender_smoke.py
T
2026-09-03 03:17:27 +09:00

91 lines
2.7 KiB
Python

"""Run with: blender --background --factory-startup --python tests/blender_smoke.py"""
import importlib.util
import sys
import types
from pathlib import Path
import bpy
ROOT = Path(__file__).resolve().parents[1]
PACKAGE_NAME = "blender_se_palette"
spec = importlib.util.spec_from_file_location(
PACKAGE_NAME,
ROOT / "__init__.py",
submodule_search_locations=[str(ROOT)],
)
addon = importlib.util.module_from_spec(spec)
sys.modules[PACKAGE_NAME] = addon
spec.loader.exec_module(addon)
addon.register()
try:
assert hasattr(addon.panels, "SEPALETTE_PT_main")
scene = bpy.context.scene
props = scene.se_palette
props.folder = "/home/hare/Assets/SE/"
count = addon.operators.populate_items(props)
assert count == 42, f"Expected 42 sounds, got {count}"
valid_icons = bpy.types.UILayout.bl_rna.functions["operator"].parameters["icon"].enum_items.keys()
for icon, *_rest in addon.operators.ICON_ITEMS:
assert icon in valid_icons, f"Unknown Blender icon: {icon}"
# Headless Blender has no OpenAL output device, but the same decoder used by
# the preview operator must still be able to load the selected file.
import aud
aud.Sound(props.items[0].filepath)
# Repeated previews must reuse a single output device instead of leaking
# one OpenAL device per button press.
real_aud = sys.modules["aud"]
created_devices = []
class FakeHandle:
status = 1
def stop(self):
self.status = 3
class FakeDevice:
def __init__(self):
created_devices.append(self)
def play(self, sound):
return FakeHandle()
def stopAll(self):
pass
sys.modules["aud"] = types.SimpleNamespace(
Device=FakeDevice,
Sound=lambda filepath: filepath,
STATUS_PLAYING=1,
)
try:
addon.operators.stop_preview(release_device=True)
addon.operators._play_preview(props.items[0].filepath)
first_device = addon.operators._preview_device
addon.operators.stop_preview()
addon.operators._play_preview(props.items[1].filepath)
assert addon.operators._preview_device is first_device
assert len(created_devices) == 1
finally:
addon.operators.stop_preview(release_device=True)
sys.modules["aud"] = real_aud
result = bpy.ops.se_palette.insert(filepath=props.items[0].filepath)
assert result == {"FINISHED"}, result
assert len(scene.sequence_editor.strips_all) == 1
strip = scene.sequence_editor.active_strip
assert strip.type == "SOUND"
assert strip.channel == props.channel
assert Path(strip.sound.filepath).name == props.items[0].filename
finally:
addon.unregister()
print("SE_PALETTE_BLENDER_SMOKE_OK")