import typing
from typing import TYPE_CHECKING

import numpy as np
from scipy import linalg

from test.assertions import QuaternionTest

if TYPE_CHECKING:
    import pyquat.pyquat as pq
    import pyquat.pyquat.random as random
else:
    import pyquat as pq
    import pyquat.random as random

class TestRandom(QuaternionTest):
    def test_uniform_random_axis(self) -> None:
        """A unit axis is generated by uniform_random_axis()"""
        v = random.uniform_random_axis()
        uv = v / linalg.norm(v)
        np.testing.assert_array_almost_equal(v, uv, decimal=12)

    def test_randu(self) -> None:
        """urand() produces random numbers which are inside the correct range (-1,+1). """
        for ii in range(0,100):
            v = random.randu()
            self.assertLessEqual(-1.0, v)
            self.assertGreaterEqual(1.0, v)

    def test_rand(self) -> None:
        """rand() produces a quaternion on the unit sphere"""
        qr = random.rand()
        self.assertEqual(type(qr), pq.Quat)

        v = qr.to_vector()
        self.assertAlmostEqual(linalg.norm(v), 1.0, places=15)

        for ii in range(0,4):
            self.assertLessEqual(-1.0, v[ii])
            self.assertGreaterEqual(1.0, v[ii])
        
