import unittest
import numpy as np
import vg
from .surface_normals import surface_normal


class TestSurfaceNormals(unittest.TestCase):
    def test_surface_normal_single(self):
        points = np.array([
            [3.0, 0.0, 0.0],
            [0.0, 3.0, 0.0],
            [0.0, 0.0, 3.0],
        ])

        np.testing.assert_allclose(
            surface_normal(points),
            np.array([3 ** -0.5, 3 ** -0.5, 3 ** -0.5]))

        np.testing.assert_allclose(
            surface_normal(points, normalize=False),
            np.array([9.0, 9.0, 9.0]))

    def test_surface_normal_vectorized(self):
        from .shapes import create_triangular_prism

        p1 = np.array([3.0, 0.0, 0.0])
        p2 = np.array([0.0, 3.0, 0.0])
        p3 = np.array([0.0, 0.0, 3.0])
        vertices = create_triangular_prism(p1, p2, p3, 1.0)

        expected_normals = vg.normalize(np.array([
            [1.0, 1.0, 1.0],
            [1.0, 1.0, -2.0],
            [1.0, 1.0, -2.0],
            [-2.0, 1.0, 1.0],
            [-2.0, 1.0, 1.0],
            [1.0, -2.0, 1.0],
            [1.0, -2.0, 1.0],
            [-1.0, -1.0, -1.0],
        ]))

        np.testing.assert_allclose(
            surface_normal(vertices),
            expected_normals)
