zorba-coders team mailing list archive
-
zorba-coders team
-
Mailing list archive
-
Message #08638
[Merge] lp:~zorba-coders/zorba/feature_fots into lp:zorba
Sorin Marian Nasoi has proposed merging lp:~zorba-coders/zorba/feature_fots into lp:zorba.
Requested reviews:
Zorba Coders (zorba-coders)
Related bugs:
Bug #918156 in Zorba: "fots driver for Zorba"
https://bugs.launchpad.net/zorba/+bug/918156
Bug #956460 in Zorba: "Zorba FOTS driver: assert-serialization bug"
https://bugs.launchpad.net/zorba/+bug/956460
Bug #967173 in Zorba: "Zorba FOTS driver: assert-any-of bug"
https://bugs.launchpad.net/zorba/+bug/967173
Bug #973410 in Zorba: "Zorba FOTS driver: assert-deep-eq bug"
https://bugs.launchpad.net/zorba/+bug/973410
Bug #973412 in Zorba: "Zorba FOTS driver: assert-permutation bug"
https://bugs.launchpad.net/zorba/+bug/973412
Bug #973416 in Zorba: "Zorba FOTS driver: assert-assert bug"
https://bugs.launchpad.net/zorba/+bug/973416
Bug #973417 in Zorba: "Zorba FOTS driver: assert-serialization-error bug"
https://bugs.launchpad.net/zorba/+bug/973417
Bug #973434 in Zorba: "Zorba FOTS driver: assert-error bug"
https://bugs.launchpad.net/zorba/+bug/973434
For more details, see:
https://code.launchpad.net/~zorba-coders/zorba/feature_fots/+merge/103494
Added the Zorba FOTS Driver.
--
https://code.launchpad.net/~zorba-coders/zorba/feature_fots/+merge/103494
Your team Zorba Coders is requested to review the proposed merge of lp:~zorba-coders/zorba/feature_fots 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-04-25 14:58:22 +0000
@@ -0,0 +1,23 @@
+In order to use the FOTS driver for Zorba, one should 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
+
+2) Check out the examples in the ZORBA_FOLDER/test/fots_driver/fots.xq for:
+ - listing the available test sets in the FOTS (see function fots:list-test-sets)
+ - running all test cases in the test sets (see fots:run-fots functions)
+ - running a single test set if you are a module developer (see fots:run-test-set function)
+ - running a single test case (see fots:test function)
+
+3) run
+ ./zorba -f
+ -q ../../test/fots_driver/fots.xq
+ -e fotsPath:="/home/spungi/work/zorba/w3c_repo/2011/QT3-test-suite"
+ -o failures.xml
+ --indent
=== added file 'test/fots_driver/fots-check.xqy'
--- test/fots_driver/fots-check.xqy 1970-01-01 00:00:00 +0000
+++ test/fots_driver/fots-check.xqy 2012-04-25 14:58:22 +0000
@@ -0,0 +1,332 @@
+xquery version "3.0";
+
+module namespace check = "http://www.w3.org/2010/09/qt-fots-catalog/check";
+declare namespace err="http://www.w3.org/2005/xqt-errors";
+
+import module namespace xqxq = "http://www.zorba-xquery.com/modules/xqxq";
+import module namespace schema = "http://www.zorba-xquery.com/modules/schema";
+import schema namespace output = "http://www.w3.org/2010/xslt-xquery-serialization";
+
+import module namespace ser = "http://www.w3.org/2010/09/qt-fots-catalog/serialize" at "serialize.xqy";
+
+declare namespace ann = "http://www.zorba-xquery.com/annotations";
+declare namespace features = "http://www.zorba-xquery.com/options/features";
+declare option features:enable "hof";
+
+(:~
+ : Errors namespace URI.
+:)
+declare variable $check:errNS as xs:string := "http://www.w3.org/2010/09/qt-fots-catalog/check";
+
+(:~
+ : xs:QName with namespace URI="http://www.w3.org/2010/09/qt-fots-catalog/check" and local name "check:errNA"
+:)
+declare variable $check:errNA as xs:QName := fn:QName($check:errNS, "check:errNA");
+
+declare %private function check:is-value-in-sequence
+ ( $value as xs:anyAtomicType?,
+ $seq as xs:anyAtomicType*) as xs:boolean {
+ $value = $seq
+ } ;
+
+(:~
+ : The serialization parameters for XML serialization.
+ :)
+declare %private variable $check:serParamXml :=
+ <output:serialization-parameters>
+ <output:method value="xml" />
+ <output:indent value="no" />
+ <output:omit-xml-declaration value="yes" />
+ </output:serialization-parameters>;
+
+declare %private %ann:sequential function check:res(
+ $result as item()*,
+ $expResult as element()
+) as xs:string* {
+ let $test := local-name($expResult)
+ return switch($test)
+ case 'all-of'
+ return
+ for $tmp in $expResult/*
+ return check:res($result, $tmp)
+ case 'any-of'
+ return
+ let $results := for $tmp in $expResult/*
+ return empty(check:res($result, $tmp))
+ return
+ if (check:is-value-in-sequence(fn:true(), (for $result in $results return $result)))
+ then ()
+ else concat("'any-of' assertion returned: ",
+ string-join(for $result in $results return fn:string($result),', '))
+ case 'assert'
+ return check:assert($result, $expResult)
+ case 'assert-count'
+ return
+ let $count := count($result),
+ $exp := xs:integer($expResult)
+ return if($count eq $exp) then ()
+ else concat('Expected ', $exp, ' items, found ', $count, '.')
+ case 'assert-deep-eq'
+ return check:assert-deep-eq($result, $expResult)
+ case 'assert-empty'
+ return if(empty($result)) then () else 'Result is not empty.'
+ case 'assert-eq'
+ return check:assert-eq($result, $expResult)
+ case 'assert-false'
+ return check:assert-bool($result, $expResult, fn:false())
+ case 'assert-permutation'
+ return check:assert-permutation($result, $expResult)
+ case 'assert-serialization'
+ return check:assert-serialization($result, $expResult)
+ case 'assert-serialization-error'
+ return check:assert-serialization-error($result, $expResult)
+ case 'assert-string-value'
+ return check:assert-string-value($result, $expResult)
+ case 'assert-true'
+ return check:assert-bool($result, $expResult, fn:true())
+ case 'assert-type'
+ return check:assert-type($result, $expResult)
+ case 'error'
+ return concat('Expected Error [', $result/@code, ']')
+ default return error(
+ fn:QName('http://www.w3.org/2005/xqt-errors', 'FOTS9999'),
+ concat('Unknown assertion: "', $test, '"'))
+};
+
+(: http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_any-of :)
+declare function check:any-of(
+ $res as item()*,
+ $result as element()
+) as xs:string* {
+ fn:error($check:errNA, "Assertion type 'any-of' not implemented")
+};
+
+(: http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_assert :)
+declare %ann:sequential function check:assert(
+ $result as item()*,
+ $expResult as element()
+) as xs:string* {
+ try {
+ let $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(trace($queryText,"assert")),
+ $queryKeyResult := xqxq:bind-variable($queryKey, xs:QName('result'), $result),
+ $queryResult := xqxq:evaluate($queryKey)
+ return if($queryResult) then ()
+ else concat('Assertion ''', $expResult, ''' failed.')
+ } catch * {
+ concat('Assertion ''',
+ $expResult,
+ ''' failed with: [',
+ $err:code,
+ '] ',
+ $err:description)
+ }
+};
+
+(: http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_assert-deep-eq :)
+declare %ann:sequential function check:assert-deep-eq(
+ $result as item()*,
+ $expResult as element()
+) as xs:string* {
+ try {
+ let $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)
+ return if($queryResult) then ()
+ else concat('Result is not deep-equal to ''', $expResult, '''.')
+ } catch * {
+ concat('Deep comparison to ''', $expResult, ''' failed with: [',
+ $err:code, '] ', $err:description)
+ }
+};
+
+(: http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_assert-eq :)
+declare %ann:sequential function check:assert-eq(
+ $result as item()*,
+ $expResult as element()
+) as xs:string* {
+ try {
+ let $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;",
+ "declare function local:f($y) as xs:boolean {$x eq xs:string(fn:data($y))};",
+ "let $f := local:f#1 return $f(", $expResult, ")"),
+ $queryKey := xqxq:prepare-main-module(trace($queryText,"assert-eq")),
+ $queryKeyResult := xqxq:bind-variable($queryKey, xs:QName('x'), $result),
+ $queryResult := xqxq:evaluate($queryKey)
+ return
+ if($queryResult) then ()
+ else concat('Result doesn''t match expected item ''', xs:string($expResult), '''.')
+ } catch * {
+ concat('Comparison to ''', $expResult/text(), ''' failed with: [',
+ $err:code, '] ', $err:description)
+ }
+};
+
+declare function check:assert-bool(
+ $res as item()*,
+ $result as element(),
+ $exp as xs:boolean
+) {
+ if($res instance of xs:boolean and $res eq $exp) then ()
+ else fn:concat('Query doesn''t evaluate to ''', $exp, '''')
+};
+
+declare %ann:sequential function check:assert-permutation(
+ $result as item()*,
+ $expResult as element()
+) {
+ try {
+ let $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) = count(union) then the sequences are identical :)
+ "(count(distinct-values($x[ . = $y])) = count(fn:distinct-values(($x, $y))))"),
+ $queryKey := xqxq:prepare-main-module($queryText),
+ $queryKeyResult := xqxq:bind-variable($queryKey, xs:QName('x'), $result),
+ $queryResult := xqxq:evaluate($queryKey)
+ return if($queryResult) then ()
+ else concat('Result isn''t a permutation of ''', $expResult, '''.')
+ } catch * {
+ concat('Unordered comparison to ''', $expResult, ''' failed with: [',
+ $err:code, '] ', $err:description)
+ }
+};
+
+(: http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_assert-serialization :)
+declare function check:assert-serialization(
+ $result as item()*,
+ $expResult as element()
+) {
+ try {
+ let $cmpRes as xs:string := if($result instance of node())
+ then fn:string-join(fn:serialize($result,
+ $check:serParamXml)
+ , ' ')
+ else fn:string($result)
+ return
+ if($cmpRes eq string($expResult))
+ then ()
+ else fn:concat('Serialized result ''', $cmpRes, ''' not equal to ''', $expResult, '''.')
+ } catch * {
+ concat('Serialized comparison to ''', $expResult, ''' failed with: [',
+ $err:code, '] ', $err:description)
+ }
+};
+
+(: http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_assert-serialization-error :)
+declare function check:assert-serialization-error(
+ $result as item()*,
+ $expResult as element()
+) {
+ try {
+ let $cmpRes as xs:string := if($result instance of node())
+ then fn:string-join(fn:serialize($result,
+ $check:serParamXml)
+ , ' ')
+ else fn:string($result)
+ return
+ fn:concat('Expected serialization error but got result ''', $cmpRes, '''.')
+ } catch * {
+ check:error($err:code,
+ $err:description,
+ $expResult)
+ }
+};
+
+(: http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_assert-string-value :)
+declare function check:assert-string-value(
+ $res as item()*,
+ $result as element()
+) as xs:string* {
+ try {
+ let $str := fn:string-join(for $r in $res return xs:string($r), " "),
+ $exp := xs:string($result)
+ return if($str eq $exp) then ()
+ else fn:concat('Expected ''', $exp, ''', found ''', $str, '''.')
+ } catch * {
+ fn:concat('String eq comparison to ', $result, ' failed with: [',
+ $err:code, '] ', $err:description)
+ }
+};
+
+(: http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_assert-type :)
+declare function check:assert-type(
+ $result as item()*,
+ $expResult as element()
+) as xs:string* {
+ try {
+ let $typeResult := xs:string(schema:schema-type($result[1])),
+ $type := xs:string($expResult)
+ return if($type eq $typeResult) then ()
+ else concat('Result doesn''t have type ''', $type, '''.')
+ } catch * {
+ concat('Type check for ''', $result,
+ ''' failed with: [', $err:code, '] ', $err:description)
+ }
+};
+
+declare %ann:sequential function check:result(
+ $result as item()*,
+ $expResult as element()
+) as element()? {
+ let $err := check:res($result, $expResult)
+ return if(empty($err)) then () else
+ <out>
+ <result>{ser:serialize($result)}
+ </result>
+ <errors>{ser:serialize($err)}
+ </errors>
+ </out>
+};
+
+declare function check:error(
+ $code as xs:QName,
+ $error as xs:string,
+ $result as element()
+) as element()? {
+ let $err := check:err($code, $error, $result)
+ return if(empty($err)) then () else
+ <out>
+ <result>Error: {concat('[', $code, '] ', $error)}</result>
+ <errors>{$err}</errors>
+ </out>
+};
+
+declare %private function check:err(
+ $code as xs:QName,
+ $err as xs:string,
+ $result as element()
+) as xs:string* {
+ let $errors := $result/descendant-or-self::*:error
+ return
+ if(exists($errors[@code = "*"]))
+ then ()
+ else
+ if(fn:namespace-uri-from-QName($code) = 'http://www.w3.org/2005/xqt-errors' and
+ exists($errors[@code = fn:local-name-from-QName($code)]))
+ then ()
+ else if(exists($errors)) then (
+ concat('Wrong error code [', $code, '] (', $err, '), expected: [',
+ string-join($errors//@code, '], ['), ']')
+ ) else (
+ concat('Expected result, found error: [', $code, '] ', $err)
+ )
+};
\ No newline at end of file
=== added file 'test/fots_driver/fots-environment.xqy'
--- test/fots_driver/fots-environment.xqy 1970-01-01 00:00:00 +0000
+++ test/fots_driver/fots-environment.xqy 2012-04-25 14:58:22 +0000
@@ -0,0 +1,109 @@
+xquery version "3.0";
+
+module namespace env = "http://www.w3.org/2010/09/qt-fots-catalog/environment";
+
+declare namespace ann = "http://www.zorba-xquery.com/annotations";
+import module namespace xqxq = "http://www.zorba-xquery.com/modules/xqxq";
+
+import module namespace file = "http://expath.org/ns/file";
+
+declare function env:var-decl-with-value(
+ $env,
+ $envCase
+) as xs:string? {
+ fn:string-join(
+ for $param in ($env/*:param, $envCase/*:param)
+ where fn:exists($param[@declared="false"])
+ return concat("declare variable $",
+ fn:data($param/@name),
+ " external := ",
+ fn:data($param/@select),";")
+ ," ")
+};
+
+declare function env:var-decl-without-value(
+ $env,
+ $envCase,
+ $path as xs:string?
+) as xs:string? {
+ fn:string-join(
+ for $param in ($env/*:param, $envCase/*:param)
+ where fn:not(fn:exists($param[@declared="false"]))
+ return concat("declare variable $",
+ fn:data($param/@name),
+ " external;")
+ ," ")
+};
+
+(:~
+ : binds the variables that were added with attribute declared="true".
+ :
+ : @param $queryKey the query key.
+ : @param $env the environment of the catalog or the test-set (given with 'ref').
+ : @param $envCase the environment of the test-case.
+ : @return the queryKey after the variables were bound.
+ :)
+declare %ann:sequential function env:set-variables(
+ $queryKey as xs:anyURI,
+ $env,
+ $envCase,
+ $relativePath as xs:string?
+) {
+ variable $select := for $param in ($env/*:param, $envCase/*:param)
+ where fn:not(fn:exists($param[@declared="false"]))
+ return fn:translate(fn:data($param/@select), "'", ""),
+ $name := for $param in ($env/*:param, $envCase/*:param)
+ where fn:not(fn:exists($param[@declared="false"]))
+ return fn:data($param/@name),
+ $suffix := for $source in ($env/*:source, $envCase/*:source)
+ where $source[@file = $select]
+ return data($source/@uri),
+
+ $doc := concat($relativePath,
+ file:directory-separator(),
+ $suffix);
+ if(fn:exists($name)) then
+ xqxq:bind-variable( $queryKey,
+ fn:QName("", $name),
+ $doc);
+ else ();
+};
+
+(:~
+ : Adds the necessary declare namespace statements.
+ :
+ : @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 namespace statements.
+ :)
+declare function env:decl-namespaces(
+ $env,
+ $envCase
+) as xs:string? {
+ string-join(for $ns in ($env/*:namespace, $envCase/*:namespace)
+ where fn:not($ns[@prefix=""])
+ 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,
+ $envCase
+) as xs:string? {
+ for $ns in ($env/*:namespace, $envCase/*:namespace)
+ where $ns[@prefix=""]
+ return concat('declare default element namespace "',
+ fn:data($ns/@uri),
+ '";')
+};
\ No newline at end of file
=== added file 'test/fots_driver/fots-reporting.xqy'
--- test/fots_driver/fots-reporting.xqy 1970-01-01 00:00:00 +0000
+++ test/fots_driver/fots-reporting.xqy 2012-04-25 14:58:22 +0000
@@ -0,0 +1,102 @@
+xquery version "3.0";
+
+module namespace reporting = "http://www.w3.org/2010/09/qt-fots-catalog/reporting";
+
+import module namespace file = "http://expath.org/ns/file";
+import module namespace fots = "http://www.w3.org/2010/09/qt-fots-catalog" at 'fots.xqy';
+
+declare namespace err ="http://www.w3.org/2005/xqt-errors";
+declare namespace ann = "http://www.zorba-xquery.com/annotations";
+
+declare default element namespace "http://www.w3.org/2010/09/qt-fots-catalog";
+
+(:~
+ : Loops through the test-sets, runs then and creates statistics.
+ : @param $pathFOTSCatalog path to the FOTS catalog file.
+ : @param $except lists of tests that should not be 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:sequential function reporting:run-and-report(
+ $pathFOTSCatalog as xs:string,
+ $except as xs:string*,
+ $verbose as xs:boolean
+) {
+ variable $failures := fots:run-fots($pathFOTSCatalog,
+ fots:list-test-sets($pathFOTSCatalog, ""),
+ "",
+ $except);
+
+ reporting:do-reporting($pathFOTSCatalog, $failures, $except, $verbose)
+};
+
+(:~
+ : Loops through the test-sets, reads the report of the failures and creates statistics.
+ : @param $pathFOTSCatalog path to the FOTS catalog file.
+ : @param $pathFailures path to the FOTS failures.
+ : @param $except lists of tests that should not be 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:report(
+ $pathFOTSCatalog as xs:string,
+ $pathFailures as xs:string,
+ $except as xs:string*,
+ $verbose as xs:boolean
+) {
+ if(not(file:is-file($pathFailures))) then
+ {
+ fn:error("The file failures file was not found. Suggestion: use fots:run-fots to generate it or use reporting:run-and-report function.")
+ }
+ else
+ try
+ {
+ let $failures := fn:parse-xml(file:read-text($pathFailures))
+ return
+ reporting:do-reporting($pathFOTSCatalog, $failures, $except, $verbose)
+ }
+ catch *
+ {
+ fn:error(fn:concat( "The file <",
+ $pathFailures,
+ "> does not have the correct structure."))
+ }
+};
+
+
+(:~
+ : 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 $except lists of tests that are not run.
+ : @param $verbose is set to TRUE it will also output the actual failures.
+ : @return a report of tests run.
+ :)
+declare %ann:nondeterministic %private function reporting:do-reporting(
+ $pathFOTSCatalog as xs:string,
+ $failures,
+ $except,
+ $verbose as xs:boolean
+) {
+ <report>{
+ let $catalog := fots:doc($pathFOTSCatalog, 'catalog.xml')
+ return
+ for $testSetFile in $catalog//test-set
+ let $file := fn:data($testSetFile/@file),
+ $testSet := fots:doc($pathFOTSCatalog, $file),
+ $testSetName := fn:data($testSet/test-set/@name),
+ $totalNoTestCases := fn:count($testSet//test-case),
+ $totalFailures := for $testCase in $failures//test-case
+ where $testCase/test-set[@name = $testSetName]
+ return $testCase
+ (:where $testSetName = "fn-format-dateTime":)
+ return
+ <test-set name="{$testSetName}"
+ noTestsCases="{$totalNoTestCases}"
+ noFailures="{fn:count($totalFailures)}">
+ {if ($verbose) then $totalFailures else ()}
+ </test-set>
+ }
+ <except>{$except}</except>
+ </report>
+};
\ No newline at end of file
=== added file 'test/fots_driver/fots.xq'
--- test/fots_driver/fots.xq 1970-01-01 00:00:00 +0000
+++ test/fots_driver/fots.xq 2012-04-25 14:58:22 +0000
@@ -0,0 +1,94 @@
+xquery version "3.0";
+
+import module namespace fots = "http://www.w3.org/2010/09/qt-fots-catalog"
+ at 'fots.xqy';
+import module namespace reporting = "http://www.w3.org/2010/09/qt-fots-catalog/reporting"
+ at 'fots-reporting.xqy';
+
+declare default element namespace "http://www.w3.org/2010/09/qt-fots-catalog";
+declare variable $fotsPath as xs:string external;
+
+(:~ The test in this list have bugs assigned already and should not be run :)
+variable $tests := (
+"context-item-1" (:see bug #867199:)
+,"xqhof7", "xqhof13", "xqhof14" (:see bug #947051:)
+,"FunctionCall-020" (:see bug #947064:)
+,"group-005" (:see bug #947079:)
+,"generate-id-901", "generate-id-902" (:see bug #947130:)
+,"try-catch-function-call-3", "try-catch-function-call-4" (:see bug #:)
+);
+
+(: example for running a single test case :)
+(:
+fots:test(
+ <test-case name="fn-absint1args-1">
+ <description>Test: absint1args-1 The "abs" function with the arguments set as follows: $arg = xs:int(lower bound) </description>
+ <created by="Carmelo Montanez" on="2004-12-13"/>
+ <environment ref="empty"/>
+ <test>fn:abs(xs:int("-2147483648"))</test>
+ <result>
+ <all-of>
+ <assert-eq>2147483648</assert-eq>
+ <assert-type>xs:integer</assert-type>
+ </all-of>
+ </result>
+ </test-case>
+ )
+:)
+
+(: example for list-matching-test-cases function :)
+(:
+fots:list-matching-test-cases("/home/spungi/work/zorba/w3c_repo/2011/QT3-test-suite",
+ "!",
+ "")
+:)
+
+(: List all available test-sets in the FOTS
+ app, fn, map, math, misc, op, prod, xs :)
+(:
+ fots:list-test-sets(
+ $fotsPath,
+ ""
+ )
+:)
+
+(: example for running a single test set from the FOTS:)
+(:
+ fots:run-fots($fotsPath,
+ 'fn-abs', (: the test-sets :)
+ 'K2-ABSFunc-35', (: the test-cases :)
+ ())
+:)
+
+(: example for running a test set for an external module :)
+(:
+fots:run-test-set('/home/spungi/Downloads/has-children.xml',
+ 'fn-has-children-001'
+ )
+:)
+
+(: example for running the FOTS testsuite :)
+(:
+ fots:run-fots($fotsPath,
+ fots:list-test-sets($fotsPath, ""),
+ '',
+ $tests
+ )
+:)
+
+(: example for running the FOTS testsuite and reporting statistics :)
+
+ reporting:run-and-report( $fotsPath,
+ $tests,
+ fn:false()
+ )
+
+
+(: example for loading a failures file and reporting statistics :)
+(:
+ reporting:report( $fotsPath,
+ "/home/spungi/work/zorba/repo/feature_fots/build_release/bin/failures.xml",
+ $tests,
+ fn:false()
+ )
+:)
\ No newline at end of file
=== added file 'test/fots_driver/fots.xqy'
--- test/fots_driver/fots.xqy 1970-01-01 00:00:00 +0000
+++ test/fots_driver/fots.xqy 2012-04-25 14:58:22 +0000
@@ -0,0 +1,383 @@
+xquery version "3.0";
+
+(: global namespace of the test suite. :)
+module namespace fots = "http://www.w3.org/2010/09/qt-fots-catalog";
+
+declare default element namespace "http://www.w3.org/2010/09/qt-fots-catalog";
+
+declare namespace ann = "http://www.zorba-xquery.com/annotations";
+import module namespace xqxq = "http://www.zorba-xquery.com/modules/xqxq";
+
+declare namespace err = "http://www.w3.org/2005/xqt-errors";
+import module namespace file = "http://expath.org/ns/file";
+
+import module namespace functx = "http://www.functx.com/";
+
+import module namespace check = "http://www.w3.org/2010/09/qt-fots-catalog/check"
+ at "fots-check.xqy";
+
+import module namespace env = "http://www.w3.org/2010/09/qt-fots-catalog/environment"
+ at "fots-environment.xqy";
+
+(:~
+ : Loops through the FOTS catalog and returns all available test set names.
+ : @param $path path to the FOTS catalog file.
+ : @return available fots test-cases element names.
+ :)
+declare %ann:nondeterministic function fots:list-test-sets(
+ $path as xs:string,
+ $catalogs as xs:string*
+) as xs:string* {
+ let $doc := fots:doc($path, 'catalog.xml'),
+ $env := $doc//environment
+ return
+ for $catalog in $catalogs
+ for $testSet in $doc//test-set[starts-with(@name, $catalog)]
+ return
+ fn:data($testSet/@name)
+};
+
+(:~
+ : Loops through the FOTS catalog and returns all test cases that match given pattern using given flags.
+ : @param $path 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 fots:list-matching-test-cases(
+ $path as xs:string,
+ $pattern as xs:string,
+ $flags as xs:string?
+) as xs:string* {
+ let $catalog := fots:doc($path, 'catalog.xml')
+ return
+ for $testSet in $catalog//test-set
+ let $file := fn:data($testSet/@file),
+ $testSet := fots:doc($path, $file)
+ for $testCase in $testSet//test-case
+ where fn:matches(fn:data($testCase/*:test), $pattern, $flags)
+ return
+ fn:concat("File: ", $path, file:directory-separator(), $file,
+ ", test name:", fn:data($testCase/@name),"
+")
+};
+
+(:~
+ : Loops throgh the test set and evaluates all test cases.
+ : @param $path path to the FOTS catalog file.
+ : @return an element containing all failed tests
+ :)
+declare %ann:sequential function fots:run-fots(
+ $path as xs:string
+) as element(fots:failures) {
+ fots:run-fots($path, '', '','')
+};
+
+(:~
+ : Loops throgh the test set and evaluates all test cases.
+ : @param $fotsPath path to the FOTS catalog file.
+ : @param $except lists of tests that should not be run(empty string means all tests will be run).
+ : @return an element containing all failed tests
+ :)
+declare %ann:sequential function fots:run-fots(
+ $fotsPath as xs:string,
+ $except as xs:string*
+) as element(fots:failures) {
+ fots:run-fots($fotsPath,
+ fots:list-test-sets($fotsPath, ""),
+ '',
+ $except)
+};
+
+(:~
+ : Loops through the test sets and evaluates all test cases.
+ : @param $path path to the FOTS catalog file.
+ : @param $category name the catalog to use (empty string means all).
+ : @param $prefix prefix of test-cases to use (empty string means all).
+ : @param $except lists of tests that should not be run(empty string means all tests will be run).
+ : @return an element containing all failed tests
+ :)
+declare %ann:sequential function fots:run-fots(
+ $path as xs:string,
+ $categories as xs:string*,
+ $prefixes as xs:string*,
+ $except as xs:string*
+) as element(fots:failures) {
+ <failures>{
+ let $catalog := fots:doc($path, 'catalog.xml')
+ for $category in $categories
+ for $testSet in $catalog//test-set
+ let $file := fn:data($testSet/@file),
+ $testSetDoc := fots:doc($path, $file),
+ $testSetName := fn:data($testSet/@name)
+ where $testSetName = $category
+ for $testCase in $testSetDoc//test-case
+ let $envName := fn:data($testCase/environment/@ref),
+ $envTestSet := $testSetDoc/test-set//environment[@name = $envName],
+ $pathTestSet := fots:path($path, $file),
+ $envCatalog := $catalog/catalog//environment[@name = $envName],
+ $pathCatalog := $path,
+ $dep := ($testSetDoc/test-set/dependency, $testCase/dependency),
+ $runQuery := fots:check-should-run-test($dep),
+ $shouldRun := (($prefixes eq xs:string('')) or fn:exists(functx:value-intersect($prefixes,xs:string(fn:data($testCase/@name))))),
+ $isExcepted := fn:exists(functx:value-intersect($except, xs:string(fn:data($testCase/@name))))
+ where $shouldRun and fn:not($isExcepted)
+ order by fn:data($testCase/@name)
+ return
+ if(fn:empty($envTestSet)
+ and $runQuery
+ and fn:not($isExcepted))
+ then fots:test( $testCase,
+ $envCatalog,
+ $path,
+ $dep,
+ $testSetName)
+ else if (fn:exists($envTestSet)
+ and $runQuery
+ and fn:not($isExcepted))
+ then fots:test( $testCase,
+ $envTestSet,
+ $pathTestSet,
+ $dep,
+ $testSetName)
+ else ()
+
+ }</failures>
+};
+
+(:~
+ : Loops through the test set and evaluates all test cases.
+ : @param $path path to the test set file.
+ : @param $prefix prefix of test-cases to use (empty string means all).
+ : @return an element containing all failed tests
+ :)
+declare %ann:sequential function fots:run-test-set(
+ $path as xs:string,
+ $prefixes as xs:string*
+) as element(fots:failures) {
+ <failures>{
+ let $testSet := fots:doc($path, '')/test-set
+ for $prefix in $prefixes
+ for $testCase in $testSet//test-case[starts-with(@name, $prefix)]
+ let $envName := fn:data($testCase/environment/@ref),
+ $env := if(empty($envName)) then ()
+ else fots:get-environment((), $testSet, $envName),
+ $testSetDep := $testSet/dependency,
+ $testSetName := fn:data($testSet/@name)
+ return fots:test( $testCase,
+ $env,
+ "",
+ $testSetDep,
+ $testSetName)
+ }</failures>
+};
+
+
+(:~
+ : Helper function: Runs a single test.
+ :
+ : @param $case test-case element
+ : @return empty sequence on success, the failed
+ : test-case element with additional information otherwise
+ :)
+declare %ann:sequential function fots:test(
+ $case as element(fots:test-case)
+) as element(fots:test-case)? {
+ fots:test($case, (), (), (), ())
+};
+
+declare %private %ann:sequential function fots:xqxq-invoke(
+ $queryText as xs:string,
+ $case as element(fots:test-case),
+ $env as element(fots:environment)?,
+ $path as xs:string?)
+{
+ try {
+ let $queryKey := xqxq:prepare-main-module($queryText),
+ $queryKeyResult := fots:set-environment($queryKey, $env, $path),
+ $queryKeyResult1 := env:set-variables($queryKey, $env, $case/environment, $path),
+ $queryResult := xqxq:evaluate($queryKey)
+ return check:result($queryResult, $case/*:result/*)
+ } catch * {
+ check:error($err:code,
+ $err:description,
+ $case/*:result/*)
+ }
+};
+
+(:~
+ : Runs a single test.
+ :
+ : @param $case test-case element
+ : @param $env the environment
+ : @param $path the relative path used to calculate the full path for the
+ : different children of the environment that have a "file" attribute
+ : @param $testSetName the name of the test-set
+ : @return empty sequence on success, the failed
+ : test-case element with additional information otherwise
+ :)
+declare %ann:sequential function fots:test(
+ $case as element(fots:test-case),
+ $env as element(fots:environment)?,
+ $path as xs:string?,
+ $deps as element(fots:dependency)*,
+ $testSetName as xs:string?
+) as element(fots:test-case)? {
+ let $queryName := trace(fn:data($case/@name),"test-case-name:"),
+ $queryText as xs:string := fn:string-join(
+ (fots:add-xquery-30(($deps, $case//dependency)),
+ fots:add-var-decl($env, $case, $path),
+ env:decl-def-elem-namespace($env, $case/environment),
+ env:decl-namespaces($env, $case/environment),
+ fots:enable-HOF-feature(($deps, $case//dependency)),
+ xs:string(fn:data($case/*:test))
+ )," "),
+ $result := fots:xqxq-invoke($queryText, $case, $env, $path)
+ return if(fn:empty($result)) then ()
+ else fots:wrong($case, $result, $queryText, $testSetName)
+};
+
+(: gives feedback on an erroneous query :)
+declare %private %ann:sequential function fots:wrong(
+ $test as element(fots:test-case),
+ $result as item()*,
+ $zorbaQuery as xs:string,
+ $testSetName as xs:string?
+) as element(fots:test-case)? {
+ let $tmp := $test
+ return {
+ insert node
+ <wrong>
+ <query>
+ { $zorbaQuery }
+ </query>
+ {$result}
+ </wrong>
+ as last into $tmp;
+
+ insert node
+ <test-set name="{$testSetName}" />
+ as first into $tmp;
+
+ delete node $tmp/description;
+
+ delete nodes $tmp/descendant::comment();
+
+ $tmp
+ }
+};
+
+(: retrieves a document using a path and a suffix supplied as xs:strings
+ and returns the correponding document node :)
+declare %ann:nondeterministic function fots: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
+ )
+ )
+ )
+ )
+};
+
+(: retrieves the path given 2 different components
+ example: fots:path('/home','user/file.ext') returns '/home/user' :)
+declare %private function fots: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 the environment node from a test-set or catalog given a environment name :)
+declare %private function fots:get-environment (
+ $catalog,
+ $set,
+ $envName as xs:string
+) as element(fots:environment)? {
+ let $envTestSet := $set/test-set//environment[@name = $envName]
+ return
+ if (fn:empty($envTestSet))
+ then $catalog/catalog//environment[@name = $envName]
+ else $envTestSet
+};
+
+(: applies the given environment to the $query-key :)
+declare %private %ann:sequential function fots:set-environment(
+ $queryKey as xs:anyURI,
+ $env as element(fots:environment)?,
+ $relativePath as xs:string?
+) {
+ try {
+ if(data($env/@name) = 'empty')
+ then $queryKey
+ else
+ {
+ (: Set context item if this exists :)
+ if (fn:exists($env/*:source[@role = "."])) then
+ {
+ variable $xml := fots:doc($relativePath, fn:data($env/*:source/@file));
+ xqxq:bind-context-item($queryKey, $xml);
+ }
+ else ();
+ }
+ }
+ catch * {
+ fn:error("fots:set-environment")
+ }
+};
+
+(: see http://dev.w3.org/cvsweb/~checkout~/2011/QT3-test-suite/catalog-schema.html?rev=1.1;content-type=text%2Fhtml#elem_dependency :)
+declare %private function fots:check-should-run-test(
+ $deps as element(fots:dependency)*
+) as xs:boolean {
+ let $values := for $dep in $deps return fn:exists($dep[@satisfied="false"])
+ return
+ switch(fn:count(fn:distinct-values($values)))
+ case xs:integer(2) return fn:false()
+ case xs:integer(1) return fn:boolean(fn:not(fn:distinct-values($values)))
+ default return fn:true()
+};
+
+declare %private function fots:add-xquery-30(
+ $deps as element(fots:dependency)*
+) as xs:string? {
+ let $val := for $dep in $deps
+ where $dep[@type="spec"] and fn:contains(fn:data($dep/@value), "30")
+ return fn:true()
+ return
+ if($val[1])
+ then "xquery version '3.0';"
+ else ()
+};
+
+declare %private function fots:enable-HOF-feature(
+ $deps as element(fots:dependency)*
+) as xs:string? {
+ let $val := for $dep in $deps
+ where $dep[@type="spec"] and fn:contains(fn:data($dep/@value), "30")
+ return fn:true()
+ return
+ if($val[1])
+ then concat("declare namespace o = 'http://www.zorba-xquery.com/options/features';",
+ "declare option o:enable 'hof';")
+ else ()
+};
+
+declare %private function fots: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/environment),
+ env:var-decl-without-value($env, $case/environment, $path))
+};
=== added file 'test/fots_driver/serialize.xqy'
--- test/fots_driver/serialize.xqy 1970-01-01 00:00:00 +0000
+++ test/fots_driver/serialize.xqy 2012-04-25 14:58:22 +0000
@@ -0,0 +1,39 @@
+xquery version "3.0";
+
+module namespace ser = "http://www.w3.org/2010/09/qt-fots-catalog/serialize";
+
+declare function ser:serialize(
+ $seq as item()*
+) as xs:string {
+ fn:concat('(', fn:string-join(
+ (for $it in $seq
+ return ser:item($it))
+ , ', '), ')')
+};
+
+declare %private function ser:item(
+ $it as item()
+) as xs:string {
+ typeswitch($it)
+ case attribute()
+ return fn:concat(fn:name($it), '="', $it, '"')
+ case node()
+ return fn:serialize($it)
+ case function(*)
+ return ser:func($it)
+ case xs:untypedAtomic
+ return fn:concat('"', fn:replace($it, '"', '""'), '"')
+ case xs:string
+ return fn:concat('"', fn:replace($it, '"', '""'), '"')
+ default
+ return xs:string($it)
+};
+
+declare %private function ser:func(
+ $func as function(*)
+) as xs:string {
+ let $arity := fn:function-arity($func),
+ $name := if(fn:exists(fn:function-name($func)))
+ then fn:function-name($func) else '*function*'
+ return fn:concat($name, '#', $arity)
+};
\ No newline at end of file
Follow ups