/*******************************************************************************
* Copyright 2013 SAP AG
*
* Licensed 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 com.sap.core.odata.core.uri.expression;
import static org.junit.Assert.fail;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.junit.Test;
public class TestTokenizer {
@Test
public void tokenizeWhiteSpaces() throws Exception {
//space
getTTW(" ").at(0).aKind(TokenKind.WHITESPACE).aUriLiteral(" ").aPosition(0);
getTTW(" ").at(0).aKind(TokenKind.WHITESPACE).aUriLiteral(" ").aPosition(0);
getTTW("A ").at(1).aKind(TokenKind.WHITESPACE).aUriLiteral(" ").aPosition(1);
getTTW(" B").at(0).aKind(TokenKind.WHITESPACE).aUriLiteral(" ").aPosition(0);
getTTW("A B").at(1).aKind(TokenKind.WHITESPACE).aUriLiteral(" ").aPosition(1).at(2).aKind(TokenKind.LITERAL).aUriLiteral("B").aPosition(4);
getTTW("A B C").at(3).aKind(TokenKind.WHITESPACE).aUriLiteral(" ").aPosition(5);
}
@Test
public void tokenizeSymbols() throws Exception {
//parentheses
getTT("(").aKind(TokenKind.OPENPAREN).aUriLiteral("(");
getTT("abc(").at(1).aKind(TokenKind.OPENPAREN).aUriLiteral("(").aPosition(3);
getTT(")").aKind(TokenKind.CLOSEPAREN).aUriLiteral(")");
getTT("abc)").at(1).aKind(TokenKind.CLOSEPAREN).aUriLiteral(")").aPosition(3);
//symbol
getTT(",").aKind(TokenKind.COMMA).aUriLiteral(",");
getTT("abc,").at(1).aKind(TokenKind.COMMA).aUriLiteral(",").aPosition(3);
//minus
getTT("-").aKind(TokenKind.SYMBOL).aUriLiteral("-");
getTT("abc -").at(1).aKind(TokenKind.SYMBOL).aUriLiteral("-").aPosition(4);
//minus after literal belongs to literal
getTT("abc-").at(0).aKind(TokenKind.LITERAL).aUriLiteral("abc-").aPosition(0);
}
public static String HexToBase64(final String hex) {
String base64 = "";
byte bArr[];
try {
bArr = Hex.decodeHex(hex.toCharArray());
base64 = Base64.encodeBase64String(bArr);
} catch (DecoderException e) {
fail("Error in Unittest preparation ( HEX->base64");
}
return base64;
}
@Test
public void tokenizeTypes() throws Exception {
getTT("a").aKind(TokenKind.LITERAL).aUriLiteral("a").aPosition(0);
getTT("abc a").at(1).aKind(TokenKind.LITERAL).aUriLiteral("a").aPosition(4);
//string
getTT("'a'").aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("'a'").aPosition(0);
getTT("abc 'a'").at(1).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("'a'").aPosition(4);
//"prefixed type
getTT("X'00'").aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("X'00'").aPosition(0);
getTT("abc X'00'").at(1).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("X'00'").aPosition(4);
//simple types
getTT("null").aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("null").aPosition(0);
getTT("abc null").at(1).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("null").aPosition(4);
getTT("128").aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("128").aPosition(0);
getTT("abc 128").at(1).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("128").aPosition(4);
//do special types
getTT("datetime'2011-01-12T00:00:00'").aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("datetime'2011-01-12T00:00:00'").aPosition(0);
getTT("abc datetime'2011-01-12T00:00:00'").at(1).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("datetime'2011-01-12T00:00:00'").aPosition(4);
}
@Test
public void tokenizeOperators() throws Exception {
getTT("a eq b").at(1).aKind(TokenKind.LITERAL).aUriLiteral("eq");
getTT("a eqotto b").at(1).aKind(TokenKind.LITERAL).aUriLiteral("eqotto");
}
@Test
public void testExceptions() throws Exception {
//http://services.odata.org/Northwind/Northwind.svc/Products(1)/Supplier?$filter='a
//-->Unterminated string literal at position 2 in ''a'.
getTT("'a").aExMsgText("Unterminated string literal at position 1 in \"'a\".");
//http://services.odata.org/Northwind/Northwind.svc/Products(1)/Supplier?$filter=X'g'
//-->Unrecognized 'Edm.Binary' literal 'X'g'' in '0'.
getTT("X'g'").aExMsgText("Type detection error for string like token 'X'g'' at position '1'.");
//http://services.odata.org/Northwind/Northwind.svc/Products(1)/Supplier?$filter=\
//-->Syntax error '\' at position 0.
getTT("\\").aExMsgText("Unknown character '\\' at position '0' detected in \"\\\".");
}
@Test
public void tokenizeFunction() throws Exception {
getTT("substringof('10')").at(0).aKind(TokenKind.LITERAL).aUriLiteral("substringof").at(2).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("'10'");
getTT("substringof ( '10' ) ").at(0).aKind(TokenKind.LITERAL).aUriLiteral("substringof").at(2).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("'10'");
}
@Test
public void testEx1111ceptions() throws Exception {
getTT("a 1").at(0).aKind(TokenKind.LITERAL).aUriLiteral("a").at(1).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("1");
getTT("a eq b").at(0).aKind(TokenKind.LITERAL).aUriLiteral("a").at(1).aKind(TokenKind.LITERAL).aUriLiteral("eq").at(2).aKind(TokenKind.LITERAL).aUriLiteral("b");
getTT("start_date eq datetime'2011-01-12T00:00:00' and end_date eq datetime'2011-12-31T00:00:00'").at(2).aUriLiteral("datetime'2011-01-12T00:00:00'");
getTT("'a%b'").at(0).aKind(TokenKind.SIMPLE_TYPE).aUriLiteral("'a%b'");
}
/**
* Create TokenTool ( and Token list) without respecting whitespaces
* @param expression Expression to be tokenized
*/
public TokenTool getTT(final String expression) {
return new TokenTool(expression, false);
}
/**
* Create TokenTool ( and Token list) without respecting whitespaces
* @param expression Expression to be tokenized
*/
public TokenTool getTTW(final String expression) {
return new TokenTool(expression, true);
}
}