class TestSymmetryC2H6(TestCase):

    def setUp(self):
        carbon_1 = MagicMock(element='CARBON', charge=6, mass=12, coordinates=(0.7516, -0.0225, -0.0209))
        carbon_2 = MagicMock(element='CARBON', charge=6, mass=12, coordinates=(-0.7516, 0.0225, 0.0209))
        hydrogen_1 = MagicMock(element='HYDROGEN', charge=1, mass=1, coordinates=(1.1851, -0.0039, 0.9875))
        hydrogen_2 = MagicMock(element='HYDROGEN', charge=1, mass=1, coordinates=(1.1669, 0.8330, -0.5693))
        hydrogen_3 = MagicMock(element='HYDROGEN', charge=1, mass=1, coordinates=(1.1155, -0.9329, -0.5145))
        hydrogen_4 = MagicMock(element='HYDROGEN', charge=1, mass=1, coordinates=(-1.1669, -0.8334, 0.5687))
        hydrogen_5 = MagicMock(element='HYDROGEN', charge=1, mass=1, coordinates=(-1.1157, 0.9326, 0.5151))
        hydrogen_6 = MagicMock(element='HYDROGEN', charge=1, mass=1, coordinates=(-1.1850, 0.0044, -0.9875))
        self.nuclei_array_c2h6 = [carbon_1, carbon_2, hydrogen_1, hydrogen_2, hydrogen_3, hydrogen_4, hydrogen_5,
        hydrogen_6]
        self.molecule_factory = MoleculeFactory()
        self.symmetry_factory = SymmetryFactory()

    def test_check_linear_returns_false(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_c2h6)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_linear(nuclei_array)
        self.assertEqual(boolean, False)

    def test_check_high_symmetry_returns_false(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_c2h6)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_high_symmetry(rotation)
        self.assertEqual(boolean, False)

    def test_check_n_two_fold_rotation_perpendicular_to_n_fold_returns_true(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_c2h6)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_n_two_fold_perpendicular_to_n_fold(rotation)
        self.assertEqual(boolean, True)

    def test_check_sigma_h_returns_false(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_c2h6)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_sigma_h(reflection)
        self.assertEqual(boolean, False)

    def test_check_n_sigma_v_returns_true(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_c2h6)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_n_sigma_v(3, reflection)
        self.assertEqual(boolean, True)

    def test_point_group_returns_d_3d_symmetry_for_cubane(self):
        symmetry = self.molecule_factory.point_group(self.nuclei_array_c2h6).point_group.label
        testing.assert_equal(symmetry, 'D_{3d}')
class TestSymmetryH2O(TestCase):
    def setUp(self):
        oxygen_1 = MagicMock(
            element="OXYGEN", charge=8, mass=16, coordinates=(0.0000000000, 0.0000000000, -0.1363928482)
        )
        hydrogen_1 = MagicMock(
            element="HYDROGEN", charge=1, mass=1, coordinates=(0.0000000000, 1.4236595095, 0.9813433754)
        )
        hydrogen_2 = MagicMock(
            element="HYDROGEN", charge=1, mass=1, coordinates=(0.0000000000, -1.4236595095, 0.9813433754)
        )
        self.nuclei_array_h2o = [oxygen_1, hydrogen_1, hydrogen_2]
        self.molecule_factory = MoleculeFactory()
        self.symmetry_factory = SymmetryFactory()

    def test_brute_force_rotation_symmetry_returns_list_of_one_axis_of_rotations(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.assertEqual(len(rotation), 1)

    def test_brute_force_rotation_symmetry_returns_axis_of_rotation_of_two_fold_symmetry(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.assertEqual(rotation[0].fold, 2)

    def test_brute_force_reflection_symmetry_returns_list_of_two_reflection_planes(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.assertEqual(len(reflection), 2)

    def test_check_linear_returns_false(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_linear(nuclei_array)
        self.assertEqual(boolean, False)

    def test_check_high_symmetry_returns_false(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_high_symmetry(rotation)
        self.assertEqual(boolean, False)

    def test_get_n_fold_returns_two(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        n = self.molecule_factory.return_principal_axis(rotation).fold
        self.assertEqual(n, 2)

    def test_check_n_two_fold_rotation_perpendicular_to_n_fold_returns_false(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_n_two_fold_perpendicular_to_n_fold(rotation)
        self.assertEqual(boolean, False)

    def test_check_sigma_h_returns_false(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_sigma_h(reflection)
        self.assertEqual(boolean, False)

    def test_check_n_sigma_v_returns_true(self):
        nuclei_array = self.molecule_factory.center_molecule(self.nuclei_array_h2o)
        rotation, reflection, improper, inversion = self.symmetry_factory.brute_force_symmetry(nuclei_array)
        self.molecule_factory.standard_orientation(nuclei_array, rotation, reflection)
        boolean = self.molecule_factory.check_n_sigma_v(2, reflection)
        self.assertEqual(boolean, True)

    def test_point_group_returns_c_2v_symmetry_for_water(self):
        symmetry = self.molecule_factory.point_group(self.nuclei_array_h2o).point_group.label
        testing.assert_equal(symmetry, "C_{2v}")