bfdadf49a45efe9d4e085445ddc410a6f312c963
[idea/community.git] / platform / structuralsearch / testSource / com / intellij / structuralsearch / impl / matcher / compiler / StringToConstraintsTransformerTest.java
1 package com.intellij.structuralsearch.impl.matcher.compiler;
2
3 import com.intellij.structuralsearch.MalformedPatternException;
4 import com.intellij.structuralsearch.MatchOptions;
5 import com.intellij.structuralsearch.MatchVariableConstraint;
6 import com.intellij.structuralsearch.UnsupportedPatternException;
7 import com.intellij.structuralsearch.plugin.ui.Configuration;
8 import org.junit.Before;
9 import org.junit.Test;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertTrue;
13 import static org.junit.Assert.assertFalse;
14
15 /**
16  * @author Bas Leijdekkers
17  */
18 public class StringToConstraintsTransformerTest {
19
20   private MatchOptions myOptions;
21
22   @Before
23   public void setUp() throws Exception {
24     myOptions = new MatchOptions();
25   }
26
27   @Test(expected = MalformedPatternException.class)
28   public void testCharacterExpectedAfterQuote() {
29     test("' asdf");
30   }
31
32   @Test(expected = MalformedPatternException.class)
33   public void testCharacterExpectedAfterQuote2() {
34     test("'");
35   }
36
37   @Test(expected = MalformedPatternException.class)
38   public void testUnexpectedEndOfPattern() {
39     test("'_a{");
40   }
41
42   @Test(expected = MalformedPatternException.class)
43   public void testDigitExpected() {
44     test("'a{a");
45   }
46
47   @Test(expected = MalformedPatternException.class)
48   public void testDigitExpected2() {
49     test("'a{1,a}");
50   }
51
52   @Test
53   public void testZeroOccurs() {
54     test("'a{,}");
55     final MatchVariableConstraint constraint = myOptions.getVariableConstraint("a");
56     assertEquals(0, constraint.getMinCount());
57     assertEquals(0, constraint.getMaxCount());
58   }
59
60   @Test(expected = MalformedPatternException.class)
61   public void testOverflow() {
62     test("'a{2147483648}");
63   }
64
65   @Test(expected = MalformedPatternException.class)
66   public void testMissingBrace() {
67     test("'a{1,3");
68   }
69
70   @Test(expected = MalformedPatternException.class)
71   public void testNoOptions() {
72     test("'a:");
73   }
74
75   @Test
76   public void testColon() {
77     test("for('_t 'a : '_b) {}");
78     assertEquals("for($t$ $a$ : $b$) {}", myOptions.getSearchPattern());
79   }
80
81   @Test(expected = MalformedPatternException.class)
82   public void testNoOptions2() {
83     test("'a:+");
84   }
85
86   @Test(expected = MalformedPatternException.class)
87   public void testUnclosedCondition() {
88     test("'a:[");
89   }
90
91   @Test(expected = MalformedPatternException.class)
92   public void testClosedCondition() {
93     test("'a:[]");
94   }
95
96   @Test(expected = MalformedPatternException.class)
97   public void testEmptyNegated() {
98     test("'a:[!]");
99   }
100
101   @Test(expected = UnsupportedPatternException.class)
102   public void testCondition() {
103     test("'a:[aap()]");
104   }
105
106   @Test(expected = MalformedPatternException.class)
107   public void testIncompleteCondition() {
108     test("'a:[regex(]");
109   }
110
111   @Test(expected = MalformedPatternException.class)
112   public void testIncompleteCondition2() {
113     test("'a:[regex()]");
114   }
115
116   @Test(expected = MalformedPatternException.class)
117   public void testIncompleteMultipleCondition() {
118     test("'a:[regex( a ) &&]");
119   }
120
121   @Test(expected = MalformedPatternException.class)
122   public void testInvalidRegularExpression() {
123     test("'a:x!(");
124   }
125
126   @Test(expected = MalformedPatternException.class)
127   public void testRepeatingConstraints() {
128     test("'a*:foo 'a+:[regex( bla )]");
129   }
130
131   @Test(expected = MalformedPatternException.class)
132   public void testRepeatingConstraints2() {
133     test("'a:foo 'a*");
134   }
135
136   @Test
137   public void testMethodReference() {
138     test("'_a::'_b");
139     assertEquals("$a$::$b$", myOptions.getSearchPattern());
140   }
141
142   @Test
143   public void testCompleteMatchConditions() {
144     test("[within( \"if('_a) { 'st*; }\" )]1+1");
145     assertEquals("1+1", myOptions.getSearchPattern());
146     final MatchVariableConstraint constraint = myOptions.getVariableConstraint(Configuration.CONTEXT_VAR_NAME);
147     assertEquals("\"if('_a) { 'st*; }\"", constraint.getWithinConstraint());
148   }
149
150   @Test(expected = MalformedPatternException.class)
151   public void testBadWithin() {
152     test("'_type 'a:[within( \"if ('_a) { '_st*; }\" )] = '_b;");
153   }
154
155   @Test
156   public void testNestedPatterns() {
157     test("[within( \"if ('_a:[regex( .*e.* )]) { '_st*; }\" )]'_type 'a = '_b;");
158     assertEquals("$type$ $a$ = $b$;", myOptions.getSearchPattern());
159     final MatchVariableConstraint constraint = myOptions.getVariableConstraint(Configuration.CONTEXT_VAR_NAME);
160     assertEquals("\"if ('_a:[regex( .*e.* )]) { '_st*; }\"", constraint.getWithinConstraint());
161
162     test("[!within( \"<'_tag:[regex( ul|ol )] />\" )]<li />");
163     assertEquals("<li />", myOptions.getSearchPattern());
164     final MatchVariableConstraint constraint2 = myOptions.getVariableConstraint(Configuration.CONTEXT_VAR_NAME);
165     assertEquals("\"<'_tag:[regex( ul|ol )] />\"", constraint2.getWithinConstraint());
166     assertTrue(constraint2.isInvertWithinConstraint());
167
168     test("[within( \"if ('_a:[regex( \".*\" )]) { '_st*; }\" )]'_type 'a = '_b;");
169     assertEquals("$type$ $a$ = $b$;", myOptions.getSearchPattern());
170     final MatchVariableConstraint constraint3 = myOptions.getVariableConstraint(Configuration.CONTEXT_VAR_NAME);
171     assertEquals("\"if ('_a:[regex( \".*\" )]) { '_st*; }\"", constraint3.getWithinConstraint());
172   }
173
174   @Test
175   public void testEscaping() {
176     test("\\[within( \"if ('_a) { '_st*; }\" )]");
177     assertEquals("[within( \"if ($a$) { $st$; }\" )]", myOptions.getSearchPattern());
178     test("\\[");
179     assertEquals("[", myOptions.getSearchPattern());
180     test("\\'aaa");
181     assertEquals("'aaa", myOptions.getSearchPattern());
182     test("'a\\:");
183     assertEquals("$a$:", myOptions.getSearchPattern());
184   }
185
186   @Test
187   public void testQuotes() {
188     test("''");
189     assertEquals("'", myOptions.getSearchPattern());
190     test("'''c");
191     assertEquals("'$c$", myOptions.getSearchPattern());
192     test("'a''b");
193     assertEquals("'a'$b$", myOptions.getSearchPattern());
194     test("'aa'_bb");
195     assertEquals("$aa$$bb$", myOptions.getSearchPattern());
196     test("'\\n''z");
197     assertEquals("'\\n'$z$", myOptions.getSearchPattern());
198     test("'\\u0123''a");
199     assertEquals("'\\u0123'$a$", myOptions.getSearchPattern());
200   }
201
202   @Test
203   public void testComplexRegexes() {
204     test("'_t:[regex( *Object\\[\\] ) ] '_t2");
205     assertEquals("$t$ $t2$", myOptions.getSearchPattern());
206     final MatchVariableConstraint constraint = myOptions.getVariableConstraint("t");
207     assertTrue(constraint.isWithinHierarchy());
208     assertEquals("Object\\[\\]", constraint.getRegExp());
209
210     test("// 'Comment:[regex( .*(?:comment).* )]");
211     assertEquals("// $Comment$", myOptions.getSearchPattern());
212     final MatchVariableConstraint constraint1 = myOptions.getVariableConstraint("Comment");
213     assertEquals(".*(?:comment).*", constraint1.getRegExp());
214   }
215
216   @Test
217   public void testInvert() {
218     test("'a:[!read&&write]");
219     assertEquals("$a$", myOptions.getSearchPattern());
220     final MatchVariableConstraint constraint = myOptions.getVariableConstraint("a");
221     assertTrue(constraint.isReadAccess());
222     assertTrue(constraint.isInvertReadAccess());
223     assertTrue(constraint.isWriteAccess());
224     assertFalse(constraint.isInvertWriteAccess());
225   }
226
227   @Test(expected = MalformedPatternException.class)
228   public void testAmpersandsExpected() {
229     test("'a:[read write]");
230   }
231
232   @Test(expected = MalformedPatternException.class)
233   public void testUnexpectedAmpersands() {
234     test("'a:[&&read]");
235   }
236
237   @Test(expected = MalformedPatternException.class)
238   public void testUnbalancedSpacesSurroundingContent() {
239     test("'a:[regex(  .* ) ]");
240   }
241
242   private void test(String pattern) {
243     myOptions.setSearchPattern(pattern);
244     StringToConstraintsTransformer.transformOldPattern(myOptions);
245   }
246 }