wip
This commit is contained in:
Binary file not shown.
143
tests/e2e/scripts/test_texture_generation.py
Normal file
143
tests/e2e/scripts/test_texture_generation.py
Normal file
@@ -0,0 +1,143 @@
|
||||
#!/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()
|
||||
Reference in New Issue
Block a user