This project has retired. For details please refer to its Attic page.
ProcessQueryTest xref

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   * http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.chemistry.opencmis.inmemory.query;
20  
21  import static org.junit.Assert.assertEquals;
22  import static org.junit.Assert.assertFalse;
23  import static org.junit.Assert.assertTrue;
24  
25  import java.util.GregorianCalendar;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Map.Entry;
30  
31  import org.antlr.runtime.tree.Tree;
32  import org.apache.chemistry.opencmis.commons.definitions.TypeDefinition;
33  import org.apache.chemistry.opencmis.inmemory.TypeManagerImpl;
34  import org.apache.chemistry.opencmis.server.support.query.CalendarHelper;
35  import org.apache.chemistry.opencmis.server.support.query.CmisQlStrictLexer;
36  import org.apache.chemistry.opencmis.server.support.query.QueryObject;
37  import org.apache.chemistry.opencmis.server.support.query.TextSearchLexer;
38  import org.apache.commons.logging.Log;
39  import org.apache.commons.logging.LogFactory;
40  import org.junit.Before;
41  import org.junit.Test;
42  
43  public class ProcessQueryTest extends AbstractQueryTest {
44  
45      private static final Log LOG = LogFactory.getLog(ProcessQueryTest.class);
46  
47      private static class TestQueryProcessor extends AbstractQueryConditionProcessor {
48  
49          private static final String ON_START = "onStartWasCalled";
50          private static final String ON_STOP = "onStopWasCalled";
51          private static final String ON_EQUALS = "onEqualsWasCalled";
52          private static final String ON_NOT_EQUALS = "onNotEqualsWasCalled";
53          private static final String ON_GREATER_THAN = "onGreaterThanWasCalled";
54          private static final String ON_GREATER_OR_EQUALS ="onGreaterOrEqualsWasCalled";
55          private static final String ON_LESS_THAN = "onLessThanWasCalled";
56          private static final String ON_LESS_OR_EQUALS = "onLessOrEqualsWasCalled";
57          private static final String ON_NOT = "onNotWasCalled";
58          private static final String ON_AND = "onAndWasCalled";
59          private static final String ON_OR = "onOrWasCalled";
60          private static final String ON_IN = "onInWasCalled";
61          private static final String ON_NOT_IN = "onNotInWasCalled";
62          private static final String ON_IN_ANY = "onInAnyWasCalled";
63          private static final String ON_NOT_IN_ANY ="onNotInAnyWasCalled";
64          private static final String ON_EQ_ANY = "onEqAnyWasCalled";
65          private static final String ON_IS_NULL = "onIsNullWasCalled";
66          private static final String ON_IS_NOT_NULL ="onIsNotNullWasCalled";
67          private static final String ON_IS_LIKE = "onIsLikeWasCalled";
68          private static final String ON_IS_NOT_LIKE = "onIsNotLikeWasCalled";
69          private static final String ON_CONTAINS  = "onContainsWasCalled";
70          private static final String ON_IN_FOLDER  = "onInFolderWasCalled";
71          private static final String ON_IN_TREE  = "onInTreeWasCalled";
72          private static final String ON_SCORE = "onScoreWasCalled";
73          private static final String ON_TEXT_AND = "onTextAndWasCalled";
74          private static final String ON_TEXT_OR = "onTextOrWasCalled";
75          private static final String ON_TEXT_MINUS = "onTextMinusWasCalled";
76          private static final String ON_TEXT_PHRASE = "onTextPhraseWasCalled";
77          private static final String ON_TEXT_WORD = "onTextWordWasCalled";
78  
79  
80          final Map<String, Integer> rulesTrackerMap =
81              new HashMap<String, Integer>() {
82                  private static final long serialVersionUID = 1L;
83              {
84                  put(ON_START, 0);
85                  put(ON_STOP, 0);
86                  put(ON_EQUALS, 0);
87                  put(ON_NOT_EQUALS, 0);
88                  put(ON_GREATER_THAN, 0);
89                  put(ON_GREATER_OR_EQUALS, 0);
90                  put(ON_LESS_THAN, 0);
91                  put(ON_LESS_OR_EQUALS, 0);
92                  put(ON_NOT, 0);
93                  put(ON_AND, 0);
94                  put(ON_OR, 0);
95                  put(ON_IN, 0);
96                  put(ON_NOT_IN, 0);
97                  put(ON_IN_ANY, 0);
98                  put(ON_NOT_IN_ANY, 0);
99                  put(ON_EQ_ANY, 0);
100                 put(ON_IS_NULL, 0);
101                 put(ON_IS_NOT_NULL, 0);
102                 put(ON_IS_LIKE, 0);
103                 put(ON_IS_NOT_LIKE, 0);
104                 put(ON_CONTAINS, 0);
105                 put(ON_IN_FOLDER, 0);
106                 put(ON_IN_TREE, 0);
107                 put(ON_SCORE, 0);
108                 put(ON_TEXT_AND, 0);
109                 put(ON_TEXT_OR, 0);
110                 put(ON_TEXT_MINUS, 0);
111                 put(ON_TEXT_PHRASE, 0);
112                 put(ON_TEXT_WORD, 0);
113            }};
114 
115            private int counter;
116 
117        public TestQueryProcessor() {
118            counter = 1;
119        }
120 
121        @Override
122        public void onStartProcessing(Tree node) {
123             LOG.debug("TestQueryProcessor:onStartProcessing()");
124             rulesTrackerMap.put(ON_START, counter++);
125             assertEquals(CmisQlStrictLexer.WHERE, node.getParent().getType());
126        }
127 
128        @Override
129        public void onStopProcessing() {
130            LOG.debug("TestQueryProcessor:onStopProcessing()");
131            rulesTrackerMap.put(ON_STOP, counter++);
132        }
133 
134 
135        @Override
136        public void onEquals(Tree eqNode, Tree leftNode, Tree rightNode) {
137            rulesTrackerMap.put(ON_EQUALS, counter++);
138            assertEquals(CmisQlStrictLexer.EQ, eqNode.getType());
139            assertTrue(CmisQlStrictLexer.COL==leftNode.getType() || CmisQlStrictLexer.SCORE==leftNode.getType());
140            assertTrue(isLiteral(rightNode));
141        }
142 
143        @Override
144        public void onNotEquals(Tree neNode, Tree leftNode, Tree rightNode) {
145            rulesTrackerMap.put(ON_NOT_EQUALS, counter++);
146            assertEquals(CmisQlStrictLexer.NEQ, neNode.getType());
147            assertEquals(CmisQlStrictLexer.COL, leftNode.getType());
148            assertTrue(isLiteral(rightNode));
149            Object value=onLiteral(rightNode, Integer.class);
150            assertEquals(100, value);
151        }
152 
153        @Override
154        public void onLessOrEquals(Tree leqNode, Tree leftNode, Tree rightNode) {
155            rulesTrackerMap.put(ON_LESS_OR_EQUALS, counter++);
156            assertEquals(CmisQlStrictLexer.LTEQ, leqNode.getType());
157            assertEquals(CmisQlStrictLexer.COL, leftNode.getType());
158            assertTrue(isLiteral(rightNode));
159            Object value=onLiteral(rightNode, Integer.class);
160            assertEquals(100, value);
161        }
162 
163        @Override
164        public void onLessThan(Tree ltNode, Tree leftNode, Tree rightNode) {
165            rulesTrackerMap.put(ON_LESS_THAN, counter++);
166            assertEquals(CmisQlStrictLexer.LT, ltNode.getType());
167            assertEquals(CmisQlStrictLexer.COL, leftNode.getType());
168            assertTrue(isLiteral(rightNode));
169            Object value=onLiteral(rightNode, Integer.class);
170            assertEquals(100, value);
171        }
172 
173        @Override
174        public void onGreaterOrEquals(Tree geNode, Tree leftNode, Tree rightNode) {
175            rulesTrackerMap.put(ON_GREATER_OR_EQUALS, counter++);
176            assertEquals(CmisQlStrictLexer.GTEQ, geNode.getType());
177            assertEquals(CmisQlStrictLexer.COL, leftNode.getType());
178            assertTrue(isLiteral(rightNode));
179            Object value=onLiteral(rightNode, Integer.class);
180            assertEquals(100, value);
181        }
182 
183        @Override
184        public void onGreaterThan(Tree gtNode, Tree leftNode, Tree rightNode) {
185            rulesTrackerMap.put(ON_GREATER_THAN, counter++);
186            assertEquals(CmisQlStrictLexer.GT, gtNode.getType());
187            assertEquals(CmisQlStrictLexer.COL, leftNode.getType());
188            assertTrue(isLiteral(rightNode));
189            Object value=onLiteral(rightNode, Integer.class);
190            assertEquals(100, value);
191        }
192 
193        @Override
194        public void onNot(Tree opNode, Tree leftNode) {
195            rulesTrackerMap.put(ON_NOT, counter++);
196            assertEquals(CmisQlStrictLexer.NOT, opNode.getType());
197        }
198 
199        @Override
200        public void onAnd(Tree opNode, Tree leftNode, Tree rightNode) {
201            assertEquals(CmisQlStrictLexer.AND, opNode.getType());
202            rulesTrackerMap.put(ON_AND, counter++);
203        }
204 
205        @Override
206        public void onOr(Tree opNode, Tree leftNode, Tree rightNode) {
207            assertEquals(CmisQlStrictLexer.OR, opNode.getType());
208            rulesTrackerMap.put(ON_OR, counter++);
209        }
210 
211        @Override
212        public void onIn(Tree opNode, Tree colNode, Tree listNode) {
213            assertEquals(CmisQlStrictLexer.IN, opNode.getType());
214            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
215            assertEquals(CmisQlStrictLexer.IN_LIST, listNode.getType());
216            Object value=onLiteral(listNode.getChild(0), String.class);
217            assertEquals("'Joe'", value);
218            value=onLiteral(listNode.getChild(1), String.class);
219            assertEquals("'Jim'", value);
220            rulesTrackerMap.put(ON_IN, counter++);
221        }
222 
223        @Override
224        public void onNotIn(Tree node, Tree colNode, Tree listNode) {
225            assertEquals(CmisQlStrictLexer.NOT_IN, node.getType());
226            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
227            assertEquals(CmisQlStrictLexer.IN_LIST, listNode.getType());
228            Object value=onLiteral(listNode.getChild(0), String.class);
229            assertEquals("'Joe'", value);
230            value=onLiteral(listNode.getChild(1), String.class);
231            assertEquals("'Jim'", value);
232            rulesTrackerMap.put(ON_NOT_IN, counter++);
233        }
234 
235        @Override
236        public void onEqAny(Tree node, Tree literalNode, Tree colNode) {
237            assertEquals(CmisQlStrictLexer.EQ_ANY, node.getType());
238            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
239            assertTrue(isLiteral(literalNode));
240            Object value=onLiteral(literalNode, String.class);
241            assertEquals("'Joe'", value);
242            rulesTrackerMap.put(ON_EQ_ANY, counter++);
243        }
244 
245        @Override
246        public void onInAny(Tree node, Tree colNode, Tree listNode) {
247            assertEquals(CmisQlStrictLexer.IN_ANY, node.getType());
248            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
249            assertEquals(CmisQlStrictLexer.IN_LIST, listNode.getType());
250            Object value=onLiteral(listNode.getChild(0), String.class);
251            assertEquals("'Joe'", value);
252            value=onLiteral(listNode.getChild(1), String.class);
253            assertEquals("'Jim'", value);
254            rulesTrackerMap.put(ON_IN_ANY, counter++);
255        }
256 
257        @Override
258        public void onNotInAny(Tree node, Tree colNode, Tree listNode) {
259            assertEquals(CmisQlStrictLexer.NOT_IN_ANY, node.getType());
260            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
261            assertEquals(CmisQlStrictLexer.IN_LIST, listNode.getType());
262            Object value=onLiteral(listNode.getChild(0), String.class);
263            assertEquals("'Joe'", value);
264            value=onLiteral(listNode.getChild(1), String.class);
265            assertEquals("'Jim'", value);
266            rulesTrackerMap.put(ON_NOT_IN_ANY, counter++);
267        }
268 
269        @Override
270        public void onIsNull(Tree nullNode, Tree colNode) {
271            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
272            assertEquals(CmisQlStrictLexer.IS_NULL, nullNode.getType());
273            rulesTrackerMap.put(ON_IS_NULL, counter++);
274        }
275 
276        @Override
277        public void onIsNotNull(Tree notNullNode, Tree colNode) {
278            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
279            assertEquals(CmisQlStrictLexer.IS_NOT_NULL, notNullNode.getType());
280            rulesTrackerMap.put(ON_IS_NOT_NULL, counter++);
281        }
282 
283        @Override
284        public void onIsLike(Tree node, Tree colNode, Tree stringNode) {
285            assertEquals(CmisQlStrictLexer.LIKE, node.getType());
286            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
287            assertEquals(CmisQlStrictLexer.STRING_LIT, stringNode.getType());
288            Object value=onLiteral(stringNode, String.class);
289            assertEquals("'Harry%'", value);
290            rulesTrackerMap.put(ON_IS_LIKE, counter++);
291        }
292 
293        @Override
294        public void onIsNotLike(Tree node, Tree colNode, Tree stringNode) {
295            assertEquals(CmisQlStrictLexer.NOT_LIKE, node.getType());
296            assertEquals(CmisQlStrictLexer.COL, colNode.getType());
297            assertEquals(CmisQlStrictLexer.STRING_LIT, stringNode.getType());
298            Object value=onLiteral(stringNode, String.class);
299            assertEquals("'Harry%'", value);
300            rulesTrackerMap.put(ON_IS_NOT_LIKE, counter++);
301        }
302 
303        @Override
304        public void onContains(Tree node, Tree typeNode, Tree searchExprNode) {
305            assertEquals(CmisQlStrictLexer.CONTAINS, node.getType());
306            assertTrue( null != searchExprNode);
307            rulesTrackerMap.put(ON_CONTAINS, counter++);
308            super.onContains(node, typeNode, searchExprNode);
309        }
310 
311        @Override
312        public void onInFolder(Tree node, Tree colNode, Tree paramNode) {
313            assertEquals(CmisQlStrictLexer.IN_FOLDER, node.getType());
314            assertTrue(colNode==null || CmisQlStrictLexer.STRING_LIT == paramNode.getType());
315            assertEquals(CmisQlStrictLexer.STRING_LIT, paramNode.getType());
316            rulesTrackerMap.put(ON_IN_FOLDER, counter++);
317        }
318 
319        @Override
320        public void onInTree(Tree node, Tree colNode, Tree paramNode) {
321            assertEquals(CmisQlStrictLexer.IN_TREE, node.getType());
322            assertTrue(colNode==null || CmisQlStrictLexer.STRING_LIT == paramNode.getType());
323            assertEquals(CmisQlStrictLexer.STRING_LIT, paramNode.getType());
324            rulesTrackerMap.put(ON_IN_TREE, counter++);
325        }
326 
327        @Override
328        public void onScore(Tree node) {
329            assertEquals(CmisQlStrictLexer.SCORE, node.getType());
330            rulesTrackerMap.put(ON_SCORE, counter++);
331        }
332 
333        @Override
334        public void onTextAnd(Tree node, List<Tree> conjunctionNodes) {
335            assertEquals(TextSearchLexer.TEXT_AND, node.getType());
336            assertTrue(conjunctionNodes.size() >= 2);
337            rulesTrackerMap.put(ON_TEXT_AND, counter++);
338        }
339 
340        @Override
341        public void onTextOr(Tree node, List<Tree> termNodes) {
342            assertEquals(TextSearchLexer.TEXT_OR, node.getType());
343            assertTrue(termNodes.size() >= 2);
344            rulesTrackerMap.put(ON_TEXT_OR, counter++);
345        }
346 
347        @Override
348        public void onTextMinus(Tree node, Tree notNode) {
349            assertEquals(TextSearchLexer.TEXT_MINUS, node.getType());
350            assertTrue(notNode.getType() == TextSearchLexer.TEXT_SEARCH_PHRASE_STRING_LIT ||
351                    notNode.getType() == TextSearchLexer.TEXT_SEARCH_WORD_LIT);
352            rulesTrackerMap.put(ON_TEXT_MINUS, counter++);
353        }
354 
355        @Override
356        public void onTextWord(String word) {
357            assertTrue(word != null && word.length() > 0);
358            rulesTrackerMap.put(ON_TEXT_WORD, counter++);
359        }
360 
361        @Override
362        public void onTextPhrase(String phrase) {
363            assertTrue(phrase != null && phrase.length() > 0);
364            rulesTrackerMap.put(ON_TEXT_PHRASE, counter++);
365        }
366 
367 
368        // private helper functions:
369 
370        private static boolean isLiteral(Tree node) {
371            int type = node.getType();
372            return type==CmisQlStrictLexer.BOOL_LIT || type==CmisQlStrictLexer.NUM_LIT ||
373            type==CmisQlStrictLexer.STRING_LIT || type==CmisQlStrictLexer.TIME_LIT;
374        }
375 
376        private static Object onLiteral(Tree node, Class<?> clazz) {
377            int type = node.getType();
378            switch (type) {
379            case CmisQlStrictLexer.BOOL_LIT:
380                return clazz==Boolean.class ? Boolean.parseBoolean(node.getText()) : null;
381            case CmisQlStrictLexer.NUM_LIT:
382                if (clazz == Integer.class) {
383                 return Integer.parseInt(node.getText());
384             } else if (clazz == Long.class) {
385                 return Long.parseLong(node.getText());
386             } else if (clazz == Short.class) {
387                 return Short.parseShort(node.getText());
388             } else if (clazz == Double.class) {
389                 return Double.parseDouble(node.getText());
390             } else if (clazz == Float.class) {
391                 return Float.parseFloat(node.getText());
392             } else {
393                 return null;
394             }
395            case CmisQlStrictLexer.STRING_LIT:
396                return clazz==String.class ? node.getText() : null;
397            case CmisQlStrictLexer.TIME_LIT:
398                return clazz==GregorianCalendar.class ?  CalendarHelper.fromString(node.getText()) : null;
399            default:
400                LOG.error("Unknown literal. " + node);
401                return null;
402            }
403        }
404 
405     }
406 
407     private TypeManagerImpl tm;
408     private TestQueryProcessor queryProcessor;
409 
410     @Before
411     public void setUp() {
412         tm = new TypeManagerImpl();
413         tm.initTypeSystem(null); // create CMIS default types
414 
415         // create some types for testing
416         List<TypeDefinition> typeDefs = super.createTypes();
417         for (TypeDefinition typeDef : typeDefs) {
418             tm.addTypeDefinition(typeDef);
419         }
420 
421         // initialize query object with type manager
422         queryProcessor = new TestQueryProcessor();
423         QueryObject qo = new QueryObject(tm);
424         super.setUp(qo, queryProcessor);
425     }
426 
427     @Test
428     public void testStartStopProcessing() {
429         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN = 100";
430         traverseStatementAndCatchExc(statement); // calls query processor
431         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_START) > 0);
432         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_STOP) > 0);
433     }
434 
435     @Test
436     public void testEq() {
437         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN = 100";
438         testStatement(statement, TestQueryProcessor.ON_EQUALS);
439     }
440 
441     @Test
442     public void testNeq() {
443         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN <> 100";
444         testStatement(statement, TestQueryProcessor.ON_NOT_EQUALS);
445     }
446 
447     @Test
448     public void testLt() {
449         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN < 100";
450         testStatement(statement, TestQueryProcessor.ON_LESS_THAN);
451     }
452 
453     @Test
454     public void testLteq() {
455         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN <= 100";
456         testStatement(statement, TestQueryProcessor.ON_LESS_OR_EQUALS);
457     }
458 
459     @Test
460     public void testGt() {
461         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN > 100";
462         testStatement(statement, TestQueryProcessor.ON_GREATER_THAN);
463     }
464 
465     @Test
466     public void testGteq() {
467         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN >= 100";
468         testStatement(statement, TestQueryProcessor.ON_GREATER_OR_EQUALS);
469     }
470 
471     @Test
472     public void testNot() {
473         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE NOT ISBN = 100";
474         testStatementMultiRule(statement, TestQueryProcessor.ON_NOT);
475     }
476 
477     @Test
478     public void testAnd() {
479         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN = 100 AND Title LIKE 'Harry%'";
480         testStatementMultiRule(statement, TestQueryProcessor.ON_AND);
481         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_START) == 1);
482         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_EQUALS) == 2);
483         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_AND) == 3);
484         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_IS_LIKE) == 4);
485         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_STOP) == 5);
486     }
487 
488     @Test
489     public void testOr() {
490         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ISBN = 100 OR Title LIKE 'Harry%'";
491         testStatementMultiRule(statement,TestQueryProcessor.ON_OR);
492         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_START) == 1);
493         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_EQUALS) == 2);
494         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_OR) == 3);
495         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_IS_LIKE) == 4);
496         assertTrue(queryProcessor.rulesTrackerMap.get(TestQueryProcessor.ON_STOP) == 5);
497     }
498 
499     @Test
500     public void testIn() {
501         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author IN ('Joe', 'Jim')";
502         testStatement(statement, TestQueryProcessor.ON_IN);
503     }
504 
505     @Test
506     public void testNotIn() {
507         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author NOT IN ('Joe', 'Jim')";
508         testStatement(statement, TestQueryProcessor.ON_NOT_IN);
509     }
510 
511     @Test
512     public void testEqAny() {
513         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE 'Joe' = ANY Author";
514         testStatement(statement, TestQueryProcessor.ON_EQ_ANY);
515     }
516 
517     @Test
518     public void testInAny() {
519         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ANY Author IN ('Joe', 'Jim')";
520         testStatement(statement, TestQueryProcessor.ON_IN_ANY);
521     }
522 
523     @Test
524     public void testNotInAny() {
525         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE ANY Author NOT IN ('Joe', 'Jim')";
526         testStatement(statement, TestQueryProcessor.ON_NOT_IN_ANY);
527     }
528 
529     @Test
530     public void testOnIsNullWasCalled() {
531         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author IS NULL";
532         testStatement(statement, TestQueryProcessor.ON_IS_NULL);
533     }
534 
535     @Test
536     public void testOnIsNotNullWasCalled() {
537         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author IS NOT NULL";
538         testStatement(statement, TestQueryProcessor.ON_IS_NOT_NULL);
539     }
540 
541     @Test
542     public void testOnLikeWasCalled() {
543         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author LIKE 'Harry%'";
544         testStatement(statement, TestQueryProcessor.ON_IS_LIKE);
545     }
546 
547     @Test
548     public void testOnNotLikeWasCalled() {
549         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE Author NOT LIKE 'Harry%'";
550         testStatement(statement, TestQueryProcessor.ON_IS_NOT_LIKE);
551     }
552 
553     @Test
554     public void testOnContainsWasCalled1() {
555         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE CONTAINS('Hello')";
556         testStatementMultiRule(statement, TestQueryProcessor.ON_CONTAINS);
557     }
558 
559     @Test
560     public void testOnContainsWasCalled2() {
561         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE CONTAINS(BookType, 'Harry')";
562         testStatementMultiRule(statement, TestQueryProcessor.ON_CONTAINS);
563     }
564 
565     @Test
566     public void testOnInFolderWasCalled1() {
567         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE IN_FOLDER('ID1234')";
568         testStatement(statement, TestQueryProcessor.ON_IN_FOLDER);
569     }
570 
571     @Test
572     public void testOnInFolderWasCalled2() {
573         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE IN_FOLDER(BookType, 'ID1234')";
574         testStatement(statement, TestQueryProcessor.ON_IN_FOLDER);
575     }
576 
577     @Test
578     public void testOnInTreeWasCalled1() {
579         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE IN_Tree('ID1234')";
580         testStatement(statement, TestQueryProcessor.ON_IN_TREE);
581     }
582 
583     @Test
584     public void testOnInTreeWasCalled2() {
585         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE IN_Tree(BookType, 'ID1234')";
586         testStatement(statement, TestQueryProcessor.ON_IN_TREE);
587     }
588 
589     @Test
590     public void testOnScoreCalled() {
591         String statement = "SELECT BookType.Title, BookType.Author FROM BookType WHERE SCORE()=100";
592         testStatementMultiRule(statement, TestQueryProcessor.ON_SCORE);
593     }
594 
595     @Test
596     public void testOnTextWordLiteral() {
597         String statement = "SELECT * FROM BookType WHERE CONTAINS('abc')";
598         testStatementMultiRule(statement, TestQueryProcessor.ON_TEXT_WORD);
599     }
600 
601     @Test
602     public void testOnTextPhraseLiteral() {
603         String statement = "SELECT * FROM BookType WHERE CONTAINS('\\'abc\\'')";
604         testStatementMultiRule(statement, TestQueryProcessor.ON_TEXT_PHRASE);
605     }
606 
607     @Test
608     public void testOnTextAnd() {
609         String statement = "SELECT * FROM BookType WHERE CONTAINS('abc def')";
610         testStatementMultiRule(statement, TestQueryProcessor.ON_TEXT_AND);
611     }
612 
613     @Test
614     public void testOnTextOr() {
615         String statement = "SELECT * FROM BookType WHERE CONTAINS('abc OR def')";
616         testStatementMultiRule(statement, TestQueryProcessor.ON_TEXT_OR);
617     }
618 
619     @Test
620     public void testOnTextMinus() {
621         String statement = "SELECT * FROM BookType WHERE CONTAINS('abc -def')";
622         testStatementMultiRule(statement, TestQueryProcessor.ON_TEXT_MINUS);
623     }
624 
625     // private helper functions
626 
627     private void testStatementMultiRule(String statement, String ruleAssertion) {
628         traverseStatementAndCatchExc(statement); // calls query processor
629         assertTrue(queryProcessor.rulesTrackerMap.get(ruleAssertion) > 0);
630     }
631 
632     private void testStatement(String statement, String ruleAssertion) {
633         testStatementMultiRule(statement, ruleAssertion);
634         checkOtherRulesNotCalled(ruleAssertion);
635     }
636 
637     private void checkOtherRulesNotCalled(String ruleAssertion) {
638         for (Entry<String, Integer> e : queryProcessor.rulesTrackerMap.entrySet()) {
639             if (!e.getKey().equals(ruleAssertion) && !e.getKey().equals("onPropertyValueWasCalled")
640                     && !e.getKey().equals(TestQueryProcessor.ON_START) && !e.getKey().equals(TestQueryProcessor.ON_STOP)
641                     && !e.getKey().contains("Literal")) {
642                 assertFalse("Rule " + e.getKey() + " was expected not to be executed, but was executed.",
643                         queryProcessor.rulesTrackerMap.get(e.getKey()) > 0);
644             }
645         }
646     }
647 
648 }