Files
AnyImage/tests/anyimage/operators/test_native_ai_failures.py
nan 489003c2cc Add new tests and functionality for image processing and geometry handling
- Introduced color_image.py for preparing standalone color images for tests.
- Added hdr_image.py to create HDR textures for testing.
- Implemented test_image_depth_panorama.py to evaluate panorama topology, UVs, and depth discontinuities.
- Created test_shadeless.py to validate the opacity and HDR color endpoints of the Shadeless group.
- Developed moge3_export.py for exporting dynamic MoGe-3 backbone and ONNX graphs.
- Added material.py to inherit material slots onto generated geometry.
- Built image_depth_panorama.py to construct a quad panorama with depth separation and sampling.
2026-09-10 14:42:17 +08:00

78 lines
3.3 KiB
Python

from unittest.mock import patch
import bpy
import pytest
from anyimage.operators import ai_setup, remove_background
from anyimage.operators.convert_to_plane import operators as plane
@pytest.mark.parametrize("kind", ["background", "depth", "relief"])
def test_nested_native_operator_preserves_plain_error(kind, tmp_path, capfd):
reason = "Unsupported input format: .tiff"
if kind == "background":
inner, outer = remove_background.RunBackgroundRemoval, remove_background.RemoveImageBackground
else:
inner = plane.GenerateDepthPlane
outer = plane.ConvertToDepthPlane if kind == "depth" else plane.ConvertToReliefPlane
def reject(operator, context):
operator.report({"ERROR"}, reason)
return {"CANCELLED"}
prepared = tmp_path / "prepared"
prepared.mkdir()
path = prepared / "input.png"
path.touch()
with (
patch.object(inner, "execute", reject),
patch.object(outer, "poll", classmethod(lambda cls, context: True)),
patch.object(plane, "invoke_ai_setup_if_needed", return_value=None),
patch.object(plane, "prepare_material_color_input", return_value=path),
patch.object(plane, "material_analysis_input", return_value=path),
patch.object(plane, "depth_plane_settings", return_value=("model", 5)),
patch.object(plane, "configured_max_ai_input_size", return_value=2048),
):
owner = bpy.data.objects.new("Native validation source", None)
image = bpy.data.images.new("Native validation image", width=1, height=1)
owner.empty_display_type = "IMAGE"
owner.data = image
bpy.context.scene.collection.objects.link(owner)
bpy.context.view_layer.objects.active = owner
bpy.utils.register_class(inner)
bpy.utils.register_class(outer)
try:
with pytest.raises(RuntimeError) as error:
getattr(bpy.ops.anyimage, outer.bl_idname.split(".")[1])()
assert str(error.value).strip() == f"Error: {reason}"
assert "Traceback" not in capfd.readouterr().err
if kind != "background":
assert not prepared.exists()
finally:
bpy.utils.unregister_class(outer)
bpy.utils.unregister_class(inner)
bpy.data.objects.remove(owner, do_unlink=True)
bpy.data.images.remove(image)
def test_native_setup_operator_preserves_plain_error(capfd):
class RejectInstall(bpy.types.Operator):
bl_idname = "anyimage.install_environment"
bl_label = "Reject Install"
def execute(self, context):
self.report({"ERROR"}, "Setup unavailable")
return {"CANCELLED"}
with patch.object(ai_setup, "ai_status", return_value={"ready": False, "environment_ready": False}):
bpy.utils.register_class(RejectInstall)
bpy.utils.register_class(ai_setup.SetupAIEnvironment)
try:
with pytest.raises(RuntimeError) as error:
bpy.ops.anyimage.setup_ai_environment(use_mirror=False)
assert str(error.value).strip() == "Error: Setup unavailable"
assert "Traceback" not in capfd.readouterr().err
finally:
bpy.utils.unregister_class(ai_setup.SetupAIEnvironment)
bpy.utils.unregister_class(RejectInstall)