http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/72fcaa1a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/SearchParserTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/SearchParserTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/SearchParserTest.java
new file mode 100644
index 0000000..743439a
--- /dev/null
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/SearchParserTest.java
@@ -0,0 +1,187 @@
+/*
+ * 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.olingo.server.core.uri.parser;
+
+import java.util.Collections;
+
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edmx.EdmxReference;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.core.uri.parser.search.SearchParserException;
+import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
+import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
+import org.junit.Test;
+
+/** Tests of the parts of the URI parser that parse the sytem query option 
$search. */
+public class SearchParserTest {
+
+  private static final Edm edm = OData.newInstance().createServiceMetadata(
+      new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
+
+  private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
+
+  @Test
+  public void search() throws Exception {
+    testUri.run("ESTwoKeyNav", "$search=abc");
+    testUri.run("ESTwoKeyNav", "$search=NOT abc");
+
+    testUri.run("ESTwoKeyNav", "$search=abc AND def");
+    testUri.run("ESTwoKeyNav", "$search=abc  OR def");
+    testUri.run("ESTwoKeyNav", "$search=abc     def");
+
+    testUri.run("ESTwoKeyNav", "$search=abc AND def AND ghi");
+    testUri.run("ESTwoKeyNav", "$search=abc AND def  OR ghi");
+    testUri.run("ESTwoKeyNav", "$search=abc AND def     ghi");
+
+    testUri.run("ESTwoKeyNav", "$search=abc  OR def AND ghi");
+    testUri.run("ESTwoKeyNav", "$search=abc  OR def  OR ghi");
+    testUri.run("ESTwoKeyNav", "$search=abc  OR def     ghi");
+
+    testUri.run("ESTwoKeyNav", "$search=abc     def AND ghi");
+    testUri.run("ESTwoKeyNav", "$search=abc     def  OR ghi");
+    testUri.run("ESTwoKeyNav", "$search=abc     def     ghi");
+
+    // mixed not
+    testUri.run("ESTwoKeyNav", "$search=    abc         def AND     ghi");
+    testUri.run("ESTwoKeyNav", "$search=NOT abc  NOT    def  OR NOT ghi");
+    testUri.run("ESTwoKeyNav", "$search=    abc         def     NOT ghi");
+
+    // parenthesis
+    testUri.run("ESTwoKeyNav", "$search=(abc)");
+    testUri.run("ESTwoKeyNav", "$search=(abc AND  def)");
+    testUri.run("ESTwoKeyNav", "$search=(abc AND  def)   OR  ghi ");
+    testUri.run("ESTwoKeyNav", "$search=(abc AND  def)       ghi ");
+    testUri.run("ESTwoKeyNav", "$search=abc AND (def    OR  ghi)");
+    testUri.run("ESTwoKeyNav", "$search=abc AND (def        ghi)");
+
+    // search in function-import return value
+    testUri.run("FICRTCollESTwoKeyNavParam(ParameterInt16=1)", "$search=test");
+
+    // percent encoded characters
+    testUri.run("ESTwoKeyNav", "$search=%41%42%43");
+    testUri.run("ESTwoKeyNav", "$search=\"100%25\"");
+
+    // escaped characters
+    testUri.run("ESTwoKeyNav", "$search=\"abc\"");
+    testUri.run("ESTwoKeyNav", "$search=\"a\\\"bc\"");
+    testUri.run("ESTwoKeyNav", "$search=%22abc%22");
+    testUri.run("ESTwoKeyNav", "$search=%22a%5C%22bc%22");
+    testUri.run("ESTwoKeyNav", "$search=%22a%5C%5Cbc%22");
+
+    // wrong escaped characters
+    testUri.runEx("ESTwoKeyNav", "$search=%22a%22bc%22")
+        
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
+    testUri.runEx("ESTwoKeyNav", "$search=%22a%5Cbc%22")
+        
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
+    testUri.runEx("ESTwoKeyNav", "$search=not%27allowed")
+        
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
+  }
+
+  @Test
+  public void searchTree() throws Exception {
+    testUri.run("ESTwoKeyNav", "$expand=NavPropertyETKeyNavMany($search=(abc 
AND def) OR NOT ghi)")
+        .goExpand().isSearchSerialized("{{'abc' AND 'def'} OR {NOT 'ghi'}}");
+  }
+
+  /**
+   * See <a href=
+   * 
"https://tools.oasis-open.org/version-control/browse/wsvn/odata/trunk/spec/ABNF/odata-abnf-testcases.xml";>test
+   * cases at OASIS</a>.
+   */
+  @Test
+  public void searchQueryPhraseAbnfTestcases() throws Exception {
+    // <TestCase Name="5.1.7 Search - simple phrase" Rule="queryOptions">
+    testUri.run("ESTwoKeyNav", "$search=\"blue%20green\"");
+    // <TestCase Name="5.1.7 Search - simple phrase" Rule="queryOptions">
+    testUri.run("ESTwoKeyNav", "$search=\"blue%20green%22");
+    // <TestCase Name="5.1.7 Search - phrase with escaped double-quote" 
Rule="queryOptions">
+    // <Input>$search="blue\"green"</Input>
+    testUri.run("ESTwoKeyNav", "$search=\"blue\\\"green\"");
+
+    // <TestCase Name="5.1.7 Search - phrase with escaped backslash" 
Rule="queryOptions">
+    // <Input>$search="blue\\green"</Input>
+    testUri.run("ESTwoKeyNav", "$search=\"blue\\\\green\"");
+    // <TestCase Name="5.1.7 Search - phrase with unescaped double-quote" 
Rule="queryOptions" FailAt="14">
+    testUri.runEx("ESTwoKeyNav", "$search=\"blue\"green\"")
+        
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
+    // <TestCase Name="5.1.7 Search - phrase with unescaped double-quote" 
Rule="queryOptions" FailAt="16">
+    testUri.runEx("ESTwoKeyNav", "$search=\"blue%22green\"")
+        
.isExceptionMessage(SearchParserException.MessageKeys.TOKENIZER_EXCEPTION);
+
+    // <TestCase Name="5.1.7 Search - implicit AND" Rule="queryOptions">
+    // <Input>$search=blue green</Input>
+    // SearchassertQuery("\"blue%20green\"").resultsIn();
+    testUri.run("ESTwoKeyNav", "$search=blue green");
+    // <TestCase Name="5.1.7 Search - implicit AND, encoced" 
Rule="queryOptions">
+    // SearchassertQuery("blue%20green").resultsIn();
+    testUri.run("ESTwoKeyNav", "$search=blue%20green");
+
+    // <TestCase Name="5.1.7 Search - AND" Rule="queryOptions">
+    // <Input>$search=blue AND green</Input>
+    testUri.run("ESTwoKeyNav", "$search=blue AND green");
+
+    // <TestCase Name="5.1.7 Search - OR" Rule="queryOptions">
+    // <Input>$search=blue OR green</Input>
+    testUri.run("ESTwoKeyNav", "$search=blue OR green");
+
+    // <TestCase Name="5.1.7 Search - NOT" Rule="queryOptions">
+    // <Input>$search=blue NOT green</Input>
+    testUri.run("ESTwoKeyNav", "$search=blue NOT green");
+
+    // <TestCase Name="5.1.7 Search - only NOT" Rule="queryOptions">
+    // <Input>$search=NOT blue</Input>
+    testUri.run("ESTwoKeyNav", "$search=NOT blue");
+
+    // <TestCase Name="5.1.7 Search - multiple" Rule="queryOptions">
+    // <Input>$search=foo AND bar OR foo AND baz OR that AND bar OR that AND 
baz</Input>
+    testUri.run("ESTwoKeyNav", "$search=foo AND bar OR foo AND baz OR that AND 
bar OR that AND baz");
+
+    // <TestCase Name="5.1.7 Search - multiple" Rule="queryOptions">
+    // <Input>$search=(foo OR that) AND (bar OR baz)</Input>
+    testUri.run("ESTwoKeyNav", "$search=(foo OR that) AND (bar OR baz)");
+
+    // <TestCase Name="5.1.7 Search - grouping" Rule="queryOptions">
+    // <Input>$search=foo AND (bar OR baz)</Input>
+    testUri.run("ESTwoKeyNav", "$search=foo AND (bar OR baz)");
+
+    // <TestCase Name="5.1.7 Search - grouping" Rule="queryOptions">
+    // <Input>$search=(foo AND bar) OR baz</Input>
+    testUri.run("ESTwoKeyNav", "$search=(foo AND bar) OR baz");
+
+    // <TestCase Name="5.1.7 Search - grouping" Rule="queryOptions">
+    // <Input>$search=(NOT foo) OR baz</Input>
+    testUri.run("ESTwoKeyNav", "$search=(NOT foo) OR baz");
+
+    // <TestCase Name="5.1.7 Search - grouping" Rule="queryOptions">
+    // <Input>$search=(NOT foo)</Input>
+    testUri.run("ESTwoKeyNav", "$search=(NOT foo)");
+
+    // <TestCase Name="5.1.7 Search - on entity set" Rule="odataUri">
+    // <Input>http://serviceRoot/Products?$search=blue</Input>
+    testUri.run("ESTwoKeyNav", "$search=blue");
+
+    // <TestCase Name="5.1.7 Search - on entity container" Rule="odataUri">
+    // <Input>http://serviceRoot/Model.Container/$all?$search=blue</Input>
+    testUri.run("$all", "$search=blue");
+
+    // <TestCase Name="5.1.7 Search - on service" Rule="odataUri">
+    // <Input>http://serviceRoot/$all?$search=blue</Input>
+    testUri.run("$all", "$search=blue");
+  }
+}

http://git-wip-us.apache.org/repos/asf/olingo-odata4/blob/72fcaa1a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/SelectParserTest.java
----------------------------------------------------------------------
diff --git 
a/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/SelectParserTest.java
 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/SelectParserTest.java
new file mode 100644
index 0000000..b906fcc
--- /dev/null
+++ 
b/lib/server-test/src/test/java/org/apache/olingo/server/core/uri/parser/SelectParserTest.java
@@ -0,0 +1,177 @@
+/*
+ * 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.olingo.server.core.uri.parser;
+
+import java.util.Collections;
+
+import org.apache.olingo.commons.api.edm.Edm;
+import org.apache.olingo.commons.api.edm.FullQualifiedName;
+import org.apache.olingo.commons.api.edmx.EdmxReference;
+import org.apache.olingo.server.api.OData;
+import org.apache.olingo.server.api.uri.UriInfoKind;
+import 
org.apache.olingo.server.core.uri.parser.UriParserSemanticException.MessageKeys;
+import org.apache.olingo.server.core.uri.testutil.TestUriValidator;
+import org.apache.olingo.server.tecsvc.provider.ActionProvider;
+import org.apache.olingo.server.tecsvc.provider.ComplexTypeProvider;
+import org.apache.olingo.server.tecsvc.provider.EdmTechProvider;
+import org.apache.olingo.server.tecsvc.provider.EntityTypeProvider;
+import org.apache.olingo.server.tecsvc.provider.EnumTypeProvider;
+import org.apache.olingo.server.tecsvc.provider.FunctionProvider;
+import org.apache.olingo.server.tecsvc.provider.PropertyProvider;
+import org.apache.olingo.server.tecsvc.provider.TypeDefinitionProvider;
+import org.junit.Test;
+
+/** Tests of the parts of the URI parser that parse the sytem query option 
$select. */
+public class SelectParserTest {
+
+  private static final Edm edm = OData.newInstance().createServiceMetadata(
+      new EdmTechProvider(), Collections.<EdmxReference> emptyList()).getEdm();
+
+  private final TestUriValidator testUri = new TestUriValidator().setEdm(edm);
+
+  @Test
+  public void select() throws Exception {
+    testUri.run("ESTwoKeyNav", "$select=*")
+        .isSelectItemStar(0);
+
+    testUri.run("ESTwoKeyNav", "$select=olingo.odata.test1.*")
+        .isSelectItemAllOp(0, new FullQualifiedName("olingo.odata.test1", 
"*"));
+    testUri.run("ESTwoKeyNav", "$select=Namespace1_Alias.*")
+        .isSelectItemAllOp(0, new FullQualifiedName("Namespace1_Alias", "*"));
+
+    testUri.run("ESTwoKeyNav", "$select=PropertyString")
+        .goSelectItemPath(0).isPrimitiveProperty("PropertyString", 
PropertyProvider.nameString, false);
+
+    testUri.run("ESTwoKeyNav", "$select=PropertyComp")
+        .goSelectItemPath(0).isComplexProperty("PropertyComp", 
ComplexTypeProvider.nameCTPrimComp, false);
+
+    testUri.run("ESAllPrim", 
"$select=PropertyTimeOfDay,PropertyDate,NavPropertyETTwoPrimOne")
+        .isKind(UriInfoKind.resource)
+        .goSelectItemPath(0).first().isPrimitiveProperty("PropertyTimeOfDay", 
PropertyProvider.nameTimeOfDay, false)
+        .goUpUriValidator()
+        .goSelectItemPath(1).first().isPrimitiveProperty("PropertyDate", 
PropertyProvider.nameDate, false)
+        .goUpUriValidator()
+        .goSelectItemPath(2).first().isNavProperty("NavPropertyETTwoPrimOne", 
EntityTypeProvider.nameETTwoPrim, false);
+
+    testUri.run("ESMixEnumDefCollComp",
+        
"$select=PropertyEnumString,PropertyDefString,CollPropertyEnumString,CollPropertyDefString")
+        .isKind(UriInfoKind.resource)
+        .goSelectItemPath(0).isPrimitiveProperty("PropertyEnumString", 
EnumTypeProvider.nameENString, false)
+        .goUpUriValidator()
+        .goSelectItemPath(1).isPrimitiveProperty("PropertyDefString", 
TypeDefinitionProvider.nameTDString, false)
+        .goUpUriValidator()
+        .goSelectItemPath(2).isPrimitiveProperty("CollPropertyEnumString", 
EnumTypeProvider.nameENString, true)
+        .goUpUriValidator()
+        .goSelectItemPath(3).isPrimitiveProperty("CollPropertyDefString", 
TypeDefinitionProvider.nameTDString, true);
+
+    testUri.run("ESTwoKeyNav", "$select=PropertyComp/PropertyInt16")
+        .goSelectItemPath(0)
+        .first()
+        .isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, 
false)
+        .n()
+        .isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, 
false);
+
+    testUri.run("ESTwoKeyNav", "$select=PropertyComp/PropertyComp")
+        .goSelectItemPath(0)
+        .first()
+        .isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTPrimComp, 
false)
+        .n()
+        .isComplexProperty("PropertyComp", ComplexTypeProvider.nameCTAllPrim, 
false);
+
+    testUri.run("ESTwoKeyNav", "$select=olingo.odata.test1.ETBaseTwoKeyNav")
+        .isSelectStartType(0, EntityTypeProvider.nameETBaseTwoKeyNav);
+
+    testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='2')",
+        "$select=olingo.odata.test1.ETBaseTwoKeyNav/PropertyInt16")
+        .isKind(UriInfoKind.resource).goPath()
+        .first()
+        .isKeyPredicate(0, "PropertyInt16", "1")
+        .isKeyPredicate(1, "PropertyString", "'2'")
+        .goUpUriValidator()
+        .isSelectStartType(0, EntityTypeProvider.nameETBaseTwoKeyNav)
+        .goSelectItemPath(0)
+        .first()
+        .isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, 
false);
+
+    
testUri.run("ESTwoKeyNav(PropertyInt16=1,PropertyString='1')/PropertyCompNav",
+        "$select=olingo.odata.test1.CTTwoBasePrimCompNav")
+        .isSelectStartType(0, ComplexTypeProvider.nameCTTwoBasePrimCompNav);
+
+    testUri.run("ESTwoKeyNav", 
"$select=PropertyCompNav/olingo.odata.test1.CTTwoBasePrimCompNav")
+        .goSelectItemPath(0)
+        .first()
+        .isComplexProperty("PropertyCompNav", 
ComplexTypeProvider.nameCTBasePrimCompNav, false)
+        .isTypeFilter(ComplexTypeProvider.nameCTTwoBasePrimCompNav);
+
+    testUri.run("ESTwoKeyNav", 
"$select=PropertyCompNav/Namespace1_Alias.CTTwoBasePrimCompNav/PropertyInt16")
+        .goSelectItemPath(0)
+        .first()
+        .isComplexProperty("PropertyCompNav", 
ComplexTypeProvider.nameCTBasePrimCompNav, false)
+        .isTypeFilter(ComplexTypeProvider.nameCTTwoBasePrimCompNav)
+        .n()
+        .isPrimitiveProperty("PropertyInt16", PropertyProvider.nameInt16, 
false);
+
+    testUri.run("ESAllPrim", 
"$select=olingo.odata.test1.BAESAllPrimRTETAllPrim")
+        .goSelectItemPath(0)
+        .first()
+        .isAction(ActionProvider.nameBAESAllPrimRTETAllPrim.getName());
+    testUri.run("ESTwoKeyNav", 
"$select=Namespace1_Alias.BFCESTwoKeyNavRTString")
+        .goSelectItemPath(0)
+        .first()
+        .isFunction(FunctionProvider.nameBFCESTwoKeyNavRTString.getName());
+    testUri.run("ESTwoKeyNav", 
"$select=olingo.odata.test1.BFCESTwoKeyNavRTStringParam(ParameterComp)")
+        .goSelectItemPath(0)
+        .first()
+        
.isFunction(FunctionProvider.nameBFCESTwoKeyNavRTStringParam.getName());
+
+    testUri.runEx("ESMixPrimCollComp", "$select=wrong")
+        .isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
+    testUri.runEx("ESMixPrimCollComp", "$select=PropertyComp/wrong")
+        .isExSemantic(MessageKeys.EXPRESSION_PROPERTY_NOT_IN_TYPE);
+    testUri.runEx("ESMixPrimCollComp", "$select=PropertyComp///PropertyInt16")
+        .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
+    testUri.runEx("ESMixPrimCollComp", "$select=/PropertyInt16")
+        .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
+    testUri.runEx("ESMixPrimCollComp", "$select=PropertyInt16+")
+        
.isExSyntax(UriParserSyntaxException.MessageKeys.WRONG_VALUE_FOR_SYSTEM_QUERY_OPTION);
+    testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.1")
+        .isExSemantic(MessageKeys.UNKNOWN_PART);
+    testUri.runEx("ESTwoKeyNav", 
"$select=unknown_namespace.*").isExSemantic(MessageKeys.UNKNOWN_PART);
+    testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.ETKeyNav")
+        .isExSemantic(MessageKeys.INCOMPATIBLE_TYPE_FILTER);
+    testUri.runEx("ESTwoKeyNav", 
"$select=PropertyCompNav/olingo.odata.test1.CTTwoPrim")
+        .isExSemantic(MessageKeys.INCOMPATIBLE_TYPE_FILTER);
+    testUri.runEx("ESTwoKeyNav", 
"$select=PropertyCompNav/olingo.odata.test1.CTwrong")
+        .isExSemantic(MessageKeys.UNKNOWN_TYPE);
+    testUri.runEx("ESTwoKeyNav", "$select=PropertyCompNav/.")
+        .isExSemantic(MessageKeys.UNKNOWN_PART);
+    testUri.runEx("ESTwoKeyNav", 
"$select=PropertyCompNav/olingo.odata.test1.CTTwoBasePrimCompNav/.")
+        .isExSemantic(MessageKeys.UNKNOWN_PART);
+    testUri.runEx("AIRT", "$select=wrong")
+        .isExSemantic(MessageKeys.ONLY_FOR_TYPED_PARTS);
+    testUri.runEx("AIRT", "$select=olingo.odata.test1.BAESAllPrimRT")
+        .isExSemantic(MessageKeys.ONLY_FOR_TYPED_PARTS);
+    testUri.runEx("ESTwoKeyNav", "$select=olingo.odata.test1.BFwrong")
+        .isExSemantic(MessageKeys.UNKNOWN_PART);
+    testUri.runEx("ESTwoKeyNav", 
"$select=olingo.odata.test1.BFCESTwoKeyNavRTStringParam()")
+        .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
+    testUri.runEx("ESTwoKeyNav", 
"$select=Namespace1_Alias.BFCESTwoKeyNavRTStringParam(ParameterComp,...)")
+        .isExSyntax(UriParserSyntaxException.MessageKeys.SYNTAX);
+  }
+}

Reply via email to