#!/usr/bin/env python3 """Tests for ora_ops module.""" import io import os import sys import tempfile import zipfile from pathlib import Path from PIL import Image # Add parent directory to path sys.path.insert(0, str(Path(__file__).parent.parent)) from ora_editor.ora_ops import ( load_ora, create_ora_from_png, add_masked_layer, rename_layer, delete_layer, reorder_layer, get_layer_visibility, set_layer_visibility, save_ora, parse_stack_xml, get_image_size, get_groups_and_layers ) def test_create_ora_from_png(): """Test creating an ORA from a PNG file.""" # Create a simple test PNG test_img = Image.new('RGBA', (100, 100), (255, 0, 0, 255)) with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as png_f: test_img.save(png_f.name) png_path = png_f.name with tempfile.NamedTemporaryFile(suffix='.ora', delete=False) as ora_f: ora_path = ora_f.name try: result = create_ora_from_png(png_path, ora_path) assert result['success'], f"Failed to create ORA: {result.get('error')}" assert os.path.exists(ora_path), "ORA file was not created" # Verify we can load it back loaded = load_ora(ora_path) assert 'layers' in loaded, "Loaded ORA has no layers" assert len(loaded['layers']) == 1, f"Expected 1 layer, got {len(loaded['layers'])}" print("✓ create_ora_from_png passed") return True finally: os.unlink(png_path) if os.path.exists(ora_path): os.unlink(ora_path) def test_load_ora(): """Test loading an existing ORA file.""" with tempfile.NamedTemporaryFile(suffix='.ora', delete=False) as ora_f: ora_path = ora_f.name try: # Create a test PNG first test_img = Image.new('RGBA', (200, 150), (0, 255, 0, 255)) with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as png_f: test_img.save(png_f.name) png_path = png_f.name try: create_ora_from_png(png_path, ora_path) loaded = load_ora(ora_path) assert loaded['width'] == 200, f"Expected width 200, got {loaded['width']}" assert loaded['height'] == 150, f"Expected height 150, got {loaded['height']}" assert len(loaded['layers']) > 0, "No layers found in ORA" print("✓ load_ora passed") return True finally: os.unlink(png_path) finally: if os.path.exists(ora_path): os.unlink(ora_path) def test_add_masked_layer(): """Test adding a masked layer to an ORA.""" # Create base PNG base_img = Image.new('RGBA', (100, 100), (255, 0, 0, 255)) with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as png_f: base_img.save(png_f.name) png_path = png_f.name ora_path = png_path.replace('.png', '.ora') # Create mask (white where visible, black where transparent) mask_img = Image.new('L', (100, 100), 255) with tempfile.NamedTemporaryFile(suffix='.mask.png', delete=False) as mask_f: mask_img.save(mask_f.name) mask_path = mask_f.name try: result = add_masked_layer(ora_path, 'door', mask_path) assert result['success'], f"Failed to add masked layer: {result.get('error')}" assert 'layer_name' in result, "No layer_name in result" assert result['layer_name'] == 'door_0', f"Expected door_0, got {result['layer_name']}" # Verify the layer was added loaded = load_ora(ora_path) layer_names = [l['name'] for l in loaded['layers']] assert 'base' in layer_names, "Base layer missing" assert 'door_0' in layer_names, "Door layer not found" print("✓ add_masked_layer passed") return True finally: os.unlink(png_path) if os.path.exists(ora_path): os.unlink(ora_path) os.unlink(mask_path) def test_rename_layer(): """Test renaming a layer.""" # Create base PNG base_img = Image.new('RGBA', (100, 100), (255, 0, 0, 255)) with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as png_f: base_img.save(png_f.name) png_path = png_f.name ora_path = png_path.replace('.png', '.ora') # Create mask for a new layer mask_img = Image.new('L', (100, 100), 255) with tempfile.NamedTemporaryFile(suffix='.mask.png', delete=False) as mask_f: mask_img.save(mask_f.name) mask_path = mask_f.name try: # First add a layer to rename result = add_masked_layer(ora_path, 'door', mask_path) assert result['success'] # Now rename it result = rename_layer(ora_path, 'door_0', 'wooden_door_0') assert result['success'], f"Failed to rename: {result.get('error')}" loaded = load_ora(ora_path) layer_names = [l['name'] for l in loaded['layers']] assert 'wooden_door_0' in layer_names, "Renamed layer not found" assert 'door_0' not in layer_names, "Old layer name still exists" print("✓ rename_layer passed") return True finally: os.unlink(png_path) if os.path.exists(ora_path): os.unlink(ora_path) os.unlink(mask_path) def test_delete_layer(): """Test deleting a layer.""" # Create base PNG base_img = Image.new('RGBA', (100, 100), (255, 0, 0, 255)) with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as png_f: base_img.save(png_f.name) png_path = png_f.name ora_path = png_path.replace('.png', '.ora') # Create mask for a new layer mask_img = Image.new('L', (100, 100), 255) with tempfile.NamedTemporaryFile(suffix='.mask.png', delete=False) as mask_f: mask_img.save(mask_f.name) mask_path = mask_f.name try: # First add a layer to delete result = add_masked_layer(ora_path, 'door', mask_path) assert result['success'] # Now delete it result = delete_layer(ora_path, 'door_0') assert result['success'], f"Failed to delete: {result.get('error')}" loaded = load_ora(ora_path) layer_names = [l['name'] for l in loaded['layers']] assert 'door_0' not in layer_names, "Deleted layer still exists" print("✓ delete_layer passed") return True finally: os.unlink(png_path) if os.path.exists(ora_path): os.unlink(ora_path) os.unlink(mask_path) def test_reorder_layer(): """Test reordering layers.""" # Create base PNG base_img = Image.new('RGBA', (100, 100), (255, 0, 0, 255)) with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as png_f: base_img.save(png_f.name) png_path = png_f.name ora_path = png_path.replace('.png', '.ora') # Create mask for new layers mask_img = Image.new('L', (100, 100), 255) layer_paths = [] for i in range(3): with tempfile.NamedTemporaryFile(suffix='.mask.png', delete=False) as mask_f: mask_img.save(mask_f.name) layer_paths.append(mask_f.name) try: # Add multiple layers for i, mask_path in enumerate(layer_paths): result = add_masked_layer(ora_path, f'layer{i}', mask_path) assert result['success'], f"Failed to add layer {i}" # Get initial order loaded = load_ora(ora_path) initial_order = [l['name'] for l in loaded['layers']] # Move layer0_0 down (it should stay or move one position) result = reorder_layer(ora_path, 'layer0_0', 'down') assert result['success'], f"Failed to reorder: {result.get('error')}" loaded = load_ora(ora_path) new_order = [l['name'] for l in loaded['layers']] # Verify order changed or stayed valid assert len(new_order) == len(initial_order), "Layer count changed during reorder" print("✓ reorder_layer passed") return True finally: os.unlink(png_path) if os.path.exists(ora_path): os.unlink(ora_path) for path in layer_paths: os.unlink(path) def test_set_layer_visibility(): """Test setting layer visibility.""" base_img = Image.new('RGBA', (100, 100), (255, 0, 0, 255)) with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as png_f: base_img.save(png_f.name) png_path = png_f.name ora_path = png_path.replace('.png', '.ora') mask_img = Image.new('L', (100, 100), 255) with tempfile.NamedTemporaryFile(suffix='.mask.png', delete=False) as mask_f: mask_img.save(mask_f.name) mask_path = mask_f.name try: add_masked_layer(ora_path, 'door', mask_path) # Set visibility to false result = set_layer_visibility(ora_path, 'door_0', False) assert result['success'], f"Failed to set visibility: {result.get('error')}" visible = get_layer_visibility(ora_path, 'door_0') assert visible is False, "Layer should be hidden" # Set visibility back to true result = set_layer_visibility(ora_path, 'door_0', True) assert result['success'] visible = get_layer_visibility(ora_path, 'door_0') assert visible is True, "Layer should be visible" print("✓ set_layer_visibility passed") return True finally: os.unlink(png_path) if os.path.exists(ora_path): os.unlink(ora_path) os.unlink(mask_path) def test_save_ora(): """Test saving an ORA file.""" base_img = Image.new('RGBA', (100, 100), (255, 0, 0, 255)) with tempfile.NamedTemporaryFile(suffix='.png', delete=False) as png_f: base_img.save(png_f.name) png_path = png_f.name ora_path = png_path.replace('.png', '.ora') try: create_ora_from_png(png_path, ora_path) # Save should work without errors result = save_ora(ora_path) assert result, "Failed to save ORA" # Verify we can still load it loaded = load_ora(ora_path) assert len(loaded['layers']) > 0, "Layers missing after save" print("✓ save_ora passed") return True finally: os.unlink(png_path) if os.path.exists(ora_path): os.unlink(ora_path) if __name__ == '__main__': tests = [ test_create_ora_from_png, test_load_ora, test_add_masked_layer, test_rename_layer, test_delete_layer, test_reorder_layer, test_set_layer_visibility, test_save_ora, ] passed = 0 failed = 0 for test in tests: try: if test(): passed += 1 else: failed += 1 except Exception as e: print(f"✗ {test.__name__} failed with exception: {e}") import traceback traceback.print_exc() failed += 1 print(f"\n{passed}/{len(tests)} tests passed") if failed > 0: sys.exit(1)