- Implemented a preview tool for rectifying images with interactive aspect controls in `preview.py`. - Added tests for depth metadata loading to ensure consistent schema usage in `test_depth_metadata.py`. - Developed comprehensive tests for cutout calibration processes in `test_cutout_calibration.py`, including stability checks and depth calibration. - Created tests for frame compositing operations in `test_frame_compositing.py`, ensuring correct handling of depth and transparency. - Introduced material slot inheritance functionality in `material_slots.py` to manage geometry material assignments. - Built shared shader nodes for material processing in `shader.py`, including roughness and bump mapping setups.
101 lines
3.1 KiB
Python
101 lines
3.1 KiB
Python
from tests.support.paths import PROJECT_ROOT
|
|
import importlib.util
|
|
from unittest.mock import patch
|
|
import pytest
|
|
|
|
|
|
SCRIPT_PATH = PROJECT_ROOT / "tools" / "nodes" / "cli.py"
|
|
|
|
|
|
def load_launcher():
|
|
specification = importlib.util.spec_from_file_location(
|
|
"node_asset_launcher",
|
|
SCRIPT_PATH,
|
|
)
|
|
module = importlib.util.module_from_spec(specification)
|
|
specification.loader.exec_module(module)
|
|
return module
|
|
|
|
|
|
def test_blender_path_prefers_explicit_path(tmp_path):
|
|
launcher = load_launcher()
|
|
executable = tmp_path / "blender"
|
|
executable.touch()
|
|
|
|
with patch.dict("os.environ", {"BLENDER_BIN": "ignored"}):
|
|
assert launcher.blender_path(executable) == executable
|
|
|
|
|
|
def test_blender_path_reads_environment(tmp_path):
|
|
launcher = load_launcher()
|
|
executable = tmp_path / "blender"
|
|
executable.touch()
|
|
|
|
with patch.dict("os.environ", {"BLENDER_BIN": str(executable)}):
|
|
assert launcher.blender_path() == executable
|
|
|
|
|
|
def test_blender_path_reads_project_dotenv(tmp_path):
|
|
launcher = load_launcher()
|
|
executable = tmp_path / "Blender 4.5" / "blender.exe"
|
|
executable.parent.mkdir()
|
|
executable.touch()
|
|
env_path = tmp_path / ".env"
|
|
env_path.write_text(
|
|
f'BLENDER_BIN="{executable}"\n',
|
|
encoding="utf-8",
|
|
)
|
|
|
|
with patch.dict("os.environ", {}, clear=True), patch.object(
|
|
launcher,
|
|
"PROJECT_ROOT",
|
|
tmp_path,
|
|
):
|
|
assert launcher.blender_path() == executable
|
|
|
|
|
|
def test_blender_path_reports_missing_configuration(tmp_path):
|
|
launcher = load_launcher()
|
|
|
|
with patch.dict("os.environ", {}, clear=True), patch.object(
|
|
launcher.shutil,
|
|
"which",
|
|
return_value=None,
|
|
), patch.object(
|
|
launcher,
|
|
"PROJECT_ROOT",
|
|
tmp_path,
|
|
):
|
|
with pytest.raises(RuntimeError, match="Blender not found"):
|
|
launcher.blender_path()
|
|
|
|
|
|
@pytest.mark.parametrize("arguments,modules,run_tests", [
|
|
(["build"], ("tools.nodes.build", "tools.nodes.check"), True),
|
|
(["check", "--skip-tests"], ("tools.nodes.check",), False),
|
|
(["preview", "--fragment"], ("tools.nodes.preview.export",), False),
|
|
])
|
|
def test_commands_dispatch_requested_work(monkeypatch, tmp_path, arguments, modules, run_tests):
|
|
launcher = load_launcher()
|
|
output = tmp_path / "node groups.html"
|
|
command = ["node-group", *arguments]
|
|
if arguments[0] == "preview":
|
|
command += ["--output", str(output)]
|
|
monkeypatch.setattr("sys.argv", command)
|
|
monkeypatch.setattr(launcher, "blender_path", lambda _: "blender")
|
|
with (
|
|
patch.object(launcher, "run_blender_modules") as blender,
|
|
patch.object(launcher, "run") as run,
|
|
patch.object(launcher.webbrowser, "open") as open_browser,
|
|
):
|
|
launcher.main()
|
|
if arguments[0] == "preview":
|
|
blender.assert_called_once_with("blender", modules, ["--output", str(output), "--fragment"])
|
|
open_browser.assert_not_called()
|
|
else:
|
|
blender.assert_called_once_with("blender", modules)
|
|
if run_tests:
|
|
run.assert_called_once_with((launcher.sys.executable, "-m", "pytest"))
|
|
else:
|
|
run.assert_not_called()
|