McRogueFace/tests/unit/discretemap_arithmetic_test.py

226 lines
6.6 KiB
Python

#!/usr/bin/env python3
"""Unit tests for DiscreteMap arithmetic and bitwise operations."""
import mcrfpy
import sys
def test_add_scalar():
"""Test adding a scalar value."""
dmap = mcrfpy.DiscreteMap((10, 10), fill=50)
dmap.add(25)
assert dmap[5, 5] == 75, f"Expected 75, got {dmap[5, 5]}"
# Test saturation at 255
dmap.fill(250)
dmap.add(20) # 250 + 20 = 270 -> saturates to 255
assert dmap[0, 0] == 255, f"Expected 255 (saturated), got {dmap[0, 0]}"
print(" [PASS] Add scalar")
def test_add_map():
"""Test adding another DiscreteMap."""
dmap1 = mcrfpy.DiscreteMap((10, 10), fill=50)
dmap2 = mcrfpy.DiscreteMap((10, 10), fill=30)
dmap1.add(dmap2)
assert dmap1[5, 5] == 80, f"Expected 80, got {dmap1[5, 5]}"
# Test saturation
dmap1.fill(200)
dmap2.fill(100)
dmap1.add(dmap2)
assert dmap1[0, 0] == 255, f"Expected 255 (saturated), got {dmap1[0, 0]}"
print(" [PASS] Add map")
def test_subtract_scalar():
"""Test subtracting a scalar value."""
dmap = mcrfpy.DiscreteMap((10, 10), fill=100)
dmap.subtract(25)
assert dmap[5, 5] == 75, f"Expected 75, got {dmap[5, 5]}"
# Test saturation at 0
dmap.fill(10)
dmap.subtract(20) # 10 - 20 = -10 -> saturates to 0
assert dmap[0, 0] == 0, f"Expected 0 (saturated), got {dmap[0, 0]}"
print(" [PASS] Subtract scalar")
def test_subtract_map():
"""Test subtracting another DiscreteMap."""
dmap1 = mcrfpy.DiscreteMap((10, 10), fill=100)
dmap2 = mcrfpy.DiscreteMap((10, 10), fill=30)
dmap1.subtract(dmap2)
assert dmap1[5, 5] == 70, f"Expected 70, got {dmap1[5, 5]}"
# Test saturation
dmap1.fill(50)
dmap2.fill(100)
dmap1.subtract(dmap2)
assert dmap1[0, 0] == 0, f"Expected 0 (saturated), got {dmap1[0, 0]}"
print(" [PASS] Subtract map")
def test_multiply():
"""Test scalar multiplication."""
dmap = mcrfpy.DiscreteMap((10, 10), fill=50)
dmap.multiply(2.0)
assert dmap[5, 5] == 100, f"Expected 100, got {dmap[5, 5]}"
# Test saturation
dmap.fill(100)
dmap.multiply(3.0) # 100 * 3 = 300 -> saturates to 255
assert dmap[0, 0] == 255, f"Expected 255 (saturated), got {dmap[0, 0]}"
# Test fractional
dmap.fill(100)
dmap.multiply(0.5)
assert dmap[0, 0] == 50, f"Expected 50, got {dmap[0, 0]}"
print(" [PASS] Multiply")
def test_copy_from():
"""Test copy_from operation."""
dmap1 = mcrfpy.DiscreteMap((10, 10), fill=0)
dmap2 = mcrfpy.DiscreteMap((5, 5), fill=99)
dmap1.copy_from(dmap2, pos=(2, 2))
assert dmap1[2, 2] == 99, f"Expected 99 at (2,2), got {dmap1[2, 2]}"
assert dmap1[6, 6] == 99, f"Expected 99 at (6,6), got {dmap1[6, 6]}"
assert dmap1[0, 0] == 0, f"Expected 0 at (0,0), got {dmap1[0, 0]}"
assert dmap1[7, 7] == 0, f"Expected 0 at (7,7), got {dmap1[7, 7]}"
print(" [PASS] Copy from")
def test_max():
"""Test element-wise max."""
dmap1 = mcrfpy.DiscreteMap((10, 10), fill=50)
dmap2 = mcrfpy.DiscreteMap((10, 10), fill=70)
# Set some values in dmap1 higher
dmap1[3, 3] = 100
dmap1.max(dmap2)
assert dmap1[0, 0] == 70, f"Expected 70 at (0,0), got {dmap1[0, 0]}"
assert dmap1[3, 3] == 100, f"Expected 100 at (3,3), got {dmap1[3, 3]}"
print(" [PASS] Max")
def test_min():
"""Test element-wise min."""
dmap1 = mcrfpy.DiscreteMap((10, 10), fill=50)
dmap2 = mcrfpy.DiscreteMap((10, 10), fill=30)
# Set some values in dmap1 lower
dmap1[3, 3] = 10
dmap1.min(dmap2)
assert dmap1[0, 0] == 30, f"Expected 30 at (0,0), got {dmap1[0, 0]}"
assert dmap1[3, 3] == 10, f"Expected 10 at (3,3), got {dmap1[3, 3]}"
print(" [PASS] Min")
def test_bitwise_and():
"""Test bitwise AND."""
dmap1 = mcrfpy.DiscreteMap((10, 10), fill=0xFF) # 11111111
dmap2 = mcrfpy.DiscreteMap((10, 10), fill=0x0F) # 00001111
dmap1.bitwise_and(dmap2)
assert dmap1[0, 0] == 0x0F, f"Expected 0x0F, got {hex(dmap1[0, 0])}"
# Test specific pattern
dmap1.fill(0b10101010)
dmap2.fill(0b11110000)
dmap1.bitwise_and(dmap2)
assert dmap1[0, 0] == 0b10100000, f"Expected 0b10100000, got {bin(dmap1[0, 0])}"
print(" [PASS] Bitwise AND")
def test_bitwise_or():
"""Test bitwise OR."""
dmap1 = mcrfpy.DiscreteMap((10, 10), fill=0x0F) # 00001111
dmap2 = mcrfpy.DiscreteMap((10, 10), fill=0xF0) # 11110000
dmap1.bitwise_or(dmap2)
assert dmap1[0, 0] == 0xFF, f"Expected 0xFF, got {hex(dmap1[0, 0])}"
print(" [PASS] Bitwise OR")
def test_bitwise_xor():
"""Test bitwise XOR."""
dmap1 = mcrfpy.DiscreteMap((10, 10), fill=0xFF)
dmap2 = mcrfpy.DiscreteMap((10, 10), fill=0xFF)
dmap1.bitwise_xor(dmap2)
assert dmap1[0, 0] == 0x00, f"Expected 0x00, got {hex(dmap1[0, 0])}"
dmap1.fill(0b10101010)
dmap2.fill(0b11110000)
dmap1.bitwise_xor(dmap2)
assert dmap1[0, 0] == 0b01011010, f"Expected 0b01011010, got {bin(dmap1[0, 0])}"
print(" [PASS] Bitwise XOR")
def test_invert():
"""Test invert (returns new map)."""
dmap = mcrfpy.DiscreteMap((10, 10), fill=100)
result = dmap.invert()
# Original unchanged
assert dmap[0, 0] == 100, f"Original should be unchanged, got {dmap[0, 0]}"
# Result is inverted
assert result[0, 0] == 155, f"Expected 155 (255-100), got {result[0, 0]}"
# Test edge cases
dmap.fill(0)
result = dmap.invert()
assert result[0, 0] == 255, f"Expected 255, got {result[0, 0]}"
dmap.fill(255)
result = dmap.invert()
assert result[0, 0] == 0, f"Expected 0, got {result[0, 0]}"
print(" [PASS] Invert")
def test_region_operations():
"""Test operations with region parameters."""
dmap1 = mcrfpy.DiscreteMap((20, 20), fill=10)
dmap2 = mcrfpy.DiscreteMap((20, 20), fill=5)
# Add only in a region
dmap1.add(dmap2, pos=(5, 5), source_pos=(0, 0), size=(5, 5))
assert dmap1[5, 5] == 15, f"Expected 15 in region, got {dmap1[5, 5]}"
assert dmap1[9, 9] == 15, f"Expected 15 in region, got {dmap1[9, 9]}"
assert dmap1[0, 0] == 10, f"Expected 10 outside region, got {dmap1[0, 0]}"
assert dmap1[10, 10] == 10, f"Expected 10 outside region, got {dmap1[10, 10]}"
print(" [PASS] Region operations")
def main():
print("Running DiscreteMap arithmetic tests...")
test_add_scalar()
test_add_map()
test_subtract_scalar()
test_subtract_map()
test_multiply()
test_copy_from()
test_max()
test_min()
test_bitwise_and()
test_bitwise_or()
test_bitwise_xor()
test_invert()
test_region_operations()
print("All DiscreteMap arithmetic tests PASSED!")
sys.exit(0)
if __name__ == "__main__":
main()