import struct

import numpy as np
import pytest

import miniglm


def test_add_vec_vec():
    res = miniglm.add((1.0, 2.0, 3.0), (1.5, 1.8, 1.2))
    np.testing.assert_almost_equal(res, (2.5, 3.8, 4.2))
    assert type(res) is tuple


def test_add_vec_scalar():
    res = miniglm.add((1.0, 2.0, 3.0), 0.5)
    np.testing.assert_almost_equal(res, (1.5, 2.5, 3.5))
    assert type(res) is tuple


def test_sub_vec_vec():
    res = miniglm.sub((5.0, 6.0, 7.0), (1.5, 1.8, 1.2))
    np.testing.assert_almost_equal(res, (3.5, 4.2, 5.8))
    assert type(res) is tuple


def test_sub_vec_scalar():
    res = miniglm.sub((5.0, 6.0, 7.0), 1.5)
    np.testing.assert_almost_equal(res, (3.5, 4.5, 5.5))
    assert type(res) is tuple


def test_mul_vec_vec():
    res = miniglm.mul((5.0, 6.0, 7.0), (1.5, 1.8, 1.2))
    np.testing.assert_almost_equal(res, (7.5, 10.8, 8.4))
    assert type(res) is tuple


def test_mul_vec_scalar():
    res = miniglm.mul((1.0, 2.0, 3.0), 2.0)
    np.testing.assert_almost_equal(res, (2.0, 4.0, 6.0))
    assert type(res) is tuple


def test_cross():
    res = miniglm.cross((2.0, 3.5, 7.1), (0.2, 10.0, 3.3))
    np.testing.assert_almost_equal(res, (-59.45, -5.18, 19.3))
    assert type(res) is tuple


def test_dot_vec():
    res = miniglm.dot((2.0, 3.5, 7.1), (0.2, 10.0, 3.3))
    np.testing.assert_almost_equal(res, 58.83)


def test_dot_quat():
    res = miniglm.dot((2.0, 3.5, 7.1), (0.2, 10.0, 3.3))
    np.testing.assert_almost_equal(res, 58.83)


def test_mix_vec():
    res = miniglm.mix((2.5, 3.4, 4.6), (7.2, 1.1, 3.2), 0.2)
    np.testing.assert_almost_equal(res, (3.44, 2.94, 4.32))
    assert type(res) is tuple


def test_mix_scalar():
    res = miniglm.mix(1.0, 3.0, 0.5)
    np.testing.assert_almost_equal(res, 2.0)


def test_rotate():
    res = miniglm.rotate(miniglm.pi / 3.0, miniglm.norm((0.48, 0.60, 0.64)))
    expected = (0.24, 0.3, 0.32, 0.8660254037844387)
    np.testing.assert_almost_equal(res, expected)
    assert type(res) is tuple


def test_split_quat():
    quat = (0.24, 0.3, 0.32, 0.8660254037844387)
    angle, axis = miniglm.split(quat)
    np.testing.assert_almost_equal(angle, miniglm.pi / 3.0)
    np.testing.assert_almost_equal(axis, (0.48, 0.60, 0.64))
    assert type(axis) is tuple


def test_rotate_x_90_deg():
    res = miniglm.rotate(miniglm.pi / 2.0, (1.0, 0.0, 0.0))
    np.testing.assert_almost_equal(res, (np.sqrt(2.0) / 2.0, 0.0, 0.0, np.sqrt(2.0) / 2.0))


def test_rotate_y_90_deg():
    res = miniglm.rotate(miniglm.pi / 2.0, (0.0, 1.0, 0.0))
    np.testing.assert_almost_equal(res, (0.0, np.sqrt(2.0) / 2.0, 0.0, np.sqrt(2.0) / 2.0))


def test_rotate_z_90_deg():
    res = miniglm.rotate(miniglm.pi / 2.0, (0.0, 0.0, 1.0))
    np.testing.assert_almost_equal(res, (0.0, 0.0, np.sqrt(2.0) / 2.0, np.sqrt(2.0) / 2.0))


def test_norm_vec():
    res = miniglm.norm((48.0, 60.0, 64.0))
    expected = (0.48, 0.60, 0.64)
    np.testing.assert_almost_equal(res, expected)
    assert type(res) is tuple


def test_norm_quat():
    res = miniglm.norm((2.0, 4.0, 8.0, 4.0))
    expected = (0.2, 0.4, 0.8, 0.4)
    np.testing.assert_almost_equal(res, expected)
    assert type(res) is tuple


def test_norm_mat():
    mat = (
        0.074, 0.962, -0.259,
        -0.518, 0.259, 0.814,
        0.851, 0.074, 0.518,
    )
    res = miniglm.norm(mat)
    np.testing.assert_almost_equal(miniglm.det(res), 1.0)
    np.testing.assert_almost_equal(miniglm.cross(res[0:3], res[3:6]), res[6:9])
    np.testing.assert_almost_equal(miniglm.dot(res[0:3], res[3:6]), 0.0)
    np.testing.assert_almost_equal(miniglm.dot(res[3:6], res[6:9]), 0.0)
    np.testing.assert_almost_equal(miniglm.dot(res[0:3], res[6:9]), 0.0)
    assert type(res) is tuple


def test_cast():
    quat = (0.2, 0.4, 0.8, 0.4)
    mat = (-0.6, 0.8, 0.0, -0.48, -0.36, 0.8, 0.64, 0.48, 0.6)
    np.testing.assert_almost_equal(miniglm.cast(quat), mat)
    np.testing.assert_almost_equal(miniglm.cast(mat), quat)
    np.testing.assert_almost_equal(miniglm.cast(miniglm.cast(quat)), quat)
    np.testing.assert_almost_equal(miniglm.cast(miniglm.cast(mat)), mat)


def test_swizzle_vec():
    res = miniglm.swizzle((1.0, 2.0, 3.0), 'yxz')
    np.testing.assert_almost_equal(res, (2.0, 1.0, 3.0))


def test_swizzle_quat():
    res = miniglm.swizzle((0.1, 0.7, 0.5, 0.5), 'wxyz')
    np.testing.assert_almost_equal(res, (0.5, 0.1, 0.7, 0.5))


def test_pack_scalar():
    assert miniglm.pack(1.75) == struct.pack('f', 1.75)


def test_pack_vec():
    vec = (1.0, 2.0, 3.0)
    assert miniglm.pack(vec) == struct.pack('fff', *vec)


def test_pack_quat():
    quat = (0.1, 0.7, 0.5, 0.5)
    assert miniglm.pack(quat) == struct.pack('ffff', *quat)


def test_pack_mat():
    mat = (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0)
    assert miniglm.pack(mat) == struct.pack('fffffffff', *mat)

[((100, 145), 'miniglm.add', 'miniglm.add', (['(1.0, 2.0, 3.0)', '(1.5, 1.8, 1.2)'], {}), '((1.0, 2.0, 3.0), (1.5, 1.8, 1.2))\n', (111, 145), False, 'import miniglm\n'), ((150, 202), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(2.5, 3.8, 4.2)'], {}), '(res, (2.5, 3.8, 4.2))\n', (180, 202), True, 'import numpy as np\n'), ((272, 305), 'miniglm.add', 'miniglm.add', (['(1.0, 2.0, 3.0)', '(0.5)'], {}), '((1.0, 2.0, 3.0), 0.5)\n', (283, 305), False, 'import miniglm\n'), ((310, 362), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(1.5, 2.5, 3.5)'], {}), '(res, (1.5, 2.5, 3.5))\n', (340, 362), True, 'import numpy as np\n'), ((429, 474), 'miniglm.sub', 'miniglm.sub', (['(5.0, 6.0, 7.0)', '(1.5, 1.8, 1.2)'], {}), '((5.0, 6.0, 7.0), (1.5, 1.8, 1.2))\n', (440, 474), False, 'import miniglm\n'), ((479, 531), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(3.5, 4.2, 5.8)'], {}), '(res, (3.5, 4.2, 5.8))\n', (509, 531), True, 'import numpy as np\n'), ((601, 634), 'miniglm.sub', 'miniglm.sub', (['(5.0, 6.0, 7.0)', '(1.5)'], {}), '((5.0, 6.0, 7.0), 1.5)\n', (612, 634), False, 'import miniglm\n'), ((639, 691), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(3.5, 4.5, 5.5)'], {}), '(res, (3.5, 4.5, 5.5))\n', (669, 691), True, 'import numpy as np\n'), ((758, 803), 'miniglm.mul', 'miniglm.mul', (['(5.0, 6.0, 7.0)', '(1.5, 1.8, 1.2)'], {}), '((5.0, 6.0, 7.0), (1.5, 1.8, 1.2))\n', (769, 803), False, 'import miniglm\n'), ((808, 861), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(7.5, 10.8, 8.4)'], {}), '(res, (7.5, 10.8, 8.4))\n', (838, 861), True, 'import numpy as np\n'), ((931, 964), 'miniglm.mul', 'miniglm.mul', (['(1.0, 2.0, 3.0)', '(2.0)'], {}), '((1.0, 2.0, 3.0), 2.0)\n', (942, 964), False, 'import miniglm\n'), ((969, 1021), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(2.0, 4.0, 6.0)'], {}), '(res, (2.0, 4.0, 6.0))\n', (999, 1021), True, 'import numpy as np\n'), ((1082, 1130), 'miniglm.cross', 'miniglm.cross', (['(2.0, 3.5, 7.1)', '(0.2, 10.0, 3.3)'], {}), '((2.0, 3.5, 7.1), (0.2, 10.0, 3.3))\n', (1095, 1130), False, 'import miniglm\n'), ((1135, 1193), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(-59.45, -5.18, 19.3)'], {}), '(res, (-59.45, -5.18, 19.3))\n', (1165, 1193), True, 'import numpy as np\n'), ((1256, 1302), 'miniglm.dot', 'miniglm.dot', (['(2.0, 3.5, 7.1)', '(0.2, 10.0, 3.3)'], {}), '((2.0, 3.5, 7.1), (0.2, 10.0, 3.3))\n', (1267, 1302), False, 'import miniglm\n'), ((1307, 1349), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(58.83)'], {}), '(res, 58.83)\n', (1337, 1349), True, 'import numpy as np\n'), ((1383, 1429), 'miniglm.dot', 'miniglm.dot', (['(2.0, 3.5, 7.1)', '(0.2, 10.0, 3.3)'], {}), '((2.0, 3.5, 7.1), (0.2, 10.0, 3.3))\n', (1394, 1429), False, 'import miniglm\n'), ((1434, 1476), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(58.83)'], {}), '(res, 58.83)\n', (1464, 1476), True, 'import numpy as np\n'), ((1509, 1559), 'miniglm.mix', 'miniglm.mix', (['(2.5, 3.4, 4.6)', '(7.2, 1.1, 3.2)', '(0.2)'], {}), '((2.5, 3.4, 4.6), (7.2, 1.1, 3.2), 0.2)\n', (1520, 1559), False, 'import miniglm\n'), ((1564, 1619), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(3.44, 2.94, 4.32)'], {}), '(res, (3.44, 2.94, 4.32))\n', (1594, 1619), True, 'import numpy as np\n'), ((1685, 1711), 'miniglm.mix', 'miniglm.mix', (['(1.0)', '(3.0)', '(0.5)'], {}), '(1.0, 3.0, 0.5)\n', (1696, 1711), False, 'import miniglm\n'), ((1716, 1756), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(2.0)'], {}), '(res, 2.0)\n', (1746, 1756), True, 'import numpy as np\n'), ((1912, 1957), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', 'expected'], {}), '(res, expected)\n', (1942, 1957), True, 'import numpy as np\n'), ((2080, 2099), 'miniglm.split', 'miniglm.split', (['quat'], {}), '(quat)\n', (2093, 2099), False, 'import miniglm\n'), ((2104, 2159), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['angle', '(miniglm.pi / 3.0)'], {}), '(angle, miniglm.pi / 3.0)\n', (2134, 2159), True, 'import numpy as np\n'), ((2164, 2219), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['axis', '(0.48, 0.6, 0.64)'], {}), '(axis, (0.48, 0.6, 0.64))\n', (2194, 2219), True, 'import numpy as np\n'), ((2292, 2341), 'miniglm.rotate', 'miniglm.rotate', (['(miniglm.pi / 2.0)', '(1.0, 0.0, 0.0)'], {}), '(miniglm.pi / 2.0, (1.0, 0.0, 0.0))\n', (2306, 2341), False, 'import miniglm\n'), ((2474, 2523), 'miniglm.rotate', 'miniglm.rotate', (['(miniglm.pi / 2.0)', '(0.0, 1.0, 0.0)'], {}), '(miniglm.pi / 2.0, (0.0, 1.0, 0.0))\n', (2488, 2523), False, 'import miniglm\n'), ((2656, 2705), 'miniglm.rotate', 'miniglm.rotate', (['(miniglm.pi / 2.0)', '(0.0, 0.0, 1.0)'], {}), '(miniglm.pi / 2.0, (0.0, 0.0, 1.0))\n', (2670, 2705), False, 'import miniglm\n'), ((2831, 2863), 'miniglm.norm', 'miniglm.norm', (['(48.0, 60.0, 64.0)'], {}), '((48.0, 60.0, 64.0))\n', (2843, 2863), False, 'import miniglm\n'), ((2902, 2947), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', 'expected'], {}), '(res, expected)\n', (2932, 2947), True, 'import numpy as np\n'), ((3012, 3046), 'miniglm.norm', 'miniglm.norm', (['(2.0, 4.0, 8.0, 4.0)'], {}), '((2.0, 4.0, 8.0, 4.0))\n', (3024, 3046), False, 'import miniglm\n'), ((3087, 3132), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', 'expected'], {}), '(res, expected)\n', (3117, 3132), True, 'import numpy as np\n'), ((3303, 3320), 'miniglm.norm', 'miniglm.norm', (['mat'], {}), '(mat)\n', (3315, 3320), False, 'import miniglm\n'), ((4126, 4165), 'miniglm.swizzle', 'miniglm.swizzle', (['(1.0, 2.0, 3.0)', '"""yxz"""'], {}), "((1.0, 2.0, 3.0), 'yxz')\n", (4141, 4165), False, 'import miniglm\n'), ((4170, 4222), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(2.0, 1.0, 3.0)'], {}), '(res, (2.0, 1.0, 3.0))\n', (4200, 4222), True, 'import numpy as np\n'), ((4260, 4305), 'miniglm.swizzle', 'miniglm.swizzle', (['(0.1, 0.7, 0.5, 0.5)', '"""wxyz"""'], {}), "((0.1, 0.7, 0.5, 0.5), 'wxyz')\n", (4275, 4305), False, 'import miniglm\n'), ((4310, 4367), 'numpy.testing.assert_almost_equal', 'np.testing.assert_almost_equal', (['res', '(0.5, 0.1, 0.7, 0.5)'], {}), '(res, (0.5, 0.1, 0.7, 0.5))\n', (4340, 4367), True, 'import numpy as np\n'), ((1821, 1852), 'miniglm.norm', 'miniglm.norm', (['(0.48, 0.6, 0.64)'], {}), '((0.48, 0.6, 0.64))\n', (1833, 1852), False, 'import miniglm\n'), ((3356, 3372), 'miniglm.det', 'miniglm.det', (['res'], {}), '(res)\n', (3367, 3372), False, 'import miniglm\n'), ((3414, 3447), 'miniglm.cross', 'miniglm.cross', (['res[0:3]', 'res[3:6]'], {}), '(res[0:3], res[3:6])\n', (3427, 3447), False, 'import miniglm\n'), ((3494, 3525), 'miniglm.dot', 'miniglm.dot', (['res[0:3]', 'res[3:6]'], {}), '(res[0:3], res[3:6])\n', (3505, 3525), False, 'import miniglm\n'), ((3567, 3598), 'miniglm.dot', 'miniglm.dot', (['res[3:6]', 'res[6:9]'], {}), '(res[3:6], res[6:9])\n', (3578, 3598), False, 'import miniglm\n'), ((3640, 3671), 'miniglm.dot', 'miniglm.dot', (['res[0:3]', 'res[6:9]'], {}), '(res[0:3], res[6:9])\n', (3651, 3671), False, 'import miniglm\n'), ((3857, 3875), 'miniglm.cast', 'miniglm.cast', (['quat'], {}), '(quat)\n', (3869, 3875), False, 'import miniglm\n'), ((3917, 3934), 'miniglm.cast', 'miniglm.cast', (['mat'], {}), '(mat)\n', (3929, 3934), False, 'import miniglm\n'), ((4405, 4423), 'miniglm.pack', 'miniglm.pack', (['(1.75)'], {}), '(1.75)\n', (4417, 4423), False, 'import miniglm\n'), ((4427, 4449), 'struct.pack', 'struct.pack', (['"""f"""', '(1.75)'], {}), "('f', 1.75)\n", (4438, 4449), False, 'import struct\n'), ((4510, 4527), 'miniglm.pack', 'miniglm.pack', (['vec'], {}), '(vec)\n', (4522, 4527), False, 'import miniglm\n'), ((4531, 4555), 'struct.pack', 'struct.pack', (['"""fff"""', '*vec'], {}), "('fff', *vec)\n", (4542, 4555), False, 'import struct\n'), ((4623, 4641), 'miniglm.pack', 'miniglm.pack', (['quat'], {}), '(quat)\n', (4635, 4641), False, 'import miniglm\n'), ((4645, 4671), 'struct.pack', 'struct.pack', (['"""ffff"""', '*quat'], {}), "('ffff', *quat)\n", (4656, 4671), False, 'import struct\n'), ((4762, 4779), 'miniglm.pack', 'miniglm.pack', (['mat'], {}), '(mat)\n', (4774, 4779), False, 'import miniglm\n'), ((4783, 4813), 'struct.pack', 'struct.pack', (['"""fffffffff"""', '*mat'], {}), "('fffffffff', *mat)\n", (4794, 4813), False, 'import struct\n'), ((3990, 4008), 'miniglm.cast', 'miniglm.cast', (['quat'], {}), '(quat)\n', (4002, 4008), False, 'import miniglm\n'), ((4065, 4082), 'miniglm.cast', 'miniglm.cast', (['mat'], {}), '(mat)\n', (4077, 4082), False, 'import miniglm\n'), ((2383, 2395), 'numpy.sqrt', 'np.sqrt', (['(2.0)'], {}), '(2.0)\n', (2390, 2395), True, 'import numpy as np\n'), ((2413, 2425), 'numpy.sqrt', 'np.sqrt', (['(2.0)'], {}), '(2.0)\n', (2420, 2425), True, 'import numpy as np\n'), ((2570, 2582), 'numpy.sqrt', 'np.sqrt', (['(2.0)'], {}), '(2.0)\n', (2577, 2582), True, 'import numpy as np\n'), ((2595, 2607), 'numpy.sqrt', 'np.sqrt', (['(2.0)'], {}), '(2.0)\n', (2602, 2607), True, 'import numpy as np\n'), ((2757, 2769), 'numpy.sqrt', 'np.sqrt', (['(2.0)'], {}), '(2.0)\n', (2764, 2769), True, 'import numpy as np\n'), ((2777, 2789), 'numpy.sqrt', 'np.sqrt', (['(2.0)'], {}), '(2.0)\n', (2784, 2789), True, 'import numpy as np\n')]