Squashed commit of the following: [alpha_streamline_1]
the low-hanging fruit of pre-existing issues and standardizing the
Python interfaces
Special thanks to Claude Code, ~100k output tokens for this merge
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <noreply@anthropic.com>
commit 99f301e3a0
Author: John McCardle <mccardle.john@gmail.com>
Date: Sat Jul 5 16:25:32 2025 -0400
Add position tuple support and pos property to UI elements
closes #83, closes #84
- Issue #83: Add position tuple support to constructors
- Frame and Sprite now accept both (x, y) and ((x, y)) forms
- Also accept Vector objects as position arguments
- Caption and Entity already supported tuple/Vector forms
- Uses PyVector::from_arg for flexible position parsing
- Issue #84: Add pos property to Frame and Sprite
- Added pos getter that returns a Vector
- Added pos setter that accepts Vector or tuple
- Provides consistency with Caption and Entity which already had pos properties
- All UI elements now have a uniform way to get/set positions as Vectors
Both features improve API consistency and make it easier to work with positions.
commit 2f2b488fb5
Author: John McCardle <mccardle.john@gmail.com>
Date: Sat Jul 5 16:18:10 2025 -0400
Standardize sprite_index property and add scale_x/scale_y to UISprite
closes #81, closes #82
- Issue #81: Standardized property name to sprite_index across UISprite and UIEntity
- Added sprite_index as the primary property name
- Kept sprite_number as a deprecated alias for backward compatibility
- Updated repr() methods to use sprite_index
- Updated animation system to recognize both names
- Issue #82: Added scale_x and scale_y properties to UISprite
- Enables non-uniform scaling of sprites
- scale property still works for uniform scaling
- Both properties work with the animation system
All existing code using sprite_number continues to work due to backward compatibility.
commit 5a003a9aa5
Author: John McCardle <mccardle.john@gmail.com>
Date: Sat Jul 5 16:09:52 2025 -0400
Fix multiple low priority issues
closes #12, closes #80, closes #95, closes #96, closes #99
- Issue #12: Set tp_new to NULL for GridPoint and GridPointState to prevent instantiation from Python
- Issue #80: Renamed Caption.size to Caption.font_size for semantic clarity
- Issue #95: Fixed UICollection repr to show actual derived types instead of generic UIDrawable
- Issue #96: Added extend() method to UICollection for API consistency with UIEntityCollection
- Issue #99: Exposed read-only properties for Texture (sprite_width, sprite_height, sheet_width, sheet_height, sprite_count, source) and Font (family, source)
All issues have corresponding tests that verify the fixes work correctly.
commit e5affaf317
Author: John McCardle <mccardle.john@gmail.com>
Date: Sat Jul 5 15:50:09 2025 -0400
Fix critical issues: script loading, entity types, and color properties
- Issue #37: Fix Windows scripts subdirectory not checked
- Updated executeScript() to use executable_path() from platform.h
- Scripts now load correctly when working directory differs from executable
- Issue #76: Fix UIEntityCollection returns wrong type
- Updated UIEntityCollectionIter::next() to check for stored Python object
- Derived Entity classes now preserve their type when retrieved from collections
- Issue #9: Recreate RenderTexture when resized (already fixed)
- Confirmed RenderTexture recreation already implemented in set_size() and set_float_member()
- Uses 1.5x padding and 4096 max size limit
- Issue #79: Fix Color r, g, b, a properties return None
- Implemented get_member() and set_member() in PyColor.cpp
- Color component properties now work correctly with proper validation
- Additional fix: Grid.at() method signature
- Changed from METH_O to METH_VARARGS to accept two arguments
All fixes include comprehensive tests to verify functionality.
closes #37, closes #76, closes #9, closes #79
This commit is contained in:
parent
e6dbb2d560
commit
cd0bd5468b
41 changed files with 4212 additions and 34 deletions
169
tests/issue_95_uicollection_repr_test.py
Normal file
169
tests/issue_95_uicollection_repr_test.py
Normal file
|
|
@ -0,0 +1,169 @@
|
|||
#!/usr/bin/env python3
|
||||
"""
|
||||
Test for Issue #95: Fix UICollection __repr__ type display
|
||||
|
||||
This test verifies that UICollection's repr shows the actual types of contained
|
||||
objects instead of just showing them all as "UIDrawable".
|
||||
"""
|
||||
|
||||
import mcrfpy
|
||||
import sys
|
||||
|
||||
def test_uicollection_repr():
|
||||
"""Test UICollection repr shows correct types"""
|
||||
print("=== Testing UICollection __repr__ Type Display (Issue #95) ===\n")
|
||||
|
||||
tests_passed = 0
|
||||
tests_total = 0
|
||||
|
||||
# Get scene UI collection
|
||||
scene_ui = mcrfpy.sceneUI("test")
|
||||
|
||||
# Test 1: Empty collection
|
||||
print("--- Test 1: Empty collection ---")
|
||||
tests_total += 1
|
||||
repr_str = repr(scene_ui)
|
||||
print(f"Empty collection repr: {repr_str}")
|
||||
if "0 objects" in repr_str:
|
||||
print("✓ PASS: Empty collection shows correctly")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print("✗ FAIL: Empty collection repr incorrect")
|
||||
|
||||
# Test 2: Add various UI elements
|
||||
print("\n--- Test 2: Mixed UI elements ---")
|
||||
tests_total += 1
|
||||
|
||||
# Add Frame
|
||||
frame = mcrfpy.Frame(10, 10, 100, 100)
|
||||
scene_ui.append(frame)
|
||||
|
||||
# Add Caption
|
||||
caption = mcrfpy.Caption((150, 50), "Test", mcrfpy.Font("assets/JetbrainsMono.ttf"))
|
||||
scene_ui.append(caption)
|
||||
|
||||
# Add Sprite
|
||||
sprite = mcrfpy.Sprite(200, 100)
|
||||
scene_ui.append(sprite)
|
||||
|
||||
# Add Grid
|
||||
grid = mcrfpy.Grid(10, 10)
|
||||
grid.x = 300
|
||||
grid.y = 100
|
||||
scene_ui.append(grid)
|
||||
|
||||
# Check repr
|
||||
repr_str = repr(scene_ui)
|
||||
print(f"Collection repr: {repr_str}")
|
||||
|
||||
# Verify it shows the correct types
|
||||
expected_types = ["1 Frame", "1 Caption", "1 Sprite", "1 Grid"]
|
||||
all_found = all(expected in repr_str for expected in expected_types)
|
||||
|
||||
if all_found and "UIDrawable" not in repr_str:
|
||||
print("✓ PASS: All types shown correctly, no generic UIDrawable")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print("✗ FAIL: Types not shown correctly")
|
||||
for expected in expected_types:
|
||||
if expected in repr_str:
|
||||
print(f" ✓ Found: {expected}")
|
||||
else:
|
||||
print(f" ✗ Missing: {expected}")
|
||||
if "UIDrawable" in repr_str:
|
||||
print(" ✗ Still shows generic UIDrawable")
|
||||
|
||||
# Test 3: Multiple of same type
|
||||
print("\n--- Test 3: Multiple objects of same type ---")
|
||||
tests_total += 1
|
||||
|
||||
# Add more frames
|
||||
frame2 = mcrfpy.Frame(10, 120, 100, 100)
|
||||
frame3 = mcrfpy.Frame(10, 230, 100, 100)
|
||||
scene_ui.append(frame2)
|
||||
scene_ui.append(frame3)
|
||||
|
||||
repr_str = repr(scene_ui)
|
||||
print(f"Collection repr: {repr_str}")
|
||||
|
||||
if "3 Frames" in repr_str:
|
||||
print("✓ PASS: Plural form shown correctly for multiple Frames")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print("✗ FAIL: Plural form not correct")
|
||||
|
||||
# Test 4: Check total count
|
||||
print("\n--- Test 4: Total count verification ---")
|
||||
tests_total += 1
|
||||
|
||||
# Should have: 3 Frames, 1 Caption, 1 Sprite, 1 Grid = 6 total
|
||||
if "6 objects:" in repr_str:
|
||||
print("✓ PASS: Total count shown correctly")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print("✗ FAIL: Total count incorrect")
|
||||
|
||||
# Test 5: Nested collections (Frame with children)
|
||||
print("\n--- Test 5: Nested collections ---")
|
||||
tests_total += 1
|
||||
|
||||
# Add child to frame
|
||||
child_sprite = mcrfpy.Sprite(10, 10)
|
||||
frame.children.append(child_sprite)
|
||||
|
||||
# Check frame's children collection
|
||||
children_repr = repr(frame.children)
|
||||
print(f"Frame children repr: {children_repr}")
|
||||
|
||||
if "1 Sprite" in children_repr:
|
||||
print("✓ PASS: Nested collection shows correct type")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print("✗ FAIL: Nested collection type incorrect")
|
||||
|
||||
# Test 6: Collection remains valid after modifications
|
||||
print("\n--- Test 6: Collection after modifications ---")
|
||||
tests_total += 1
|
||||
|
||||
# Remove an item
|
||||
scene_ui.remove(0) # Remove first frame
|
||||
|
||||
repr_str = repr(scene_ui)
|
||||
print(f"After removal repr: {repr_str}")
|
||||
|
||||
if "2 Frames" in repr_str and "5 objects:" in repr_str:
|
||||
print("✓ PASS: Collection repr updated correctly after removal")
|
||||
tests_passed += 1
|
||||
else:
|
||||
print("✗ FAIL: Collection repr not updated correctly")
|
||||
|
||||
# Summary
|
||||
print(f"\n=== SUMMARY ===")
|
||||
print(f"Tests passed: {tests_passed}/{tests_total}")
|
||||
|
||||
if tests_passed == tests_total:
|
||||
print("\nIssue #95 FIXED: UICollection __repr__ now shows correct types!")
|
||||
else:
|
||||
print("\nIssue #95: Some tests failed")
|
||||
|
||||
return tests_passed == tests_total
|
||||
|
||||
def run_test(runtime):
|
||||
"""Timer callback to run the test"""
|
||||
try:
|
||||
success = test_uicollection_repr()
|
||||
print("\nOverall result: " + ("PASS" if success else "FAIL"))
|
||||
except Exception as e:
|
||||
print(f"\nTest error: {e}")
|
||||
import traceback
|
||||
traceback.print_exc()
|
||||
print("\nOverall result: FAIL")
|
||||
|
||||
sys.exit(0)
|
||||
|
||||
# Set up the test scene
|
||||
mcrfpy.createScene("test")
|
||||
mcrfpy.setScene("test")
|
||||
|
||||
# Schedule test to run after game loop starts
|
||||
mcrfpy.setTimer("test", run_test, 100)
|
||||
Loading…
Add table
Add a link
Reference in a new issue