1 package uk.ac.cam.ch.wwmm.opsin;
2 
3 import static org.junit.Assert.*;
4 
5 import java.util.List;
6 import java.util.Set;
7 
8 import org.junit.Test;
9 
10 import uk.ac.cam.ch.wwmm.opsin.BondStereo.BondStereoValue;
11 
12 public class SMILESFragmentBuilderTest {
13 
14 	private SMILESFragmentBuilder sBuilder = new SMILESFragmentBuilder(new IDManager());
15 
16 	@Test
testBuild()17 	public void testBuild() throws StructureBuildingException {
18 		Fragment fragment = sBuilder.build("C");
19 		assertNotNull("Got a fragment", fragment);
20 	}
21 
22 	@Test
testSimple1()23 	public void testSimple1() throws StructureBuildingException {
24 		Fragment fragment = sBuilder.build("CC");
25 		List<Atom> atomList = fragment.getAtomList();
26 		assertEquals(2, atomList.size());
27 		assertEquals(ChemEl.C, atomList.get(0).getElement());
28 		assertEquals(ChemEl.C, atomList.get(1).getElement());
29 	}
30 
31 	@Test
testSimple2()32 	public void testSimple2() throws StructureBuildingException {
33 		Fragment fragment = sBuilder.build("O=C=O");
34 		List<Atom> atomList = fragment.getAtomList();
35 		assertEquals(3, atomList.size());
36 		assertEquals(ChemEl.O, atomList.get(0).getElement());
37 		assertEquals(ChemEl.C, atomList.get(1).getElement());
38 		assertEquals(ChemEl.O, atomList.get(2).getElement());
39 		Set<Bond> bonds = fragment.getBondSet();
40 		assertEquals(2, bonds.size());
41 		for (Bond bond : bonds) {
42 			assertEquals(2, bond.getOrder());
43 		}
44 	}
45 
46 	@Test
testSimple3()47 	public void testSimple3() throws StructureBuildingException {
48 		Fragment fragment = sBuilder.build("C#N");
49 		List<Atom> atomList = fragment.getAtomList();
50 		assertEquals(2, atomList.size());
51 		Set<Bond> bonds = fragment.getBondSet();
52 		assertEquals(1, bonds.size());
53 		for (Bond bond : bonds) {
54 			assertEquals(3, bond.getOrder());
55 		}
56 	}
57 
58 	@Test
testSimple4()59 	public void testSimple4() throws StructureBuildingException {
60 		Fragment fragment = sBuilder.build("CCN(CC)CC");
61 		List<Atom> atomList = fragment.getAtomList();
62 		assertEquals(7, atomList.size());
63 		Atom nitrogen = atomList.get(2);
64 		assertEquals(ChemEl.N, nitrogen.getElement());
65 		assertEquals(3, nitrogen.getBondCount());
66 		List<Atom> neighbours = nitrogen.getAtomNeighbours();//bonds and hence neighbours come from a linked hash set so the order of the neighbours is deterministic
67 		assertEquals(3, neighbours.size());
68 		assertEquals(atomList.get(1), neighbours.get(0));
69 		assertEquals(atomList.get(3), neighbours.get(1));
70 		assertEquals(atomList.get(5), neighbours.get(2));
71 	}
72 
73 	@Test
testSimple5()74 	public void testSimple5() throws StructureBuildingException {
75 		Fragment fragment = sBuilder.build("CC(=O)O");
76 		List<Atom> atomList = fragment.getAtomList();
77 		assertEquals(4, atomList.size());
78 		Atom carbon = atomList.get(1);
79 		List<Atom> neighbours = carbon.getAtomNeighbours();
80 		assertEquals(3, neighbours.size());
81 		assertEquals(atomList.get(0), neighbours.get(0));
82 		assertEquals(atomList.get(2), neighbours.get(1));
83 		assertEquals(atomList.get(3), neighbours.get(2));
84 		assertEquals(2, carbon.getBondToAtomOrThrow(atomList.get(2)).getOrder());
85 	}
86 
87 	@Test
testSimple6()88 	public void testSimple6() throws StructureBuildingException {
89 		Fragment fragment = sBuilder.build("C1CCCCC1");
90 		List<Atom> atomList = fragment.getAtomList();
91 		assertEquals(6, atomList.size());
92 		for (Atom atom : atomList) {
93 			assertEquals(2, atom.getAtomNeighbours().size());
94 			assertEquals(false, atom.hasSpareValency());
95 		}
96 	}
97 
98 	@Test
testSimple7()99 	public void testSimple7() throws StructureBuildingException {
100 		Fragment fragment = sBuilder.build("c1ccccc1");
101 		List<Atom> atomList = fragment.getAtomList();
102 		assertEquals(6, atomList.size());
103 		for (Atom atom : atomList) {
104 			assertEquals(2, atom.getAtomNeighbours().size());
105 			assertEquals(true, atom.hasSpareValency());
106 		}
107 	}
108 
109 
110 	@Test
testSimple8()111 	public void testSimple8() throws StructureBuildingException {
112 		Fragment fragment = sBuilder.build("[I-].[Na+]");
113 		List<Atom> atomList = fragment.getAtomList();
114 		assertEquals(2, atomList.size());
115 		Atom iodine = atomList.get(0);
116 		assertEquals(0, iodine.getAtomNeighbours().size());
117 		assertEquals(-1, iodine.getCharge());
118 
119 		Atom sodium = atomList.get(1);
120 		assertEquals(0, sodium.getAtomNeighbours().size());
121 		assertEquals(1, sodium.getCharge());
122 	}
123 
124 	@Test
testSimple9()125 	public void testSimple9() throws StructureBuildingException {
126 		Fragment fragment = sBuilder.build("(C(=O)O)");
127 		List<Atom> atomList = fragment.getAtomList();
128 		assertEquals(3, atomList.size());
129 		Atom carbon = atomList.get(0);
130 		assertEquals(2, carbon.getAtomNeighbours().size());
131 	}
132 
133 	@Test
testSimple10()134 	public void testSimple10() throws StructureBuildingException {
135 		Fragment fragment = sBuilder.build("C-C-O");
136 		List<Atom> atomList = fragment.getAtomList();
137 		assertEquals(3, atomList.size());
138 	}
139 
140 	@Test
testSimple11()141 	public void testSimple11() throws StructureBuildingException {
142 		Fragment fragment = sBuilder.build("NC(Cl)(Br)C(=O)O");
143 		List<Atom> atomList = fragment.getAtomList();
144 		assertEquals(7, atomList.size());
145 		assertEquals(ChemEl.Cl, atomList.get(2).getElement());
146 	}
147 
148 
149 	@Test(expected=StructureBuildingException.class)
unterminatedRingOpening()150 	public void unterminatedRingOpening() throws StructureBuildingException {
151 		sBuilder.build("C1CC");
152 		fail("Should throw exception for bad smiles");
153 	}
154 
155 	@Test
doublePositiveCharge1()156 	public void doublePositiveCharge1() throws StructureBuildingException {
157 		Fragment fragment = sBuilder.build("[C++]");
158 		List<Atom> atomList = fragment.getAtomList();
159 		assertEquals(1, atomList.size());
160 		assertEquals(2, atomList.get(0).getCharge());
161 	}
162 
163 	@Test
doublePositiveCharge2()164 	public void doublePositiveCharge2() throws StructureBuildingException {
165 		Fragment fragment = sBuilder.build("[C+2]");
166 		List<Atom> atomList = fragment.getAtomList();
167 		assertEquals(1, atomList.size());
168 		assertEquals(2, atomList.get(0).getCharge());
169 	}
170 
171 	@Test
doubleNegativeCharge1()172 	public void doubleNegativeCharge1() throws StructureBuildingException {
173 		Fragment fragment = sBuilder.build("[O--]");
174 		List<Atom> atomList = fragment.getAtomList();
175 		assertEquals(1, atomList.size());
176 		assertEquals(-2, atomList.get(0).getCharge());
177 	}
178 
179 	@Test
doubleNegativeCharge2()180 	public void doubleNegativeCharge2() throws StructureBuildingException {
181 		Fragment fragment = sBuilder.build("[O-2]");
182 		List<Atom> atomList = fragment.getAtomList();
183 		assertEquals(1, atomList.size());
184 		assertEquals(-2, atomList.get(0).getCharge());
185 	}
186 
187 	@Test
noIsotopeSpecified()188 	public void noIsotopeSpecified() throws StructureBuildingException {
189 		Fragment fragment = sBuilder.build("[NH3]");
190 		List<Atom> atomList = fragment.getAtomList();
191 		assertEquals(1, atomList.size());
192 		assertEquals(null, atomList.get(0).getIsotope());
193 	}
194 
195 	@Test
isotopeSpecified()196 	public void isotopeSpecified() throws StructureBuildingException {
197 		Fragment fragment = sBuilder.build("[15NH3]");
198 		List<Atom> atomList = fragment.getAtomList();
199 		assertEquals(1, atomList.size());
200 		assertNotNull("Isotope should not be null", atomList.get(0).getIsotope());
201 		int isotope = atomList.get(0).getIsotope();
202 		assertEquals(15, isotope);
203 	}
204 
205 	@Test(expected=StructureBuildingException.class)
badlyFormedSMILE1()206 	public void badlyFormedSMILE1() throws StructureBuildingException {
207 		sBuilder.build("H5");
208 		fail("Should throw exception for bad smiles");
209 	}
210 
211 	@Test(expected=StructureBuildingException.class)
badlyFormedSMILE2()212 	public void badlyFormedSMILE2() throws StructureBuildingException {
213 		sBuilder.build("CH4");
214 		fail("Should throw exception for bad smiles");
215 	}
216 
217 	@Test(expected=StructureBuildingException.class)
badlyFormedSMILE3()218 	public void badlyFormedSMILE3() throws StructureBuildingException {
219 		sBuilder.build("13C");
220 		fail("Should throw exception for bad smiles");
221 	}
222 
223 	@Test(expected=StructureBuildingException.class)
badlyFormedSMILE4()224 	public void badlyFormedSMILE4() throws StructureBuildingException {
225 		sBuilder.build("C=#C");
226 		fail("Should throw exception for bad smiles: is it a double or triple bond?");
227 	}
228 
229 	@Test(expected=StructureBuildingException.class)
badlyFormedSMILE5()230 	public void badlyFormedSMILE5() throws StructureBuildingException {
231 		sBuilder.build("C#=C");
232 		fail("Should throw exception for bad smiles: is it a double or triple bond?");
233 	}
234 
235 	@Test(expected=StructureBuildingException.class)
badlyFormedSMILE6()236 	public void badlyFormedSMILE6() throws StructureBuildingException {
237 		sBuilder.build("F//C=C/F");
238 		fail("Should throw exception for bad smiles: bond configuration specified twice");
239 	}
240 
241 
242 	@Test(expected=StructureBuildingException.class)
badlyFormedSMILE7()243 	public void badlyFormedSMILE7() throws StructureBuildingException {
244 		sBuilder.build("F/C=C/\\F");
245 		fail("Should throw exception for bad smiles: bond configuration specified twice");
246 	}
247 
248 	@Test(expected=StructureBuildingException.class)
badlyFormedSMILE8()249 	public void badlyFormedSMILE8() throws StructureBuildingException {
250 		sBuilder.build("F[C@@](Cl)Br");
251 		fail("Should throw exception for invalid atom parity, not enough atoms in atom parity");
252 	}
253 
254 	@Test
ringClosureHandling1()255 	public void ringClosureHandling1() throws StructureBuildingException {
256 		Fragment fragment = sBuilder.build("C=1CN1");
257 		List<Atom> atomList = fragment.getAtomList();
258 		assertEquals(3, atomList.size());
259 		assertEquals(2, atomList.get(0).getBondToAtomOrThrow(atomList.get(2)).getOrder());
260 	}
261 
262 	@Test
ringClosureHandling2()263 	public void ringClosureHandling2() throws StructureBuildingException {
264 		Fragment fragment = sBuilder.build("C1CN=1");
265 		List<Atom> atomList = fragment.getAtomList();
266 		assertEquals(3, atomList.size());
267 		assertEquals(2, atomList.get(0).getBondToAtomOrThrow(atomList.get(2)).getOrder());
268 	}
269 
270 	@Test(expected=StructureBuildingException.class)
ringClosureHandling3()271 	public void ringClosureHandling3() throws StructureBuildingException {
272 		sBuilder.build("C#1CN=1");
273 		fail("Should throw exception for bad smiles");
274 	}
275 
276 	@Test
ringClosureHandling4()277 	public void ringClosureHandling4() throws StructureBuildingException {
278 		Fragment fragment = sBuilder.build("C=1CN=1");
279 		List<Atom> atomList = fragment.getAtomList();
280 		assertEquals(3, atomList.size());
281 		assertEquals(2, atomList.get(0).getBondToAtomOrThrow(atomList.get(2)).getOrder());
282 	}
283 
284 	@Test
ringSupportGreaterThan10()285 	public void ringSupportGreaterThan10() throws StructureBuildingException {
286 		Fragment fragment = sBuilder.build("C%10CC%10");
287 		List<Atom> atomList = fragment.getAtomList();
288 		assertEquals(3, atomList.size());
289 		assertEquals(2, atomList.get(0).getAtomNeighbours().size());
290 	}
291 
292 	@Test
hydrogenHandling1()293 	public void hydrogenHandling1() throws StructureBuildingException {
294 		Fragment fragment = sBuilder.build("[OH3+]");
295 		List<Atom> atomList = fragment.getAtomList();
296 		assertEquals(1, atomList.size());
297 		assertEquals(1, atomList.get(0).getCharge());
298 		assertEquals(1, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
299 		assertEquals(3, atomList.get(0).determineValency(true));
300 	}
301 
302 	@Test
hydrogenHandling2()303 	public void hydrogenHandling2() throws StructureBuildingException {
304 		Fragment fragment = sBuilder.build("[CH3][CH2][OH]");
305 		List<Atom> atomList = fragment.getAtomList();
306 		assertEquals(3, atomList.size());
307 		assertEquals(4, atomList.get(0).determineValency(true));
308 		assertEquals(0, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
309 		assertEquals(4, atomList.get(1).determineValency(true));
310 		assertEquals(0, atomList.get(1).getProtonsExplicitlyAddedOrRemoved());
311 		assertEquals(2, atomList.get(2).determineValency(true));
312 		assertEquals(0, atomList.get(2).getProtonsExplicitlyAddedOrRemoved());
313 	}
314 
315 	@Test
hydrogenHandling3()316 	public void hydrogenHandling3() throws StructureBuildingException {
317 		Fragment fragment = sBuilder.build("[SH2]");
318 		List<Atom> atomList = fragment.getAtomList();
319 		assertEquals(1, atomList.size());
320 		assertEquals(2, atomList.get(0).determineValency(true));
321 		assertEquals(0, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
322 	}
323 
324 	@Test
hydrogenHandling4()325 	public void hydrogenHandling4() throws StructureBuildingException {
326 		Fragment fragment = sBuilder.build("[SH4]");
327 		List<Atom> atomList = fragment.getAtomList();
328 		assertEquals(1, atomList.size());
329 		int minimumVal =atomList.get(0).getMinimumValency();
330 		assertEquals(4, minimumVal);
331 		assertEquals(4, atomList.get(0).determineValency(true));
332 		assertEquals(0, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
333 	}
334 
335 	@Test
hydrogenHandling5()336 	public void hydrogenHandling5() throws StructureBuildingException {
337 		Fragment fragment = sBuilder.build("[SH6]");
338 		List<Atom> atomList = fragment.getAtomList();
339 		assertEquals(1, atomList.size());
340 		int minimumVal =atomList.get(0).getMinimumValency();
341 		assertEquals(6, minimumVal);
342 		assertEquals(6, atomList.get(0).determineValency(true));
343 		assertEquals(0, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
344 	}
345 
346 	@Test
hydrogenHandling6()347 	public void hydrogenHandling6() throws StructureBuildingException {
348 		Fragment fragment = sBuilder.build("[SH3]");
349 		List<Atom> atomList = fragment.getAtomList();
350 		assertEquals(1, atomList.size());
351 		int minimumVal =atomList.get(0).getMinimumValency();
352 		assertEquals(3, minimumVal);
353 		assertEquals(3, atomList.get(0).determineValency(true));
354 	}
355 
356 
357 	@Test
hydrogenHandling7()358 	public void hydrogenHandling7() throws StructureBuildingException {
359 		Fragment fragment = sBuilder.build("[SH3+]");
360 		List<Atom> atomList = fragment.getAtomList();
361 		assertEquals(1, atomList.size());
362 		assertEquals(1, atomList.get(0).getCharge());
363 		assertEquals(1, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
364 		assertEquals(3, atomList.get(0).determineValency(true));
365 	}
366 
367 	@Test
hydrogenHandling8()368 	public void hydrogenHandling8() throws StructureBuildingException {
369 		Fragment fragment = sBuilder.build("[SH+]");
370 		List<Atom> atomList = fragment.getAtomList();
371 		assertEquals(1, atomList.size());
372 		assertEquals(1, atomList.get(0).getCharge());
373 		assertEquals(-1, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
374 		assertEquals(1, atomList.get(0).determineValency(true));
375 	}
376 
377 	@Test
hydrogenHandling9()378 	public void hydrogenHandling9() throws StructureBuildingException {
379 		Fragment fragment = sBuilder.build("[SH3-]");
380 		List<Atom> atomList = fragment.getAtomList();
381 		assertEquals(1, atomList.size());
382 		assertEquals(-1, atomList.get(0).getCharge());
383 		assertEquals(1, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
384 		assertEquals(3, atomList.get(0).determineValency(true));
385 	}
386 
387 	@Test
hydrogenHandling10()388 	public void hydrogenHandling10() throws StructureBuildingException {
389 		Fragment fragment = sBuilder.build("[SH-]");
390 		List<Atom> atomList = fragment.getAtomList();
391 		assertEquals(1, atomList.size());
392 		assertEquals(-1, atomList.get(0).getCharge());
393 		assertEquals(-1, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
394 		assertEquals(1, atomList.get(0).determineValency(true));
395 	}
396 
397 	@Test
hydrogenHandling11()398 	public void hydrogenHandling11() throws StructureBuildingException {
399 		Fragment fragment = sBuilder.build("[SH5+]");
400 		List<Atom> atomList = fragment.getAtomList();
401 		assertEquals(1, atomList.size());
402 		int lambdaConvent =atomList.get(0).getLambdaConventionValency();
403 		assertEquals(4, lambdaConvent);
404 		assertEquals(1, atomList.get(0).getCharge());
405 		assertEquals(1, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
406 		assertEquals(5, atomList.get(0).determineValency(true));
407 	}
408 
409 	@Test
hydrogenHandling12()410 	public void hydrogenHandling12() throws StructureBuildingException {
411 		Fragment fragment = sBuilder.build("[Li+]");
412 		List<Atom> atomList = fragment.getAtomList();
413 		assertEquals(1, atomList.size());
414 		assertEquals(1, atomList.get(0).getCharge());
415 		assertEquals(0, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
416 		assertEquals(0, atomList.get(0).determineValency(true));
417 	}
418 
419 	@Test
hydrogenHandling13()420 	public void hydrogenHandling13() throws StructureBuildingException {
421 		Fragment fragment = sBuilder.build("[NaH]");
422 		List<Atom> atomList = fragment.getAtomList();
423 		assertEquals(2, atomList.size());
424 		assertEquals(0, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
425 		assertEquals(0, atomList.get(0).getCharge());
426 
427 		assertEquals(0, atomList.get(1).getProtonsExplicitlyAddedOrRemoved());
428 		assertEquals(0, atomList.get(1).getCharge());
429 		assertEquals(ChemEl.H, atomList.get(1).getElement());
430 	}
431 
432 	@Test
hydrogenHandling14()433 	public void hydrogenHandling14() throws StructureBuildingException {
434 		Fragment fragment = sBuilder.build("-[SiH3]");
435 		List<Atom> atomList = fragment.getAtomList();
436 		assertEquals(1, atomList.size());
437 		assertEquals(4, atomList.get(0).determineValency(true));
438 		assertEquals(0, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
439 	}
440 
441 	@Test
hydrogenHandling15()442 	public void hydrogenHandling15() throws StructureBuildingException {
443 		Fragment fragment = sBuilder.build("=[SiH2]");
444 		List<Atom> atomList = fragment.getAtomList();
445 		assertEquals(1, atomList.size());
446 		assertEquals(4, atomList.get(0).determineValency(true));
447 	}
448 
449 
450 	@Test
hydrogenHandling16()451 	public void hydrogenHandling16() throws StructureBuildingException {
452 		Fragment fragment = sBuilder.build("#[SiH]");
453 		List<Atom> atomList = fragment.getAtomList();
454 		assertEquals(1, atomList.size());
455 		assertEquals(4, atomList.get(0).determineValency(true));
456 	}
457 
458 	@Test
hydrogenHandling17()459 	public void hydrogenHandling17() throws StructureBuildingException {
460 		Fragment fragment = sBuilder.build("[SiH3]-");
461 		List<Atom> atomList = fragment.getAtomList();
462 		assertEquals(1, atomList.size());
463 		assertEquals(4, atomList.get(0).determineValency(true));
464 	}
465 
466 	@Test
hydrogenHandling18()467 	public void hydrogenHandling18() throws StructureBuildingException {
468 		Fragment fragment = sBuilder.build("[SiH2]=");
469 		List<Atom> atomList = fragment.getAtomList();
470 		assertEquals(1, atomList.size());
471 		assertEquals(4, atomList.get(0).determineValency(true));
472 	}
473 
474 	@Test
hydrogenHandling19()475 	public void hydrogenHandling19() throws StructureBuildingException {
476 		Fragment fragment = sBuilder.build("[SiH]#");
477 		List<Atom> atomList = fragment.getAtomList();
478 		assertEquals(1, atomList.size());
479 		assertEquals(4, atomList.get(0).determineValency(true));
480 	}
481 
482 	@Test
hydrogenHandling20()483 	public void hydrogenHandling20() throws StructureBuildingException {
484 		Fragment fragment = sBuilder.build("=[Si]=");
485 		List<Atom> atomList = fragment.getAtomList();
486 		assertEquals(1, atomList.size());
487 		assertEquals(4, atomList.get(0).determineValency(true));
488 	}
489 
490 	@Test
hydrogenHandling21()491 	public void hydrogenHandling21() throws StructureBuildingException {
492 		Fragment fragment = sBuilder.build("[o+]1ccccc1");
493 		List<Atom> atomList = fragment.getAtomList();
494 		assertEquals(6, atomList.size());
495 		assertEquals(1, atomList.get(0).getProtonsExplicitlyAddedOrRemoved());
496 		assertEquals(true, atomList.get(0).hasSpareValency());
497 		assertEquals(3, atomList.get(0).determineValency(true));
498 		assertEquals(0, atomList.get(1).getProtonsExplicitlyAddedOrRemoved());
499 		assertEquals(4, atomList.get(1).determineValency(true));
500 		assertEquals(true, atomList.get(1).hasSpareValency());
501 	}
502 
503 	@Test
indicatedHydrogen()504 	public void indicatedHydrogen() throws StructureBuildingException {
505 		Fragment fragment = sBuilder.build("Nc1[nH]c(=O)c2c(n1)nc[nH]2");
506 		List<Atom> atomList = fragment.getAtomList();
507 		assertEquals(11, atomList.size());
508 		assertEquals(2, fragment.getIndicatedHydrogen().size());
509 		assertEquals(atomList.get(2), fragment.getIndicatedHydrogen().get(0));
510 		assertEquals(atomList.get(10),  fragment.getIndicatedHydrogen().get(1));
511 	}
512 
513 	@Test
chiralityTest1()514 	public void chiralityTest1() throws StructureBuildingException {
515 		Fragment fragment = sBuilder.build("N[C@@H](F)C");
516 		List<Atom> atomList = fragment.getAtomList();
517 		assertEquals(4, atomList.size());
518 		Atom chiralAtom = atomList.get(1);
519 		assertEquals(3, chiralAtom.getAtomNeighbours().size());
520 		AtomParity atomParity  = chiralAtom.getAtomParity();
521 		Atom[] atomRefs4 = atomParity.getAtomRefs4();
522 		assertEquals(atomList.get(0), atomRefs4[0]);
523 		assertEquals(AtomParity.hydrogen, atomRefs4[1]);
524 		assertEquals(atomList.get(2), atomRefs4[2]);
525 		assertEquals(atomList.get(3), atomRefs4[3]);
526 		assertEquals(1, atomParity.getParity());
527 	}
528 
529 	@Test
chiralityTest2()530 	public void chiralityTest2() throws StructureBuildingException {
531 		Fragment fragment = sBuilder.build("N[C@H](F)C");
532 		List<Atom> atomList = fragment.getAtomList();
533 		assertEquals(4, atomList.size());
534 		Atom chiralAtom = atomList.get(1);
535 		assertEquals(3, chiralAtom.getAtomNeighbours().size());
536 		AtomParity atomParity  = chiralAtom.getAtomParity();
537 		Atom[] atomRefs4 = atomParity.getAtomRefs4();
538 		assertEquals(atomList.get(0), atomRefs4[0]);
539 		assertEquals(AtomParity.hydrogen, atomRefs4[1]);
540 		assertEquals(atomList.get(2), atomRefs4[2]);
541 		assertEquals(atomList.get(3), atomRefs4[3]);
542 		assertEquals(-1, atomParity.getParity());
543 	}
544 
545 	@Test
chiralityTest3()546 	public void chiralityTest3() throws StructureBuildingException {
547 		Fragment fragment = sBuilder.build("C2.N1.F3.[C@@H]231");
548 		List<Atom> atomList = fragment.getAtomList();
549 		assertEquals(4, atomList.size());
550 		Atom chiralAtom = atomList.get(3);
551 		assertEquals(3, chiralAtom.getAtomNeighbours().size());
552 		AtomParity atomParity  = chiralAtom.getAtomParity();
553 		Atom[] atomRefs4 = atomParity.getAtomRefs4();
554 		assertEquals(AtomParity.hydrogen, atomRefs4[0]);
555 		assertEquals(atomList.get(0), atomRefs4[1]);
556 		assertEquals(atomList.get(2), atomRefs4[2]);
557 		assertEquals(atomList.get(1), atomRefs4[3]);
558 		assertEquals(1, atomParity.getParity());
559 	}
560 
561 	@Test
chiralityTest4()562 	public void chiralityTest4() throws StructureBuildingException {
563 		Fragment fragment = sBuilder.build("[C@@H]231.C2.N1.F3");
564 		List<Atom> atomList = fragment.getAtomList();
565 		assertEquals(4, atomList.size());
566 		Atom chiralAtom = atomList.get(0);
567 		assertEquals(3, chiralAtom.getAtomNeighbours().size());
568 		AtomParity atomParity  = chiralAtom.getAtomParity();
569 		Atom[] atomRefs4 = atomParity.getAtomRefs4();
570 		assertEquals(AtomParity.hydrogen, atomRefs4[0]);
571 		assertEquals(atomList.get(1), atomRefs4[1]);
572 		assertEquals(atomList.get(3), atomRefs4[2]);
573 		assertEquals(atomList.get(2), atomRefs4[3]);
574 		assertEquals(1, atomParity.getParity());
575 	}
576 
577 	@Test
chiralityTest5()578 	public void chiralityTest5() throws StructureBuildingException {
579 		Fragment fragment = sBuilder.build("[C@@H](Cl)1[C@H](C)(F).Br1");
580 		List<Atom> atomList = fragment.getAtomList();
581 		assertEquals(6, atomList.size());
582 		Atom chiralAtom1 = atomList.get(0);
583 		assertEquals(3, chiralAtom1.getAtomNeighbours().size());
584 		AtomParity atomParity  = chiralAtom1.getAtomParity();
585 		Atom[] atomRefs4 = atomParity.getAtomRefs4();
586 		assertEquals(AtomParity.hydrogen, atomRefs4[0]);
587 		assertEquals(atomList.get(1), atomRefs4[1]);
588 		assertEquals(atomList.get(5), atomRefs4[2]);
589 		assertEquals(atomList.get(2), atomRefs4[3]);
590 		assertEquals(1, atomParity.getParity());
591 
592 		Atom chiralAtom2 = atomList.get(2);
593 		assertEquals(3, chiralAtom2.getAtomNeighbours().size());
594 		atomParity  = chiralAtom2.getAtomParity();
595 		atomRefs4 = atomParity.getAtomRefs4();
596 		assertEquals(atomList.get(0), atomRefs4[0]);
597 		assertEquals(AtomParity.hydrogen, atomRefs4[1]);
598 		assertEquals(atomList.get(3), atomRefs4[2]);
599 		assertEquals(atomList.get(4), atomRefs4[3]);
600 		assertEquals(-1, atomParity.getParity());
601 	}
602 
603 	@Test
chiralityTest6()604 	public void chiralityTest6() throws StructureBuildingException {
605 		Fragment fragment = sBuilder.build("I[C@@](Cl)(Br)F");
606 		List<Atom> atomList = fragment.getAtomList();
607 		assertEquals(5, atomList.size());
608 		Atom chiralAtom = atomList.get(1);
609 		assertEquals(4, chiralAtom.getAtomNeighbours().size());
610 		AtomParity atomParity  = chiralAtom.getAtomParity();
611 		Atom[] atomRefs4 = atomParity.getAtomRefs4();
612 		assertEquals(atomList.get(0), atomRefs4[0]);
613 		assertEquals(atomList.get(2), atomRefs4[1]);
614 		assertEquals(atomList.get(3), atomRefs4[2]);
615 		assertEquals(atomList.get(4), atomRefs4[3]);
616 		assertEquals(1, atomParity.getParity());
617 	}
618 
619 	@Test
chiralityTest7()620 	public void chiralityTest7() throws StructureBuildingException {
621 		Fragment fragment = sBuilder.build("C[S@](N)=O");
622 		List<Atom> atomList = fragment.getAtomList();
623 		assertEquals(4, atomList.size());
624 		Atom chiralAtom = atomList.get(1);
625 		assertEquals(3, chiralAtom.getAtomNeighbours().size());
626 		AtomParity atomParity  = chiralAtom.getAtomParity();
627 		Atom[] atomRefs4 = atomParity.getAtomRefs4();
628 		assertEquals(atomList.get(0), atomRefs4[0]);
629 		assertEquals(atomList.get(1), atomRefs4[1]);
630 		assertEquals(atomList.get(2), atomRefs4[2]);
631 		assertEquals(atomList.get(3), atomRefs4[3]);
632 		assertEquals(-1, atomParity.getParity());
633 	}
634 
635 	@Test
chiralityTest8()636 	public void chiralityTest8() throws StructureBuildingException {
637 		Fragment fragment = sBuilder.build("[S@](C)(N)=O");
638 		List<Atom> atomList = fragment.getAtomList();
639 		assertEquals(4, atomList.size());
640 		Atom chiralAtom = atomList.get(0);
641 		assertEquals(3, chiralAtom.getAtomNeighbours().size());
642 		AtomParity atomParity  = chiralAtom.getAtomParity();
643 		Atom[] atomRefs4 = atomParity.getAtomRefs4();
644 		assertEquals(atomList.get(0), atomRefs4[0]);
645 		assertEquals(atomList.get(1), atomRefs4[1]);
646 		assertEquals(atomList.get(2), atomRefs4[2]);
647 		assertEquals(atomList.get(3), atomRefs4[3]);
648 		assertEquals(-1, atomParity.getParity());
649 	}
650 
651 	@Test
testDoubleBondStereo1()652 	public void testDoubleBondStereo1() throws StructureBuildingException {
653 		Fragment fragment = sBuilder.build("F/C=C/F");
654 		Bond b =fragment.findBond(2, 3);
655 		assertEquals(BondStereoValue.TRANS, b.getBondStereo().getBondStereoValue());
656 	}
657 
658 	@Test
testDoubleBondStereo2()659 	public void testDoubleBondStereo2() throws StructureBuildingException {
660 		Fragment fragment = sBuilder.build("F\\C=C/F");
661 		Bond b =fragment.findBond(2, 3);
662 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
663 	}
664 
665 	@Test
testDoubleBondStereo3()666 	public void testDoubleBondStereo3() throws StructureBuildingException {
667 		Fragment fragment = sBuilder.build("C(/F)=C/F");
668 		Bond b =fragment.findBond(1, 3);
669 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
670 	}
671 
672 	@Test
testDoubleBondStereo4()673 	public void testDoubleBondStereo4() throws StructureBuildingException {
674 		Fragment fragment = sBuilder.build("C(\\F)=C/F");
675 		Bond b =fragment.findBond(1, 3);
676 		assertEquals(BondStereoValue.TRANS, b.getBondStereo().getBondStereoValue());
677 	}
678 
679 	@Test
testDoubleBondStereo5a()680 	public void testDoubleBondStereo5a() throws StructureBuildingException {
681 		Fragment fragment = sBuilder.build("CC1=C/F.O\\1");
682 		Bond b =fragment.findBond(2, 3);
683 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
684 	}
685 
686 	@Test
testDoubleBondStereo5b()687 	public void testDoubleBondStereo5b() throws StructureBuildingException {
688 		Fragment fragment = sBuilder.build("CC/1=C/F.O1");
689 		Bond b =fragment.findBond(2, 3);
690 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
691 	}
692 
693 	@Test
testDoubleBondStereo6()694 	public void testDoubleBondStereo6() throws StructureBuildingException {
695 		Fragment fragment = sBuilder.build("CC1=C/F.O/1");
696 		Bond b =fragment.findBond(2, 3);
697 		assertEquals(BondStereoValue.TRANS, b.getBondStereo().getBondStereoValue());
698 	}
699 
700 	@Test
testDoubleBondMultiStereo1()701 	public void testDoubleBondMultiStereo1() throws StructureBuildingException {
702 		Fragment fragment = sBuilder.build("F/C=C/C=C/C");
703 		Bond b =fragment.findBond(2, 3);
704 		assertEquals(BondStereoValue.TRANS, b.getBondStereo().getBondStereoValue());
705 		b =fragment.findBond(4, 5);
706 		assertEquals(BondStereoValue.TRANS, b.getBondStereo().getBondStereoValue());
707 	}
708 
709 	@Test
testDoubleBondMultiStereo2()710 	public void testDoubleBondMultiStereo2() throws StructureBuildingException {
711 		Fragment fragment = sBuilder.build("F/C=C\\C=C/C");
712 		Bond b =fragment.findBond(2, 3);
713 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
714 		b =fragment.findBond(4, 5);
715 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
716 	}
717 
718 	@Test
testDoubleBondMultiStereo3()719 	public void testDoubleBondMultiStereo3() throws StructureBuildingException {
720 		Fragment fragment = sBuilder.build("F/C=C\\C=C\\C");
721 		Bond b =fragment.findBond(2, 3);
722 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
723 		b =fragment.findBond(4, 5);
724 		assertEquals(BondStereoValue.TRANS, b.getBondStereo().getBondStereoValue());
725 	}
726 
727 	@Test
testDoubleBondMultiStereo4()728 	public void testDoubleBondMultiStereo4() throws StructureBuildingException {
729 		Fragment fragment = sBuilder.build("F/C=C\\C=CC");
730 		Bond b =fragment.findBond(2, 3);
731 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
732 		b =fragment.findBond(4, 5);
733 		assertEquals(null, b.getBondStereo());
734 	}
735 
736 	//From http://baoilleach.blogspot.com/2010/09/are-you-on-my-side-or-not-its-ez-part.html
737 	@Test
testDoubleBondNoela()738 	public void testDoubleBondNoela() throws StructureBuildingException {
739 		Fragment fragment = sBuilder.build("C/C=C\\1/NC1");
740 		Bond b =fragment.findBond(2, 3);
741 		if (BondStereoValue.TRANS.equals( b.getBondStereo().getBondStereoValue())){
742 			assertEquals("1 2 3 4", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
743 		}
744 		else{
745 			assertEquals("1 2 3 5", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
746 		}
747 	}
748 
749 	@Test
testDoubleBondNoelb()750 	public void testDoubleBondNoelb() throws StructureBuildingException {
751 		Fragment fragment = sBuilder.build("C/C=C1/NC1");
752 		Bond b =fragment.findBond(2, 3);
753 		assertEquals(BondStereoValue.TRANS, b.getBondStereo().getBondStereoValue());
754 		assertEquals("1 2 3 4", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
755 	}
756 
757 	@Test
testDoubleBondNoelc()758 	public void testDoubleBondNoelc() throws StructureBuildingException {
759 		Fragment fragment = sBuilder.build("C/C=C\\1/NC/1");
760 		Bond b =fragment.findBond(2, 3);
761 		if (BondStereoValue.TRANS.equals( b.getBondStereo().getBondStereoValue())){
762 			assertEquals("1 2 3 4", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
763 		}
764 		else{
765 			assertEquals("1 2 3 5", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
766 		}
767 	}
768 
769 	@Test
testDoubleBondNoeld()770 	public void testDoubleBondNoeld() throws StructureBuildingException {
771 		Fragment fragment = sBuilder.build("C/C=C1/NC/1");
772 		Bond b =fragment.findBond(2, 3);
773 		if (BondStereoValue.TRANS.equals( b.getBondStereo().getBondStereoValue())){
774 			assertEquals("1 2 3 4", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
775 		}
776 		else{
777 			assertEquals("1 2 3 5", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
778 		}
779 	}
780 
781 	@Test(expected=StructureBuildingException.class)
testDoubleBondNoele()782 	public void testDoubleBondNoele() throws StructureBuildingException {
783 		sBuilder.build("C/C=C\\1\\NC1");
784 		fail("Should throw exception for bad smiles: contradictory double bond configuration");
785 	}
786 
787 	@Test(expected=StructureBuildingException.class)
testDoubleBondNoelf()788 	public void testDoubleBondNoelf() throws StructureBuildingException {
789 		sBuilder.build("C/C=C\1NC\1");
790 		fail("Should throw exception for bad smiles: contradictory double bond configuration");
791 	}
792 
793 	@Test(expected=StructureBuildingException.class)
testDoubleBondNoelg()794 	public void testDoubleBondNoelg() throws StructureBuildingException {
795 		sBuilder.build("C/C=C\1/NC\1");
796 		fail("Should throw exception for bad smiles: contradictory double bond configuration");
797 	}
798 
799 	@Test
testDoubleBondCornerCase1()800 	public void testDoubleBondCornerCase1() throws StructureBuildingException {
801 		Fragment fragment = sBuilder.build("C\\1NC1=C/C");
802 		Bond b =fragment.findBond(3, 4);
803 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
804 		assertEquals("1 3 4 5", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
805 	}
806 
807 	@Test
testDoubleBondCornerCase2()808 	public void testDoubleBondCornerCase2() throws StructureBuildingException {
809 		Fragment fragment = sBuilder.build("C1NC/1=C/C");
810 		Bond b =fragment.findBond(3, 4);
811 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
812 		assertEquals("1 3 4 5", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
813 	}
814 
815 	@Test(expected=StructureBuildingException.class)
testDoubleBondCornerCase3()816 	public void testDoubleBondCornerCase3() throws StructureBuildingException {
817 		sBuilder.build("C/1=C/CCCCCC/1");
818 		fail("Should throw exception for bad smiles: contradictory double bond configuration");
819 	}
820 
821 	@Test(expected=StructureBuildingException.class)
testDoubleBondCornerCase4()822 	public void testDoubleBondCornerCase4() throws StructureBuildingException {
823 		sBuilder.build("C\\1=C/CCCCCC\\1");
824 		fail("Should throw exception for bad smiles: contradictory double bond configuration");
825 	}
826 
827 	@Test
testDoubleBondCornerCase5()828 	public void testDoubleBondCornerCase5() throws StructureBuildingException {
829 		Fragment fragment = sBuilder.build("C\\1=C/CCCCCC/1");
830 		Bond b = fragment.findBond(1, 2);
831 		assertEquals(BondStereoValue.TRANS, b.getBondStereo().getBondStereoValue());
832 		assertEquals("8 1 2 3", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
833 	}
834 
835 	@Test
testDoubleBondCornerCase6()836 	public void testDoubleBondCornerCase6() throws StructureBuildingException {
837 		Fragment fragment = sBuilder.build("C/1=C/CCCCCC\\1");
838 		Bond b = fragment.findBond(1, 2);
839 		assertEquals(BondStereoValue.CIS, b.getBondStereo().getBondStereoValue());
840 		assertEquals("8 1 2 3", atomRefsToIdStr(b.getBondStereo().getAtomRefs4()));
841 	}
842 
atomRefsToIdStr(Atom[] atomRefs4)843 	private String atomRefsToIdStr(Atom[] atomRefs4) {
844 		StringBuilder sb = new StringBuilder();
845 		for (int i = 0; i < atomRefs4.length; i++) {
846 			sb.append(atomRefs4[i].getID());
847 			if (i + 1 < atomRefs4.length) {
848 				sb.append(' ');
849 			}
850 		}
851 		return sb.toString();
852 	}
853 }
854