Skip to content

Instantly share code, notes, and snippets.

@line-o
Last active February 26, 2026 11:46
Show Gist options
  • Select an option

  • Save line-o/4731ed367f437be9cd036b152a18d340 to your computer and use it in GitHub Desktop.

Select an option

Save line-o/4731ed367f437be9cd036b152a18d340 to your computer and use it in GitHub Desktop.
This test suite illustrates an issue in test isolation in eXist-db's XQSuite test runner
<testsuites>
<testsuite package="http://exist-db.org/xquery/test/xqsuite-test-isolation" timestamp="2026-02-26T11:44:55.85Z" tests="6" failures="0" errors="4" pending="0" time="PT0.019S">
<testcase name="xqsuite-test-isolation:test-1" class="xqsuite-test-isolation:test-1"/>
<testcase name="xqsuite-test-isolation:test-2" class="xqsuite-test-isolation:test-2">
<error type="java:org.exist.xquery.XPathException" message="exerr:ERROR XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: test:normalize-node($node as node()) as item()*. Expected cardinality: exactly one, got 2. [at line 829, column 13, source: jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;In function:&#xA;&#x9;test:normalize-node($node as node()) as item()* [829:13:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:normalize-node($node as node()) as item()* [823:14:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:normalize($nodes as node()*) as item()* [809:17:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:equals($annotation-value as element(value), $result as item()) as xs:boolean [-1:-1:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:assertEquals($values as element(value)*, $result as item()*) as element(report)? [719:17:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:check-assertions($assertions as element(annotation)*, $result as item()*) as element(report)* [302:38:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]. XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: test:normalize-node($node as node()) as item()*. Expected cardinality: exactly one, got 2."/>
</testcase>
<testcase name="xqsuite-test-isolation:test-3" class="xqsuite-test-isolation:test-3">
<error type="java:org.exist.xquery.XPathException" message="exerr:ERROR XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: test:normalize-node($node as node()) as item()*. Expected cardinality: exactly one, got 2. [at line 829, column 13, source: jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;In function:&#xA;&#x9;test:normalize-node($node as node()) as item()* [829:13:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:normalize-node($node as node()) as item()* [823:14:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:normalize($nodes as node()*) as item()* [809:17:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:equals($annotation-value as element(value), $result as item()) as xs:boolean [-1:-1:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:assertEquals($values as element(value)*, $result as item()*) as element(report)? [719:17:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:check-assertions($assertions as element(annotation)*, $result as item()*) as element(report)* [302:38:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]. XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: test:normalize-node($node as node()) as item()*. Expected cardinality: exactly one, got 2."/>
</testcase>
<testcase name="xqsuite-test-isolation:test-4" class="xqsuite-test-isolation:test-4">
<error type="java:org.exist.xquery.XPathException" message="exerr:ERROR XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: test:normalize-node($node as node()) as item()*. Expected cardinality: exactly one, got 2. [at line 829, column 13, source: jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;In function:&#xA;&#x9;test:normalize-node($node as node()) as item()* [829:13:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:normalize-node($node as node()) as item()* [823:14:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:normalize($nodes as node()*) as item()* [809:17:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:equals($annotation-value as element(value), $result as item()) as xs:boolean [-1:-1:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:assertEquals($values as element(value)*, $result as item()*) as element(report)? [719:17:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:check-assertions($assertions as element(annotation)*, $result as item()*) as element(report)* [302:38:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]. XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: test:normalize-node($node as node()) as item()*. Expected cardinality: exactly one, got 2."/>
</testcase>
<testcase name="xqsuite-test-isolation:test-5" class="xqsuite-test-isolation:test-5">
<error type="java:org.exist.xquery.XPathException" message="exerr:ERROR XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: test:normalize-node($node as node()) as item()*. Expected cardinality: exactly one, got 2. [at line 829, column 13, source: jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;In function:&#xA;&#x9;test:normalize-node($node as node()) as item()* [829:13:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:normalize-node($node as node()) as item()* [823:14:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:normalize($nodes as node()*) as item()* [809:17:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:equals($annotation-value as element(value), $result as item()) as xs:boolean [-1:-1:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:assertEquals($values as element(value)*, $result as item()*) as element(report)? [719:17:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]&#xA;&#x9;test:check-assertions($assertions as element(annotation)*, $result as item()*) as element(report)* [302:38:jar:file:/exist/lib/exist.uber.jar!/org/exist/xquery/lib/xqsuite/xqsuite.xql]. XPTY0004: The actual cardinality for parameter 1 does not match the cardinality declared in the function's signature: test:normalize-node($node as node()) as item()*. Expected cardinality: exactly one, got 2."/>
</testcase>
<testcase name="xqsuite-test-isolation:test-two-calls-in-one-function" class="xqsuite-test-isolation:test-two-calls-in-one-function"/>
</testsuite>
</testsuites>
# test isolation in eXist-db's XQSuite test runner
The tests in xqsuite-test-isolation.xqm do interfere with each other in the form they are presented here.
The calls to fn:transform seem to return not only their own result but _also all previously generated ones_.
I found two ways to mitigate this
1. setting the "delivery-format" option to "serialized" which will return the exact expected string
2. modifying the return value by adding a second sequence item: an empty-sequence
(:
: eXist-db Open Source Native XML Database
: Copyright (C) 2001 The eXist-db Authors
:
: info@exist-db.org
: http://www.exist-db.org
:
: This library 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.1 of the License, or (at your option) any later version.
:
: This library 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 library; if not, write to the Free Software
: Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
:)
xquery version "3.1";
module namespace xqsuite-test-isolation="http://exist-db.org/xquery/test/xqsuite-test-isolation";
import module namespace xmldb="http://exist-db.org/xquery/xmldb";
declare namespace test="http://exist-db.org/xquery/xqsuite";
declare namespace xsl="http://www.w3.org/1999/XSL/Transform";
declare variable $xqsuite-test-isolation:collection-name := "regression-test";
declare variable $xqsuite-test-isolation:collection := "/db/" || $xqsuite-test-isolation:collection-name;
declare variable $xqsuite-test-isolation:source-doc-name := "source-document.xml";
declare variable $xqsuite-test-isolation:stylesheet-unnamed-template :=
<xsl:stylesheet version='1.0'>
<xsl:output omit-xml-declaration="yes"/>
<xsl:param name='v'/>
<xsl:template match='/'>
<v><xsl:value-of select='$v'/></v>
</xsl:template>
</xsl:stylesheet>
;
declare variable $xqsuite-test-isolation:stylesheet-named-template :=
<xsl:stylesheet version='1.0'>
<xsl:output omit-xml-declaration="yes"/>
<xsl:param name='v'/>
<xsl:template name='named-template' match='/'>
<v><xsl:value-of select='$v'/></v>
</xsl:template>
</xsl:stylesheet>
;
declare variable $xqsuite-test-isolation:document :=
<document>
<catalog>
<book id="bk101">
<author>Gambardella, Matthew</author>
</book>
<book id="bk102">
<author>Ralls, Kim</author>
</book>
</catalog>
</document>
;
declare
%test:setUp
function xqsuite-test-isolation:setup() {
xmldb:create-collection("/db", $xqsuite-test-isolation:collection-name),
xmldb:store($xqsuite-test-isolation:collection, "unnamed-template.xsl", $xqsuite-test-isolation:stylesheet-unnamed-template, "application/xslt+xml"),
xmldb:store($xqsuite-test-isolation:collection, "with-named-template.xsl", $xqsuite-test-isolation:stylesheet-named-template, "application/xslt+xml"),
xmldb:store($xqsuite-test-isolation:collection, $xqsuite-test-isolation:source-doc-name, $xqsuite-test-isolation:document, "application/document")
};
declare
%test:tearDown
function xqsuite-test-isolation:cleanup() {
xmldb:remove($xqsuite-test-isolation:collection)
};
declare
%test:assertEquals("<v>Gambardella, MatthewRalls, Kim</v>")
function xqsuite-test-isolation:test-1() {
transform(map{
"source-node": document { <dummy/> },
"stylesheet-node": doc($xqsuite-test-isolation:collection || "/unnamed-template.xsl"),
"stylesheet-params": map {
xs:QName("v"): doc($xqsuite-test-isolation:collection || "/" || $xqsuite-test-isolation:source-doc-name)
}
(: ,"delivery-format": "serialized":)
})?output
(: ,():)
};
declare
%test:assertEquals("<v>2</v>")
function xqsuite-test-isolation:test-2() {
transform(map{
"source-node": document { <dummy/> },
"stylesheet-node": doc($xqsuite-test-isolation:collection || "/unnamed-template.xsl"),
"stylesheet-params": map { xs:QName("v"): "2" }
(: ,"delivery-format": "serialized":)
})?output
(: ,():)
};
declare
%test:assertEquals("<v>Gambardella, MatthewRalls, Kim</v>")
function xqsuite-test-isolation:test-3() {
transform(map{
"source-node": document { <dummy/> },
"stylesheet-node": doc($xqsuite-test-isolation:collection || "/with-named-template.xsl"),
"initial-template": xs:QName('named-template'),
"global-context-item" : doc($xqsuite-test-isolation:collection || $xqsuite-test-isolation:source-doc-name),
"stylesheet-params": map {
xs:QName('v'): doc($xqsuite-test-isolation:collection || "/" || $xqsuite-test-isolation:source-doc-name)
}
(: ,"delivery-format": "serialized":)
})?output
(: ,():)
};
declare
%test:assertEquals("<v>Gambardella, MatthewRalls, Kim</v>")
function xqsuite-test-isolation:test-4() {
transform(map{
"source-node": document { <dummy/> },
"stylesheet-node": doc($xqsuite-test-isolation:collection || "/with-named-template.xsl"),
"initial-template": xs:QName('named-template'),
"stylesheet-params": map {
xs:QName('v'): doc($xqsuite-test-isolation:collection || "/" || $xqsuite-test-isolation:source-doc-name)
}
(: ,"delivery-format": "serialized":)
})?output
(: ,():)
};
declare
%test:assertEquals("<v>Gambardella, MatthewRalls, Kim</v>")
function xqsuite-test-isolation:test-5() {
transform(map{
"source-node": document { <dummy/> },
"stylesheet-node": doc($xqsuite-test-isolation:collection || "/with-named-template.xsl"),
"initial-template": xs:QName('named-template'),
"global-context-item" : doc($xqsuite-test-isolation:collection || $xqsuite-test-isolation:source-doc-name),
"stylesheet-params": map {
xs:QName('v'): doc($xqsuite-test-isolation:collection || "/" || $xqsuite-test-isolation:source-doc-name)
}
(: ,"delivery-format": "serialized":)
})?output
(: ,():)
};
declare
%test:assertEquals("<v>Gambardella, MatthewRalls, Kim</v>","<v>Gambardella, MatthewRalls, Kim</v>")
function xqsuite-test-isolation:test-two-calls-in-one-function() {
transform(map{
"source-node": document { <dummy/> },
"stylesheet-node": doc($xqsuite-test-isolation:collection || "/with-named-template.xsl"),
"initial-template": xs:QName('named-template'),
"stylesheet-params": map {
xs:QName('v'): doc($xqsuite-test-isolation:collection || "/" || $xqsuite-test-isolation:source-doc-name)
}
(: ,"delivery-format": "serialized":)
})?output,
transform(map{
"source-node": document { <dummy/> },
"stylesheet-node": doc($xqsuite-test-isolation:collection || "/with-named-template.xsl"),
"initial-template": xs:QName('named-template'),
"stylesheet-params": map {
xs:QName('v'): doc($xqsuite-test-isolation:collection || "/" || $xqsuite-test-isolation:source-doc-name)
}
(: ,"delivery-format": "serialized":)
})?output
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment