| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package org.apache.cassandra.cql3; |
| |
| import org.junit.Test; |
| |
| import org.antlr.runtime.ANTLRStringStream; |
| import org.antlr.runtime.BaseRecognizer; |
| import org.antlr.runtime.CharStream; |
| import org.antlr.runtime.CommonTokenStream; |
| import org.antlr.runtime.RecognitionException; |
| import org.antlr.runtime.TokenStream; |
| import org.apache.cassandra.cql3.statements.PropertyDefinitions; |
| |
| import static org.junit.Assert.*; |
| |
| public class CqlParserTest |
| { |
| @Test |
| public void testAddErrorListener() throws Exception |
| { |
| SyntaxErrorCounter firstCounter = new SyntaxErrorCounter(); |
| SyntaxErrorCounter secondCounter = new SyntaxErrorCounter(); |
| |
| CharStream stream = new ANTLRStringStream("SELECT * FORM FROM test"); |
| CqlLexer lexer = new CqlLexer(stream); |
| |
| TokenStream tokenStream = new CommonTokenStream(lexer); |
| CqlParser parser = new CqlParser(tokenStream); |
| parser.addErrorListener(firstCounter); |
| parser.addErrorListener(secondCounter); |
| |
| // By default CqlParser should recover from the syntax error by removing FORM |
| // but as recoverFromMismatchedToken and recover have been overloaded, it will not |
| // and the returned ParsedStatement will be null. |
| assertNull(parser.query()); |
| |
| // Only one error must be reported (mismatched: FORM). |
| assertEquals(1, firstCounter.count); |
| assertEquals(1, secondCounter.count); |
| } |
| |
| @Test |
| public void testRemoveErrorListener() throws Exception |
| { |
| SyntaxErrorCounter firstCounter = new SyntaxErrorCounter(); |
| SyntaxErrorCounter secondCounter = new SyntaxErrorCounter(); |
| |
| CharStream stream = new ANTLRStringStream("SELECT * FORM test;"); |
| CqlLexer lexer = new CqlLexer(stream); |
| |
| TokenStream tokenStream = new CommonTokenStream(lexer); |
| CqlParser parser = new CqlParser(tokenStream); |
| parser.addErrorListener(firstCounter); |
| parser.addErrorListener(secondCounter); |
| parser.removeErrorListener(secondCounter); |
| |
| parser.query(); |
| |
| assertEquals(1, firstCounter.count); |
| assertEquals(0, secondCounter.count); |
| } |
| |
| @Test |
| public void testDuplicateProperties() throws Exception |
| { |
| parseAndCountErrors("properties = { 'foo' : 'value1', 'bar': 'value2' };", 0, (p) -> p.properties(new PropertyDefinitions())); |
| parseAndCountErrors("properties = { 'foo' : 'value1', 'foo': 'value2' };", 1, (p) -> p.properties(new PropertyDefinitions())); |
| parseAndCountErrors("foo = 'value1' AND bar = 'value2' };", 0, (p) -> p.properties(new PropertyDefinitions())); |
| parseAndCountErrors("foo = 'value1' AND foo = 'value2' };", 1, (p) -> p.properties(new PropertyDefinitions())); |
| } |
| |
| private void parseAndCountErrors(String cql, int expectedErrors, ParserOperation operation) throws RecognitionException |
| { |
| SyntaxErrorCounter counter = new SyntaxErrorCounter(); |
| CharStream stream = new ANTLRStringStream(cql); |
| CqlLexer lexer = new CqlLexer(stream); |
| TokenStream tokenStream = new CommonTokenStream(lexer); |
| CqlParser parser = new CqlParser(tokenStream); |
| parser.addErrorListener(counter); |
| |
| operation.perform(parser); |
| |
| assertEquals(expectedErrors, counter.count); |
| } |
| |
| @FunctionalInterface |
| private interface ParserOperation |
| { |
| void perform(CqlParser cqlParser) throws RecognitionException; |
| } |
| |
| private static final class SyntaxErrorCounter implements ErrorListener |
| { |
| private int count; |
| |
| @Override |
| public void syntaxError(BaseRecognizer recognizer, String[] tokenNames, RecognitionException e) |
| { |
| count++; |
| } |
| |
| @Override |
| public void syntaxError(BaseRecognizer recognizer, String errorMsg) |
| { |
| count++; |
| } |
| } |
| } |