1 /* Copyright (C) 2004-2007  Egon Willighagen <egonw@users.sf.net>
2  *
3  * Contact: cdk-devel@lists.sourceforge.net
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public License
7  * as published by the Free Software Foundation; either version 2.1
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  */
19 package org.openscience.cdk.smarts;
20 
21 import org.hamcrest.CoreMatchers;
22 import org.junit.Test;
23 import org.openscience.cdk.CDKTestCase;
24 import org.openscience.cdk.interfaces.IChemObjectBuilder;
25 import org.openscience.cdk.isomorphism.matchers.Expr;
26 import org.openscience.cdk.silent.SilentChemObjectBuilder;
27 import org.openscience.cdk.smarts.Smarts;
28 
29 import static org.junit.Assert.assertThat;
30 
31 /**
32  * JUnit test routines for the SMARTS parser.
33  *
34  * @author Egon Willighagen
35  * @cdk.module test-smarts
36  * @cdk.require ant1.6
37  */
38 public class ParserTest extends CDKTestCase {
39 
40     private static final class InvalidSmarts extends Exception {
InvalidSmarts(String message)41         public InvalidSmarts(String message) {
42             super(message);
43         }
44     }
45 
parse(String smarts, int flav)46     private void parse(String smarts, int flav) throws Exception {
47         IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
48         if (!Smarts.parse(builder.newAtomContainer(), smarts, flav))
49             throw new InvalidSmarts(Smarts.getLastErrorMesg());
50     }
51 
parse(String smarts)52     private void parse(String smarts) throws Exception {
53         parse(smarts, Smarts.FLAVOR_LOOSE);
54     }
55 
56     @Test
errorHandling()57     public void errorHandling() {
58         IChemObjectBuilder builder = SilentChemObjectBuilder.getInstance();
59         if (!Smarts.parse(builder.newAtomContainer(), "CCCJCCC")) {
60             assertThat(Smarts.getLastErrorMesg(),     CoreMatchers.is("Unexpected character"));
61             assertThat(Smarts.getLastErrorLocation(), CoreMatchers.is("CCCJCCC\n   ^\n"));
62         }
63     }
64 
65     @Test
testQueryAtomCreation()66     public void testQueryAtomCreation() throws Exception {
67         parse("*");
68     }
69 
70     @Test
testAliphaticAtom()71     public void testAliphaticAtom() throws Exception {
72         parse("A");
73     }
74 
75     @Test
testAromaticAtom()76     public void testAromaticAtom() throws Exception {
77         parse("a");
78     }
79 
80     @Test
testDegree()81     public void testDegree() throws Exception {
82         parse("[D2]");
83     }
84 
85     @Test
testImplicitHCount()86     public void testImplicitHCount() throws Exception {
87         parse("[h3]");
88     }
89 
90     @Test
testTotalHCount()91     public void testTotalHCount() throws Exception {
92         parse("[H2]");
93     }
94 
95     /**
96      * @cdk.bug 1760967
97      */
98     @Test
testSingleBond()99     public void testSingleBond() throws Exception {
100         parse("C-C");
101     }
102 
103     @Test
testDoubleBond()104     public void testDoubleBond() throws Exception {
105         parse("C=C");
106     }
107 
108     @Test
testTripleBond()109     public void testTripleBond() throws Exception {
110         parse("C#C");
111     }
112 
113     @Test
testAromaticBond()114     public void testAromaticBond() throws Exception {
115         parse("C:C");
116     }
117 
118     @Test
testAnyOrderBond()119     public void testAnyOrderBond() throws Exception {
120         parse("C~C");
121     }
122 
123     /**
124      * @cdk.bug 2786624
125      */
126     @Test
test2LetterSMARTS()127     public void test2LetterSMARTS() throws Exception {
128         parse("Sc1ccccc1");
129     }
130 
131     @Test
testPattern1()132     public void testPattern1() throws Exception {
133         parse("[CX4]");
134     }
135 
136     @Test
testPattern2()137     public void testPattern2() throws Exception {
138         parse("[$([CX2](=C)=C)]");
139     }
140 
141     @Test
testPattern3()142     public void testPattern3() throws Exception {
143         parse("[$([CX3]=[CX3])]");
144     }
145 
146     @Test
testPattern4()147     public void testPattern4() throws Exception {
148         parse("[$([CX2]#C)]");
149     }
150 
151     @Test
testPattern5()152     public void testPattern5() throws Exception {
153         parse("[CX3]=[OX1]");
154     }
155 
156     @Test
testPattern6()157     public void testPattern6() throws Exception {
158         parse("[$([CX3]=[OX1]),$([CX3+]-[OX1-])]");
159     }
160 
161     @Test
testPattern7()162     public void testPattern7() throws Exception {
163         parse("[CX3](=[OX1])C");
164     }
165 
166     @Test
testPattern8()167     public void testPattern8() throws Exception {
168         parse("[OX1]=CN");
169     }
170 
171     @Test
testPattern9()172     public void testPattern9() throws Exception {
173         parse("[CX3](=[OX1])O");
174     }
175 
176     @Test
testPattern10()177     public void testPattern10() throws Exception {
178         parse("[CX3](=[OX1])[F,Cl,Br,I]");
179     }
180 
181     @Test
testPattern11()182     public void testPattern11() throws Exception {
183         parse("[CX3H1](=O)[#6]");
184     }
185 
186     @Test
testPattern12()187     public void testPattern12() throws Exception {
188         parse("[CX3](=[OX1])[OX2][CX3](=[OX1])");
189     }
190 
191     @Test
testPattern13()192     public void testPattern13() throws Exception {
193         parse("[NX3][CX3](=[OX1])[#6]");
194     }
195 
196     @Test
testPattern14()197     public void testPattern14() throws Exception {
198         parse("[NX3][CX3]=[NX3+]");
199     }
200 
201     @Test
testPattern15()202     public void testPattern15() throws Exception {
203         parse("[NX3,NX4+][CX3](=[OX1])[OX2,OX1-]");
204     }
205 
206     @Test
testPattern16()207     public void testPattern16() throws Exception {
208         parse("[NX3][CX3](=[OX1])[OX2H0]");
209     }
210 
211     @Test
testPattern17()212     public void testPattern17() throws Exception {
213         parse("[NX3,NX4+][CX3](=[OX1])[OX2H,OX1-]");
214     }
215 
216     @Test
testPattern18()217     public void testPattern18() throws Exception {
218         parse("[CX3](=O)[O-]");
219     }
220 
221     @Test
testPattern19()222     public void testPattern19() throws Exception {
223         parse("[CX3](=[OX1])(O)O");
224     }
225 
226     @Test
testPattern20()227     public void testPattern20() throws Exception {
228         parse("[CX3](=[OX1])([OX2])[OX2H,OX1H0-1]");
229     }
230 
231     @Test
testPattern21()232     public void testPattern21() throws Exception {
233         parse("[CX3](=O)[OX2H1]");
234     }
235 
236     @Test
testPattern22()237     public void testPattern22() throws Exception {
238         parse("[CX3](=O)[OX1H0-,OX2H1]");
239     }
240 
241     @Test
testPattern23()242     public void testPattern23() throws Exception {
243         parse("[NX3][CX2]#[NX1]");
244     }
245 
246     @Test
testPattern24()247     public void testPattern24() throws Exception {
248         parse("[#6][CX3](=O)[OX2H0][#6]");
249     }
250 
251     @Test
testPattern25()252     public void testPattern25() throws Exception {
253         parse("[#6][CX3](=O)[#6]");
254     }
255 
256     @Test
testPattern26()257     public void testPattern26() throws Exception {
258         parse("[OD2]([#6])[#6]");
259     }
260 
261     @Test
testPattern27()262     public void testPattern27() throws Exception {
263         parse("[H]");
264     }
265 
266     @Test
testPattern28()267     public void testPattern28() throws Exception {
268         parse("[!#1]");
269     }
270 
271     @Test
testPattern29()272     public void testPattern29() throws Exception {
273         parse("[H+]");
274     }
275 
276     @Test
testPattern30()277     public void testPattern30() throws Exception {
278         parse("[+H]");
279     }
280 
281     @Test
testPattern31()282     public void testPattern31() throws Exception {
283         parse("[NX3;H2,H1;!$(NC=O)]");
284     }
285 
286     @Test
testPattern32()287     public void testPattern32() throws Exception {
288         parse("[NX3][CX3]=[CX3]");
289     }
290 
291     @Test
testPattern33()292     public void testPattern33() throws Exception {
293         parse("[NX3;H2,H1;!$(NC=O)].[NX3;H2,H1;!$(NC=O)]");
294     }
295 
296     @Test
testPattern34()297     public void testPattern34() throws Exception {
298         parse("[NX3][$(C=C),$(cc)]");
299     }
300 
301     @Test
testPattern35()302     public void testPattern35() throws Exception {
303         parse("[NX3,NX4+][CX4H]([*])[CX3](=[OX1])[O,N]");
304     }
305 
306     @Test
testPattern36()307     public void testPattern36() throws Exception {
308         parse("[NX3H2,NH3X4+][CX4H]([*])[CX3](=[OX1])[NX3,NX4+][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-]");
309     }
310 
311     @Test
testPattern37()312     public void testPattern37() throws Exception {
313         parse("[$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-,N]");
314     }
315 
316     @Test
testPattern38()317     public void testPattern38() throws Exception {
318         parse("[CH3X4]");
319     }
320 
321     @Test
testPattern39()322     public void testPattern39() throws Exception {
323         parse("[CH2X4][CH2X4][CH2X4][NHX3][CH0X3](=[NH2X3+,NHX2+0])[NH2X3]");
324     }
325 
326     @Test
testPattern40()327     public void testPattern40() throws Exception {
328         parse("[CH2X4][CX3](=[OX1])[NX3H2]");
329     }
330 
331     @Test
testPattern41()332     public void testPattern41() throws Exception {
333         parse("[CH2X4][CX3](=[OX1])[OH0-,OH]");
334     }
335 
336     @Test
testPattern42()337     public void testPattern42() throws Exception {
338         parse("[CH2X4][SX2H,SX1H0-]");
339     }
340 
341     @Test
testPattern43()342     public void testPattern43() throws Exception {
343         parse("[CH2X4][CH2X4][CX3](=[OX1])[OH0-,OH]");
344     }
345 
346     @Test
testPattern44()347     public void testPattern44() throws Exception {
348         parse("[$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H2][CX3](=[OX1])[OX2H,OX1-,N])]");
349     }
350 
351     @Test
testPattern45()352     public void testPattern45() throws Exception {
353         parse("[CH2X4][#6X3]1:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:[#6X3H]:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:[#6X3H]1");
354     }
355 
356     @Test
testPattern47()357     public void testPattern47() throws Exception {
358         parse("[CHX4]([CH3X4])[CH2X4][CH3X4]");
359     }
360 
361     @Test
testPattern48()362     public void testPattern48() throws Exception {
363         parse("[CH2X4][CHX4]([CH3X4])[CH3X4]");
364     }
365 
366     @Test
testPattern49()367     public void testPattern49() throws Exception {
368         parse("[CH2X4][CH2X4][CH2X4][CH2X4][NX4+,NX3+0]");
369     }
370 
371     @Test
testPattern50()372     public void testPattern50() throws Exception {
373         parse("[CH2X4][CH2X4][SX2][CH3X4]");
374     }
375 
376     @Test
testPattern51()377     public void testPattern51() throws Exception {
378         parse("[CH2X4][cX3]1[cX3H][cX3H][cX3H][cX3H][cX3H]1");
379     }
380 
381     @Test
testPattern52()382     public void testPattern52() throws Exception {
383         parse("[$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]");
384     }
385 
386     @Test
testPattern53()387     public void testPattern53() throws Exception {
388         parse("[CH2X4][OX2H]");
389     }
390 
391     @Test
testPattern54()392     public void testPattern54() throws Exception {
393         parse("[NX3][CX3]=[SX1]");
394     }
395 
396     @Test
testPattern55()397     public void testPattern55() throws Exception {
398         parse("[CHX4]([CH3X4])[OX2H]");
399     }
400 
401     @Test
testPattern56()402     public void testPattern56() throws Exception {
403         parse("[CH2X4][cX3]1[cX3H][nX3H][cX3]2[cX3H][cX3H][cX3H][cX3H][cX3]12");
404     }
405 
406     @Test
testPattern57()407     public void testPattern57() throws Exception {
408         parse("[CH2X4][cX3]1[cX3H][cX3H][cX3]([OHX2,OH0X1-])[cX3H][cX3H]1");
409     }
410 
411     @Test
testPattern58()412     public void testPattern58() throws Exception {
413         parse("[CHX4]([CH3X4])[CH3X4]");
414     }
415 
416     @Test
testPattern59()417     public void testPattern59() throws Exception {
418         parse("[CH3X4]");
419     }
420 
421     @Test
testPattern60()422     public void testPattern60() throws Exception {
423         parse("[CH2X4][CH2X4][CH2X4][NHX3][CH0X3](=[NH2X3+,NHX2+0])[NH2X3]");
424     }
425 
426     @Test
testPattern61()427     public void testPattern61() throws Exception {
428         parse("[CH2X4][CX3](=[OX1])[NX3H2]");
429     }
430 
431     @Test
testPattern62()432     public void testPattern62() throws Exception {
433         parse("[CH2X4][CX3](=[OX1])[OH0-,OH]");
434     }
435 
436     @Test
testPattern63()437     public void testPattern63() throws Exception {
438         parse("[CH2X4][SX2H,SX1H0-]");
439     }
440 
441     @Test
testPattern64()442     public void testPattern64() throws Exception {
443         parse("[CH2X4][CH2X4][CX3](=[OX1])[OH0-,OH]");
444     }
445 
446     @Test
testPattern65()447     public void testPattern65() throws Exception {
448         parse("[CH2X4][#6X3]1:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:[#6X3H]:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:[#6X3H]1");
449     }
450 
451     @Test
testPattern67()452     public void testPattern67() throws Exception {
453         parse("[CHX4]([CH3X4])[CH2X4][CH3X4]");
454     }
455 
456     @Test
testPattern68()457     public void testPattern68() throws Exception {
458         parse("[CH2X4][CHX4]([CH3X4])[CH3X4]");
459     }
460 
461     @Test
testPattern69()462     public void testPattern69() throws Exception {
463         parse("[CH2X4][CH2X4][CH2X4][CH2X4][NX4+,NX3+0]");
464     }
465 
466     @Test
testPattern70()467     public void testPattern70() throws Exception {
468         parse("[CH2X4][CH2X4][SX2][CH3X4]");
469     }
470 
471     @Test
testPattern71()472     public void testPattern71() throws Exception {
473         parse("[CH2X4][cX3]1[cX3H][cX3H][cX3H][cX3H][cX3H]1");
474     }
475 
476     @Test
testPattern72()477     public void testPattern72() throws Exception {
478         parse("[CH2X4][OX2H]");
479     }
480 
481     @Test
testPattern73()482     public void testPattern73() throws Exception {
483         parse("[CHX4]([CH3X4])[OX2H]");
484     }
485 
486     @Test
testPattern74()487     public void testPattern74() throws Exception {
488         parse("[CH2X4][cX3]1[cX3H][nX3H][cX3]2[cX3H][cX3H][cX3H][cX3H][cX3]12");
489     }
490 
491     @Test
testPattern75()492     public void testPattern75() throws Exception {
493         parse("[CH2X4][cX3]1[cX3H][cX3H][cX3]([OHX2,OH0X1-])[cX3H][cX3H]1");
494     }
495 
496     @Test
testPattern76()497     public void testPattern76() throws Exception {
498         parse("[CHX4]([CH3X4])[CH3X4]");
499     }
500 
501     @Test
testPattern77()502     public void testPattern77() throws Exception {
503         parse("[$(*-[NX2-]-[NX2+]#[NX1]),$(*-[NX2]=[NX2+]=[NX1-])]");
504     }
505 
506     @Test
testPattern78()507     public void testPattern78() throws Exception {
508         parse("[$([NX1-]=[NX2+]=[NX1-]),$([NX1]#[NX2+]-[NX1-2])]");
509     }
510 
511     @Test
testPattern79()512     public void testPattern79() throws Exception {
513         parse("[#7]");
514     }
515 
516     @Test
testPattern80()517     public void testPattern80() throws Exception {
518         parse("[NX2]=N");
519     }
520 
521     @Test
testPattern81()522     public void testPattern81() throws Exception {
523         parse("[NX2]=[NX2]");
524     }
525 
526     @Test
testPattern82()527     public void testPattern82() throws Exception {
528         parse("[$([NX2]=[NX3+]([O-])[#6]),$([NX2]=[NX3+0](=[O])[#6])]");
529     }
530 
531     @Test
testPattern83()532     public void testPattern83() throws Exception {
533         parse("[$([#6]=[N+]=[N-]),$([#6-]-[N+]#[N])]");
534     }
535 
536     @Test
testPattern84()537     public void testPattern84() throws Exception {
538         parse("[$([nr5]:[nr5,or5,sr5]),$([nr5]:[cr5]:[nr5,or5,sr5])]");
539     }
540 
541     @Test
testPattern85()542     public void testPattern85() throws Exception {
543         parse("[NX3][NX3]");
544     }
545 
546     @Test
testPattern86()547     public void testPattern86() throws Exception {
548         parse("[NX3][NX2]=[*]");
549     }
550 
551     @Test
testPattern87()552     public void testPattern87() throws Exception {
553         parse("[CX3;$([C]([#6])[#6]),$([CH][#6])]=[NX2][#6]");
554     }
555 
556     @Test
testPattern88()557     public void testPattern88() throws Exception {
558         parse("[$([CX3]([#6])[#6]),$([CX3H][#6])]=[$([NX2][#6]),$([NX2H])]");
559     }
560 
561     @Test
testPattern89()562     public void testPattern89() throws Exception {
563         parse("[NX3+]=[CX3]");
564     }
565 
566     @Test
testPattern90()567     public void testPattern90() throws Exception {
568         parse("[CX3](=[OX1])[NX3H][CX3](=[OX1])");
569     }
570 
571     @Test
testPattern91()572     public void testPattern91() throws Exception {
573         parse("[CX3](=[OX1])[NX3H0]([#6])[CX3](=[OX1])");
574     }
575 
576     @Test
testPattern92()577     public void testPattern92() throws Exception {
578         parse("[CX3](=[OX1])[NX3H0]([NX3H0]([CX3](=[OX1]))[CX3](=[OX1]))[CX3](=[OX1])");
579     }
580 
581     @Test
testPattern93()582     public void testPattern93() throws Exception {
583         parse("[$([NX3](=[OX1])(=[OX1])O),$([NX3+]([OX1-])(=[OX1])O)]");
584     }
585 
586     @Test
testPattern94()587     public void testPattern94() throws Exception {
588         parse("[$([OX1]=[NX3](=[OX1])[OX1-]),$([OX1]=[NX3+]([OX1-])[OX1-])]");
589     }
590 
591     @Test
testPattern95()592     public void testPattern95() throws Exception {
593         parse("[NX1]#[CX2]");
594     }
595 
596     @Test
testPattern96()597     public void testPattern96() throws Exception {
598         parse("[CX1-]#[NX2+]");
599     }
600 
601     @Test
testPattern97()602     public void testPattern97() throws Exception {
603         parse("[$([NX3](=O)=O),$([NX3+](=O)[O-])][!#8]");
604     }
605 
606     @Test
testPattern98()607     public void testPattern98() throws Exception {
608         parse("[$([NX3](=O)=O),$([NX3+](=O)[O-])][!#8].[$([NX3](=O)=O),$([NX3+](=O)[O-])][!#8]");
609     }
610 
611     @Test
testPattern99()612     public void testPattern99() throws Exception {
613         parse("[NX2]=[OX1]");
614     }
615 
616     @Test
testPattern101()617     public void testPattern101() throws Exception {
618         parse("[$([#7+][OX1-]),$([#7v5]=[OX1]);!$([#7](~[O])~[O]);!$([#7]=[#7])]");
619     }
620 
621     @Test
testPattern102()622     public void testPattern102() throws Exception {
623         parse("[OX2H]");
624     }
625 
626     @Test
testPattern103()627     public void testPattern103() throws Exception {
628         parse("[#6][OX2H]");
629     }
630 
631     @Test
testPattern104()632     public void testPattern104() throws Exception {
633         parse("[OX2H][CX3]=[OX1]");
634     }
635 
636     @Test
testPattern105()637     public void testPattern105() throws Exception {
638         parse("[OX2H]P");
639     }
640 
641     @Test
testPattern106()642     public void testPattern106() throws Exception {
643         parse("[OX2H][#6X3]=[#6]");
644     }
645 
646     @Test
testPattern107()647     public void testPattern107() throws Exception {
648         parse("[OX2H][cX3]:[c]");
649     }
650 
651     @Test
testPattern108()652     public void testPattern108() throws Exception {
653         parse("[OX2H][$(C=C),$(cc)]");
654     }
655 
656     @Test
testPattern109()657     public void testPattern109() throws Exception {
658         parse("[$([OH]-*=[!#6])]");
659     }
660 
661     @Test
testPattern110()662     public void testPattern110() throws Exception {
663         parse("[OX2,OX1-][OX2,OX1-]");
664     }
665 
666     @Test
testPattern111()667     public void testPattern111() throws Exception { // Phosphoric_acid groups.
668         parse("[$(P(=[OX1])([$([OX2H]),$([OX1-]),$([OX2]P)])([$([OX2H]),$([OX1-]),$([OX2]P)])[$([OX2H]),$([OX1-]),$([OX2]P)]),$([P+]([OX1-])([$([OX"
669                 + "2H]),$([OX1-]),$([OX2]P)])([$([OX2H]),$([OX1-]),$([OX2]P)])[$([OX2H]),$([OX1-]),$([OX2]P)])]");
670     }
671 
672     @Test
testPattern112()673     public void testPattern112() throws Exception { // Phosphoric_ester groups.
674         parse("[$(P(=[OX1])([OX2][#6])([$([OX2H]),$([OX1-]),$([OX2][#6])])[$([OX2H]),$([OX1-]),$([OX2][#6]),$([OX2]P)]),$([P+]([OX1-])([OX2][#6])(["
675                 + "$([OX2H]),$([OX1-]),$([OX2][#6])])[$([OX2H]),$([OX1-]),$([OX2][#6]),$([OX2]P)])]");
676     }
677 
678     @Test
testPattern113()679     public void testPattern113() throws Exception {
680         parse("[S-][CX3](=S)[#6]");
681     }
682 
683     @Test
testPattern114()684     public void testPattern114() throws Exception {
685         parse("[#6X3](=[SX1])([!N])[!N]");
686     }
687 
688     @Test
testPattern115()689     public void testPattern115() throws Exception {
690         parse("[SX2]");
691     }
692 
693     @Test
testPattern116()694     public void testPattern116() throws Exception {
695         parse("[#16X2H]");
696     }
697 
698     @Test
testPattern117()699     public void testPattern117() throws Exception {
700         parse("[#16!H0]");
701     }
702 
703     @Test
testPattern118()704     public void testPattern118() throws Exception {
705         parse("[NX3][CX3]=[SX1]");
706     }
707 
708     @Test
testPattern119()709     public void testPattern119() throws Exception {
710         parse("[#16X2H0]");
711     }
712 
713     @Test
testPattern120()714     public void testPattern120() throws Exception {
715         parse("[#16X2H0][!#16]");
716     }
717 
718     @Test
testPattern121()719     public void testPattern121() throws Exception {
720         parse("[#16X2H0][#16X2H0]");
721     }
722 
723     @Test
testPattern122()724     public void testPattern122() throws Exception {
725         parse("[#16X2H0][!#16].[#16X2H0][!#16]");
726     }
727 
728     @Test
testPattern123()729     public void testPattern123() throws Exception {
730         parse("[$([#16X3](=[OX1])[OX2H0]),$([#16X3+]([OX1-])[OX2H0])]");
731     }
732 
733     @Test
testPattern124()734     public void testPattern124() throws Exception {
735         parse("[$([#16X3](=[OX1])[OX2H,OX1H0-]),$([#16X3+]([OX1-])[OX2H,OX1H0-])]");
736     }
737 
738     @Test
testPattern125()739     public void testPattern125() throws Exception {
740         parse("[$([#16X4](=[OX1])=[OX1]),$([#16X4+2]([OX1-])[OX1-])]");
741     }
742 
743     @Test
testPattern126()744     public void testPattern126() throws Exception {
745         parse("[$([#16X4](=[OX1])(=[OX1])([#6])[#6]),$([#16X4+2]([OX1-])([OX1-])([#6])[#6])]");
746     }
747 
748     @Test
testPattern127()749     public void testPattern127() throws Exception {
750         parse("[$([#16X4](=[OX1])(=[OX1])([#6])[OX2H,OX1H0-]),$([#16X4+2]([OX1-])([OX1-])([#6])[OX2H,OX1H0-])]");
751     }
752 
753     @Test
testPattern128()754     public void testPattern128() throws Exception {
755         parse("[$([#16X4](=[OX1])(=[OX1])([#6])[OX2H0]),$([#16X4+2]([OX1-])([OX1-])([#6])[OX2H0])]");
756     }
757 
758     @Test
testPattern129()759     public void testPattern129() throws Exception {
760         parse("[$([#16X4]([NX3])(=[OX1])(=[OX1])[#6]),$([#16X4+2]([NX3])([OX1-])([OX1-])[#6])]");
761     }
762 
763     @Test
testPattern130()764     public void testPattern130() throws Exception {
765         parse("[SX4](C)(C)(=O)=N");
766     }
767 
768     @Test
testPattern131()769     public void testPattern131() throws Exception {
770         parse("[$([SX4](=[OX1])(=[OX1])([!O])[NX3]),$([SX4+2]([OX1-])([OX1-])([!O])[NX3])]");
771     }
772 
773     @Test
testPattern132()774     public void testPattern132() throws Exception {
775         parse("[$([#16X3]=[OX1]),$([#16X3+][OX1-])]");
776     }
777 
778     @Test
testPattern133()779     public void testPattern133() throws Exception {
780         parse("[$([#16X3](=[OX1])([#6])[#6]),$([#16X3+]([OX1-])([#6])[#6])]");
781     }
782 
783     @Test
testPattern134()784     public void testPattern134() throws Exception {
785         parse("[$([#16X4](=[OX1])(=[OX1])([OX2H,OX1H0-])[OX2][#6]),$([#16X4+2]([OX1-])([OX1-])([OX2H,OX1H0-])[OX2][#6])]");
786     }
787 
788     @Test
testPattern135()789     public void testPattern135() throws Exception {
790         parse("[$([SX4](=O)(=O)(O)O),$([SX4+2]([O-])([O-])(O)O)]");
791     }
792 
793     @Test
testPattern136()794     public void testPattern136() throws Exception {
795         parse("[$([#16X4](=[OX1])(=[OX1])([OX2][#6])[OX2][#6]),$([#16X4](=[OX1])(=[OX1])([OX2][#6])[OX2][#6])]");
796     }
797 
798     @Test
testPattern137()799     public void testPattern137() throws Exception {
800         parse("[$([#16X4]([NX3])(=[OX1])(=[OX1])[OX2][#6]),$([#16X4+2]([NX3])([OX1-])([OX1-])[OX2][#6])]");
801     }
802 
803     @Test
testPattern138()804     public void testPattern138() throws Exception {
805         parse("[$([#16X4]([NX3])(=[OX1])(=[OX1])[OX2H,OX1H0-]),$([#16X4+2]([NX3])([OX1-])([OX1-])[OX2H,OX1H0-])]");
806     }
807 
808     @Test
testPattern139()809     public void testPattern139() throws Exception {
810         parse("[#16X2][OX2H,OX1H0-]");
811     }
812 
813     @Test
testPattern140()814     public void testPattern140() throws Exception {
815         parse("[#16X2][OX2H0]");
816     }
817 
818     @Test
testPattern141()819     public void testPattern141() throws Exception {
820         parse("[#6][F,Cl,Br,I]");
821     }
822 
823     @Test
testPattern142()824     public void testPattern142() throws Exception {
825         parse("[F,Cl,Br,I]");
826     }
827 
828     @Test
testPattern143()829     public void testPattern143() throws Exception {
830         parse("[F,Cl,Br,I].[F,Cl,Br,I].[F,Cl,Br,I]");
831     }
832 
833     @Test
testPattern144()834     public void testPattern144() throws Exception {
835         parse("[CX3](=[OX1])[F,Cl,Br,I]");
836     }
837 
838     @Test
testPattern145()839     public void testPattern145() throws Exception {
840         parse("[$([#6X4@](*)(*)(*)*),$([#6X4@H](*)(*)*)]");
841     }
842 
843     @Test
testPattern146()844     public void testPattern146() throws Exception {
845         parse("[$([cX2+](:*):*)]");
846     }
847 
848     @Test
testPattern147()849     public void testPattern147() throws Exception {
850         parse("[$([cX3](:*):*),$([cX2+](:*):*)]");
851     }
852 
853     @Test
testPattern148()854     public void testPattern148() throws Exception {
855         parse("[$([cX3](:*):*),$([cX2+](:*):*),$([CX3]=*),$([CX2+]=*)]");
856     }
857 
858     @Test
testPattern149()859     public void testPattern149() throws Exception {
860         parse("[$([nX3](:*):*),$([nX2](:*):*),$([#7X2]=*),$([NX3](=*)=*),$([#7X3+](-*)=*),$([#7X3+H]=*)]");
861     }
862 
863     @Test
testPattern150()864     public void testPattern150() throws Exception {
865         parse("[$([#1X1][$([nX3](:*):*),$([nX2](:*):*),$([#7X2]=*),$([NX3](=*)=*),$([#7X3+](-*)=*),$([#7X3+H]=*)])]");
866     }
867 
868     @Test
testPattern151()869     public void testPattern151() throws Exception {
870         parse("[$([NX4+]),$([NX3]);!$(*=*)&!$(*:*)]");
871     }
872 
873     @Test
testPattern152()874     public void testPattern152() throws Exception {
875         parse("[$([#1X1][$([NX4+]),$([NX3]);!$(*=*)&!$(*:*)])]");
876     }
877 
878     @Test
testPattern153()879     public void testPattern153() throws Exception {
880         parse("[$([$([NX3]=O),$([NX3+][O-])])]");
881     }
882 
883     @Test
testPattern154()884     public void testPattern154() throws Exception {
885         parse("[$([$([NX4]=O),$([NX4+][O-])])]");
886     }
887 
888     @Test
testPattern155()889     public void testPattern155() throws Exception {
890         parse("[$([$([NX4]=O),$([NX4+][O-,#0])])]");
891     }
892 
893     @Test
testPattern156()894     public void testPattern156() throws Exception {
895         parse("[$([NX4+]),$([NX4]=*)]");
896     }
897 
898     @Test
testPattern157()899     public void testPattern157() throws Exception {
900         parse("[$([SX3]=N)]");
901     }
902 
903     @Test
testPattern158()904     public void testPattern158() throws Exception {
905         parse("[$([SX1]=[#6])]");
906     }
907 
908     @Test
testPattern159()909     public void testPattern159() throws Exception {
910         parse("[$([NX1]#*)]");
911     }
912 
913     @Test
testPattern160()914     public void testPattern160() throws Exception {
915         parse("[$([OX2])]");
916     }
917 
918     @Test
testPattern161()919     public void testPattern161() throws Exception {
920         parse("[R0;D2][R0;D2][R0;D2][R0;D2]");
921     }
922 
923     @Test
testPattern162()924     public void testPattern162() throws Exception {
925         parse("[R0;D2]~[R0;D2]~[R0;D2]~[R0;D2]");
926     }
927 
928     @Test
testPattern163()929     public void testPattern163() throws Exception {
930         parse("[AR0]~[AR0]~[AR0]~[AR0]~[AR0]~[AR0]~[AR0]~[AR0]");
931     }
932 
933     @Test
testPattern164()934     public void testPattern164() throws Exception {
935         parse("[!$([#6+0]);!$(C(F)(F)F);!$(c(:[!c]):[!c])!$([#6]=,#[!#6])]");
936     }
937 
938     @Test
testPattern165()939     public void testPattern165() throws Exception {
940         parse("[$([#6+0]);!$(C(F)(F)F);!$(c(:[!c]):[!c])!$([#6]=,#[!#6])]");
941     }
942 
943     @Test
testPattern166()944     public void testPattern166() throws Exception {
945         parse("[$([SX1]~P)]");
946     }
947 
948     @Test
testPattern167()949     public void testPattern167() throws Exception {
950         parse("[$([NX3]C=N)]");
951     }
952 
953     @Test
testPattern168()954     public void testPattern168() throws Exception {
955         parse("[$([NX3]N=C)]");
956     }
957 
958     @Test
testPattern169()959     public void testPattern169() throws Exception {
960         parse("[$([NX3]N=N)]");
961     }
962 
963     @Test
testPattern170()964     public void testPattern170() throws Exception {
965         parse("[$([OX2]C=N)]");
966     }
967 
968     @Test
testPattern171()969     public void testPattern171() throws Exception {
970         parse("[!$(*#*)&!D1]-!@[!$(*#*)&!D1]");
971     }
972 
973     @Test
testPattern172()974     public void testPattern172() throws Exception {
975         parse("[$([*R2]([*R])([*R])([*R]))].[$([*R2]([*R])([*R])([*R]))]");
976     }
977 
978     @Test
testPattern173()979     public void testPattern173() throws Exception {
980         parse("*-!:aa-!:*");
981     }
982 
983     @Test
testPattern174()984     public void testPattern174() throws Exception {
985         parse("*-!:aaa-!:*");
986     }
987 
988     @Test
testPattern175()989     public void testPattern175() throws Exception {
990         parse("*-!:aaaa-!:*");
991     }
992 
993     @Test
testPattern176()994     public void testPattern176() throws Exception {
995         parse("*-!@*");
996     }
997 
998     @Test
testPattern177()999     public void testPattern177() throws Exception { // CIS or TRANS double or aromatic bond in a ring
1000         parse("*/,\\[R]=,:;@[R]/,\\*");
1001     }
1002 
1003     @Test
testPattern178()1004     public void testPattern178() throws Exception { // Fused benzene rings
1005         parse("c12ccccc1cccc2");
1006     }
1007 
1008     @Test
testPattern179()1009     public void testPattern179() throws Exception {
1010         parse("[r;!r3;!r4;!r5;!r6;!r7]");
1011     }
1012 
1013     @Test
testPattern180()1014     public void testPattern180() throws Exception {
1015         parse("[sX2r5]");
1016     }
1017 
1018     @Test
testPattern181()1019     public void testPattern181() throws Exception {
1020         parse("[oX2r5]");
1021     }
1022 
1023     @Test
testPattern182()1024     public void testPattern182() throws Exception { // Unfused benzene ring
1025         parse("[cR1]1[cR1][cR1][cR1][cR1][cR1]1");
1026     }
1027 
1028     @Test
testPattern183()1029     public void testPattern183() throws Exception { // Multiple non-fused benzene rings
1030         parse("[cR1]1[cR1][cR1][cR1][cR1][cR1]1.[cR1]1[cR1][cR1][cR1][cR1][cR1]1");
1031     }
1032 
1033     @Test
testPattern184()1034     public void testPattern184() throws Exception { // Generic amino acid: low specificity.
1035         parse("[NX3,NX4+][CX4H]([*])[CX3](=[OX1])[O,N]");
1036     }
1037 
1038     @Test
testPattern185()1039     public void testPattern185() throws Exception { //Template for 20 standard a.a.s
1040         parse("[$([$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]),"
1041                 + "$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX"
1042                 + "4H2][CX3](=[OX1])[OX2H,OX1-,N]),$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-,N])]");
1043     }
1044 
1045     @Test
testPattern186()1046     public void testPattern186() throws Exception { // Proline
1047         parse("[$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]");
1048     }
1049 
1050     @Test
testPattern187()1051     public void testPattern187() throws Exception { // Glycine
1052         parse("[$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H2][CX3](=[OX1])[OX2H,OX1-,N])]");
1053     }
1054 
1055     @Test
testPattern188()1056     public void testPattern188() throws Exception { // Alanine
1057         parse("[$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([CH3X4])[CX3](=[OX1])[OX2H,OX1-,N]");
1058     }
1059 
1060     @Test
testPattern189()1061     public void testPattern189() throws Exception { //18_standard_aa_side_chains.
1062         parse("([$([CH3X4]),$([CH2X4][CH2X4][CH2X4][NHX3][CH0X3](=[NH2X3+,NHX2+0])[NH2X3]),"
1063                 + "$([CH2X4][CX3](=[OX1])[NX3H2]),$([CH2X4][CX3](=[OX1])[OH0-,OH]),"
1064                 + "$([CH2X4][SX2H,SX1H0-]),$([CH2X4][CH2X4][CX3](=[OX1])[OH0-,OH]),"
1065                 + "$([CH2X4][#6X3]1:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:"
1066                 + "[#6X3H]:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:[#6X3H]1),"
1067                 + "$([CHX4]([CH3X4])[CH2X4][CH3X4]),$([CH2X4][CHX4]([CH3X4])[CH3X4]),"
1068                 + "$([CH2X4][CH2X4][CH2X4][CH2X4][NX4+,NX3+0]),$([CH2X4][CH2X4][SX2][CH3X4]),"
1069                 + "$([CH2X4][cX3]1[cX3H][cX3H][cX3H][cX3H][cX3H]1),$([CH2X4][OX2H]),"
1070                 + "$([CHX4]([CH3X4])[OX2H]),$([CH2X4][cX3]1[cX3H][nX3H][cX3]2[cX3H][cX3H][cX3H][cX3H][cX3]12),"
1071                 + "$([CH2X4][cX3]1[cX3H][cX3H][cX3]([OHX2,OH0X1-])[cX3H][cX3H]1),$([CHX4]([CH3X4])[CH3X4])])");
1072     }
1073 
1074     @Test
testPattern190()1075     public void testPattern190() throws Exception { // N in Any_standard_amino_acid.
1076         parse("[$([$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3]"
1077                 + "(=[OX1])[OX2H,OX1-,N]),$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H2][CX3]"
1078                 + "(=[OX1])[OX2H,OX1-,N]),$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([$([CH3X4]),"
1079                 + "$([CH2X4][CH2X4][CH2X4][NHX3][CH0X3](=[NH2X3+,NHX2+0])[NH2X3]),$"
1080                 + "([CH2X4][CX3](=[OX1])[NX3H2]),$([CH2X4][CX3](=[OX1])[OH0-,OH]),"
1081                 + "$([CH2X4][SX2H,SX1H0-]),$([CH2X4][CH2X4][CX3](=[OX1])[OH0-,OH]),"
1082                 + "$([CH2X4][#6X3]1:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:"
1083                 + "[#6X3H]:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:[#6X3H]1),"
1084                 + "$([CHX4]([CH3X4])[CH2X4][CH3X4]),$([CH2X4][CHX4]([CH3X4])[CH3X4]),"
1085                 + "$([CH2X4][CH2X4][CH2X4][CH2X4][NX4+,NX3+0]),$([CH2X4][CH2X4][SX2][CH3X4]),"
1086                 + "$([CH2X4][cX3]1[cX3H][cX3H][cX3H][cX3H][cX3H]1),$([CH2X4][OX2H]),"
1087                 + "$([CHX4]([CH3X4])[OX2H]),$([CH2X4][cX3]1[cX3H][nX3H][cX3]2[cX3H][cX3H][cX3H][cX3H][cX3]12),"
1088                 + "$([CH2X4][cX3]1[cX3H][cX3H][cX3]([OHX2,OH0X1-])[cX3H][cX3H]1),"
1089                 + "$([CHX4]([CH3X4])[CH3X4])])[CX3](=[OX1])[OX2H,OX1-,N])]");
1090     }
1091 
1092     @Test
testPattern191()1093     public void testPattern191() throws Exception { // Non-standard amino acid.
1094         parse("[$([NX3,NX4+][CX4H]([*])[CX3](=[OX1])[O,N]);!$([$([$([NX3H,NX4H2+]),"
1095                 + "$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]),"
1096                 + "$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H2][CX3](=[OX1])[OX2H,OX1-,N]),"
1097                 + "$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([$([CH3X4]),$([CH2X4][CH2X4][CH2X4][NHX3][CH0X3]"
1098                 + "(=[NH2X3+,NHX2+0])[NH2X3]),$([CH2X4][CX3](=[OX1])[NX3H2]),$([CH2X4][CX3](=[OX1])[OH0-,OH]),"
1099                 + "$([CH2X4][SX2H,SX1H0-]),$([CH2X4][CH2X4][CX3](=[OX1])[OH0-,OH]),$([CH2X4][#6X3]1:"
1100                 + "[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),$([#7X3H])]:"
1101                 + "[#6X3H]:[$([#7X3H+,#7X2H0+0]:[#6X3H]:[#7X3H]),"
1102                 + "$([#7X3H])]:[#6X3H]1),$([CHX4]([CH3X4])[CH2X4][CH3X4]),$([CH2X4][CHX4]([CH3X4])[CH3X4]),"
1103                 + "$([CH2X4][CH2X4][CH2X4][CH2X4][NX4+,NX3+0]),$([CH2X4][CH2X4][SX2][CH3X4]),"
1104                 + "$([CH2X4][cX3]1[cX3H][cX3H][cX3H][cX3H][cX3H]1),$([CH2X4][OX2H]),$([CHX4]([CH3X4])[OX2H]),"
1105                 + "$([CH2X4][cX3]1[cX3H][nX3H][cX3]2[cX3H][cX3H][cX3H][cX3H][cX3]12),"
1106                 + "$([CH2X4][cX3]1[cX3H][cX3H][cX3]([OHX2,OH0X1-])[cX3H][cX3H]1),"
1107                 + "$([CHX4]([CH3X4])[CH3X4])])[CX3](=[OX1])[OX2H,OX1-,N])])]");
1108     }
1109 
1110     @Test
testPattern192()1111     public void testPattern192() throws Exception { //Azide group
1112         parse("[$(*-[NX2-]-[NX2+]#[NX1]),$(*-[NX2]=[NX2+]=[NX1-])]");
1113     }
1114 
1115     @Test
testPattern193()1116     public void testPattern193() throws Exception { // Azide ion
1117         parse("[$([NX1-]=[NX2+]=[NX1-]),$([NX1]#[NX2+]-[NX1-2])]");
1118     }
1119 
1120     @Test
testPattern194()1121     public void testPattern194() throws Exception { //Azide or azide ion
1122         parse("[$([$(*-[NX2-]-[NX2+]#[NX1]),$(*-[NX2]=[NX2+]=[NX1-])]),$([$([NX1-]=[NX2+]=[NX1-]),$([NX1]#[NX2+]-[NX1-2])])]");
1123     }
1124 
1125     @Test
testPattern195()1126     public void testPattern195() throws Exception { // Sulfide
1127         parse("[#16X2H0]");
1128     }
1129 
1130     @Test
testPattern196()1131     public void testPattern196() throws Exception { // Mono-sulfide
1132         parse("[#16X2H0][!#16]");
1133     }
1134 
1135     @Test
testPattern197()1136     public void testPattern197() throws Exception { // Di-sulfide
1137         parse("[#16X2H0][#16X2H0]");
1138     }
1139 
1140     @Test
testPattern198()1141     public void testPattern198() throws Exception { // Two sulfides
1142         parse("[#16X2H0][!#16].[#16X2H0][!#16]");
1143     }
1144 
1145     @Test
testPattern199()1146     public void testPattern199() throws Exception { // Acid/conj-base
1147         parse("[OX2H,OX1H0-]");
1148     }
1149 
1150     @Test
testPattern200()1151     public void testPattern200() throws Exception { // Non-acid Oxygen
1152         parse("[OX2H0]");
1153     }
1154 
1155     @Test
testPattern201()1156     public void testPattern201() throws Exception { // Acid/base
1157         parse("[H1,H0-]");
1158     }
1159 
1160     @Test
testPattern202()1161     public void testPattern202() throws Exception {
1162         parse("([Cl!$(Cl~c)].[c!$(c~Cl)])");
1163     }
1164 
1165     @Test
testPattern203()1166     public void testPattern203() throws Exception {
1167         parse("([Cl]).([c])");
1168     }
1169 
1170     @Test
testPattern204()1171     public void testPattern204() throws Exception {
1172         parse("([Cl].[c])");
1173     }
1174 
1175     @Test
testPattern205()1176     public void testPattern205() throws Exception {
1177         parse("[NX3;H2,H1;!$(NC=O)].[NX3;H2,H1;!$(NC=O)]");
1178     }
1179 
1180     @Test
testPattern206()1181     public void testPattern206() throws Exception {
1182         parse("[#0]");
1183     }
1184 
1185     @Test
testPattern207()1186     public void testPattern207() throws Exception {
1187         parse("[*!H0,#1]");
1188     }
1189 
1190     @Test
testPattern208()1191     public void testPattern208() throws Exception {
1192         parse("[#6!H0,#1]");
1193     }
1194 
1195     @Test
testPattern209()1196     public void testPattern209() throws Exception {
1197         parse("[H,#1]");
1198     }
1199 
1200     @Test
testPattern210()1201     public void testPattern210() throws Exception {
1202         parse("[!H0;F,Cl,Br,I,N+,$([OH]-*=[!#6]),+]");
1203     }
1204 
1205     @Test
testPattern211()1206     public void testPattern211() throws Exception {
1207         parse("[CX3](=O)[OX2H1]");
1208     }
1209 
1210     @Test
testPattern212()1211     public void testPattern212() throws Exception {
1212         parse("[CX3](=O)[OX1H0-,OX2H1]");
1213     }
1214 
1215     @Test
testPattern213()1216     public void testPattern213() throws Exception {
1217         parse("[$([OH]-*=[!#6])]");
1218     }
1219 
1220     @Test
testPattern214()1221     public void testPattern214() throws Exception { // Phosphoric_Acid
1222         parse("[$(P(=[OX1])([$([OX2H]),$([OX1-]),$([OX2]P)])([$([OX2H]),$([OX1-]),$([OX2]P)])[$([OX2H]),$([OX1-]),$([OX2]P)]),$([P+]([OX1-])([$([OX"
1223                 + "2H]),$([OX1-]),$([OX2]P)])([$([OX2H]),$([OX1-]),$([OX2]P)])[$([OX2H]),$([OX1-]),$([OX2]P)])]");
1224     }
1225 
1226     @Test
testPattern215()1227     public void testPattern215() throws Exception { // Sulfonic Acid. High specificity.
1228         parse("[$([#16X4](=[OX1])(=[OX1])([#6])[OX2H,OX1H0-]),$([#16X4+2]([OX1-])([OX1-])([#6])[OX2H,OX1H0-])]");
1229     }
1230 
1231     @Test
testPattern216()1232     public void testPattern216() throws Exception { // Acyl Halide
1233         parse("[CX3](=[OX1])[F,Cl,Br,I]");
1234     }
1235 
1236     @Test
testPattern217()1237     public void testPattern217() throws Exception {
1238         parse("[NX2-]");
1239     }
1240 
1241     @Test
testPattern218()1242     public void testPattern218() throws Exception {
1243         parse("[OX2H+]=*");
1244     }
1245 
1246     @Test
testPattern219()1247     public void testPattern219() throws Exception {
1248         parse("[OX3H2+]");
1249     }
1250 
1251     @Test
testPattern220()1252     public void testPattern220() throws Exception {
1253         parse("[#6+]");
1254     }
1255 
1256     @Test
testPattern221()1257     public void testPattern221() throws Exception {
1258         parse("[$([cX2+](:*):*)]");
1259     }
1260 
1261     @Test
testPattern222()1262     public void testPattern222() throws Exception {
1263         parse("[$([NX1-]=[NX2+]=[NX1-]),$([NX1]#[NX2+]-[NX1-2])]");
1264     }
1265 
1266     @Test
testPattern223()1267     public void testPattern223() throws Exception {
1268         parse("[+1]~*~*~[-1]");
1269     }
1270 
1271     @Test
testPattern224()1272     public void testPattern224() throws Exception {
1273         parse("[$([!-0!-1!-2!-3!-4]~*~[!+0!+1!+2!+3!+4]),$([!-0!-1!-2!-3!-4]~*~*~[!+0!+1!+2!+3!+4]),$([!-0!-1!-2!-3!-4]~*~*~*~[!+0!+1!+2!+3!+4]),$([!-0!-1!-2!-3!-4]~*~*~*~*~[!+0!+1!+2!+3!+4]),$([!-0!-1!-2!-3!-4]~*~*~*~*~*~[!+0!+1!+2!+3!+4]),$([!-0!-1!-2!-3!-4]~*~*~*~*~*~*~[!+0!+1!+2!+3!+4]),$([!-0!-1!-2!-3!-4]~*~*~*~*~*~*~*~[!+0!+1!+2!+3!+4]),$([!-0!-1!-2!-3!-4]~*~*~*~*~*~*~*~*~[!+0!+1!+2!+3!+4]),$([!-0!-1!-2!-3!-4]~*~*~*~*~*~*~*~*~*~[!+0!+1!+2!+3!+4])]");
1274     }
1275 
1276     @Test
testPattern225()1277     public void testPattern225() throws Exception {
1278         parse("([!-0!-1!-2!-3!-4].[!+0!+1!+2!+3!+4])");
1279     }
1280 
1281     @Test
testPattern226()1282     public void testPattern226() throws Exception { // Hydrogen-bond acceptor, Only hits carbonyl and nitroso
1283         parse("[#6,#7;R0]=[#8]");
1284     }
1285 
1286     @Test
testPattern227()1287     public void testPattern227() throws Exception { // Hydrogen-bond acceptor
1288         parse("[!$([#6,F,Cl,Br,I,o,s,nX3,#7v5,#15v5,#16v4,#16v6,*+1,*+2,*+3])]");
1289     }
1290 
1291     @Test
testPattern228()1292     public void testPattern228() throws Exception {
1293         parse("[!$([#6,H0,-,-2,-3])]");
1294     }
1295 
1296     @Test
testPattern229()1297     public void testPattern229() throws Exception {
1298         parse("[!H0;#7,#8,#9]");
1299     }
1300 
1301     @Test
testPattern230()1302     public void testPattern230() throws Exception {
1303         parse("[O,N;!H0]-*~*-*=[$([C,N;R0]=O)]");
1304     }
1305 
1306     @Test
testPattern231()1307     public void testPattern231() throws Exception {
1308         parse("[#6;X3v3+0]");
1309     }
1310 
1311     @Test
testPattern232()1312     public void testPattern232() throws Exception {
1313         parse("[#7;X2v4+0]");
1314     }
1315 
1316     @Test
testPattern233()1317     public void testPattern233() throws Exception { // Amino Acid
1318         parse("[$([$([NX3H,NX4H2+]),$([NX3](C)(C)(C))]1[CX4H]([CH2][CH2][CH2]1)[CX3](=[OX1])[OX2H,OX1-,N]),$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H2]["
1319                 + "CX3](=[OX1])[OX2H,OX1-,N]),$([$([NX3H2,NX4H3+]),$([NX3H](C)(C))][CX4H]([*])[CX3](=[OX1])[OX2H,OX1-,N])]");
1320     }
1321 
1322     @Test
testPattern234()1323     public void testPattern234() throws Exception {
1324         parse("[#6][CX3](=O)[$([OX2H0]([#6])[#6]),$([#7])]");
1325     }
1326 
1327     @Test
testPattern235()1328     public void testPattern235() throws Exception {
1329         parse("[#8]=[C,N]-aaa[F,Cl,Br,I]");
1330     }
1331 
1332     @Test
testPattern236()1333     public void testPattern236() throws Exception {
1334         parse("[O,N;!H0;R0]");
1335     }
1336 
1337     @Test
testPattern237()1338     public void testPattern237() throws Exception {
1339         parse("[#8]=[C,N]");
1340     }
1341 
1342     @Test
testPattern238()1343     public void testPattern238() throws Exception { // PCB
1344         parse("[$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)]-[$(c:cCl),$(c:c:cCl),$(c:c:c:cCl)]");
1345     }
1346 
1347     @Test
testPattern239()1348     public void testPattern239() throws Exception { // Imidazolium Nitrogen
1349         parse("[nX3r5+]:c:n");
1350     }
1351 
1352     @Test
testPattern240()1353     public void testPattern240() throws Exception { // 1-methyl-2-hydroxy benzene with either a Cl or H at the 5 position.
1354         parse("Cc1:c(O):c:c:[$(cCl),$([cH])]:c1");
1355     }
1356 
1357     @Test
testPattern241()1358     public void testPattern241() throws Exception { // Nonstandard atom groups.
1359         parse("[!#1;!#2;!#3;!#5;!#6;!#7;!#8;!#9;!#11;!#12;!#15;!#16;!#17;!#19;!#20;!#35;!#53]");
1360     }
1361 
1362     @Test
testRing()1363     public void testRing() throws Exception {
1364         parse("[$([C;#12]=1CCCCC1)]");
1365     }
1366 
1367     @Test
testHydrogen()1368     public void testHydrogen() throws Exception {
1369         parse("[H]");
1370     }
1371 
1372     @Test
testHybridizationNumber1()1373     public void testHybridizationNumber1() throws Exception {
1374         parse("[^1]");
1375     }
1376 
1377     @Test
testHybridizationNumber2()1378     public void testHybridizationNumber2() throws Exception {
1379         parse("[^1&N]");
1380     }
1381 
1382     @Test
testHybridizationNumber3()1383     public void testHybridizationNumber3() throws Exception {
1384         parse("[^1&N,^2&C]");
1385     }
1386 
1387     @Test(expected = Exception.class)
testHybridizationNumber4()1388     public void testHybridizationNumber4() throws Exception {
1389         parse("[^]");
1390     }
1391 
1392     @Test(expected = Exception.class)
testHybridizationNumber5()1393     public void testHybridizationNumber5() throws Exception {
1394         parse("[^X]");
1395     }
1396 
1397     @Test(expected = Exception.class)
testHybridizationNumber6()1398     public void testHybridizationNumber6() throws Exception {
1399         parse("[^0]");
1400     }
1401 
1402     @Test(expected = Exception.class)
testHybridizationNumber7()1403     public void testHybridizationNumber7() throws Exception {
1404         parse("[^9]");
1405     }
1406 
1407     @Test
testNonCHHeavyAtom1()1408     public void testNonCHHeavyAtom1() throws Exception {
1409         parse("[#X]");
1410     }
1411 
1412     @Test
testNonCHHeavyAtom2()1413     public void testNonCHHeavyAtom2() throws Exception {
1414         parse("C#[#X]");
1415     }
1416 
1417     @Test
testPeriodicGroupNumber1()1418     public void testPeriodicGroupNumber1() throws Exception {
1419         parse("[G14]", Smarts.FLAVOR_CDK_LEGACY);
1420     }
1421 
1422     @Test
testPeriodicGroupNumber2()1423     public void testPeriodicGroupNumber2() throws Exception {
1424         parse("[G14,G15]", Smarts.FLAVOR_CDK_LEGACY);
1425     }
1426 
1427     @Test(expected = Exception.class)
testPeriodicGroupNumber3()1428     public void testPeriodicGroupNumber3() throws Exception {
1429         parse("[G19]", Smarts.FLAVOR_CDK_LEGACY);
1430     }
1431 
1432     @Test(expected = Exception.class)
testPeriodicGroupNumber4()1433     public void testPeriodicGroupNumber4() throws Exception {
1434         parse("[G0]", Smarts.FLAVOR_CDK_LEGACY);
1435     }
1436 
1437     @Test(expected = Exception.class)
testPeriodicGroupNumber5()1438     public void testPeriodicGroupNumber5() throws Exception {
1439         parse("[G345]", Smarts.FLAVOR_CDK_LEGACY);
1440     }
1441 
1442     @Test(expected = Exception.class)
testPeriodicGroupNumber6()1443     public void testPeriodicGroupNumber6() throws Exception {
1444         parse("[G]", Smarts.FLAVOR_CDK_LEGACY);
1445     }
1446 
1447     @Test(expected = Exception.class)
testPeriodicGroupNumber7()1448     public void testPeriodicGroupNumber7() throws Exception {
1449         parse("[GA]");
1450     }
1451 
1452     @Test
testGroup5Elements()1453     public void testGroup5Elements() throws Exception {
1454         parse("[V,Cr,Mn,Nb,Mo,Tc,Ta,W,Re]");
1455     }
1456 
endOnSpace()1457     @Test public void endOnSpace() throws Exception {
1458         parse("C ");
1459     }
1460 
endOnTab()1461     @Test public void endOnTab() throws Exception {
1462         parse("C\t");
1463     }
1464 
endOnNewline()1465     @Test public void endOnNewline() throws Exception {
1466         parse("C\n");
1467     }
1468 
endOnCarriageReturn()1469     @Test public void endOnCarriageReturn() throws Exception {
1470         parse("C\r");
1471     }
1472 
1473     @Test(expected = Exception.class)
badReaction1()1474     public void badReaction1() throws Exception {
1475         parse("C>");
1476     }
1477 
1478     @Test(expected = Exception.class)
badReaction2()1479     public void badReaction2() throws Exception {
1480         parse(">");
1481     }
1482 
1483     @Test(expected = Exception.class)
badReaction3()1484     public void badReaction3() throws Exception {
1485         parse(">C");
1486     }
1487 
1488     @Test(expected = Exception.class)
badReaction4()1489     public void badReaction4() throws Exception {
1490         parse("CC(C>C)C>CC");
1491     }
1492 
1493     @Test
emptyReaction()1494     public void emptyReaction() throws Exception {
1495         parse(">>");
1496     }
1497 
1498     @Test
atomMaps()1499     public void atomMaps() throws Exception {
1500         parse("[C&x2X4:1]1-[C&x2X4:2]-[C&x2X4h2]-[N&x2X3h1]-[C&x2X4h2]-[C&x2X4h2]-1");
1501     }
1502 
1503     @Test
atomMaps2()1504     public void atomMaps2() throws Exception {
1505         parse("[O!RX2:2]-[C&x2X3h0]1=[C&x2X3h1]-[C&x3X3h0]2=[C&x3X3h0](-[C&x2X4h2]-[C&x2X4h2]-[C&x2X3h0](=[O!RX&h0])-[N&x2X3h1]-2)-[C&x2X3h1]=[C&x2X3h1]-1");
1506     }
1507 
1508     /**
1509      * @cdk.bug 909
1510      */
bug909()1511     @Test public void bug909() throws Exception {
1512         parse("O=C1NCCSc2ccccc12");
1513     }
1514 
1515     @Test(expected = InvalidSmarts.class)
testBondPrefix()1516     public void testBondPrefix() throws Exception {
1517         parse("-CCO");
1518     }
1519 
1520     @Test(expected = InvalidSmarts.class)
trailingBond()1521     public void trailingBond() throws Exception {
1522         parse("CCO-");
1523     }
1524 
1525 }
1526