← Back to team overview

zorba-coders team mailing list archive

[Merge] lp:~zorba-coders/zorba/zorba_FOTS_driver into lp:zorba

 

Sorin Marian Nasoi has proposed merging lp:~zorba-coders/zorba/zorba_FOTS_driver into lp:zorba.

Commit message:
Added Zorba FOTS driver.

Requested reviews:
  Zorba Coders (zorba-coders)
Related bugs:
  Bug #918156 in Zorba: "fots driver for Zorba"
  https://bugs.launchpad.net/zorba/+bug/918156

For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/zorba_FOTS_driver/+merge/132980

Added Zorba FOTS driver.
-- 
https://code.launchpad.net/~zorba-coders/zorba/zorba_FOTS_driver/+merge/132980
Your team Zorba Coders is requested to review the proposed merge of lp:~zorba-coders/zorba/zorba_FOTS_driver into lp:zorba.
=== added directory 'test/fots_driver'
=== added file 'test/fots_driver/README.TXT'
--- test/fots_driver/README.TXT	1970-01-01 00:00:00 +0000
+++ test/fots_driver/README.TXT	2012-11-05 21:58:22 +0000
@@ -0,0 +1,30 @@
+Information about the W3C XQuery/XPath/XSLT 3.* Test Suite can be found here: http://dev.w3.org/2011/QT3-test-suite.
+
+In order to use the Zorba FOTS driver (written in XQuery) one has to follow these steps:
+
+1)  Download the FOTS testsuite from W3C
+    Since currently there is no official release, a simple "cvs get" will do:
+
+      $ export CVSROOT=":pserver:anonymous@xxxxxxxxxx:/sources/public"
+      $ cvs login
+        (Logging in to anonymous@xxxxxxxxxx)
+        CVS password: anonymous
+      $ cvs get 2011/QT3-test-suite
+
+3)  run
+    ./zorba -f
+            -q ../../test/fots_driver/cli.xq
+
+and get a list of options you can pass to the FOTS driver in order to:
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-test-sets
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-test-sets -e verbose:=true
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-test-sets -e testSetPrefixes:=prod,app
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-test-cases -e testSetPrefixes:=prod-Literal
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-matching-test-cases -e pattern:=catch
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-sets -e testSetPrefixes:=prod-Literal
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-sets -e testSetPrefixes:=prod-Literal -e verbose:=true
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-cases -e testSetPrefixes:=prod-Literal -e testCasePrefixes:=Literal
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-cases -e assertType:=assert-count -e testSetPrefixes:=fn-innermost
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-cases -e assertType:=assert-count -e verbose:=true
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-and-report
+    zorba -f -q /path/to/cli.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=report -e failuresFilePath:=failures.xml -e verbose:=true
\ No newline at end of file

=== added file 'test/fots_driver/cli.xq'
--- test/fots_driver/cli.xq	1970-01-01 00:00:00 +0000
+++ test/fots_driver/cli.xq	2012-11-05 21:58:22 +0000
@@ -0,0 +1,168 @@
+(:
+ : Copyright 2006-2011 The FLWOR Foundation.
+ :
+ : 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.
+ :)
+
+(:~
+ : Zorba FOTS driver CLI
+ : @author Ghislain Fourny, Sorin Nasoi
+ :)
+
+(:declare default element namespace "http://www.w3.org/2010/09/qt-fots-catalog";:)
+
+import module namespace driver = "http://www.zorba-xquery.com/zorba-fots-driver"; at "zorba-fots-driver.xqy";
+import module namespace reporting = "http://www.zorba-xquery.com/zorba-fots-driver/reporting"; at "reporting.xqy";
+
+(:~ path to the place where FOTS can be found :)
+declare variable $fotsPath as xs:string external := "";
+
+(:~ The path to the results from a previous run :)
+declare variable $failuresFilePath as xs:string external := "";
+
+(:~ choose the CLI option you want to run :)
+declare variable $mode as xs:string external := "";
+
+(:~ name/criteria for the test sets :)
+declare variable $testSetPrefixes as xs:string external := "";
+
+(:~ name/criteria for the test cases :)
+declare variable $testCasePrefixes as xs:string external := "";
+
+(:~ Enable or disable verbose output :)
+declare variable $verbose as xs:string external := "false";
+
+(:~ 
+  Enable or disable showing the actual query result in the output.
+  True by default.
+:)
+declare variable $showResult as xs:string external := "true";
+
+(:~ list of assertion types :)
+declare variable $assertType as xs:string external := "";
+
+(:~ regex for the tests in the 'list-matching-test-cases' option :)
+declare variable $pattern as xs:string external := "";
+
+(:~ flags for the tests in the 'list-matching-test-cases' option :)
+declare variable $flags as xs:string external := "";
+
+declare %private function local:tokenize-comma-or-empty-string(
+  $input as xs:string
+) as xs:string*
+{
+  let $tokens := tokenize($input, ",")
+  return if (exists($tokens)) then $tokens else ""
+};
+
+declare function local:usage() as xs:string
+{
+  string-join((
+    "Zorba FOTS driver usage examples:",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-test-sets",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-test-sets -e verbose:=true",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-test-sets -e testSetPrefixes:=prod,app",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-test-cases -e testSetPrefixes:=prod-Literal",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=list-matching-test-cases -e pattern:=catch",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-sets -e testSetPrefixes:=prod-Literal",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-sets -e testSetPrefixes:=prod-Literal -e verbose:=true",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-cases -e testSetPrefixes:=prod-Literal -e testCasePrefixes:=Literal",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-cases -e assertType:=assert-count -e testSetPrefixes:=fn-innermost",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-test-cases -e assertType:=assert-count -e verbose:=true",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=run-and-report",
+    "zorba -f -q /path/to/fots.xq -e fotsPath:=/path/to/w3c/dev/2011/QT3-test-suite/ -e mode:=report -e failuresFilePath:=failures.xml -e verbose:=true",
+    ""
+    ), "
")
+};
+
+(:~ The test cases in this list have bugs assigned already and should not be run :)
+variable $exceptedTestCases := (
+"context-item-1"                                                      (:see bug lp:867199  :)
+, "xqhof7", "xqhof13", "xqhof14"                                      (:see bug lp:947051  :)
+, "FunctionCall-020"                                                  (:see bug lp:947064  :)
+, "generate-id-901", "generate-id-902"                                (:see bug lp:947130  :)
+, "try-catch-function-call-3", "try-catch-function-call-4"            (:see bug lp:1070706 :)
+, "fn-nilled-29"                                                      (:see bug lp:1070709 :)
+, "CastAsNamespaceSensitiveType-4", "CastAsNamespaceSensitiveType-5"  (:see bug lp:1070722 :)
+, "instanceof131"                                                     (:see bug lp:947051  :)
+, "cbcl-subsequence-011", "cbcl-subsequence-012", "cbcl-subsequence-013", "cbcl-subsequence-014" (:see bug lp:1069794 :)
+
+, "function-literal-350", "function-literal-354", "function-literal-358", "function-literal-279", "function-literal-049"
+, "function-literal-280", "function-literal-283", "function-literal-284", "function-literal-276", "function-literal-272"
+, "function-literal-271", "function-literal-268", "function-literal-267", "function-literal-264", "function-literal-263"
+, "function-literal-113", "function-literal-114", "function-literal-110", "function-literal-109", "function-literal-017"
+, "function-literal-018", "function-literal-022", "function-literal-021", "function-literal-010", "function-literal-009"
+, "function-literal-416", "function-literal-415", "function-literal-404", "function-literal-403", "function-literal-014"
+, "function-literal-401", "function-literal-402", "function-literal-006", "function-literal-302", "function-literal-005"
+, "function-literal-002", "function-literal-300", "function-literal-060", "function-literal-001", "function-literal-052"
+, "function-literal-050"                                              (:see bug lp:1070504 :)
+
+, "re00975", "re00976", "re00976a"                                    (:see bug lp:1070533 :)
+, "fn-unparsed-text-lines-052"                                        (:see bug lp:1073175 :)
+);
+
+(:~  The test in this list have bugs assigned already and should not be run :)
+variable $exceptedTestSets := (
+"misc-HigherOrderFunctions" (: these test-sets have a lot of seg faults :)
+);
+
+switch ($mode)
+case "list-test-sets"
+  return string-join((driver:list-test-sets($fotsPath,
+                                            local:tokenize-comma-or-empty-string($testSetPrefixes))),
+                     "
")
+case "list-test-cases"
+  return string-join((driver:list-test-cases($fotsPath,
+                                             local:tokenize-comma-or-empty-string($testSetPrefixes)), ""),
+                     "
")
+case "list-matching-test-cases"
+  return string-join((driver:list-matching-test-cases($fotsPath,
+                                                      $pattern,
+                                                      $flags), ""),
+                     "
")
+case "run-test-sets"
+  return driver:run-fots( $fotsPath,
+                          driver:list-test-sets($fotsPath,
+                                                local:tokenize-comma-or-empty-string($testSetPrefixes)),
+                          '',
+                          $exceptedTestCases,
+                          $exceptedTestSets,
+                          $assertType,
+                          xs:boolean($verbose),
+                          xs:boolean($showResult))
+case "run-test-cases"
+  return driver:run-fots( $fotsPath,
+                          local:tokenize-comma-or-empty-string($testSetPrefixes),
+                          local:tokenize-comma-or-empty-string($testCasePrefixes),
+                          $exceptedTestCases,
+                          $exceptedTestSets,
+                          $assertType,
+                          xs:boolean($verbose),
+                          xs:boolean($showResult))
+case "run-and-report"
+  return reporting:run-and-report($fotsPath,
+                                  driver:list-test-sets($fotsPath,
+                                                        local:tokenize-comma-or-empty-string($testSetPrefixes)),
+                                  local:tokenize-comma-or-empty-string($testCasePrefixes),
+                                  $exceptedTestCases,
+                                  $exceptedTestSets,
+                                  xs:boolean($verbose),
+                                  xs:boolean($showResult))
+case "report"
+  return reporting:report($fotsPath,
+                          $failuresFilePath,
+                          $exceptedTestCases,
+                          $exceptedTestSets,
+                          xs:boolean($verbose))
+default
+  return local:usage()

=== added file 'test/fots_driver/environment.xqy'
--- test/fots_driver/environment.xqy	1970-01-01 00:00:00 +0000
+++ test/fots_driver/environment.xqy	2012-11-05 21:58:22 +0000
@@ -0,0 +1,409 @@
+(:
+ : Copyright 2006-2011 The FLWOR Foundation.
+ :
+ : 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.
+ :)
+
+(:~
+ : Zorba FOTS driver environment
+ : @author Sorin Nasoi
+ :)
+
+module namespace env = "http://www.zorba-xquery.com/zorba-fots-driver/environment";;
+
+import module namespace file = "http://expath.org/ns/file";;
+
+import module namespace xqxq = "http://www.zorba-xquery.com/modules/xqxq";;
+import module namespace util = "http://www.zorba-xquery.com/zorba-fots-driver/util"; at "util.xqy";
+
+declare namespace fots = "http://www.w3.org/2010/09/qt-fots-catalog";;
+
+declare namespace ann = "http://www.zorba-xquery.com/annotations";;
+
+
+declare variable $env:hof as xs:string :=
+  string-join(( "declare namespace op = 'http://www.zorba-xquery.com/options/features';",
+                "declare namespace f = 'http://www.zorba-xquery.com/features';",
+                "declare option op:enable 'f:hof';")
+              ,"
");
+
+(:~
+ : Retrieves the environment from a test-set or catalog given an environment name.
+ : @param $catalog FOTS catalog file.
+ : @param $testSet test set.
+ : @param $envName name of the environment.
+ : @return the environment with the given name.
+ :)
+declare function env:get-environment (
+  $catalog,
+  $testSet  as element (fots:test-set),
+  $envName  as xs:string
+) as element(fots:environment)? {
+  let $envTestSet := $testSet/test-set//environment[@name = $envName]
+  return
+    if (fn:empty($envTestSet))
+    then $catalog/catalog//environment[@name = $envName]
+    else $envTestSet
+};
+
+declare %ann:nondeterministic function env:add-var-decl(
+  $env  as element(fots:environment)?,
+  $case as element(fots:test-case),
+  $path as xs:string?
+) as xs:string? {
+  fn:concat(env:var-decl-with-value($env, $case/fots:environment),
+            env:var-decl-without-value($env, $case/fots:environment, $path))
+};
+
+(:  if defined, returns the string for setting the context item  :)
+declare function env:set-context-item(
+  $env          as element(fots:environment)?,
+  $relativePath as xs:string?
+) as xs:string? {
+  if(empty($env)) then ()
+  else if(data($env/@name) = 'empty') then ()
+  else if (fn:exists($env/fots:source[@role = "."])) then
+      string-join((env:declare-context-item($env, $relativePath),
+                  'xqxq:bind-context-item($queryID, $contextItem);')
+                 ,"
")
+    else ()
+};
+
+(:~
+ : Returns the strings for variable binding in XQXQ.
+ :
+ : @param $env the environment of the catalog or the test-set (given with 'ref').
+ : @param $envCase the environment of the test-case.
+ : @param $relativePath the relative path for the environment.
+ : @return the queryKey after the variables were bound.
+ :)
+declare function env:set-variables(
+  $env          as element(fots:environment)?,
+  $pathEnv      as xs:string
+) as xs:string? {
+  if(empty($env)) then ()
+  else
+  let $srcNames := for $source in $env/fots:source
+                   where fn:starts-with(fn:data($source/@role),"$")
+                   return substring-after(fn:data($source/@role),"$"),
+      $srcValues := for $srcName in $srcNames
+                    return concat('fn:doc("',
+                                  $pathEnv,
+                                  file:directory-separator(),
+                                  for $source in $env/fots:source
+                                  where $source[@role = concat("$",$srcName)]
+                                  return data($source/@file),
+                                  '")')
+  return
+  string-join((for $srcName in $srcNames
+               let $index := index-of($srcNames, $srcName)
+               return
+                concat('xqxq:bind-variable( $queryID, xs:QName("', $srcName, '")',
+                       ', ', $srcValues[$index], ');'),
+              
+              for $param in $env/fots:param
+              let $select:= fn:data($param/@select)
+              let $varValue :=  if(starts-with($select, "'") and ends-with($select, "'")) then 
+                                concat('"',
+                                      $pathEnv,
+                                      file:directory-separator(),
+                                      for $source in $env/fots:source
+                                      where $source[@uri = fn:translate(fn:data($param/@select), "'", "")]
+                                      return fn:data($source/@file),
+                                      '"')
+                                else $select
+              let $varName := fn:data($param/@name)
+              return
+                concat('xqxq:bind-variable( $queryID, xs:QName("', fn:data($param/@name), '")',
+                       ', ', $varValue, ');')
+              ), "
")
+};
+
+(:~
+ : Adds the necessary declare namespace statements.
+ :
+ : @param $env the environment of the catalog or the test-set (given with 'ref').
+ : @param $case the test-case.
+ : @param $pathTestSet the path to the test set.
+ : @return the declare namespace statements.
+ :)
+declare %ann:nondeterministic function env:decl-namespaces(
+  $env          as element(fots:environment)?,
+  $case         as element(fots:test-case),
+  $pathTestSet  as xs:string
+) as xs:string? {
+  string-join(for $ns in ($env/fots:namespace, $case/fots:environment/fots:namespace)
+              where fn:not($ns[@prefix=""]) and not(env:is-schema-prefix-bound(fn:data($ns/@prefix), $case, $pathTestSet))
+              return concat('declare namespace ',
+                            fn:data($ns/@prefix),
+                            ' = "',
+                            fn:data($ns/@uri),
+                            '";')
+              ," ")
+};
+
+(:~
+ : Sets the declared default element namespace.
+ :
+ : @param $env the environment of the catalog or the test-set (given with 'ref').
+ : @param $envCase the environment of the test-case.
+ : @return the declare default element namespace.
+ :)
+declare function env:decl-def-elem-namespace(
+  $env      as element(fots:environment)?,
+  $envCase  as element(fots:environment)?
+) as xs:string? {
+  for $ns in ($env/fots:namespace, $envCase/fots:namespace)
+  where $ns[@prefix=""]
+  return concat('declare default element namespace "',
+                 fn:data($ns/@uri),
+                '";')
+};
+
+(:~
+ : Sets the static base uri.
+ :
+ : @param $env the environment of the catalog or the test-set (given with 'ref').
+ : @param $envCase the environment of the test-case.
+ : @return the declare base-uri prolog statement.
+ :)
+declare function env:decl-base-uri(
+  $env      as element(fots:environment)?,
+  $envCase  as element(fots:environment)?
+) as xs:string? {
+  for $baseURI in ($env/fots:static-base-uri, $envCase/fots:static-base-uri)
+  return concat("declare base-uri '",
+                 fn:data($baseURI/@uri),
+                "';")
+};
+(:~
+ : Return true if the prefix will be bound to a schema in the Query
+ : It's a bug in the FOTS if this function returns true: I have reported the issue and made this fix until relevant FOTS tests are fixed.
+ :)
+declare %private %ann:nondeterministic function env:is-schema-prefix-bound(
+  $prefix       as xs:string,
+  $case         as element(fots:test-case),
+  $pathTestSet  as xs:string
+) as xs:boolean {
+  contains( util:get-value($case, $pathTestSet, "test"),
+            concat("import schema namespace ", $prefix))
+};
+
+declare %private function env:get-schema-import (
+  $env  as element(fots:environment)?
+) as xs:string {
+  if (empty($env)) then ""
+  else
+    let $namespace := $env/fots:namespace[@uri = fn:data($env/fots:schema/@uri)]
+    let $prefix as xs:string := if(exists($namespace)) then xs:string(fn:data($namespace/@prefix)) else "p"
+    return
+    if($prefix = "")
+    then concat('import schema default element namespace "',
+                  $env/fots:schema/@uri,
+                  '";
')
+    else concat('import schema namespace ',
+                $prefix,
+                ' = "',
+                $env/fots:schema/@uri,
+                '";
')
+};
+
+declare %private function env:var-decl-with-value(
+  $env      as element(fots:environment)?,
+  $envCase  as element(fots:environment)?
+) as xs:string? {
+  fn:string-join(
+                  for $param in ($env/fots:param, $envCase/fots:param)
+                  where fn:exists(fn:data($param/@select)) 
+                        and not(starts-with(fn:data($param/@select),"'"))
+                        and empty(fn:data($param[@declared="true"]))
+                  return concat("declare variable $",
+                                 fn:data($param/@name),
+                                " := ",
+                                fn:data($param/@select),";")
+                  ," ")
+};
+
+declare %private function env:var-decl-without-value(
+  $env  as element(fots:environment)?,
+  $envCase,
+  $path as xs:string?
+) as xs:string? {
+  fn:string-join(
+                  (for $param in ($env/fots:param, $envCase/fots:param)
+                  where (fn:empty(fn:data($param/@select)) or
+                        (fn:exists(fn:data($param/@select)) 
+                        and starts-with(fn:data($param/@select),"'")))
+                        and empty(fn:data($param[@declared="true"]))
+                  return concat("declare variable $",
+                                 fn:data($param/@name),
+                                " external;"),
+                  for $source in ($env/fots:source, $envCase/fots:source)
+                  where fn:starts-with(fn:data($source/@role),"$")
+                  return concat("declare variable ",
+                                 fn:data($source/@role),
+                                " external;"))
+                  ," ")
+};
+
+declare %private function env:declare-context-item(
+  $env          as element(fots:environment)?,
+  $relativePath as xs:string?
+) as xs:string {
+  let $ciDoc := concat( $relativePath,
+                        file:directory-separator(),
+                        fn:data($env/fots:source[@role = "."]/@file))
+  return
+  if(empty($env/fots:source[@validation = "strict"])) then
+    concat('variable $contextItem := doc("', $ciDoc, '");')
+  else
+    string-join(("
","variable $contextItemQuery := xqxq:prepare-main-module('",
+                 env:get-schema-import($env),
+                 concat('validate { doc("', $ciDoc, '")', "}',", " "),
+                 "resolver:url-resolver#2, ());",
+                 "variable $contextItem := xqxq:evaluate($contextItemQuery);")
+                 ,"
")
+};
+
+(:~
+ : Returns the needed XQXQ URL resolver declaration.
+ : @param $case the test case.
+ : @param $env the environment.
+ : @param $pathEnv path to the environment.
+ : @param $pathTestSet path to the test set that defines the test case.
+ : @return the needed XQXQ URL resolver declaration.
+ :)
+declare function env:resolver(
+  $case         as element(fots:test-case),
+  $env          as element(fots:environment)?,
+  $pathEnv      as xs:string?,
+  $pathTestSet  as xs:string
+) as xs:string?
+{
+  let $envSchema := $env/fots:schema,
+      $tcSchema := $case/fots:environment/fots:schema,
+      $schemas := ($envSchema, $tcSchema),
+      $modules := $case/fots:module,
+      $resources := ($env/fots:resource, $case/fots:environment/fots:schema)
+  return
+    if (empty($schemas) and empty($modules) and empty($resources)) then ()
+    else
+    string-join(("declare namespace resolver = 'http://www.zorba-xquery.com/modules/xqxq/url-resolver';",
+                 $env:hof,
+                "declare function resolver:url-resolver($namespace as xs:string, $entity as xs:string) {",
+                "switch($entity)",
+    if (exists($schemas)) then
+    string-join(("case 'schema'",
+                 "  return switch($namespace)",
+                 (for $schema in $envSchema
+                  return concat("         case '",
+                                 data($schema/@uri),
+                                 "' return doc('",
+                                 concat($pathEnv, file:directory-separator(), data($schema/@file)),
+                                 "')"),
+                  for $schema in $tcSchema
+                  return concat("         case '",
+                                 data($schema/@uri),
+                                 "' return doc('",
+                                 concat($pathTestSet, file:directory-separator(), data($schema/@file)),
+                                 "')")),
+                 "         default return ()")
+                ,"
")
+    else (),
+    if (exists($modules)) then
+    string-join(("case 'module'",
+                 "  return switch($namespace)",
+                  for $module in $modules
+                  return concat("         case '",
+                                 data($module/@uri),
+                                 "' return fn:unparsed-text('",
+                                 concat($pathTestSet, file:directory-separator(), data($module/@file)),
+                                 "') "),
+                 "         default return ()")
+                ,"
")
+    else (),
+    if (exists($resources)) then
+    string-join(("case ''",
+                 "  return switch($namespace)",
+                  for $resource in $resources
+                  return concat("         case '",
+                                 data($resource/@uri),
+                                 "' return fn:unparsed-text('",
+                                 concat($pathEnv, file:directory-separator(), data($resource/@file)),
+                                 "'",
+                                 if(exists($resource/@encoding)) then concat (",'", data($resource/@encoding),"'")
+                                 else (),
+                                 ") "),
+                 "         default return ()")
+                ,"
")
+    else ()
+    , "default return ()","};"),
+    "
")
+};
+
+(:~
+ : Check if the dependencies are met.
+ :
+ : @param $deps the dependencies of the test set and test case.
+ : @return true if this is an XQuery test.
+ :)
+declare function env:dependencies-present(
+  $deps   as element(fots:dependency)*
+) as xs:boolean {
+  let $dependencies := string-join(distinct-values(for $dep in $deps
+                                              where $dep[@type="spec"]
+                                              return data($dep/@value)),"")
+  return
+    if (contains($dependencies,"XT30")) then fn:false()
+    else if(contains($dependencies,"XP30")
+            and not(contains($dependencies,"XQ30") or contains($dependencies,"XQ10"))) then fn:false()
+    else fn:true()
+};
+
+(:~
+ : Check if an XQuery version declaration needs to be added.
+ :
+ : @param $deps the dependencies of the test set and test case.
+ : @param $test the Query test.
+ : @return if necessary the XQuery version declaration.
+ :)
+declare function env:add-xquery-30(
+  $deps as element(fots:dependency)*,
+  $test as xs:string
+) as xs:string? {
+  let $dependencies := string-join(distinct-values( for $dep in $deps
+                                                    where $dep[@type="spec"]
+                                                    return data($dep/@value)),"")
+  return
+    if (contains($dependencies,"XQ30") and 
+        not(contains($test, "xquery version ")))
+    then "xquery version '3.0';"
+    else ()
+};
+
+(:~
+ : If there is a dependency on XQuery 3.0 return the strings for enabling the HOF feature.
+ :
+ : @param $deps the dependencies of the test set and test case
+ : @return if necessary the strings for enabling the HOF feature
+ :)
+declare function env:enable-HOF-feature(
+  $deps   as element(fots:dependency)*
+) as xs:string? {
+  let $dependencies := string-join(distinct-values( for $dep in $deps
+                                                    where $dep[@type="spec"]
+                                                    return data($dep/@value)),"")
+  return
+    if (contains($dependencies,"XQ30"))
+    then $env:hof else ()
+};

=== added file 'test/fots_driver/errors.xqy'
--- test/fots_driver/errors.xqy	1970-01-01 00:00:00 +0000
+++ test/fots_driver/errors.xqy	2012-11-05 21:58:22 +0000
@@ -0,0 +1,32 @@
+(:
+ : Copyright 2006-2011 The FLWOR Foundation.
+ :
+ : 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.
+ :)
+
+(:~
+ : Zorba FOTS driver errors
+ : @author Sorin Nasoi
+ :)
+
+module namespace err = "http://www.zorba-xquery.com/zorba-fots-driver/errors";;
+
+(:~
+ : Errors namespace URI.
+:)
+declare variable $err:errNS as xs:string := "http://www.zorba-xquery.com/zorba-fots-driver/errors";;
+
+(:~
+ : xs:QName with namespace URI="http://www.w3.org/2010/09/qt-fots-catalog/errors"; and local name "err:errNA"
+:)
+declare variable $err:errNA as xs:QName := fn:QName($err:errNS, "check:errNA");
\ No newline at end of file

=== added file 'test/fots_driver/evaluate.xqy'
--- test/fots_driver/evaluate.xqy	1970-01-01 00:00:00 +0000
+++ test/fots_driver/evaluate.xqy	2012-11-05 21:58:22 +0000
@@ -0,0 +1,399 @@
+(:
+ : Copyright 2006-2011 The FLWOR Foundation.
+ :
+ : 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.
+ :)
+
+(:~
+ : Zorba FOTS driver evaluate
+ : @author Sorin Nasoi
+ :)
+
+module namespace eval = "http://www.zorba-xquery.com/zorba-fots-driver/evaluate";;
+
+import module namespace xqxq    = "http://www.zorba-xquery.com/modules/xqxq";;
+import module namespace schema  = "http://www.zorba-xquery.com/modules/schema";;
+
+import module namespace fots-err = "http://www.zorba-xquery.com/zorba-fots-driver/errors"; at "errors.xqy";
+import module namespace util = "http://www.zorba-xquery.com/zorba-fots-driver/util"; at "util.xqy";
+
+declare namespace err = "http://www.w3.org/2005/xqt-errors";;
+declare namespace fots = "http://www.w3.org/2010/09/qt-fots-catalog";;
+
+declare namespace ann = "http://www.zorba-xquery.com/annotations";;
+
+declare namespace features = "http://www.zorba-xquery.com/options/features";;
+declare option features:enable "hof";
+
+declare %ann:sequential function eval:result(
+  $result     as item()*,
+  $expResult  as element(),
+  $showResult as xs:boolean?
+) as element()? {
+  let $err := eval:check-assertion($result, $expResult, (), "", $showResult)
+  return if(empty($err)) then () else
+    <out>
+      <expected-result>{$expResult}</expected-result>
+      {
+        if($showResult) then <result>{$result}</result>
+        else ()
+      }
+      {
+        if($showResult) then <errors>{$err}</errors>
+        else ()
+      }
+    </out>
+};
+
+declare %ann:sequential function eval:error(
+  $result           as item()*,
+  $expResult        as element(),
+  $code             as xs:QName?,
+  $errorDescription as xs:string?,
+  $showResult       as xs:boolean?
+) as xs:string* {
+  if(empty($result)) then
+    let $err := eval:error-code( $code,
+                                  $errorDescription,
+                                  $expResult)
+    return 
+      if(empty($err)) then () else $err
+  else
+    concat("Expected error &#xA;",
+          data($expResult/@code),
+          ",&#xA; found result ",
+          if ($showResult) then util:serialize-result($result)
+          else ())
+};
+
+declare %private %ann:sequential function eval:error-code(
+  $code             as xs:QName?,
+  $errorDescription as xs:string?,
+  $expResult        as element()
+) as xs:string* {
+  let $assertName := local-name($expResult)
+  return
+  if( $assertName = "error") then
+    if (exists($expResult[@code = "*"]) or
+        exists($expResult[@code = fn:local-name-from-QName($code)])) then ()
+    else
+        concat("Expected error: ", fn:data($expResult/@code), 
+               ". Found error: ", fn:local-name-from-QName($code))
+  else if (($assertName = "any-of") or ($assertName = "all-of")) then
+    eval:check-assertion((), $expResult, $code, $errorDescription, fn:true())
+  else
+    concat("Expected result: &#xA;", fn:data($expResult),
+           ".&#xA; Found error ", fn:local-name-from-QName($code), " - ", $errorDescription)
+};
+declare %private %ann:sequential function eval:check-assertion(
+  $result           as item()*,
+  $expResult        as element(),
+  $code             as xs:QName?,
+  $errorDescription as xs:string?,
+  $showResult       as xs:boolean?
+) as xs:string* {
+  let $test := local-name($expResult)
+  return switch($test)
+    case 'all-of'
+      return eval:assert-all-of($result, $expResult, $code, $errorDescription, $showResult)
+    case 'any-of'
+      return eval:assert-any-of($result, $expResult, $code, $errorDescription, $showResult)
+    case 'assert'
+      return eval:assert($result, $expResult)
+    case 'assert-count'
+      return eval:assert-count($result, $expResult)
+    case 'assert-deep-eq'
+      return eval:assert-deep-eq($result, $expResult)
+    case 'assert-empty'
+      return eval:assert-empty($result)
+    case 'assert-eq'
+      return eval:assert-eq($result, $expResult)
+    case 'assert-false'
+      return eval:assert-false($result)
+    case 'assert-permutation'
+      return eval:assert-permutation($result, $expResult)
+    case 'assert-xml'
+      return eval:assert-xml($result, $expResult)
+    case 'assert-serialization-error'
+      return eval:assert-serialization-error($result, $expResult)
+    case 'assert-string-value'
+      return eval:assert-string-value($result, $expResult)
+    case 'assert-true'
+      return eval:assert-true($result)
+    case 'assert-type'
+      return eval:assert-type($result, $expResult)
+    case 'serialization-matches'
+      return eval:serialization-matches($result, $expResult)
+    case 'error'
+      return eval:error($result, $expResult, $code, $errorDescription, $showResult)
+    default return fn:error($fots-err:errNA, "The requested assertion type is not implemented.")
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_any-of  :)
+declare %private %ann:sequential function eval:assert-any-of(
+  $result           as item()*,
+  $expResult        as element(),
+  $code             as xs:QName?,
+  $errorDescription as xs:string?,
+  $showResult       as xs:boolean
+) as xs:string? {
+(:TODO
+let $results := for $tmp in $expResult/descendant-or-self::*
+:)
+  let $results := for $tmp in $expResult/*
+                  return empty(eval:check-assertion($result, $tmp, $code, $errorDescription, $showResult))
+  return 
+    if (some $result in $results satisfies $result)
+    then ()
+    else concat("Assert-any-of returned: ", util:serialize-result($results))
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_all-of  :)
+declare %private %ann:sequential function eval:assert-all-of(
+  $result           as item()*,
+  $expResult        as element(),
+  $code             as xs:QName?,
+  $errorDescription as xs:string?,
+  $showResult       as xs:boolean
+) as xs:string* {
+  for $tmp in $expResult/*
+  return eval:check-assertion($result, $tmp, $code, $errorDescription, $showResult)
+};
+
+(: TODO: implement this new assertion :)
+declare %private function eval:serialization-matches(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+  "Assert 'Serialization-matches' is not defined in the FOTS schema."
+};
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert  :)
+declare %private %ann:sequential function eval:assert(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+    try {
+    {
+      variable $queryText := concat(
+        "xquery version '3.0';",
+        "declare namespace o = 'http://www.zorba-xquery.com/options/features';",
+        "declare option o:enable 'hof';",
+        "declare variable $result external; ",
+        xs:string($expResult)),
+      $queryKey := xqxq:prepare-main-module($queryText),
+      $queryKeyResult := xqxq:bind-variable($queryKey, xs:QName('result'), $result),
+      $queryResult := xqxq:evaluate($queryKey);
+      if($queryResult) then ()
+      else concat("Assertion ", $expResult, " failed")
+    }
+  } catch * {
+    concat("Assertion &#xA;'",
+           $expResult,
+           "'&#xA; failed with error ",
+           $err:code, " : ", $err:description)
+  }
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-count  :)
+declare %private function eval:assert-count(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+  if(count($result) eq xs:integer($expResult)) then ()
+  else "The number of items found is different than the expected number of items."
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-deep-eq  :)
+declare %private %ann:sequential function eval:assert-deep-eq(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+  try {
+    {
+      variable $queryText := concat(
+        "xquery version '3.0';",
+        "declare namespace o = 'http://www.zorba-xquery.com/options/features';",
+        "declare option o:enable 'hof';",
+        "declare variable $x external;",
+        "let $y := (",fn:string(fn:data($expResult)),") return ",
+        "every $i in 1 to max((count($x),count($y))) satisfies deep-equal($x[$i],$y[$i])"),
+      $queryKey := xqxq:prepare-main-module($queryText),
+      $queryKeyResult := xqxq:bind-variable($queryKey, xs:QName('x'), $result),
+      $queryResult := xqxq:evaluate($queryKey);
+      if($queryResult) then ()
+      else concat("Result is not deep-equal to &#xA;'", $expResult, "'&#xA;")
+    }
+  } catch * {
+    concat("Assert-deep-eq &#xA;'", $expResult, "'&#xA; failed with error ",
+            $err:code, " : ", $err:description)
+  }
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-empty  :)
+declare %private function eval:assert-empty(
+  $result    as item()*
+) as xs:string? {
+  if(empty($result)) then ()
+  else "Result is not empty as expected"
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-eq  :)
+declare %private %ann:sequential function eval:assert-eq(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+  try {
+  {
+    variable  $type :=  if (empty($result[1]) or (count($result) gt 1)) then ()
+                        else 
+                          let $tmp := xs:string(schema:schema-type($result[1]))
+                          (: add exception for the types defined in schemas available in the environment of the tests :)
+                          return
+                            if (starts-with($tmp, 'xs:')) then $tmp else ();
+    variable  $queryText := concat(
+                "declare variable $x external;",
+                "$x eq ", 
+                if (starts-with(data($expResult), $type)) then data($expResult)
+                else concat($type,"(", data($expResult), ")"));
+    variable  $queryKey := xqxq:prepare-main-module($queryText);
+    xqxq:bind-variable($queryKey, xs:QName('x'), $result);
+    variable $queryResult := xqxq:evaluate($queryKey);
+    if($queryResult) then ()
+    else concat("Assert-eq: Result '", util:serialize-result($result),
+                "' doesn't match expected item '", xs:string($expResult), "'.")
+  }
+} catch * {
+    concat("Comparison to '", $expResult/text(), "' failed with error: ",
+            $err:code ," : ", $err:description)
+  }
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-true  :)
+declare %private function eval:assert-true(
+  $result as item()*
+) as xs:string? {
+  if($result eq fn:true()) then ()
+  else "Query doesn't evaluate to true."
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-false :)
+declare %private function eval:assert-false(
+  $result as item()*
+) as xs:string? {
+  if($result eq fn:false()) then ()
+  else "Query doesn't evaluate to false."
+};
+
+(: http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-permutation :)
+declare %private %ann:sequential function eval:assert-permutation(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+  try {
+    {
+      variable $queryText := concat(
+        "xquery version '3.0';",
+        "declare namespace o = 'http://www.zorba-xquery.com/options/features';",
+        "declare option o:enable 'hof';",
+        "declare variable $x external;",
+        "let $y := (",fn:string(fn:data($expResult)),") return ",
+        (: if count(intersection(M1,M2)) = count(union(M1,M2)) = count(M1) then the sequences are identical :)
+        "(count(distinct-values($x[ . = $y])) = count(fn:distinct-values(($x, $y)))) = count(fn:distinct-values($x))"),
+      $queryKey := xqxq:prepare-main-module($queryText),
+      $queryKeyResult := xqxq:bind-variable($queryKey, xs:QName('x'), $result),
+      $queryResult := xqxq:evaluate($queryKey);
+      if($queryResult) then ()
+      else concat("Result isn't a permutation of &#xA;'", $expResult, "'&#xA;")
+    }
+  } catch * {
+    concat("Assert-permutation failed with error: ",
+            $err:code ," : ", $err:description)
+  }
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-xml  :)
+declare %private function eval:assert-xml(
+  $result    as item()*,
+  $expResult as element()
+) {
+  try {
+    let $serializedResult as xs:string := util:serialize-result($result)
+    return
+      if($serializedResult eq string($expResult))
+      then ()
+      else concat("Result &#xA;'", $serializedResult ,"'&#xA; is different from the expected result &#xA;'", string($expResult),"'.")
+  } catch * {
+    concat("Assert-xml failed with error:",
+            $err:code, " : ", $err:description)
+  }
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-serialization-error  :)
+declare %private %ann:sequential function eval:assert-serialization-error(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+  try {
+    let $serializedResult as xs:string := util:serialize-result($result)
+    return
+      fn:concat("Expected serialization error but got result: ", $serializedResult)
+  } catch * {
+    eval:error((),
+                $expResult,
+                $err:code,
+                $err:description,
+                fn:true())
+  }
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-string-value :)
+declare %private function eval:assert-string-value(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+  try {
+    let $serRes := util:serialize-result($result),
+        $res := if (empty($expResult[@normalize-space="true"]))
+                then $serRes
+                else fn:normalize-space($serRes),
+        $expRes :=  if (empty($expResult[@normalize-space="true"]))
+                    then xs:string($expResult)
+                    else fn:normalize-space(xs:string($expResult))
+    return if($res eq $expRes) then ()
+      else fn:concat("Expected  &#xA;'", $expRes, "'&#xA; found  &#xA;'", $res, "'")
+  } catch * {
+    fn:concat("String-value failed with error: ",
+               $err:code, " : ", $err:description)
+  }
+};
+
+(:  http://dev.w3.org/2011/QT3-test-suite/catalog-schema.html#elem_assert-type  :)
+declare %private %ann:sequential function eval:assert-type(
+  $result    as item()*,
+  $expResult as element()
+) as xs:string? {
+  try {
+    {
+      variable  $queryText := concat( "declare variable $x external; $x instance of ",fn:data($expResult)),
+                $queryKey := xqxq:prepare-main-module($queryText),
+                $queryKeyResult := xqxq:bind-variable($queryKey, xs:QName('x'), $result),
+                $queryResult := xqxq:evaluate($queryKey);
+      if($queryResult) then ()
+      else concat("Result doesn't have type '", fn:data($expResult), "'")
+    }
+  } catch * {
+    fn:concat("Assert-type failed with error: ",
+               $err:code, " : ", $err:description)
+  }
+};
+

=== added file 'test/fots_driver/reporting.xqy'
--- test/fots_driver/reporting.xqy	1970-01-01 00:00:00 +0000
+++ test/fots_driver/reporting.xqy	2012-11-05 21:58:22 +0000
@@ -0,0 +1,182 @@
+(:
+ : Copyright 2006-2011 The FLWOR Foundation.
+ :
+ : 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.
+ :)
+
+(:~
+ : Zorba FOTS driver reporting
+ : @author Sorin Nasoi
+ :)
+
+module namespace reporting = "http://www.zorba-xquery.com/zorba-fots-driver/reporting";;
+
+import module namespace file = "http://expath.org/ns/file";;
+
+import module namespace driver = "http://www.zorba-xquery.com/zorba-fots-driver"; at "zorba-fots-driver.xqy";
+import module namespace util = "http://www.zorba-xquery.com/zorba-fots-driver/util"; at "util.xqy";
+import module namespace fots-err = "http://www.zorba-xquery.com/zorba-fots-driver/errors"; at "errors.xqy";
+
+declare default element namespace "http://www.w3.org/2010/09/qt-fots-catalog";;
+
+declare namespace err ="http://www.w3.org/2005/xqt-errors";;
+declare namespace fots = "http://www.w3.org/2010/09/qt-fots-catalog";;
+
+declare namespace ann = "http://www.zorba-xquery.com/annotations";;
+
+(:~
+ : Loops through the test-sets, runs then and creates statistics.
+ : @param $pathFOTSCatalog path to the FOTS catalog file.
+ : @param $testSetPrefixes name/criteria for the test sets (empty string means all).
+ : @param $testCasePrefixes name/criteria for the test cases (empty string means all).
+ : @param $exceptedTestCases lists of test cases that are not run(empty string means all tests will be run).
+ : @param $exceptedTestSets lists of test sets that are not run(empty string means all tests will be run).
+ : @param $verbose if set to TRUE it will also output the actual failures.
+ : @param $showResult if set to TRUE it will also show the actual result of the Query run.
+ : @return a report of tests run.
+ :)
+declare %ann:sequential function reporting:run-and-report(
+  $pathFOTSCatalog    as xs:string,
+  $testSetPrefixes    as xs:string*,
+  $testCasePrefixes   as xs:string*,
+  $exceptedTestCases  as xs:string*,
+  $exceptedTestSets   as xs:string*,
+  $verbose            as xs:boolean,
+  $showResult         as xs:boolean
+) 
+{
+  try {
+    {
+      variable $failures := driver:run-fots($pathFOTSCatalog,
+                                            $testSetPrefixes,
+                                            $testCasePrefixes,
+                                            $exceptedTestCases,
+                                            $exceptedTestSets,
+                                            '',                   (: assert filter :)
+                                            $verbose,
+                                            $showResult);
+
+      file:write("failures.xml", $failures, $util:serParamXml);
+
+      reporting:do-reporting($pathFOTSCatalog, $failures, $exceptedTestCases, $exceptedTestSets, $verbose)
+    }
+  }
+  catch *
+  {
+    fn:error($err:code, $err:description)
+  }
+};
+
+(:~
+ : Loops through the test cases report and creates statistics.
+ : @param $pathFOTSCatalog path to the FOTS catalog file.
+ : @param $pathFailures path to the FOTS failures.
+ : @param $exceptedTestCases lists of test cases that are not run(empty string means all tests will be run).
+ : @param $exceptedTestSets lists of test sets that are not run(empty string means all tests will be run).
+ : @param $verbose if set to TRUE it will also output the actual failures.
+ : @param $showResult if set to TRUE it will also show the actual result of the Query run..
+ : @return a report of tests run.
+ :)
+declare %ann:nondeterministic function reporting:report(
+  $pathFOTSCatalog    as xs:string,
+  $pathFailures       as xs:string,
+  $exceptedTestCases  as xs:string*,
+  $exceptedTestSets   as xs:string*,
+  $verbose            as xs:boolean
+) 
+{
+  try {
+    {
+      if(not(file:is-file($pathFailures))) then
+      {
+        fn:error($fots-err:errNA, "The file failures file was not found. Suggestion: use driver:run-fots to generate it or use reporting:run-and-report function.");
+      }
+      else ();
+    
+      variable $failures := fn:parse-xml(file:read-text($pathFailures));
+      
+      reporting:do-reporting($pathFOTSCatalog, $failures, $exceptedTestCases, $exceptedTestSets, $verbose)
+    }
+  }
+  catch *
+  {
+    fn:error($err:code, $err:description)
+  }
+};
+
+
+(:~
+ : Loops through the test-sets and creates statistics.
+ : @param $pathFOTSCatalog  path to the FOTS catalog file.
+ : @param $failures the test reported by Zorba as failed.
+ : @param $exceptedTestCases lists of test cases that are not run(empty string means all tests will be run).
+ : @param $exceptedTestSets lists of test sets that are not run(empty string means all tests will be run).
+ : @param $verbose is set to TRUE it will also output the actual failures.
+ : @return a report of tests run.
+ :)
+declare %ann:nondeterministic function reporting:do-reporting(
+  $pathFOTSCatalog  as xs:string,
+  $failures,
+  $exceptedTestCases  as xs:string*,
+  $exceptedTestSets   as xs:string*,
+  $verbose            as xs:boolean
+) {
+  let $catalog := util:doc($pathFOTSCatalog, 'catalog.xml'),
+      $excepted := count($exceptedTestCases)
+  return
+  <report>
+  {
+    let $totalNoTests := fn:sum(for $testSetFile in $catalog//fots:test-set
+                                  let $file := fn:data($testSetFile/@file),
+                                      $testSet := util:doc($pathFOTSCatalog, $file)
+                                  return fn:count($testSet//fots:test-case)),
+        $totalFailures := fn:sum( for $testSet in $failures//fots:test-set
+                                  return count($testSet//fots:test-case[@result ="fail"])),
+        $notRun :=  fn:sum(for $exeptedTS in $exceptedTestSets
+                                return
+                          for $testSetFile in $catalog//fots:test-set
+                          let $file := fn:data($testSetFile/@file),
+                              $testSet := util:doc($pathFOTSCatalog, $file)
+                          where (fn:data($testSet/fots:test-set/@name) = $exeptedTS)
+                          return fn:count($testSet//fots:test-case))
+    return
+    <brief  totalTests="{$totalNoTests}"
+            totalFailures="{$totalFailures}"
+            totalNotRun="{$notRun + $excepted}" />
+  }
+  { for $testSetFile in $catalog//fots:test-set
+    let $file := fn:data($testSetFile/@file),
+        $testSet := util:doc($pathFOTSCatalog, $file),
+        $testSetName := fn:data($testSet/fots:test-set/@name),
+        $totalNoTestCases := fn:count($testSet//fots:test-case),
+        $totalFailures := for $testCase in $failures//fots:test-set[@name = $testSetName]//fots:test-case[@result ="fail"]
+                          return $testCase,
+        $percent := fn:round((1 - (fn:count($totalFailures) div $totalNoTestCases))*100,2)
+    where ($percent ne 100)
+    return
+    <test-set name="{$testSetName}"
+              file="{$file}"
+              noFailures="{fn:count($totalFailures)}"
+              noTestCases="{$totalNoTestCases}"
+              percent="{$percent}"
+              failedTestNames="{fn:string-join( for $failure in $totalFailures
+                                                order by fn:data($failure/@name)
+                                                return fn:data($failure/@name)
+                                                ,",")}">
+   {if ($verbose) then $totalFailures else ()}
+    </test-set>
+   }
+   <exceptedTestCases>{$exceptedTestCases}</exceptedTestCases>
+   <exceptedTestSets>{$exceptedTestSets}</exceptedTestSets>
+   </report>
+};
\ No newline at end of file

=== added file 'test/fots_driver/util.xqy'
--- test/fots_driver/util.xqy	1970-01-01 00:00:00 +0000
+++ test/fots_driver/util.xqy	2012-11-05 21:58:22 +0000
@@ -0,0 +1,130 @@
+(:
+ : Copyright 2006-2011 The FLWOR Foundation.
+ :
+ : 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.
+ :)
+
+(:~
+ : Zorba FOTS driver util
+ : @author Sorin Nasoi
+ :)
+
+module namespace util = "http://www.zorba-xquery.com/zorba-fots-driver/util";;
+
+import schema namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";;
+
+import module namespace file  = "http://expath.org/ns/file";;
+
+import module namespace fots-err = "http://www.zorba-xquery.com/zorba-fots-driver/errors"; at "errors.xqy";
+
+declare namespace err = "http://www.w3.org/2005/xqt-errors";;
+declare namespace fots = "http://www.w3.org/2010/09/qt-fots-catalog";;
+
+declare namespace ann = "http://www.zorba-xquery.com/annotations";;
+
+
+(:~
+ : The serialization parameters for XML serialization.
+ :)
+ declare variable $util:serParamXml :=
+  <output:serialization-parameters>
+    <output:method                value="xml" />
+    <output:indent                value="no"  />
+    <output:omit-xml-declaration  value="yes" />
+  </output:serialization-parameters>;
+  
+(:  retrieves a document using a path and a suffix supplied as xs:strings 
+    and returns the corresponding document node :)
+declare %ann:nondeterministic function util:doc(
+  $path   as xs:string,
+  $suffix as xs:string
+) as document-node()? {
+  fn:parse-xml(
+    file:read-text(
+      file:resolve-path(
+        concat( $path, 
+                file:directory-separator(), 
+                $suffix
+        )
+      )
+    )
+  )
+};
+
+(:~
+ : Retrieve the value of from the given node that is either given as text node or in a file attribute.
+ :
+ : @param $case test-case element.
+ : @param $path the path of the test-set.
+ : @return the query text.
+ :)
+declare %ann:nondeterministic function util:get-value(
+  $case       as element(fots:test-case),
+  $path       as xs:string?,
+  $node-name  as xs:string
+) as xs:string {
+  try {
+    for $node in $case/descendant-or-self::*
+    where (fn:local-name-from-QName(fn:node-name($node)) = $node-name)
+    return
+      if(exists($node/@file))
+      then util:doc-as-text($path, data($node/@file))
+      else xs:string(fn:data($node))
+  } catch * {
+    fn:error($fots-err:errNA, $err:description)
+  }
+};
+
+(:~  Retrieves the path given 2 different components
+ :   example: fots:path('/home','user/file.ext') returns '/home/user'.
+ : @param $path Path.
+ : @param $suffix Suffix.
+ : @return the parent folder of the given file.
+ :)
+declare function util:path(
+  $path   as xs:string,
+  $suffix as xs:string
+) as xs:string {
+  concat($path, 
+         file:directory-separator(),
+         fn:substring-before($suffix,
+                             concat(file:directory-separator(),file:base-name($suffix)))
+        )
+};
+
+(:  retrieves a document using a path and a suffix supplied as xs:strings 
+    and returns the content as text :)
+declare %private %ann:nondeterministic function util:doc-as-text(
+  $path   as xs:string,
+  $suffix as xs:string
+) as xs:string {
+    file:read-text(
+      file:resolve-path(
+        concat( $path, 
+                file:directory-separator(), 
+                $suffix
+        )
+      )
+    )
+};
+
+declare function util:serialize-result(
+  $result    as item()*
+  ) as xs:string {
+  fn:string-join(for $res in $result
+                 return
+                  if($res instance of node())
+                  then fn:string-join(fn:serialize($result, $util:serParamXml), ' ')
+                  else fn:string($res)
+                 , ' ')
+};

=== added file 'test/fots_driver/zorba-fots-driver.xqy'
--- test/fots_driver/zorba-fots-driver.xqy	1970-01-01 00:00:00 +0000
+++ test/fots_driver/zorba-fots-driver.xqy	2012-11-05 21:58:22 +0000
@@ -0,0 +1,404 @@
+(:
+ : Copyright 2006-2011 The FLWOR Foundation.
+ :
+ : 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.
+ :)
+
+(:~
+ : Zorba FOTS driver
+ : @author Sorin Nasoi
+ :)
+
+module namespace driver = "http://www.zorba-xquery.com/zorba-fots-driver";;
+
+import module namespace file  = "http://expath.org/ns/file";;
+import module namespace functx = "http://www.functx.com/";;
+
+import module namespace xqxq  = "http://www.zorba-xquery.com/modules/xqxq";;
+import module namespace eval  = "http://www.zorba-xquery.com/zorba-fots-driver/evaluate"; at "evaluate.xqy";
+import module namespace env   = "http://www.zorba-xquery.com/zorba-fots-driver/environment"; at "environment.xqy";
+import module namespace util  = "http://www.zorba-xquery.com/zorba-fots-driver/util"; at "util.xqy";
+
+declare default element namespace "http://www.w3.org/2010/09/qt-fots-catalog";;
+
+declare namespace err = "http://www.w3.org/2005/xqt-errors";;
+declare namespace fots = "http://www.w3.org/2010/09/qt-fots-catalog";;
+
+declare namespace ann = "http://www.zorba-xquery.com/annotations";;
+
+(:~
+ : Loops through the FOTS catalog and returns all available test set names.
+ : @param $fotsPath path to the FOTS catalog file.
+ : @param $testSetPrefixes name/criteria for the test sets (empty string means all).
+ : @return available FOTS test sets.
+ :)
+declare %ann:nondeterministic function driver:list-test-sets(
+  $fotsPath         as xs:string,
+  $testSetPrefixes  as xs:string*
+) as xs:string* {
+  let $doc := util:doc($fotsPath, 'catalog.xml')
+  for $prefix in $testSetPrefixes
+    for $testSet in $doc//test-set[starts-with(@name, $prefix)]
+    return fn:data($testSet/@name)
+};
+
+(:~
+ : Loops through the given test sets and returns the corresponding test cases.
+ : @param $fotsPath path to the FOTS catalog file.
+ : @param $testSetPrefixes name/criteria for the test sets (empty string means all).
+ : @return available FOTS test cases.
+ :)
+declare %ann:nondeterministic function driver:list-test-cases(
+  $fotsPath         as xs:string,
+  $testSetPrefixes  as xs:string*
+) as xs:string* {
+  let $doc := util:doc($fotsPath, 'catalog.xml')
+  for $prefix in $testSetPrefixes
+    for $testSet in $doc//test-set[starts-with(@name, $prefix)]
+    let $file := fn:data($testSet/@file),
+        $testSet := util:doc($fotsPath, $file)
+    return fn:data($testSet//test-case/@name)
+};
+
+(:~
+ : Loops through the FOTS catalog and returns all test cases that match given pattern using given flags.
+ : @param $fotsPath path to the FOTS catalog file.
+ : @param $pattern pattern.
+ : @param $flags flags.
+ : @return available FOTS test cases matching given pattern and flags.
+ :)
+declare %ann:nondeterministic function driver:list-matching-test-cases(
+  $fotsPath as xs:string,
+  $pattern  as xs:string,
+  $flags    as xs:string?
+) as xs:string* {
+  let $catalog := util:doc($fotsPath, 'catalog.xml')
+  return
+  for $testSet in $catalog//test-set
+    let $file := fn:data($testSet/@file),
+        $testSet := util:doc($fotsPath, $file)
+      for $testCase in $testSet//test-case
+      where fn:matches(util:get-value($testCase, 
+                                      util:path($fotsPath, $file),
+                                      "test"),
+                        $pattern,
+                        $flags)
+      return
+        fn:concat("File: ",
+                  $fotsPath, file:directory-separator(), $file,
+                  ", test name:", fn:data($testCase/@name),"
+                  ")
+};
+
+(:~
+ : Loops through the FOTS catalog and evaluates all test cases.
+ : @param $path path to the FOTS catalog file.
+ : @return the failed test cases.
+ :)
+declare %ann:sequential function driver:run-fots(
+  $fotsPath as xs:string
+) as element(fots:test-case) {
+  driver:run-fots($fotsPath, '', '','','','', fn:false(), fn:false())
+};
+
+(:~
+ : Loops through the FOTS catalog and evaluates all test cases.
+ : @param $fotsPath path to the FOTS catalog file.
+ : @param $testSetPrefixes name/criteria for the test sets (empty string means all).
+ : @param $testCasePrefixes name/criteria for the test cases (empty string means all).
+ : @return the failed test cases.
+ :)
+declare %ann:sequential function driver:run-fots(
+  $fotsPath         as xs:string,
+  $testSetPrefixes  as xs:string*,
+  $testCasePrefixes as xs:string*
+) as element(fots:test-case) {
+  driver:run-fots($fotsPath,
+                driver:list-test-sets($fotsPath, ""),
+                '',
+                $testSetPrefixes,
+                $testCasePrefixes,
+                '',
+                fn:false(),
+                fn:false())
+};
+
+declare %private function driver:list-assertions(
+  $case as element(fots:test-case)
+) as xs:string* {
+  fn:distinct-values(for $assert in $case/result/descendant-or-self::*
+  return fn:local-name-from-QName(fn:node-name($assert)))
+};
+
+(:~
+ : Loops through the FOTS catalog and evaluates all test cases that have a certain assert-type.
+ : This is useful for testing the implementation of a certain assert type.
+ : @param $fotsPath path to the FOTS catalog file.
+ : @param $testSetPrefixes name/criteria for the test sets (empty string means all).
+ : @param $testCasePrefixes name/criteria for the test cases (empty string means all).
+ : @param $exceptedTestCases lists of test cases that should not be run(empty string means all tests will be run).
+ : @param $exceptedTestSets lists of test sets that should not be run(empty string means all tests will be run).
+ : @param $assert lists of tests that contain a certain assert-type(empty string means all tests will be run).
+ : @param $verbose if set to TRUE it will also output the actual failures.
+ : @param $showResult if set to TRUE it will also show the actual result of the Query run.
+ : @return an element containing all failed tests
+ :)
+declare %ann:sequential function driver:run-fots(
+  $fotsPath           as xs:string,
+  $testSetPrefixes    as xs:string*,
+  $testCasePrefixes   as xs:string*,
+  $exceptedTestCases  as xs:string*,
+  $exceptedTestSets   as xs:string*,
+  $assert             as xs:string*,
+  $verbose            as xs:boolean,
+  $showResult         as xs:boolean
+) as element(fots:test-cases) {
+  <test-cases>{
+    let $catalog := util:doc($fotsPath, 'catalog.xml'),
+        $catalogTestSets := $catalog//test-set/@name,
+        $testSets := if ($testSetPrefixes = '') then functx:value-except($catalogTestSets, $exceptedTestSets)
+                      else functx:value-except(functx:value-intersect($testSetPrefixes, $catalogTestSets), $exceptedTestSets)
+    for $testSetName in $testSets
+        let $file := fn:data($catalog//test-set[@name=$testSetName]/@file),
+            $testSetDoc := util:doc($fotsPath, $file),
+            $tsDependencies := env:dependencies-present($testSetDoc/test-set/dependency)
+    where $tsDependencies
+    return
+      <test-set name="{$testSetName}" file="{$file}">
+      {
+        for $testCase in $testSetDoc//test-case
+          let $envName := fn:data($testCase/environment/@ref),
+              $envTestSet := $testSetDoc/test-set//environment[@name = $envName],
+              $pathTestSet := util:path($fotsPath, $file),
+              $envCatalog := $catalog/catalog/fots:environment[@name = $envName],
+              $tcDependencies := env:dependencies-present($testCase/dependency),
+              $shouldRun  :=  if ($testCasePrefixes = '') then functx:value-except(xs:string(fn:data($testCase/@name)), $exceptedTestCases)
+                                  else functx:value-except(functx:value-intersect(fn:data($testCase/@name), $testCasePrefixes), $exceptedTestCases),
+              (:true if the tests-case has an assertion type that is requested :)
+              $hasReqAssert := (($assert = '') or
+                              fn:exists(functx:value-intersect(driver:list-assertions($testCase),$assert)))
+          where $shouldRun and $hasReqAssert and $tcDependencies
+          return
+        if(fn:empty($envTestSet))
+        then driver:test( $testCase,
+                        $envCatalog,
+                        $fotsPath,
+                        ($testSetDoc/test-set/dependency, $testCase/dependency),
+                        $testSetName,
+                        $pathTestSet,
+                        $verbose,
+                        $showResult)
+        else if (fn:exists($envTestSet))
+        then driver:test( $testCase,
+                        $envTestSet,
+                        $pathTestSet,
+                        ($testSetDoc/test-set/dependency, $testCase/dependency),
+                        $testSetName,
+                        $pathTestSet,
+                        $verbose,
+                        $showResult)
+        else ()
+      }</test-set>
+   }</test-cases>
+};
+
+(:~
+ : Creates the complete query that will be evaluated by adding the necessary XQXQ URL resolvers.
+ : @param $queryText the test-case/test after all the additional prolog statements were added.
+ : @param $case the test case.
+ : @param $env the environment.
+ : @param $pathEnv path to the environment.
+ : @param $pathTestSet path to the test set that defines the test case.
+ : @return the query that will be evaluated.
+ :)
+declare %private function driver:create-XQXQ-query(
+  $queryText    as xs:string,
+  $case         as element(fots:test-case),
+  $env          as element(fots:environment)?,
+  $pathEnv      as xs:string?,
+  $pathTestSet  as xs:string
+) as xs:string {
+  let $resolver as xs:string? := env:resolver($case, $env, $pathEnv, $pathTestSet)  return
+  string-join(( "import module namespace xqxq = 'http://www.zorba-xquery.com/modules/xqxq';",
+                if (exists($resolver)) then $resolver else (),
+                (concat("variable $queryID := xqxq:prepare-main-module('", "&#xA;", fn:replace($queryText,"'","''"), "'", "&#xA;",
+                if (exists($resolver)) 
+                then ", resolver:url-resolver#2, ());"
+                else ");")),
+                env:set-context-item($env, $pathEnv),
+                env:set-context-item($case/fots:environment, $pathTestSet),
+                env:set-variables($env, $pathEnv),
+                env:set-variables($case/environment, $pathTestSet),
+                "xqxq:evaluate($queryID)"
+               ),
+              "&#xA;")
+};
+
+(:~
+ : XQXQ invoke.
+ : @param $xqxqQueryText the query that will be run.
+ : @param $case the test case.
+ : @return the result of running the query with XQXQ.
+ :)
+declare %private %ann:sequential function driver:xqxq-invoke(
+  $xqxqQueryText  as xs:string,
+  $case           as element(fots:test-case),
+  $showResult     as xs:boolean?,
+  $pathTestSet    as xs:string
+) {
+  try {
+    {
+      variable $queryKey := xqxq:prepare-main-module($xqxqQueryText);
+      variable $queryResult := xqxq:evaluate-sequential($queryKey);
+      (:variable $expResult := util:get-value($case, $pathTestSet, "result");:) 
+      eval:result($queryResult,
+                  $case/fots:result/*,
+                  $showResult)
+    }
+  } catch * {
+    eval:error((),
+               $case/fots:result/*,
+               $err:code,
+               $err:description,
+               $showResult)
+  }
+};
+
+(:~
+ : Runs a single test case.
+ :
+ : @param $case test case.
+ : @param $env the environment.
+ : @param $pathEnv the relative path used to calculate the full path for the different children of the environment that have a "file" attribute.
+ : @param $deps the dependencies that should be checked for given test case.
+ : @param $testSetName the name of the test set.
+ : @param $pathTestSet the path to the test set.
+ : @param $verbose xs:boolean indicating if a result should be returned in case of success or not.
+ : @return the result of running the test case depending on $verbose.
+ :)
+declare %ann:sequential function driver:test(
+  $case         as element(fots:test-case),
+  $env          as element(fots:environment)?,
+  $pathEnv      as xs:string?,
+  $deps         as element(fots:dependency)*,
+  $testSetName  as xs:string?,
+  $pathTestSet  as xs:string,
+  $verbose      as xs:boolean,
+  $showResult   as xs:boolean?
+) as element(fots:test-case)? {
+(:TODO If the test expression includes the string "(:%VARDECL%:)" 
+  then the variable declaration should be added to replace this string; 
+  if it does not include this string, the variable declaration can be added at the start. 
+  For the moment the declarations are added at the start because there are no tests that use VARDECL:)
+  try {
+    {
+    variable $queryName := trace(fn:data($case/@name)," processing test case :"),
+(:
+  Prolog 	   ::=    	((DefaultNamespaceDecl | Setter | NamespaceDecl | Import) Separator)* ((ContextItemDecl | AnnotatedDecl | OptionDecl) Separator)*
+  Setter 	   ::=    	BoundarySpaceDecl | DefaultCollationDecl | BaseURIDecl | ConstructionDecl | OrderingModeDecl | EmptyOrderDecl | CopyNamespacesDecl | DecimalFormatDecl
+  Import 	   ::=    	SchemaImport | ModuleImport
+:)
+            $queryText as xs:string := fn:string-join(
+                                            (env:add-xquery-30(($deps, $case//dependency), fn:data($case/test)),
+                                             env:decl-def-elem-namespace($env, $case/environment),
+                                             env:decl-base-uri($env, $case/environment),
+                                             env:decl-namespaces($env, $case, $pathTestSet),
+                                             env:enable-HOF-feature($deps),
+                                             env:add-var-decl($env, $case, $pathEnv),
+                                             util:get-value($case, $pathTestSet, "test")
+                                             ),"&#xA;"),
+        $xqxqQueryText as xs:string := driver:create-XQXQ-query($queryText, $case, $env, $pathEnv, $pathTestSet),
+        (:Tests that need XML 1.1 are marked as failing:)
+        $result := if (fn:data($case/fots:dependency[@type="xml-version"]/@value) = "1.1") then
+                     <result>Zorba FOTS driver error: XML version 1.1 not supported.</result>
+                   else
+                     driver:xqxq-invoke($xqxqQueryText, $case, $showResult, $pathTestSet);
+  
+      if(fn:empty($result))
+      then if ($verbose) then driver:pass($case, $result, $xqxqQueryText, $env) else ()
+      else driver:fail($case, $result, $xqxqQueryText, $testSetName, $env)
+    }
+  } catch * {
+    driver:fail($case, <result>FOTS Driver:error catch line 318</result>, "", $testSetName, $env)
+  }
+};
+
+(:~
+ : Gives feedback on a test case run with success.
+ :
+ : @param $case test case.
+ : @return the test case after certain information was added.
+ :)
+declare  %private %ann:sequential function driver:pass(
+  $case         as element(fots:test-case),
+  $result       as item()*,
+  $zorbaQuery   as xs:string,
+  $env          as element(fots:environment)?
+) as element(fots:test-case)? {
+  let $tmp := $case
+  return {
+    insert node
+    attribute result{'pass'}
+    as last into $tmp;
+    
+    insert node
+      <info>
+        { $env }
+        <query>{ $zorbaQuery }</query>
+        {$result}
+      </info>
+    as last into $tmp;
+    
+    delete node $tmp/description;
+    delete node $tmp/created;
+    
+    $tmp
+  }
+};
+
+(:~
+ : Gives feedback on a test case run without success.
+ :
+ : @param $case test case.
+ : @return the test case after certain information was added.
+ :)
+declare %private %ann:sequential function driver:fail(
+  $case         as element(fots:test-case),
+  $result       as item()*,
+  $zorbaQuery   as xs:string,
+  $testSetName  as xs:string?,
+  $env          as element(fots:environment)?
+) as element(fots:test-case)? {
+  let $tmp := $case
+  return {
+    trace($testSetName, " test set name");
+    trace("above test case failed", " result");
+    
+    insert node
+    attribute result{'fail'}
+    as last into $tmp;
+    
+    insert node
+      <info>
+        { $env }
+        <query>{ $zorbaQuery }</query>
+        {$result}
+      </info>
+    as last into $tmp;
+    
+    delete node $tmp/description;
+    delete node $tmp/created;
+    
+    $tmp
+  }
+};


Follow ups