Files
Text-Texture-Generator-for-…/tests/e2e/scripts/test_texture_generation.py
2025-10-10 11:28:22 +02:00

143 lines
5.3 KiB
Python

#!/usr/bin/env python3
"""
Blender Python script that runs INSIDE Blender to test texture generation.
This script has NO mocks - it uses the real addon code with real bpy.
CRITICAL: This test calls the ACTUAL Blender operator (bpy.ops.text_texture.generate_shader)
because the bug is in the OPERATOR's truthiness check at generation_ops.py:241-247,
not in the generate_texture_image() function itself.
"""
import sys
import bpy
def test_shader_creation_with_texture():
"""
E2E test: Call the ACTUAL Blender operator to expose truthiness bug.
BUG LOCATION: src/operators/generation_ops.py:241-247
```python
result = generate_texture_image(props, final_width, final_height)
if not result: # ❌ BUG: (None, None) is TRUTHY in Python!
self.report({'ERROR'}, "Failed to generate texture image")
return {'CANCELLED'}
```
When generate_texture_image() returns (None, None):
- `not result` evaluates to False (non-empty tuple is truthy)
- Error check is bypassed
- Code continues until line 263 where it tries to use None values
This test MUST call bpy.ops.text_texture.generate_shader() (the operator)
NOT generate_texture_image() (the function) to expose the bug.
"""
# Clean slate - remove default objects
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete()
# Create a new cube (we need an object to attach material to)
bpy.ops.mesh.primitive_cube_add()
cube = bpy.context.active_object
# Set up scene properties for texture generation
props = bpy.context.scene.text_texture_props
# Configure text using the actual property structure
props.text = "böhm Kabel"
props.append_text = "NYY"
# Set dimensions (user-specified, not generated)
props.texture_width = 4096
props.texture_height = 512
# Configure shader settings
props.shader_type = 'PRINCIPLED'
props.shader_connection = 'BASE_COLOR'
props.auto_assign_material = True
props.generate_normal_map = False
props.background_transparent = True
print(f"\nTest scenario:")
print(f" Main text: {props.text}")
print(f" Append text: {props.append_text}")
print(f" Dimensions: {props.texture_width}x{props.texture_height}")
print(f"\nCalling bpy.ops.text_texture.generate_shader()...")
# CRITICAL: Call the OPERATOR (not the function!)
# This is the REAL code path that users trigger from the UI
try:
result = bpy.ops.text_texture.generate_shader()
print(f"Operator returned: {result}")
except Exception as e:
print(f"FAILURE: Operator raised exception: {e}")
import traceback
traceback.print_exc()
sys.exit(1)
# Assert 1: Operator should return {'FINISHED'} on success
# Current bug: Will return {'CANCELLED'} because truthiness check at line 241 is wrong
if result != {'FINISHED'}:
print(f"FAILURE: Operator returned {result} instead of {{'FINISHED'}}")
print(f"This confirms the truthiness bug at generation_ops.py:241-247")
print(f"The check 'if not result:' fails when result is (None, None)")
print(f"because non-empty tuples are truthy in Python!")
sys.exit(1)
# Assert 2: Material should be created
# The material name is based on sanitized text
materials = [m.name for m in bpy.data.materials]
print(f"Available materials: {materials}")
# Check for TextTexture_Mat prefix (the actual naming pattern used)
material_found = any("TextTexture_Mat" in m for m in materials)
if not material_found:
print(f"FAILURE: No TextTexture_Mat material found")
print(f"This indicates the operator failed to complete shader creation")
sys.exit(1)
# Assert 3: Texture image should be created
images = [i.name for i in bpy.data.images]
print(f"Available images: {images}")
# Check for TextTexture prefix (the actual naming pattern used)
image_found = any("TextTexture" in i for i in images)
if not image_found:
print(f"FAILURE: No TextTexture image found")
print(f"This indicates generate_texture_image() returned None or (None, None)")
sys.exit(1)
# Get the actual image
img = None
for image in bpy.data.images:
if "TextTexture" in image.name and "Normal" not in image.name:
img = image
break
if not img:
print(f"FAILURE: Could not retrieve texture image")
sys.exit(1)
# Assert 4: Verify dimensions
actual_width = img.size[0]
actual_height = img.size[1]
if actual_width != 4096 or actual_height != 512:
print(f"FAILURE: Wrong dimensions. Expected 4096x512, got {actual_width}x{actual_height}")
sys.exit(1)
# Assert 5: Material should be assigned to cube
if not cube.data.materials or len(cube.data.materials) == 0:
print(f"FAILURE: No material assigned to cube")
sys.exit(1)
# Success markers for test_addon_real_blender.py to detect
print("SUCCESS: Texture generated successfully with correct dimensions and shader connected")
print(f"SUCCESS: Texture '{img.name}' created with size {actual_width}x{actual_height}")
print(f"SUCCESS: Shader nodes created and connected")
sys.exit(0)
if __name__ == "__main__":
test_shader_creation_with_texture()