Return-Path: Delivered-To: apmail-jackrabbit-commits-archive@www.apache.org Received: (qmail 97848 invoked from network); 30 Jul 2008 14:06:57 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (140.211.11.2) by minotaur.apache.org with SMTP; 30 Jul 2008 14:06:57 -0000 Received: (qmail 40398 invoked by uid 500); 30 Jul 2008 14:06:56 -0000 Delivered-To: apmail-jackrabbit-commits-archive@jackrabbit.apache.org Received: (qmail 40373 invoked by uid 500); 30 Jul 2008 14:06:56 -0000 Mailing-List: contact commits-help@jackrabbit.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@jackrabbit.apache.org Delivered-To: mailing list commits@jackrabbit.apache.org Received: (qmail 40364 invoked by uid 99); 30 Jul 2008 14:06:56 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 30 Jul 2008 07:06:56 -0700 X-ASF-Spam-Status: No, hits=-2000.0 required=10.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Wed, 30 Jul 2008 14:06:09 +0000 Received: by eris.apache.org (Postfix, from userid 65534) id 2547523889B7; Wed, 30 Jul 2008 07:06:06 -0700 (PDT) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r681054 - in /jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core: integration/GQLTest.java query/AbstractQueryTest.java Date: Wed, 30 Jul 2008 14:06:03 -0000 To: commits@jackrabbit.apache.org From: mreutegg@apache.org X-Mailer: svnmailer-1.0.8 Message-Id: <20080730140606.2547523889B7@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: mreutegg Date: Wed Jul 30 07:06:00 2008 New Revision: 681054 URL: http://svn.apache.org/viewvc?rev=681054&view=rev Log: JCR-1697: Simple Google style query - integration test for GQL Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/GQLTest.java (with props) Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java Added: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/GQLTest.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/GQLTest.java?rev=681054&view=auto ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/GQLTest.java (added) +++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/GQLTest.java Wed Jul 30 07:06:00 2008 @@ -0,0 +1,278 @@ +/* + * 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.jackrabbit.core.integration; + +import org.apache.jackrabbit.core.query.AbstractQueryTest; +import org.apache.jackrabbit.commons.query.GQL; + +import javax.jcr.Node; +import javax.jcr.RepositoryException; +import javax.jcr.query.RowIterator; +import java.util.Calendar; +import java.io.ByteArrayInputStream; +import java.io.UnsupportedEncodingException; + +/** + * GQLTest performs tests on {@link GQL}. + */ +public class GQLTest extends AbstractQueryTest { + + private static final String SAMPLE_CONTENT = "the quick brown fox jumps over the lazy dog."; + + public void testPath() throws RepositoryException { + Node n1 = testRootNode.addNode("node1"); + Node n2 = testRootNode.addNode("node2"); + Node n3 = testRootNode.addNode("node3"); + superuser.save(); + RowIterator rows = GQL.execute(createStatement(""), superuser); + checkResult(rows, new Node[]{n1, n2, n3}); + } + + public void testOrder() throws RepositoryException { + Node n1 = testRootNode.addNode("node1"); + n1.setProperty("p", 1); + Node n2 = testRootNode.addNode("node2"); + n2.setProperty("p", 2); + Node n3 = testRootNode.addNode("node3"); + n3.setProperty("p", 3); + superuser.save(); + // default: ascending + String stmt = createStatement("order:p"); + RowIterator rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n1, n2, n3}); + // explicit ascending + stmt = createStatement("order:+p"); + rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n1, n2, n3}); + // explicit descending + stmt = createStatement("order:-p"); + rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n3, n2, n1}); + } + + public void testLimit() throws RepositoryException { + Node n1 = testRootNode.addNode("node1"); + n1.setProperty("p", 1); + Node n2 = testRootNode.addNode("node2"); + n2.setProperty("p", 2); + Node n3 = testRootNode.addNode("node3"); + n3.setProperty("p", 3); + superuser.save(); + // only 2 results + String stmt = createStatement("order:p limit:2"); + RowIterator rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n1, n2}); + // range with open start + stmt = createStatement("order:p limit:..2"); + rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n1, n2}); + // range with open end + stmt = createStatement("order:p limit:1.."); + rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n2, n3}); + // range + stmt = createStatement("order:p limit:1..2"); + rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n2}); + // range with end larger than max results + stmt = createStatement("order:p limit:1..7"); + rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n2, n3}); + // range start larger than end + // end is ignored in that case + stmt = createStatement("order:p limit:2..1"); + rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n3}); + // range with start larger than max results + stmt = createStatement("order:p limit:6..10"); + rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{}); + } + + public void testPhrase() throws RepositoryException { + Node file1 = addFile(testRootNode, "file1.txt", SAMPLE_CONTENT); + superuser.save(); + String stmt = createStatement("\"quick brown\""); + RowIterator rows = GQL.execute(stmt, superuser, "jcr:content"); + checkResult(rows, new Node[]{file1}); + } + + public void testExcludeTerm() throws RepositoryException { + Node n1 = testRootNode.addNode("node1"); + n1.setProperty("text", "foo"); + Node n2 = testRootNode.addNode("node2"); + n2.setProperty("text", "bar"); + Node n3 = testRootNode.addNode("node3"); + n3.setProperty("text", "foo bar"); + superuser.save(); + String stmt = createStatement("foo -bar"); + RowIterator rows = GQL.execute(stmt, superuser); + checkResult(rows, new Node[]{n1}); + } + + public void testOptionalTerm() throws RepositoryException { + Node n1 = testRootNode.addNode("node1"); + n1.setProperty("text", "apache jackrabbit"); + Node n2 = testRootNode.addNode("node2"); + n2.setProperty("text", "apache jcr"); + Node n3 = testRootNode.addNode("node3"); + n3.setProperty("text", "jackrabbit jcr"); + superuser.save(); + String stmt = createStatement("apache jackrabbit OR jcr"); + RowIterator rows = GQL.execute(stmt, superuser); + checkResult(rows, new Node[]{n1, n2}); + } + + public void testType() throws RepositoryException { + Node file = addFile(testRootNode, "file1.txt", SAMPLE_CONTENT); + Node node = testRootNode.addNode("node1"); + node.setProperty("text", SAMPLE_CONTENT); + superuser.save(); + // only nt:resource + String stmt = createStatement("quick type:\"nt:resource\""); + RowIterator rows = GQL.execute(stmt, superuser); + checkResult(rows, new Node[]{file.getNode("jcr:content")}); + // only nt:unstructured + stmt = createStatement("quick type:\"nt:unstructured\""); + rows = GQL.execute(stmt, superuser); + checkResult(rows, new Node[]{node}); + } + + public void testMixinType() throws RepositoryException { + Node node = testRootNode.addNode("node1"); + node.setProperty("text", SAMPLE_CONTENT); + node.addMixin(mixReferenceable); + superuser.save(); + String stmt = createStatement("quick type:referenceable"); + RowIterator rows = GQL.execute(stmt, superuser); + checkResult(rows, new Node[]{node}); + } + + public void testTypeInheritance() throws RepositoryException { + Node file = addFile(testRootNode, "file1.txt", SAMPLE_CONTENT); + superuser.save(); + // nt:hierarchyNode and sub types + String stmt = createStatement("quick type:hierarchyNode"); + RowIterator rows = GQL.execute(stmt, superuser, "jcr:content"); + checkResult(rows, new Node[]{file}); + } + + public void testAutoPrefixType() throws RepositoryException { + Node file = addFile(testRootNode, "file1.txt", SAMPLE_CONTENT); + Node node = testRootNode.addNode("node1"); + node.setProperty("text", SAMPLE_CONTENT); + superuser.save(); + // only nt:resource + String stmt = createStatement("quick type:resource"); + RowIterator rows = GQL.execute(stmt, superuser); + checkResult(rows, new Node[]{file.getNode("jcr:content")}); + // only nt:unstructured + stmt = createStatement("quick type:unstructured"); + rows = GQL.execute(stmt, superuser); + checkResult(rows, new Node[]{node}); + } + + public void testQuotedProperty() throws RepositoryException { + Node file1 = addFile(testRootNode, "file1.txt", SAMPLE_CONTENT); + superuser.save(); + String stmt = createStatement("\"jcr:mimeType\":text/plain"); + RowIterator rows = GQL.execute(stmt, superuser, "jcr:content"); + checkResult(rows, new Node[]{file1}); + } + + public void testAutoPrefix() throws RepositoryException { + Node file1 = addFile(testRootNode, "file1.txt", SAMPLE_CONTENT); + superuser.save(); + String stmt = createStatement("mimeType:text/plain"); + RowIterator rows = GQL.execute(stmt, superuser, "jcr:content"); + checkResult(rows, new Node[]{file1}); + } + + public void testCommonPathPrefix() throws RepositoryException { + Node file1 = addFile(testRootNode, "file1.txt", SAMPLE_CONTENT); + Node file2 = addFile(testRootNode, "file2.txt", SAMPLE_CONTENT); + Node file3 = addFile(testRootNode, "file3.txt", SAMPLE_CONTENT); + superuser.save(); + String stmt = createStatement("quick"); + RowIterator rows = GQL.execute(stmt, superuser, "jcr:content"); + checkResult(rows, new Node[]{file1, file2, file3}); + } + + public void testExcerpt() throws RepositoryException { + addFile(testRootNode, "file1.txt", SAMPLE_CONTENT); + superuser.save(); + String stmt = createStatement("quick"); + RowIterator rows = GQL.execute(stmt, superuser, "jcr:content"); + assertTrue("Expected result", rows.hasNext()); + String excerpt = rows.nextRow().getValue("rep:excerpt()").getString(); + assertTrue("No excerpt returned", excerpt.startsWith("
")); + stmt = createStatement("type:resource quick"); + rows = GQL.execute(stmt, superuser); + assertTrue("Expected result", rows.hasNext()); + excerpt = rows.nextRow().getValue("rep:excerpt()").getString(); + assertTrue("No excerpt returned", excerpt.startsWith("
")); + } + + public void testPrefixedValue() throws RepositoryException { + Node n1 = testRootNode.addNode("node1"); + n1.setProperty("jcr:title", "a"); + Node n2 = testRootNode.addNode("node2"); + n2.setProperty("jcr:title", "b"); + Node n3 = testRootNode.addNode("node3"); + n3.setProperty("jcr:title", "c"); + superuser.save(); + String stmt = createStatement("order:jcr:title"); + RowIterator rows = GQL.execute(stmt, superuser); + checkResultSequence(rows, new Node[]{n1, n2, n3}); + + } + + public void XXXtestQueryDestruction() throws RepositoryException { + char[] stmt = createStatement("title:jackrabbit \"apache software\" type:file order:+title limit:10..20").toCharArray(); + for (char c = 0; c < 255; c++) { + for (int i = 0; i < stmt.length; i++) { + char orig = stmt[i]; + stmt[i] = c; + try { + GQL.execute(new String(stmt), superuser); + } finally { + stmt[i] = orig; + } + } + } + } + + protected static Node addFile(Node folder, String name, String contents) + throws RepositoryException { + Node file = folder.addNode(name, "nt:file"); + Node resource = file.addNode("jcr:content", "nt:resource"); + resource.setProperty("jcr:lastModified", Calendar.getInstance()); + resource.setProperty("jcr:mimeType", "text/plain"); + resource.setProperty("jcr:encoding", "UTF-8"); + try { + resource.setProperty("jcr:data", new ByteArrayInputStream( + contents.getBytes("UTF-8"))); + } catch (UnsupportedEncodingException e) { + // will never happen + } + return file; + } + + protected String createStatement(String stmt) { + return "path:" + testRoot + " " + stmt; + } +} Propchange: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/integration/GQLTest.java ------------------------------------------------------------------------------ svn:eol-style = native Modified: jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java URL: http://svn.apache.org/viewvc/jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java?rev=681054&r1=681053&r2=681054&view=diff ============================================================================== --- jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java (original) +++ jackrabbit/trunk/jackrabbit-core/src/test/java/org/apache/jackrabbit/core/query/AbstractQueryTest.java Wed Jul 30 07:06:00 2008 @@ -18,11 +18,13 @@ import org.apache.jackrabbit.test.AbstractJCRTest; import org.apache.jackrabbit.spi.commons.query.jsr283.qom.QueryObjectModelFactory; +import org.apache.jackrabbit.commons.iterator.NodeIteratorAdapter; import javax.jcr.query.QueryResult; import javax.jcr.query.RowIterator; import javax.jcr.query.Query; import javax.jcr.query.QueryManager; +import javax.jcr.query.Row; import javax.jcr.NodeIterator; import javax.jcr.RepositoryException; import javax.jcr.Node; @@ -32,6 +34,7 @@ import java.util.Set; import java.util.HashSet; import java.util.Iterator; +import java.util.NoSuchElementException; /** * Abstract base class for query test cases. @@ -130,6 +133,8 @@ * the specified nodes. * @param xpath the xpath query. * @param nodes the expected result nodes. + * @throws RepositoryException if an error occurs while executing the query + * or checking the result. */ protected void executeXPathQuery(String xpath, Node[] nodes) throws RepositoryException { @@ -142,6 +147,8 @@ * the specified nodes. * @param sql the sql query. * @param nodes the expected result nodes. + * @throws RepositoryException if an error occurs while executing the query + * or checking the result. */ protected void executeSQLQuery(String sql, Node[] nodes) throws RepositoryException { @@ -153,17 +160,49 @@ * Checks if the result set contains exactly the nodes. * @param result the query result. * @param nodes the expected nodes in the result set. + * @throws RepositoryException if an error occurs while reading from the result. */ protected void checkResult(QueryResult result, Node[] nodes) throws RepositoryException { + checkResult(result.getNodes(), nodes); + } + + /** + * Checks if the result contains exactly the nodes. + * @param result the query result. + * @param nodes the expected nodes in the result set. + * @throws RepositoryException if an error occurs while reading from the result. + */ + protected void checkResult(RowIterator result, Node[] nodes) + throws RepositoryException { + checkResult(new NodeIteratorAdapter(result) { + public Object next() throws NoSuchElementException { + Row next = (Row) super.next(); + try { + return superuser.getItem(next.getValue("jcr:path").getString()); + } catch (RepositoryException e) { + throw new NoSuchElementException(); + } + } + }, nodes); + } + + /** + * Checks if the result contains exactly the nodes. + * @param result the query result. + * @param nodes the expected nodes in the result set. + * @throws RepositoryException if an error occurs while reading from the result. + */ + protected void checkResult(NodeIterator result, Node[] nodes) + throws RepositoryException { // collect paths Set expectedPaths = new HashSet(); for (int i = 0; i < nodes.length; i++) { expectedPaths.add(nodes[i].getPath()); } Set resultPaths = new HashSet(); - for (NodeIterator it = result.getNodes(); it.hasNext();) { - resultPaths.add(it.nextNode().getPath()); + while (result.hasNext()) { + resultPaths.add(result.nextNode().getPath()); } // check if all expected are in result for (Iterator it = expectedPaths.iterator(); it.hasNext();) { @@ -178,6 +217,24 @@ } /** + * Checks if the result set contains exactly the nodes in the + * given sequence. + * + * @param result the query result. + * @param nodes the expected nodes in the result set. + * @throws RepositoryException if an error occurs while reading from the result. + */ + protected void checkResultSequence(RowIterator result, Node[] nodes) + throws RepositoryException { + for (int i = 0; i < nodes.length; i++) { + assertTrue("No more results, expected " + nodes[i].getPath(), result.hasNext()); + String path = result.nextRow().getValue("jcr:path").getString(); + assertEquals("Wrong sequence", nodes[i].getPath(), path); + } + assertFalse("No more result expected", result.hasNext()); + } + + /** * Executes the query specified by statement and returns the * query result. *