1 /******************************************************************************
2
3 This source file is part of the Avogadro project.
4
5 Copyright 2011-2012 Kitware, Inc.
6
7 This source code is released under the New BSD License, (the "License").
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14
15 ******************************************************************************/
16
17 #include "utils.h"
18
19 #include <gtest/gtest.h>
20
21 #include <avogadro/core/array.h>
22 #include <avogadro/core/color3f.h>
23 #include <avogadro/core/mesh.h>
24 #include <avogadro/core/molecule.h>
25 #include <avogadro/core/vector.h>
26
27 using Avogadro::Index;
28 using Avogadro::Vector2;
29 using Avogadro::Vector3;
30 using Avogadro::Vector3f;
31 using Avogadro::Core::Array;
32 using Avogadro::Core::Atom;
33 using Avogadro::Core::Bond;
34 using Avogadro::Core::Color3f;
35 using Avogadro::Core::Mesh;
36 using Avogadro::Core::Molecule;
37 using Avogadro::Core::Variant;
38 using Avogadro::Core::VariantMap;
39
40 class MoleculeTest : public testing::Test
41 {
42 public:
43 MoleculeTest();
44
45 protected:
46 Molecule m_testMolecule;
47 };
48
MoleculeTest()49 MoleculeTest::MoleculeTest()
50 {
51 Atom o1 = m_testMolecule.addAtom(8);
52 Atom h2 = m_testMolecule.addAtom(1);
53 Atom h3 = m_testMolecule.addAtom(1);
54
55 o1.setPosition3d(Vector3(0, 0, 0));
56 h2.setPosition3d(Vector3(0.6, -0.5, 0));
57 h3.setPosition3d(Vector3(-0.6, -0.5, 0));
58
59 o1.setPosition2d(Vector2(0, 0));
60 h2.setPosition2d(Vector2(0.6, -0.5));
61 h3.setPosition2d(Vector2(-0.6, -0.5));
62
63 // Add some data
64 VariantMap data;
65 data.setValue("test", Variant("test"));
66 m_testMolecule.setDataMap(data);
67
68 // Add some bonds
69 m_testMolecule.perceiveBondsSimple();
70
71 Mesh* mesh = m_testMolecule.addMesh();
72
73 Array<Vector3f> vertices;
74 Array<Vector3f> normals;
75 Array<Color3f> colors;
76
77 Color3f color = Color3f(23, 23, 23);
78 colors.push_back(color);
79
80 Vector3f vec(1.2f, 1.3f, 1.4f);
81
82 vertices.push_back(vec);
83 normals.push_back(vec);
84
85 mesh->setColors(colors);
86 mesh->setNormals(normals);
87 mesh->setVertices(vertices);
88 mesh->setIsoValue(1.2f);
89 mesh->setName("testmesh");
90 mesh->setOtherMesh(1);
91 mesh->setStable(false);
92 }
93
TEST_F(MoleculeTest,addAtom)94 TEST_F(MoleculeTest, addAtom)
95 {
96 Molecule molecule;
97 EXPECT_EQ(molecule.atomCount(), static_cast<Index>(0));
98
99 Avogadro::Core::Atom atom = molecule.addAtom(6);
100 EXPECT_EQ(atom.isValid(), true);
101 EXPECT_EQ(molecule.atomCount(), static_cast<Index>(1));
102 EXPECT_EQ(atom.index(), 0);
103 EXPECT_EQ(atom.atomicNumber(), static_cast<unsigned char>(6));
104
105 Avogadro::Core::Atom atom2 = molecule.addAtom(1);
106 EXPECT_EQ(atom2.isValid(), true);
107 EXPECT_EQ(molecule.atomCount(), static_cast<Index>(2));
108 EXPECT_EQ(atom2.index(), 1);
109 EXPECT_EQ(atom2.atomicNumber(), static_cast<unsigned char>(1));
110 }
111
TEST_F(MoleculeTest,removeAtom)112 TEST_F(MoleculeTest, removeAtom)
113 {
114 Molecule molecule;
115 Atom atom0 = molecule.addAtom(6);
116 Atom atom1 = molecule.addAtom(1);
117 Atom atom2 = molecule.addAtom(1);
118 Atom atom3 = molecule.addAtom(1);
119 Atom atom4 = molecule.addAtom(1);
120 molecule.addBond(atom0, atom1, 1);
121 molecule.addBond(atom0, atom2, 1);
122 molecule.addBond(atom0, atom3, 1);
123 molecule.addBond(atom0, atom4, 1);
124
125 EXPECT_EQ(5, molecule.atomCount());
126 EXPECT_EQ(4, molecule.bondCount());
127
128 molecule.removeAtom(atom0);
129
130 EXPECT_EQ(4, molecule.atomCount());
131 EXPECT_EQ(0, molecule.bondCount());
132
133 molecule.clearAtoms();
134
135 EXPECT_EQ(0, molecule.atomCount());
136 }
137
TEST_F(MoleculeTest,addBond)138 TEST_F(MoleculeTest, addBond)
139 {
140 Molecule molecule;
141 EXPECT_EQ(molecule.bondCount(), static_cast<Index>(0));
142
143 Atom a = molecule.addAtom(1);
144 Atom b = molecule.addAtom(1);
145 Bond bondAB = molecule.addBond(a, b);
146 EXPECT_TRUE(bondAB.isValid());
147 EXPECT_EQ(bondAB.molecule(), &molecule);
148 EXPECT_EQ(molecule.bondCount(), static_cast<Index>(1));
149 EXPECT_EQ(bondAB.index(), static_cast<Index>(0));
150 EXPECT_EQ(bondAB.atom1().index(), a.index());
151 EXPECT_EQ(bondAB.atom2().index(), b.index());
152 EXPECT_EQ(bondAB.order(), static_cast<unsigned char>(1));
153
154 Atom c = molecule.addAtom(1);
155 Bond bondBC = molecule.addBond(b, c, 2);
156 EXPECT_TRUE(bondBC.isValid());
157 EXPECT_EQ(molecule.bondCount(), static_cast<Index>(2));
158 EXPECT_EQ(bondBC.index(), static_cast<Index>(1));
159 EXPECT_EQ(bondBC.order(), static_cast<unsigned char>(2));
160
161 // try to lookup nonexistant bond
162 Bond bond = molecule.bond(a, c);
163 EXPECT_FALSE(bond.isValid());
164
165 // try to lookup bond between a and b
166 bond = molecule.bond(a, b);
167 EXPECT_TRUE(bond.isValid());
168 EXPECT_EQ(bond.molecule(), &molecule);
169 EXPECT_EQ(bond.atom1().index(), a.index());
170 EXPECT_EQ(bond.atom2().index(), b.index());
171
172 // try to lookup bond between b and c by index
173 bond = molecule.bond(1);
174 EXPECT_TRUE(bond.isValid());
175 EXPECT_EQ(bond.molecule(), &molecule);
176 EXPECT_EQ(bond.atom1().index(), b.index());
177 EXPECT_EQ(bond.atom2().index(), c.index());
178 }
179
TEST_F(MoleculeTest,removeBond)180 TEST_F(MoleculeTest, removeBond)
181 {
182 Molecule molecule;
183 Atom a = molecule.addAtom(1);
184 Atom b = molecule.addAtom(1);
185 Bond bondAB = molecule.addBond(a, b);
186 Atom c = molecule.addAtom(1);
187 molecule.addBond(b, c, 2);
188
189 EXPECT_EQ(3, molecule.atomCount());
190 EXPECT_EQ(2, molecule.bondCount());
191 EXPECT_TRUE(molecule.bond(a, b).isValid());
192 EXPECT_TRUE(molecule.bond(b, c).isValid());
193
194 molecule.removeBond(bondAB);
195
196 EXPECT_EQ(3, molecule.atomCount());
197 EXPECT_EQ(1, molecule.bondCount());
198 EXPECT_FALSE(molecule.bond(a, b).isValid());
199 EXPECT_TRUE(molecule.bond(b, c).isValid());
200
201 molecule.clearBonds();
202
203 EXPECT_EQ(0, molecule.bondCount());
204 }
205
TEST_F(MoleculeTest,findBond)206 TEST_F(MoleculeTest, findBond)
207 {
208 Molecule molecule;
209 Atom a1 = molecule.addAtom(5);
210 Atom a2 = molecule.addAtom(6);
211 Bond b = molecule.addBond(a1, a2, 1);
212
213 EXPECT_EQ(molecule.bond(a1, a2).index(), b.index());
214 EXPECT_EQ(molecule.bond(a2, a1).index(), b.index());
215
216 Array<Bond> bonds = molecule.bonds(a1);
217 EXPECT_EQ(bonds.size(), 1);
218
219 Atom a3 = molecule.addAtom(7);
220 molecule.addBond(a1, a3, 1);
221 EXPECT_EQ(molecule.bonds(a1).size(), 2);
222 EXPECT_EQ(molecule.bonds(a3).size(), 1);
223 }
224
TEST_F(MoleculeTest,setData)225 TEST_F(MoleculeTest, setData)
226 {
227 Molecule molecule;
228 molecule.setData("name", "ethanol");
229 EXPECT_EQ(molecule.data("name").toString(), "ethanol");
230 }
231
TEST_F(MoleculeTest,dataMap)232 TEST_F(MoleculeTest, dataMap)
233 {
234 Molecule molecule;
235 molecule.setData("name", "ethanol");
236 molecule.setData("formula", "C2H6O");
237 VariantMap varMap = molecule.dataMap();
238 varMap.setValue("SMILES", "CCO");
239 molecule.setDataMap(varMap);
240 molecule.dataMap().setValue("CAS", "64-17-5");
241
242 std::vector<std::string> dataNames = molecule.dataMap().names();
243 EXPECT_EQ(dataNames.size(), 4);
244 EXPECT_EQ(molecule.hasData("name"), true);
245 EXPECT_EQ(molecule.hasData("invalid"), false);
246 EXPECT_EQ(molecule.data("name").toString(), "ethanol");
247 EXPECT_EQ(molecule.data("formula").toString(), "C2H6O");
248 EXPECT_EQ(molecule.data("SMILES").toString(), "CCO");
249 EXPECT_EQ(molecule.data("CAS").toString(), "64-17-5");
250 }
251
TEST_F(MoleculeTest,perceiveBondsSimple)252 TEST_F(MoleculeTest, perceiveBondsSimple)
253 {
254 Molecule molecule;
255 Atom o1 = molecule.addAtom(8);
256 Atom h2 = molecule.addAtom(1);
257 Atom h3 = molecule.addAtom(1);
258
259 o1.setPosition3d(Vector3(0, 0, 0));
260 h2.setPosition3d(Vector3(0.6, -0.5, 0));
261 h3.setPosition3d(Vector3(-0.6, -0.5, 0));
262 EXPECT_EQ(molecule.bondCount(), 0);
263
264 molecule.perceiveBondsSimple();
265 EXPECT_EQ(molecule.bondCount(), 2);
266 EXPECT_TRUE(molecule.bond(o1, h2).isValid());
267 EXPECT_TRUE(molecule.bond(o1, h3).isValid());
268 EXPECT_FALSE(molecule.bond(h2, h3).isValid());
269 }
270
TEST_F(MoleculeTest,copy)271 TEST_F(MoleculeTest, copy)
272 {
273 Molecule copy(m_testMolecule);
274
275 assertEqual(m_testMolecule, copy);
276 }
277
TEST_F(MoleculeTest,assignment)278 TEST_F(MoleculeTest, assignment)
279 {
280 Molecule assign;
281 assign = m_testMolecule;
282
283 assertEqual(m_testMolecule, assign);
284 }
285