/*
* This file is part of JCF.
* JCF is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JCF is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
* You should have received a copy of the GNU General Public License
* along with JCF. If not, see <http://www.gnu.org/licenses/>.
*/
package eu.bitfish.jcf.parser.antlr4;
import org.antlr.v4.runtime.ANTLRInputStream;
import org.antlr.v4.runtime.CharStream;
import org.antlr.v4.runtime.CommonTokenStream;
import org.antlr.v4.runtime.RecognitionException;
import org.junit.Test;
import eu.bitfish.jcf.parser.antlr4.error.ExceptionErrorStrategy;
import eu.bitfish.jcf.parser.antlr4.generated.jcfLexer;
import eu.bitfish.jcf.parser.antlr4.generated.jcfParser;
/**
* Grammar test cases.
*
* @author Michael Sieber
*
*/
public class GrammarTest {
/**
* Simple test with or clause.
*/
@Test
public void testQuery() {
parse("name = 'michael' || name = 'foo'");
}
/**
* Compare member with simple value.
*/
@Test
public void testQuery1() {
parse("name = 'foo'");
}
/**
* Compare member with an other member.
*/
@Test
public void testQuery2() {
parse("name = firstname");
}
/**
* Compare member with a date.
*/
@Test
public void testQuery3() {
parse("birthday = '30.10.1988'");
}
/**
* Compare member with special characters.
*/
@Test
public void testQuery4() {
parse("name = '/*-+\"�$%&/?���*.,;:_-#|^'");
}
/**
* Compare member with simple value with whitespaces, tabs and new lines.
*/
@Test
public void testQuery5() {
parse("name = 'foo' \n && \r \t firstname = 'test'");
}
/**
* Simple test for and clause.
*/
@Test
public void testQuery6() {
parse("name = 'foo' && lastname = 'bar'");
}
/**
* Simple test for and clause.
*/
@Test
public void testQuery7() {
parse("name = 'foo' and lastname = 'bar'");
}
/**
* Simple test for or clause.
*/
@Test
public void testQuery8() {
parse("name = 'foo' or lastname = 'bar'");
}
/**
* And clause with brackets.
*/
@Test
public void testQuery9() {
parse("(name = 'foo' && lastname = 'bar')");
}
/**
* Nested and clause.
*/
@Test
public void testQuery10() {
parse("(name = 'foo' && lastname = 'bar') and birthday = '10/30/1988'");
}
/**
* Nested or clause.
*/
@Test
public void testQuery11() {
parse("(name = 'foo' or lastname = 'bar') || birthday = '10/30/1988'");
}
/**
* Nested mixed and or clause.
*/
@Test
public void testQuery12() {
parse("(name = 'foo' and lastname = 'bar') || birthday = '10/30/1988'");
}
/**
* Deep nested mixed clause.
*/
@Test
public void testQuery13() {
parse("(name = 'foo' or lastname = 'bar' and (street = 'bla' && country = 'blu')) || birthday = '10/30/1988' and (test = 'asdf' || bla = 'test')");
}
/**
* Deep nested mixed clause with missed bracket
*/
@Test(expected = RecognitionException.class)
public void testQuery14() {
parse("(name = 'foo' or lastname = 'bar' and (street = 'bla' && country = 'blu')) || birthday = '10/30/1988' and (test = 'asdf' || bla = 'test'");
}
/**
* Not like and like operator test.
*/
@Test
public void testQuery15() {
parse("name like 'michael' || name not like 'foo'");
}
/**
* Greater than and smaller than test.
*/
@Test
public void testQuery16() {
parse("age > '7' || age < '18'");
}
/**
* Not test.
*/
@Test
public void testQuery17() {
parse("name != 'michael' && lastname = 'foo'");
}
/**
* Simple test with no spaces.
*/
@Test
public void testQuery18() {
parse("name='michael'||name='foo'");
}
/**
* Deep nested mixed clause with member to member comparison
*/
@Test
public void testQuery19() {
parse("(name = lastname and lastname = 'bar' or (street = 'bla' && country = 'blu')) || birthday = today and (test = 'asdf' || bla = 'test')");
}
/**
* Simple test with limit.
*/
@Test
public void testQuery20() {
parse("name = 'michael' || name = 'foo' limit 3");
}
/**
* Deep nested mixed clause with limit
*/
@Test
public void testQuery21() {
parse("(name = lastname or lastname = 'bar' and (street = 'bla' && country = 'blu')) || birthday = today and (test = 'asdf' || bla = 'test') limit 10");
}
/**
* Simple test with order by.
*/
@Test
public void testQuery22() {
parse("name = 'michael' || name = 'foo' order by name asc");
}
/**
* Deep nested mixed clause order by
*/
@Test
public void testQuery23() {
parse("(name = lastname and lastname = 'bar' or (street = 'bla' && country = 'blu')) || birthday = today and (test = 'asdf' || bla = 'test') order by lastname desc");
}
/**
* Simple test with order by and limit.
*/
@Test
public void testQuery24() {
parse("name = 'michael' || name = 'foo' order by name asc limit 5");
}
/**
* Deep nested mixed clause with order by and limit
*/
@Test
public void testQuery25() {
parse("(name = lastname and lastname = 'bar' or (street = 'bla' && country = 'blu')) || birthday = today and (test = 'asdf' || bla = 'test') order by lastname asc limit 10");
}
/**
* Simple test with limit and order by -> error because of order
*/
@Test(expected = RecognitionException.class)
public void testQuery26() {
parse("name = 'michael' || name = 'foo' limit 5 order by name desc");
}
/**
* Deep nested mixed clause with limit and order by -> error because of
* order
*/
@Test(expected = RecognitionException.class)
public void testQuery27() {
parse("(name = lastname and lastname = 'bar' or (street = 'bla' && country = 'blu')) || birthday = today and (test = 'asdf' || bla = 'test') limit 10 order by lastname desc");
}
/**
* Simple test with regular expression
*/
@Test
public void testQuery28() {
parse("regexp('\\w', 'test')");
}
/**
* Extended test with regular expression
*/
@Test
public void testQuery29() {
parse("regexp('\\w', 'test') || regexp('^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,4}$', name)");
}
/**
* Simple test with not expressions
*/
@Test
public void testQuery30() {
parse("!(name = 'michael' || name = 'foo')");
}
/**
* Deep nested mixed clause with not expressions
*/
@Test
public void testQuery31() {
parse("(name = lastname and lastname = 'bar' or (street = 'bla' && country = 'blu')) || birthday = today and !(test = 'asdf' || bla = 'test')");
}
/**
* Test greater than or equal
*/
@Test
public void testQuery32() {
parse("age >= '10'");
}
/**
* Test less than or equal
*/
@Test
public void testQuery33() {
parse("age <= '60'");
}
/**
* Deep nested mixed clause
*/
@Test
public void testQuery34() {
parse("(name = 'Michael' and lastname = 'Sieber' or !(street = 'foo' && country = 'bar')) || birthday = '10/30/1988' and (test = 'asdf' || bla = 'test')");
}
/**
* Simple test with multiple order by members.
*/
@Test
public void testQuery35() {
parse("name = 'michael' || name = 'foo' order by name, lastname, street asc");
}
/**
* Simple test with whitespaces in value.
*/
@Test
public void testQuery36() {
parse("name = 'michael' && description like 'is a programmer'");
}
/**
* Standard procedure for parsing an input string.
*
* @param input
* The input string to parse.
*/
private void parse(String input) {
CharStream charStream = new ANTLRInputStream(input);
jcfLexer lexer = new jcfLexer(charStream);
CommonTokenStream tokens = new CommonTokenStream(lexer);
jcfParser parser = new jcfParser(tokens);
parser.setErrorHandler(new ExceptionErrorStrategy());
parser.query();
}
}