def test_bbox(py_c_vec): """Test the functionality of Vec.bbox().""" Vec, Angle, Matrix, parse_vec_str = py_c_vec # No arguments with raises_typeerror: Vec.bbox() # Non-iterable with raises_typeerror: Vec.bbox(None) # Starting with non-vector. with raises_typeerror: Vec.bbox(None, Vec()) # Containing non-vector. with raises_typeerror: Vec.bbox(Vec(), None) # Empty iterable. with raises_valueerror: Vec.bbox([]) # Iterable starting with non-vector. with raises_typeerror: Vec.bbox([None]) # Iterable containing non-vector. with raises_typeerror: Vec.bbox([Vec(), None]) def test(*values): """Test these values work.""" min_x = min([v.x for v in values]) min_y = min([v.y for v in values]) min_z = min([v.z for v in values]) max_x = max([v.x for v in values]) max_y = max([v.y for v in values]) max_z = max([v.z for v in values]) # Check passing a single iterable. bb_min, bb_max = Vec.bbox(values) assert_vec(bb_min, min_x, min_y, min_z, values) assert_vec(bb_max, max_x, max_y, max_z, values) # Check passing each value individually. bb_min, bb_max = Vec.bbox(*values) assert_vec(bb_min, min_x, min_y, min_z, values) assert_vec(bb_max, max_x, max_y, max_z, values) test(Vec(0.0, 0.0, 0.0)) test(Vec(1.0, -1.0, 0.0), Vec(2.4, -2.4, 5.5)) test(Vec(2.3, 4.5, 5.6), Vec(-3.4, 4.8, -2.3), Vec(-2.3, 8.2, 3.4)) # Extreme double values. test(Vec(2.346436e47, -4.345e49, 3.59e50), Vec(-7.54e50, 3.45e127, -1.23e140))
def test_axis_angle(py_c_vec) -> None: """Test Matrix.axis_angle() computes the 6 basis vectors correctly.""" Vec, Angle, Matrix, parse_vec_str = py_c_vec def test(axis, equiv_ang: Py_Angle): for ang in range(0, 360, 15): assert_rot(Matrix.axis_angle(axis, ang), Matrix.from_angle(ang * equiv_ang), f'{axis} * {ang} != {equiv_ang}') # Inverse axis = reversed rotation. assert_rot(Matrix.axis_angle(-axis, ang), Matrix.from_angle(-ang * equiv_ang), f'{-axis} * {ang} != {equiv_ang}') test(Vec(1, 0, 0), Angle(0, 0, 1)) test(Vec(0, 1, 0), Angle(1, 0, 0)) test(Vec(0, 0, 1), Angle(0, 1, 0))
def test_order(py_c_vec): """Test ordering operations (>, <, <=, >=, ==).""" comp_ops = [op.eq, op.le, op.lt, op.ge, op.gt, op.ne] def test(x1, y1, z1, x2, y2, z2): """Check a Vec pair for incorrect comparisons.""" vec1 = Vec(x1, y1, z1) vec2 = Vec(x2, y2, z2) for op_func in comp_ops: if op_func is op.ne: # special-case - != uses or, not and corr_result = x1 != x2 or y1 != y2 or z1 != z2 else: corr_result = op_func(x1, x2) and op_func(y1, y2) and op_func( z1, z2) comp = ('Incorrect {{}} comparison for ' '({} {} {}) {} ({} {} {})'.format(x1, y1, z1, op_func.__name__, x2, y2, z2)) assert op_func(vec1, vec2) == corr_result, comp.format('Vec') assert op_func(vec1, Vec_tuple( x2, y2, z2)) == corr_result, comp.format('Vec_tuple') assert op_func(vec1, (x2, y2, z2)) == corr_result, comp.format('tuple') # Bare numbers compare magnitude.. assert op_func(vec1, x2) == op_func(vec1.mag(), x2), comp.format('x') assert op_func(vec1, y2) == op_func(vec1.mag(), y2), comp.format('y') assert op_func(vec1, z2) == op_func(vec1.mag(), z2), comp.format('z') for num in VALID_ZERONUMS: for num2 in VALID_ZERONUMS: # Test the whole comparison, then each axis pair seperately test(num, num, num, num2, num2, num2) test(0, num, num, num2, num2, num2) test(num, 0, num, num, num2, num2) test(num, num, 0, num2, num2, num2) test(num, num, num, 0, num2, num2) test(num, num, num, num, 0, num2) test(num, num, num, num, num, 0)
def test_vec_to_vec(py_c_vec): """Check that Vec() +/- Vec() does the correct thing. For +, -, two Vectors apply the operations to all values. Dot and cross products do something different. """ operators = [ ('+', op.add, op.iadd), ('-', op.sub, op.isub), ] def test(x1, y1, z1, x2, y2, z2): """Check a Vec pair for addition and subtraction.""" vec1 = Vec(x1, y1, z1) vec2 = Vec(x2, y2, z2) # These are direct methods, so no inheritence and iop to deal with. # Commutative assert vec1.dot(vec2) == (x1 * x2 + y1 * y2 + z1 * z2) assert vec2.dot(vec1) == (x1 * x2 + y1 * y2 + z1 * z2) assert_vec( vec1.cross(vec2), y1 * z2 - z1 * y2, z1 * x2 - x1 * z2, x1 * y2 - y1 * x2, ) # Ensure they haven't modified the originals assert_vec(vec1, x1, y1, z1) assert_vec(vec2, x2, y2, z2) # Addition and subtraction for op_name, op_func, op_ifunc in operators: result = ( op_func(x1, x2), op_func(y1, y2), op_func(z1, z2), ) assert_vec(op_func(vec1, vec2), *result, msg='Vec({} {} {}) {} Vec({} {} {})'.format( x1, y1, z1, op_name, x2, y2, z2, )) # Ensure they haven't modified the originals assert_vec(vec1, x1, y1, z1) assert_vec(vec2, x2, y2, z2) assert_vec(op_func(vec1, Vec_tuple(x2, y2, z2)), *result, msg='Vec({} {} {}) {} Vec_tuple({} {} {})'.format( x1, y1, z1, op_name, x2, y2, z2, )) assert_vec(vec1, x1, y1, z1) assert_vec(op_func(Vec_tuple(x1, y1, z1), vec2), *result, msg='Vec_tuple({} {} {}) {} Vec({} {} {})'.format( x1, y1, z1, op_name, x2, y2, z2, )) assert_vec(vec2, x2, y2, z2) new_vec1 = Vec(x1, y1, z1) assert_vec(op_ifunc(new_vec1, vec2), *result, msg='Return val: ({} {} {}) {}= ({} {} {})'.format( x1, y1, z1, op_name, x2, y2, z2, )) # Check it modifies the original object too. assert_vec(new_vec1, *result, msg='Original: ({} {} {}) {}= ({} {} {})'.format( x1, y1, z1, op_name, x2, y2, z2, )) new_vec1 = Vec(x1, y1, z1) assert_vec(op_ifunc(new_vec1, tuple(vec2)), *result, msg='Return val: ({} {} {}) {}= tuple({} {} {})'.format( x1, y1, z1, op_name, x2, y2, z2, )) # Check it modifies the original object too. assert_vec(new_vec1, *result, msg='Original: ({} {} {}) {}= tuple({} {} {})'.format( x1, y1, z1, op_name, x2, y2, z2, )) for num in VALID_ZERONUMS: for num2 in VALID_ZERONUMS: # Test the whole value, then each axis individually test(num, num, num, num2, num2, num2) test(0, num, num, num2, num2, num2) test(num, 0, num, num, num2, num2) test(num, num, 0, num2, num2, num2) test(num, num, num, 0, num2, num2) test(num, num, num, num, 0, num2) test(num, num, num, num, num, 0)
def test_equality(py_c_vec) -> None: """Test equality checks on Angles.""" Vec, Angle, Matrix, parse_vec_str = py_c_vec def test(p1, y1, r1, p2, y2, r2): """Check an Angle pair for incorrect comparisons.""" ang1 = Angle(p1, y1, r1) ang2 = Angle(p2, y2, r2) equal = (abs(p1 - p2) % 360.0) < 1e-6 and (abs(y1 - y2) % 360.0) < 1e-6 and (abs(r1 - r2) % 360.0) < 1e-6 comp = f'({p1} {y1} {r1}) ? ({p2} {y2} {r2})' assert (ang1 == ang2) == equal, comp + f' ang == ang' assert (ang1 == (p2, y2, r2)) == equal, comp + ' ang == tup' assert ((p1, y1, r1) == ang2) == equal, comp + ' tup == ang' assert (ang1 != ang2) != equal, comp + ' ang != ang' assert (ang1 != (p2, y2, r2)) != equal, comp + ' ang != tup' assert ((p1, y1, r1) != ang2) != equal, comp + ' tup != ang' # Test the absolute accuracy. values = VALID_ZERONUMS + [38.0, (38.0 + 1.1e6), (38.0 + 1e7)] for num in values: for num2 in values: # Test the whole comparison, then each axis pair seperately test(num, num, num, num2, num2, num2) test(0, num, num, num2, num2, num2) test(num, 0, num, num, num2, num2) test(num, num, 0, num2, num2, num2) test(num, num, num, 0, num2, num2) test(num, num, num, num, 0, num2) test(num, num, num, num, num, 0) # Test 360 wraps work. test(num, 0.0, 5.0 + num, num + 360.0, 0.0, num - 355.0)