/* * eXist Open Source Native XML Database * Copyright (C) 2005-2010 The eXist Project * http://exist-db.org * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program 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 Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program; if not, write to the Free Software Foundation * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * * $Id$ */ package org.exist.xquery; import java.nio.file.Path; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import java.util.Optional; import org.exist.test.ExistXmldbEmbeddedServer; import org.exist.util.ConfigurationHelper; import org.exist.util.FileUtils; import org.exist.xmldb.XmldbURI; import org.junit.*; import org.xmldb.api.base.Collection; import org.xmldb.api.base.ResourceSet; import org.xmldb.api.base.XMLDBException; import org.xmldb.api.modules.BinaryResource; import org.xmldb.api.modules.CollectionManagementService; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertTrue; /** * Tests for various standard XQuery functions * * @author jens * @author perig * @author wolf * @author adam * @author dannes * @author dmitriy * @author ljo * @author chrisdutz * @author harrah * @author gvalentino * @author jmvanel */ public class XQueryFunctionsTest { @ClassRule public static final ExistXmldbEmbeddedServer existEmbeddedServer = new ExistXmldbEmbeddedServer(false, true); private final static String ROOT_COLLECTION_URI = "xmldb:exist:///db"; @Test public void arguments() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("declare function local:testAnyURI($uri as xs:string) as xs:string { " + "concat('Successfully processed as xs:string : ',$uri) " + "}; " + "let $a := xs:anyURI('http://exist.sourceforge.net/') " + "return local:testAnyURI($a)"); assertEquals(1, result.getSize()); String r = (String) result.getResource(0).getContent(); assertEquals("Successfully processed as xs:string : http://exist.sourceforge.net/", r); result = existEmbeddedServer.executeQuery("declare function local:testEmpty($blah as xs:string) as element()* { " + "for $a in (1,2,3) order by $a " + "return () " + "}; " + "local:testEmpty('test')"); assertEquals(0, result.getSize()); } /** * Tests the XQuery-/XPath-function fn:round-half-to-even * with the rounding value typed xs:integer */ @Test public void roundHtE_INTEGER() throws XPathException, XMLDBException { String query = "fn:round-half-to-even( xs:integer('1'), 0 )"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals("1", r); query = "fn:round-half-to-even( xs:integer('6'), -1 )"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals("10", r); query = "fn:round-half-to-even( xs:integer('5'), -1 )"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals("0", r); } /** * Tests the XQuery-/XPath-function fn:round-half-to-even * with the rounding value typed xs:double */ @Test public void roundHtE_DOUBLE() throws XPathException, XMLDBException { /* List of Values to test with Rounding */ String[] testvalues = {"0.5", "1.5", "2.5", "3.567812E+3", "4.7564E-3", "35612.25"}; String[] resultvalues = {"0", "2", "2", "3567.81", "0", "35600"}; int[] precision = {0, 0, 0, 2, 2, -2}; for (int i = 0; i < testvalues.length; i++) { String query = "fn:round-half-to-even( xs:double('" + testvalues[i] + "'), " + precision[i] + " )"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals(resultvalues[i], r); } } /** * Tests the XQuery-XPath function fn:tokenize() */ @Test public void tokenize() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("count ( tokenize('a/b' , '/') )"); String r = (String) result.getResource(0).getContent(); assertEquals("2", r); result = existEmbeddedServer.executeQuery("count ( tokenize('a/b/' , '/') )"); r = (String) result.getResource(0).getContent(); assertEquals("3", r); result = existEmbeddedServer.executeQuery("count ( tokenize('' , '/') )"); r = (String) result.getResource(0).getContent(); assertEquals("0", r); result = existEmbeddedServer.executeQuery( "let $res := fn:tokenize('abracadabra', '(ab)|(a)')" + "let $reference := ('', 'r', 'c', 'd', 'r', '')" + "return fn:deep-equal($res, $reference)"); r = (String) result.getResource(0).getContent(); assertEquals("true", r); } @Test public void deepEqual() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery( "let $res := ('a', 'b')" + "let $reference := ('a', 'b')" + "return fn:deep-equal($res, $reference)"); String r = (String) result.getResource(0).getContent(); assertEquals("true", r); } @Test public void compare() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("fn:compare(\"Strasse\", \"Stra\u00DFe\")"); String r = (String) result.getResource(0).getContent(); assertEquals("-1", r); //result = existEmbeddedServer.executeQuery("fn:compare(\"Strasse\", \"Stra\u00DFe\", \"java:GermanCollator\")"); //r = (String) result.getResource(0).getContent(); //assertEquals( "0", r ); String query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[compare(., '+') gt 0]"; result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void distinctValues() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("declare variable $c { distinct-values(('a', 'a')) }; $c"); String r = (String) result.getResource(0).getContent(); assertEquals("a", r); result = existEmbeddedServer.executeQuery("declare variable $c { distinct-values((<a>a</a>, <b>a</b>)) }; $c"); r = (String) result.getResource(0).getContent(); assertEquals("a", r); result = existEmbeddedServer.executeQuery("let $seq := ('A', 2, 'B', 2) return distinct-values($seq) "); assertEquals(3, result.getSize()); String query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[distinct-values(.)]"; result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void sum() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("declare variable $c { sum((1, 2)) }; $c"); String r = (String) result.getResource(0).getContent(); assertEquals("3", r); result = existEmbeddedServer.executeQuery("declare variable $c { sum((<a>1</a>, <b>2</b>)) }; $c"); r = (String) result.getResource(0).getContent(); //Any untyped atomic values in the sequence are converted to xs:double values ([MK Xpath 2.0], p. 432) assertEquals("3", r); result = existEmbeddedServer.executeQuery("declare variable $c { sum((), 3) }; $c"); r = (String) result.getResource(0).getContent(); assertEquals("3", r); } @Test public void avg() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("avg((2, 2))"); String r = (String) result.getResource(0).getContent(); assertEquals("2", r); result = existEmbeddedServer.executeQuery("avg((<a>2</a>, <b>2</b>))"); r = (String) result.getResource(0).getContent(); //Any untyped atomic values in the resulting sequence //(typically, values extracted from nodes in a schemaless document) //are converted to xs:double values ([MK Xpath 2.0], p. 301) assertEquals("2", r); result = existEmbeddedServer.executeQuery("avg((3, 4, 5))"); r = (String) result.getResource(0).getContent(); assertEquals("4", r); result = existEmbeddedServer.executeQuery("avg((xdt:yearMonthDuration('P20Y'), xdt:yearMonthDuration('P10M')))"); r = (String) result.getResource(0).getContent(); assertEquals("P10Y5M", r); String message = ""; try { result = existEmbeddedServer.executeQuery("avg((xdt:yearMonthDuration('P20Y') , (3, 4, 5)))"); } catch (XMLDBException e) { message = e.getMessage(); } assertTrue(message.indexOf("FORG0006") > -1); result = existEmbeddedServer.executeQuery("avg(())"); assertEquals(0, result.getSize()); result = existEmbeddedServer.executeQuery("avg(((xs:float('INF')), xs:float('-INF')))"); r = (String) result.getResource(0).getContent(); assertEquals("NaN", r); result = existEmbeddedServer.executeQuery("avg(((3, 4, 5), xs:float('NaN')))"); r = (String) result.getResource(0).getContent(); assertEquals("NaN", r); } @Test public void min() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("min((1, 2))"); String r = (String) result.getResource(0).getContent(); assertEquals("1", r); result = existEmbeddedServer.executeQuery("min((<a>1</a>, <b>2</b>))"); r = (String) result.getResource(0).getContent(); assertEquals("1", r); result = existEmbeddedServer.executeQuery("min(())"); assertEquals(0, result.getSize()); result = existEmbeddedServer.executeQuery("min((xs:dateTime('2005-12-19T16:22:40.006+01:00'), xs:dateTime('2005-12-19T16:29:40.321+01:00')))"); r = (String) result.getResource(0).getContent(); assertEquals("2005-12-19T16:22:40.006+01:00", r); result = existEmbeddedServer.executeQuery("min(('a', 'b'))"); r = (String) result.getResource(0).getContent(); assertEquals("a", r); String message = ""; try { result = existEmbeddedServer.executeQuery("min((xs:dateTime('2005-12-19T16:22:40.006+01:00'), 'a'))"); } catch (XMLDBException e) { message = e.getMessage(); } assertTrue(message.indexOf("FORG0006") > -1); try { message = ""; result = existEmbeddedServer.executeQuery("min(1, 2)"); } catch (XMLDBException e) { message = e.getMessage(); } //depends whether we have strict type checking or not assertTrue(message.indexOf("XPTY0004") > -1 | message.indexOf("FORG0001") > -1 | message.indexOf("FOCH0002") > -1); } public void max() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("max((1, 2))"); String r = (String) result.getResource(0).getContent(); assertEquals("2", r); result = existEmbeddedServer.executeQuery("max((<a>1</a>, <b>2</b>))"); r = (String) result.getResource(0).getContent(); assertEquals("2", r); result = existEmbeddedServer.executeQuery("max(())"); assertEquals(0, result.getSize()); result = existEmbeddedServer.executeQuery("max((xs:dateTime('2005-12-19T16:22:40.006+01:00'), xs:dateTime('2005-12-19T16:29:40.321+01:00')))"); r = (String) result.getResource(0).getContent(); assertEquals("2005-12-19T16:29:40.321+01:00", r); result = existEmbeddedServer.executeQuery("max(('a', 'b'))"); r = (String) result.getResource(0).getContent(); assertEquals("b", r); String message = ""; try { result = existEmbeddedServer.executeQuery("max((xs:dateTime('2005-12-19T16:22:40.006+01:00'), 'a'))"); } catch (XMLDBException e) { message = e.getMessage(); } assertTrue(message.indexOf("FORG0006") > -1); try { message = ""; result = existEmbeddedServer.executeQuery("max(1, 2)"); } catch (XMLDBException e) { message = e.getMessage(); } //depends whether we have strict type checking or not assertTrue(message.indexOf("XPTY0004") > -1 | message.indexOf("FORG0001") > -1 | message.indexOf("FOCH0002") > -1); } @Test public void exclusiveLock() throws XPathException, XMLDBException { String query = "let $query1 := (<a/>)\n" + "let $query2 := (2, 3)\n" + "let $a := util:exclusive-lock(//*,($query1, $query2))\n" + "return $a"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(3, result.getSize()); String r = (String) result.getResource(0).getContent(); assertEquals("<a/>", r); r = (String) result.getResource(1).getContent(); assertEquals("2", r); r = (String) result.getResource(2).getContent(); assertEquals("3", r); query = "let $query1 := (<a/>)\n" + "let $query2 := (2, 3)\n" + "let $a := util:exclusive-lock((),($query1, $query2))\n" + "return $a"; result = existEmbeddedServer.executeQuery(query); assertEquals(3, result.getSize()); r = (String) result.getResource(0).getContent(); assertEquals("<a/>", r); r = (String) result.getResource(1).getContent(); assertEquals("2", r); r = (String) result.getResource(2).getContent(); assertEquals("3", r); query = "let $query1 := (<a/>)\n" + "let $query2 := (2, 3)\n" + "let $a := util:exclusive-lock((),($query1, $query2))\n" + "return $a"; result = existEmbeddedServer.executeQuery(query); assertEquals(3, result.getSize()); r = (String) result.getResource(0).getContent(); assertEquals("<a/>", r); r = (String) result.getResource(1).getContent(); assertEquals("2", r); r = (String) result.getResource(2).getContent(); assertEquals("3", r); query = "let $a := util:exclusive-lock(//*,<root/>)\n" + "return $a"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals("<root/>", r); } @Ignore @Test public void utilEval1() throws XPathException, XMLDBException { String query = "<a><b/></a>/util:eval('*')"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(1, result.getSize()); } /** * @see http://sourceforge.net/tracker/index.php?func=detail&aid=1629363&group_id=17691&atid=117691 */ @Test public void utilEval2() throws XPathException, XMLDBException { String query = "let $context := <item/> " + "return util:eval(\"<result>{$context}</result>\")"; // TODO check result ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(1, result.getSize()); } @Test public void utilEvalForFunction() throws XPathException, XMLDBException { String query = "declare function local:home()\n" + "{\n" + "<b>HOME</b>\n" + "};\n" + "util:eval(\"local:home()\")\n"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(1, result.getSize()); } @Test public void sharedLock() throws XPathException, XMLDBException { String query = "let $query1 := (<a/>)\n" + "let $query2 := (2, 3)\n" + "let $a := util:shared-lock(//*,($query1, $query2))\n" + "return $a"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(3, result.getSize()); String r = (String) result.getResource(0).getContent(); assertEquals("<a/>", r); r = (String) result.getResource(1).getContent(); assertEquals("2", r); r = (String) result.getResource(2).getContent(); assertEquals("3", r); query = "let $query1 := (<a/>)\n" + "let $query2 := (2, 3)\n" + "let $a := util:shared-lock((),($query1, $query2))\n" + "return $a"; result = existEmbeddedServer.executeQuery(query); assertEquals(3, result.getSize()); r = (String) result.getResource(0).getContent(); assertEquals("<a/>", r); r = (String) result.getResource(1).getContent(); assertEquals("2", r); r = (String) result.getResource(2).getContent(); assertEquals("3", r); query = "let $query1 := (<a/>)\n" + "let $query2 := (2, 3)\n" + "let $a := util:shared-lock((),($query1, $query2))\n" + "return $a"; result = existEmbeddedServer.executeQuery(query); assertEquals(3, result.getSize()); r = (String) result.getResource(0).getContent(); assertEquals("<a/>", r); r = (String) result.getResource(1).getContent(); assertEquals("2", r); r = (String) result.getResource(2).getContent(); assertEquals("3", r); query = "let $a := util:shared-lock(//*,<root/>)\n" + "return $a"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals("<root/>", r); } @Test public void encodeForURI() throws XMLDBException { String string = "http://www.example.com/00/Weather/CA/Los%20Angeles#ocean"; String expected = "http%3A%2F%2Fwww.example.com%2F00%2FWeather%2FCA%2FLos%2520Angeles%23ocean"; String query = "encode-for-uri(\"" + string + "\")"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals(expected, r); string = "~b\u00e9b\u00e9"; expected = "~b%C3%A9b%C3%A9"; query = "encode-for-uri(\"" + string + "\")"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals(expected, r); string = "100% organic"; expected = "100%25%20organic"; query = "encode-for-uri(\"" + string + "\")"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals(expected, r); query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[encode-for-uri(.) ne '']"; result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void iriToURI() throws XMLDBException { String string = "http://www.example.com/00/Weather/CA/Los%20Angeles#ocean"; String expected = "http://www.example.com/00/Weather/CA/Los%20Angeles#ocean"; String query = "iri-to-uri(\"" + string + "\")"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals(expected, r); string = "http://www.example.com/~b\u00e9b\u00e9"; expected = "http://www.example.com/~b%C3%A9b%C3%A9"; query = "iri-to-uri(\"" + string + "\")"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals(expected, r); string = "$"; expected = "$"; query = "iri-to-uri(\"" + string + "\")"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals(expected, r); } @Test public void escapeHTMLURI() throws XMLDBException { String string = "http://www.example.com/00/Weather/CA/Los Angeles#ocean"; String expected = "http://www.example.com/00/Weather/CA/Los Angeles#ocean"; String query = "escape-html-uri(\"" + string + "\")"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals(expected, r); string = "javascript:if (navigator.browserLanguage == 'fr') window.open('http://www.example.com/~b\u00e9b\u00e9');"; expected = "javascript:if (navigator.browserLanguage == 'fr') window.open('http://www.example.com/~b%C3%A9b%C3%A9');"; query = "escape-html-uri(\"" + string + "\")"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals(expected, r); query = "escape-html-uri('$')"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals("$", r); query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[escape-html-uri(.) ne '']"; result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void localName() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "let $a := <a><b></b></a>" + "return fn:local-name($a)"); String r = (String) result.getResource(0).getContent(); assertEquals("a", r); } @Test public void localName_empty() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "fn:local-name(())"); final String r = (String) result.getResource(0).getContent(); assertEquals("", r); } @Test public void localName_emptyElement() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "<a>b</a>/fn:local-name(c)"); final String r = (String) result.getResource(0).getContent(); assertEquals("", r); } @Test public void localName_emptyText() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "<a>b</a>/fn:local-name(text())"); final String r = (String) result.getResource(0).getContent(); assertEquals("", r); } @Test public void name() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "let $a := <a><b></b></a>" + "return fn:name($a)"); String r = (String) result.getResource(0).getContent(); assertEquals("a", r); } @Test public void name_empty() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "fn:name(())"); final String r = (String) result.getResource(0).getContent(); assertEquals("", r); } @Test public void name_emptyElement() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "<a>b</a>/fn:name(c)"); final String r = (String) result.getResource(0).getContent(); assertEquals("", r); } @Test public void name_emptyText() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "<a>b</a>/fn:local-name(text())"); final String r = (String) result.getResource(0).getContent(); assertEquals("", r); } @Test public void dateTimeConstructor() throws XPathException, XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery( "let $date := xs:date('2007-05-02+02:00') " + "return dateTime($date, xs:time('15:12:52.421+02:00'))" ); String r = (String) result.getResource(0).getContent(); assertEquals("2007-05-02T15:12:52.421+02:00", r); } @Test public void currentDateTime() throws XPathException, XMLDBException { //Do not use this test around midnight on the last day of a month ;-) ResourceSet result = existEmbeddedServer.executeQuery( "('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', " + "'Oct', 'Nov', 'Dec')[month-from-dateTime(current-dateTime())]"); String r = (String) result.getResource(0).getContent(); SimpleDateFormat df = new SimpleDateFormat("MMM", new Locale("en", "US")); Date date = new Date(); assertEquals(df.format(date), r); String query = "declare option exist:current-dateTime '2007-08-23T00:01:02.062+02:00';" + "current-dateTime()"; result = existEmbeddedServer.executeQuery(query); assertEquals(1, result.getSize()); r = (String) result.getResource(0).getContent(); assertEquals("2007-08-23T00:01:02.062+02:00", r); } /** * Bugfix 3070 * * @see http://svn.sourceforge.net/exist/?rev=3070&view=rev * <p/> * seconds-from-dateTime() returned wrong value when dateTime had * no millesecs available. Special value was returned. */ @Test public void secondsFromDateTime() throws XMLDBException { ResourceSet result = existEmbeddedServer.executeQuery("seconds-from-dateTime(xs:dateTime(\"2005-12-22T13:35:21.000\") )"); String r = (String) result.getResource(0).getContent(); assertEquals("21", r); result = existEmbeddedServer.executeQuery("seconds-from-dateTime(xs:dateTime(\"2005-12-22T13:35:21\") )"); r = (String) result.getResource(0).getContent(); assertEquals("21", r); } @Ignore @Test public void resolveQName() throws XMLDBException { String query = "declare namespace a=\"aes\"; " + "declare namespace n=\"ns1\"; " + "declare variable $d := <c xmlns:x=\"ns1\"><d>x:test</d></c>; " + "for $e in $d/d " + "return fn:resolve-QName($e/text(), $e)"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals("x:test", r); query = "declare namespace a=\"aes\"; " + "declare namespace n=\"ns1\"; " + "declare variable $d := <c xmlns:x=\"ns1\"><d xmlns:y=\"ns1\">y:test</d></c>; " + "for $e in $d/d " + "return fn:resolve-QName($e/text(), $e)"; result = existEmbeddedServer.executeQuery(query); r = (String) result.getResource(0).getContent(); assertEquals("y:test", r); } @Test public void namespaceURI() throws XMLDBException { String query = "let $var := <a xmlns='aaa'/> " + "return " + "$var[fn:namespace-uri() = 'aaa']/fn:namespace-uri()"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals("aaa", r); query = "for $a in <test><a xmlns=\"aaa\"><b><c/></b></a></test>//* " + "return namespace-uri($a)"; result = existEmbeddedServer.executeQuery(query); assertEquals(result.getSize(), 3); r = (String) result.getResource(0).getContent(); assertEquals("aaa", r); r = (String) result.getResource(1).getContent(); assertEquals("aaa", r); r = (String) result.getResource(2).getContent(); assertEquals("aaa", r); } @Test public void prefixFromQName() throws XMLDBException { String query = "declare namespace foo = \"http://example.org\"; " + "declare namespace FOO = \"http://example.org\"; " + "fn:prefix-from-QName(xs:QName(\"foo:bar\"))"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals("foo", r); } @Test public void stringJoin() throws XMLDBException { String query = "let $s := ('','a','b','') " + "return string-join($s,'/')"; ResourceSet result = existEmbeddedServer.executeQuery(query); String r = (String) result.getResource(0).getContent(); assertEquals("/a/b/", r); } @Test public void nodeName() throws XMLDBException { final String query = "let $a := <a><b>-1</b><b>-2</b></a> " + "for $b in $a/b[fn:node-name(.) = xs:QName('b')] return $b"; final ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void noeName_empty() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "fn:node-name(())"); assertEquals(0, result.getSize()); } @Test public void nodeName_emptyElement() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "<a>b</a>/fn:node-name(c)"); assertEquals(0, result.getSize()); } @Test public void nodeName_emptyText() throws XPathException, XMLDBException { final ResourceSet result = existEmbeddedServer.executeQuery( "<a>b</a>/fn:node-name(text())"); assertEquals(0, result.getSize()); } @Test public void data0() throws XMLDBException { final String query = "let $a := <a><b>1</b><b>1</b></a> " + "for $b in $a/b[data() = '1'] return $b"; final ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void data0_atomization() throws XMLDBException { final String query = "(<a>1<b>2</b>three</a>, <four>4</four>)/data()"; final ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); assertEquals("12three", result.getResource(0).getContent().toString()); assertEquals("4", result.getResource(1).getContent()); } @Test public void data1() throws XMLDBException { final String query = "let $a := <a><b>1</b><b>1</b></a> " + "for $b in $a/b[data() = '1'] return $b"; final ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void data1_atomization() throws XMLDBException { final String query = "data((<a>1<b>2</b>three</a>, <four>4</four>, xs:integer(5)))"; final ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(3, result.getSize()); assertEquals("12three", result.getResource(0).getContent().toString()); assertEquals("4", result.getResource(1).getContent()); assertEquals("5", result.getResource(2).getContent()); } @Test public void ceiling() throws XMLDBException { String query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[abs(ceiling(.))]"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void concat() throws XMLDBException { String query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[concat('+', ., '+') = '+-2+']"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(1, result.getSize()); } @Test public void documentURI() throws XMLDBException { String query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[empty(document-uri(.))]"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void implicitTimezone() throws XMLDBException { String query = "declare option exist:implicit-timezone 'PT3H';" + "implicit-timezone()"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(1, result.getSize()); String r = (String) result.getResource(0).getContent(); assertEquals("PT3H", r); } @Test public void exists() throws XMLDBException { String query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[exists(.)]"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } @Test public void floor() throws XMLDBException { String query = "let $a := <a><b>-1</b><b>-2</b></a> " + "return $a/b[abs(floor(.))]"; ResourceSet result = existEmbeddedServer.executeQuery(query); assertEquals(2, result.getSize()); } /** * ensure the test collection is removed and call collection-available, * which should return false, no exception thrown */ @Test public void collectionAvailable1() throws XMLDBException { //remove the test collection if it already exists String collectionName = "testCollectionAvailable"; String collectionPath = XmldbURI.ROOT_COLLECTION + "/" + collectionName; String collectionURI = ROOT_COLLECTION_URI + "/" + collectionName; Collection testCollection = existEmbeddedServer.getRoot().getChildCollection(collectionName); if (testCollection != null) { CollectionManagementService cms = (CollectionManagementService) existEmbeddedServer.getRoot().getService("CollectionManagementService", "1.0"); cms.removeCollection(collectionPath); } runCollectionAvailableTest(collectionPath, false); runCollectionAvailableTest(collectionURI, false); } /** * create a collection and call collection-available, which should return true, * no exception thrown */ @Test public void collectionAvailable2() throws XMLDBException { //add the test collection String collectionName = "testCollectionAvailable"; String collectionPath = XmldbURI.ROOT_COLLECTION + "/" + collectionName; String collectionURI = ROOT_COLLECTION_URI + "/" + collectionName; Collection testCollection = existEmbeddedServer.getRoot().getChildCollection(collectionName); if (testCollection == null) { CollectionManagementService cms = (CollectionManagementService) existEmbeddedServer.getRoot().getService("CollectionManagementService", "1.0"); cms.createCollection(collectionPath); } runCollectionAvailableTest(collectionPath, true); runCollectionAvailableTest(collectionURI, true); } private void runCollectionAvailableTest(String collectionPath, boolean expectedResult) throws XMLDBException { //collection-available should not throw an exception and should return expectedResult String importXMLDB = "import module namespace xdb=\"http://exist-db.org/xquery/xmldb\";\n"; String collectionAvailable = "xdb:collection-available('" + collectionPath + "')"; String query = importXMLDB + collectionAvailable; ResourceSet result = existEmbeddedServer.executeQuery(query); assertNotNull(result); assertTrue(result.getSize() == 1); assertNotNull(result.getResource(0)); String content = (String) result.getResource(0).getContent(); assertNotNull(content); assertEquals(expectedResult, Boolean.valueOf(content).booleanValue()); } @Test public void base64BinaryCast() throws XMLDBException { final String TEST_BINARY_COLLECTION = "testBinary"; final String TEST_COLLECTION = "/db/" + TEST_BINARY_COLLECTION; final String BINARY_RESOURCE_FILENAME = "logo.jpg"; final String XML_RESOURCE_FILENAME = "logo.xml"; //create a test collection CollectionManagementService colService = (CollectionManagementService) existEmbeddedServer.getRoot().getService("CollectionManagementService", "1.0"); Collection testCollection = colService.createCollection(TEST_BINARY_COLLECTION); assertNotNull(testCollection); Optional<Path> home = ConfigurationHelper.getExistHome(); Path fLogo = FileUtils.resolve(home, "webapp").resolve(BINARY_RESOURCE_FILENAME); //store the eXist logo in the test collection BinaryResource br = (BinaryResource) testCollection.createResource(BINARY_RESOURCE_FILENAME, "BinaryResource"); br.setContent(fLogo.toFile()); testCollection.storeResource(br); //create an XML resource with the logo base64 embedded in it String queryStore = "xquery version \"1.0\";\n\n" + "let $embedded := <logo><image>{util:binary-doc(\"" + TEST_COLLECTION + "/" + BINARY_RESOURCE_FILENAME + "\")}</image></logo> return\n" + "xmldb:store(\"" + TEST_COLLECTION + "\", \"" + XML_RESOURCE_FILENAME + "\", $embedded)"; ResourceSet resultStore = existEmbeddedServer.executeQuery(queryStore); assertEquals("store, Expect single result", 1, resultStore.getSize()); assertEquals("Expect stored filename as result", TEST_COLLECTION + "/" + XML_RESOURCE_FILENAME, resultStore.getResource(0).getContent().toString()); //retrieve the base64 image from the XML resource and try to cast to xs:base64Binary String queryRetreive = "xquery version \"1.0\";\n\n" + "let $image := doc(\"" + TEST_COLLECTION + "/" + XML_RESOURCE_FILENAME + "\")/logo/image return\n" + "$image/text() cast as xs:base64Binary"; ResourceSet resultRetreive = existEmbeddedServer.executeQuery(queryRetreive); assertEquals("retreive, Expect single result", 1, resultRetreive.getSize()); } }