247 lines
7.7 KiB
Python
247 lines
7.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Test #93: Vector arithmetic operations
|
|
"""
|
|
|
|
import mcrfpy
|
|
import sys
|
|
import math
|
|
|
|
def test_vector_arithmetic(runtime):
|
|
"""Test vector arithmetic operations"""
|
|
|
|
all_pass = True
|
|
|
|
# Test 1: Vector addition
|
|
try:
|
|
v1 = mcrfpy.Vector(3, 4)
|
|
v2 = mcrfpy.Vector(1, 2)
|
|
v3 = v1 + v2
|
|
|
|
assert v3.x == 4 and v3.y == 6, f"Addition failed: {v3.x}, {v3.y}"
|
|
print("+ Vector addition works correctly")
|
|
except Exception as e:
|
|
print(f"x Vector addition failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 2: Vector subtraction
|
|
try:
|
|
v1 = mcrfpy.Vector(5, 7)
|
|
v2 = mcrfpy.Vector(2, 3)
|
|
v3 = v1 - v2
|
|
|
|
assert v3.x == 3 and v3.y == 4, f"Subtraction failed: {v3.x}, {v3.y}"
|
|
print("+ Vector subtraction works correctly")
|
|
except Exception as e:
|
|
print(f"x Vector subtraction failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 3: Scalar multiplication
|
|
try:
|
|
v1 = mcrfpy.Vector(2, 3)
|
|
v2 = v1 * 3
|
|
v3 = 2 * v1 # Reverse multiplication
|
|
|
|
assert v2.x == 6 and v2.y == 9, f"Scalar multiply failed: {v2.x}, {v2.y}"
|
|
assert v3.x == 4 and v3.y == 6, f"Reverse multiply failed: {v3.x}, {v3.y}"
|
|
print("+ Scalar multiplication works correctly")
|
|
except Exception as e:
|
|
print(f"x Scalar multiplication failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 4: Scalar division
|
|
try:
|
|
v1 = mcrfpy.Vector(10, 20)
|
|
v2 = v1 / 5
|
|
|
|
assert v2.x == 2 and v2.y == 4, f"Division failed: {v2.x}, {v2.y}"
|
|
|
|
# Test division by zero
|
|
try:
|
|
v3 = v1 / 0
|
|
print("x Division by zero should raise exception")
|
|
all_pass = False
|
|
except ZeroDivisionError:
|
|
pass
|
|
|
|
print("+ Scalar division works correctly")
|
|
except Exception as e:
|
|
print(f"x Scalar division failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 5: Negation
|
|
try:
|
|
v1 = mcrfpy.Vector(3, -4)
|
|
v2 = -v1
|
|
|
|
assert v2.x == -3 and v2.y == 4, f"Negation failed: {v2.x}, {v2.y}"
|
|
print("+ Vector negation works correctly")
|
|
except Exception as e:
|
|
print(f"x Vector negation failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 6: Absolute value (magnitude)
|
|
try:
|
|
v1 = mcrfpy.Vector(3, 4)
|
|
mag = abs(v1)
|
|
|
|
assert abs(mag - 5.0) < 0.001, f"Absolute value failed: {mag}"
|
|
print("+ Absolute value (magnitude) works correctly")
|
|
except Exception as e:
|
|
print(f"x Absolute value failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 7: Boolean check
|
|
try:
|
|
v1 = mcrfpy.Vector(0, 0)
|
|
v2 = mcrfpy.Vector(1, 0)
|
|
|
|
assert not bool(v1), "Zero vector should be False"
|
|
assert bool(v2), "Non-zero vector should be True"
|
|
print("+ Boolean check works correctly")
|
|
except Exception as e:
|
|
print(f"x Boolean check failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 8: Equality comparison
|
|
try:
|
|
v1 = mcrfpy.Vector(1.5, 2.5)
|
|
v2 = mcrfpy.Vector(1.5, 2.5)
|
|
v3 = mcrfpy.Vector(1.5, 2.6)
|
|
|
|
assert v1 == v2, "Equal vectors should compare equal"
|
|
assert v1 != v3, "Different vectors should not compare equal"
|
|
print("+ Equality comparison works correctly")
|
|
except Exception as e:
|
|
print(f"x Equality comparison failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 9: magnitude() method
|
|
try:
|
|
v1 = mcrfpy.Vector(3, 4)
|
|
mag = v1.magnitude()
|
|
|
|
assert abs(mag - 5.0) < 0.001, f"magnitude() failed: {mag}"
|
|
print("+ magnitude() method works correctly")
|
|
except Exception as e:
|
|
print(f"x magnitude() method failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 10: magnitude_squared() method
|
|
try:
|
|
v1 = mcrfpy.Vector(3, 4)
|
|
mag_sq = v1.magnitude_squared()
|
|
|
|
assert mag_sq == 25, f"magnitude_squared() failed: {mag_sq}"
|
|
print("+ magnitude_squared() method works correctly")
|
|
except Exception as e:
|
|
print(f"x magnitude_squared() method failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 11: normalize() method
|
|
try:
|
|
v1 = mcrfpy.Vector(3, 4)
|
|
v2 = v1.normalize()
|
|
|
|
assert abs(v2.magnitude() - 1.0) < 0.001, f"normalize() magnitude failed: {v2.magnitude()}"
|
|
assert abs(v2.x - 0.6) < 0.001, f"normalize() x failed: {v2.x}"
|
|
assert abs(v2.y - 0.8) < 0.001, f"normalize() y failed: {v2.y}"
|
|
|
|
# Test zero vector normalization
|
|
v3 = mcrfpy.Vector(0, 0)
|
|
v4 = v3.normalize()
|
|
assert v4.x == 0 and v4.y == 0, "Zero vector normalize should remain zero"
|
|
|
|
print("+ normalize() method works correctly")
|
|
except Exception as e:
|
|
print(f"x normalize() method failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 12: dot product
|
|
try:
|
|
v1 = mcrfpy.Vector(3, 4)
|
|
v2 = mcrfpy.Vector(2, 1)
|
|
dot = v1.dot(v2)
|
|
|
|
assert dot == 10, f"dot product failed: {dot}"
|
|
print("+ dot() method works correctly")
|
|
except Exception as e:
|
|
print(f"x dot() method failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 13: distance_to()
|
|
try:
|
|
v1 = mcrfpy.Vector(1, 1)
|
|
v2 = mcrfpy.Vector(4, 5)
|
|
dist = v1.distance_to(v2)
|
|
|
|
assert abs(dist - 5.0) < 0.001, f"distance_to() failed: {dist}"
|
|
print("+ distance_to() method works correctly")
|
|
except Exception as e:
|
|
print(f"x distance_to() method failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 14: angle()
|
|
try:
|
|
v1 = mcrfpy.Vector(1, 0) # Points right
|
|
v2 = mcrfpy.Vector(0, 1) # Points up
|
|
v3 = mcrfpy.Vector(-1, 0) # Points left
|
|
v4 = mcrfpy.Vector(1, 1) # 45 degrees
|
|
|
|
a1 = v1.angle()
|
|
a2 = v2.angle()
|
|
a3 = v3.angle()
|
|
a4 = v4.angle()
|
|
|
|
assert abs(a1 - 0) < 0.001, f"Right angle failed: {a1}"
|
|
assert abs(a2 - math.pi/2) < 0.001, f"Up angle failed: {a2}"
|
|
assert abs(a3 - math.pi) < 0.001, f"Left angle failed: {a3}"
|
|
assert abs(a4 - math.pi/4) < 0.001, f"45deg angle failed: {a4}"
|
|
|
|
print("+ angle() method works correctly")
|
|
except Exception as e:
|
|
print(f"x angle() method failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 15: copy()
|
|
try:
|
|
v1 = mcrfpy.Vector(5, 10)
|
|
v2 = v1.copy()
|
|
|
|
assert v2.x == 5 and v2.y == 10, f"copy() values failed: {v2.x}, {v2.y}"
|
|
|
|
# Modify v2 and ensure v1 is unchanged
|
|
v2.x = 20
|
|
assert v1.x == 5, "copy() should create independent object"
|
|
|
|
print("+ copy() method works correctly")
|
|
except Exception as e:
|
|
print(f"x copy() method failed: {e}")
|
|
all_pass = False
|
|
|
|
# Test 16: Operations with invalid types
|
|
try:
|
|
v1 = mcrfpy.Vector(1, 2)
|
|
|
|
# These should return NotImplemented
|
|
result = v1 + "string"
|
|
assert result is NotImplemented, "Invalid addition should return NotImplemented"
|
|
|
|
result = v1 * [1, 2]
|
|
assert result is NotImplemented, "Invalid multiplication should return NotImplemented"
|
|
|
|
print("+ Type checking works correctly")
|
|
except Exception as e:
|
|
# Expected to fail with TypeError
|
|
if "unsupported operand type" in str(e):
|
|
print("+ Type checking works correctly")
|
|
else:
|
|
print(f"x Type checking failed: {e}")
|
|
all_pass = False
|
|
|
|
print(f"\n{'PASS' if all_pass else 'FAIL'}")
|
|
sys.exit(0 if all_pass else 1)
|
|
|
|
# Run test
|
|
mcrfpy.createScene("test")
|
|
mcrfpy.setTimer("test", test_vector_arithmetic, 100) |