diff --git a/.gitignore b/.gitignore index 72a43116bdbbb9594fc40e802c10563096ac5c07..22b4373ed87d456df4d2e2a89fc98bcefc822666 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ docker/frontend # exclude local scripts *.sh +!get-unit-test-failures-and-errors.sh # exlude data for commitizen node_modules diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f488f9dfda764b98e85783d8095be6c796b298b2..15cf117aceb559db1df320c24d5f5aa9272418b3 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -43,11 +43,9 @@ test_exist_app: - curl http://localhost:8080/exist/restxq/trigger-tests - sleep 60 - bash exist-app/test/bin/shutdown.sh - - failures=$(xmllint --xpath '/tests/testsuites/testsuite/@failures' exist-app/test/test-results.xml | egrep -o "[0-9]+") - - echo "There is/are currently $failures failures." - # one test fails on purpose to ensure the test suite is running correctly. - # thus we always have 1 failing test which indicates that everything is fine. - - if [[ "$failures" -gt 1 ]]; then exit 1; else exit 0; fi + - failures=$(./get-unit-test-failures-and-errors.sh) + - echo -e "\033[1;33mThere is/are currently $failures failures or errors.\033[0m" + - if [[ "$failures" -gt 0 ]]; then exit 1; else exit 0; fi artifacts: paths: - exist-app/test/test-results.xml diff --git a/CHANGELOG.md b/CHANGELOG.md index e148e46c609a9d26d8dc8d5cba1b06f49107085c..0827a56d9ff6ea39130ad6c6e44a544abbe4e8b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.11.0] - 2020-09-22 + +### Changed + +- In order to improve the clearity of the application, `tapi.xqm` now only holds the RESTXQ endpoints of the TextAPI. +All further functionality has been moved to separate module and furnished with tests. +- The test runner has been designed to be self-reporting, i.e. only faulty results are displayed fully. + +## [1.10.1] - 2020-09-24 + +### Fixed + +- Faulty link to OpenAPI documentation of the RESTXQ endpoints has been corrected. + ## [1.10.0] - 2020-09-18 ### Added diff --git a/README.md b/README.md index 64a2b96f9017db6f139ff948d47931f30b01e906..78dbfa3900eaf0b3ffcac701fb41fb4f6868a327 100644 --- a/README.md +++ b/README.md @@ -121,7 +121,7 @@ The frontend takes care of the data transfer as described in the [frontend's REA ## API documentation The backend comes shipped with an OpenAPI documentation of its API. -The docs are available at <https://ahikar-dev.uni-goettingen.de/openapi>. +The docs are available at <https://ahikar-dev.sub.uni-goettingen.de/openapi>. ### Interplay of TextAPI and AnnotationAPI diff --git a/exist-app/build.properties b/exist-app/build.properties index e6276c192186bc5edbb1315a5d88a0c57308c87e..1daf5a4be1d01c7c728b1f2fc5243355308e858a 100644 --- a/exist-app/build.properties +++ b/exist-app/build.properties @@ -1,5 +1,5 @@ project.name=https://ahikar-test.sub.uni-goettingen.de/ -project.version=1.10.0 +project.version=1.11.0 project.title=TextAPI for Ahikar project.abbrev=ahikar-test project.processorversion=5.2.0 diff --git a/exist-app/modules/annotations.xqm b/exist-app/modules/annotations.xqm index 5dbc3c3cbf8cbec3521ab394aba5312ab0592fd3..e10bcc4427ffd9e588497cba9cb1f2f06504efdc 100644 --- a/exist-app/modules/annotations.xqm +++ b/exist-app/modules/annotations.xqm @@ -1,7 +1,7 @@ xquery version "3.1"; (:~ - : This module provides the TextAPI for Ahikar. + : This module provides the Annotation Layer via TextAPI for Ahikar. : : @author Michelle Weidling : @version 1.8.1 diff --git a/exist-app/modules/commons.xqm b/exist-app/modules/commons.xqm index ece250197f97f9b6dc8173982c73d40c6a9e371d..77c61d90307bff8056780ee865b4b0656b0d31a4 100644 --- a/exist-app/modules/commons.xqm +++ b/exist-app/modules/commons.xqm @@ -2,6 +2,9 @@ xquery version "3.1"; module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons"; +declare namespace ore="http://www.openarchives.org/ore/terms/"; +declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; + declare variable $commons:expath-pkg := doc("../expath-pkg.xml"); declare variable $commons:version := $commons:expath-pkg/*/@version; declare variable $commons:tg-collection := "/db/apps/sade/textgrid"; @@ -15,4 +18,29 @@ declare variable $commons:responseHeader200 := <http:response xmlns:http="http://expath.org/ns/http-client" status="200"> <http:header name="Access-Control-Allow-Origin" value="*"/> </http:response> - </rest:response>; \ No newline at end of file + </rest:response>; + +declare function commons:get-aggregation($manifest-uri as xs:string) +as document-node() { + doc($commons:agg || $manifest-uri || ".xml") +}; + +declare function commons:get-xml-uri($manifest-uri as xs:string) +as xs:string { + let $aggregation-file := commons:get-aggregation($manifest-uri) + return + $aggregation-file//ore:aggregates[1]/@rdf:resource + => substring-after(":") +}; + +declare function commons:get-tei-xml-for-manifest($manifest-uri as xs:string) +as document-node() { + let $xml-uri := commons:get-xml-uri($manifest-uri) + return + doc($commons:data || $xml-uri || ".xml") +}; + +declare function commons:open-tei-xml($tei-xml-uri as xs:string) +as document-node() { + doc($commons:data || $tei-xml-uri || ".xml") +}; \ No newline at end of file diff --git a/exist-app/modules/tapi-collection.xqm b/exist-app/modules/tapi-collection.xqm index e70bad2219a9faed7c4909e0ac2560c26f43e071..e372b8ec873b705199723f4cec48b51f2e492784 100644 --- a/exist-app/modules/tapi-collection.xqm +++ b/exist-app/modules/tapi-collection.xqm @@ -6,39 +6,13 @@ xquery version "3.1"; : /textapi/ahikar/3r9ps/collection.json :) -module namespace t-coll="http://ahikar.sub.uni-goettingen.de/ns/tapi/collection"; +module namespace tapi-coll="http://ahikar.sub.uni-goettingen.de/ns/tapi/collection"; declare namespace ore="http://www.openarchives.org/ore/terms/"; -declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization"; declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; declare namespace tgmd="http://textgrid.info/namespaces/metadata/core/2010"; import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "commons.xqm"; -import module namespace requestr="http://exquery.org/ns/request"; -import module namespace rest="http://exquery.org/ns/restxq"; - -declare variable $t-coll:server := - if(requestr:hostname() = "existdb") then - $commons:expath-pkg/*/@name => replace("/$", "") - else - "http://localhost:8094/exist/restxq"; - -(:~ - : @see https://subugoe.pages.gwdg.de/emo/text-api/page/specs/#collection - : @see https://subugoe.pages.gwdg.de/emo/text-api/page/specs/#collection-object - : @param $collection-uri The unprefixed TextGrid URI of a collection, e.g. '3r132' - : @return A collection object as JSON - :) -declare - %rest:GET - %rest:HEAD - %rest:path("/textapi/ahikar/{$collection-uri}/collection.json") - %output:method("json") -function t-coll:endpoint($collection-uri as xs:string) -as item()+ { - $commons:responseHeader200, - t-coll:get-json($collection-uri, $t-coll:server) -}; (:~ : Returns information about the main collection for the project. This encompasses @@ -53,13 +27,13 @@ as item()+ { : @param $server A string indicating the server. This parameter has been introduced to make this function testable. : @return An object element containing all necessary information :) -declare function t-coll:get-json($collection-uri as xs:string, +declare function tapi-coll:get-json($collection-uri as xs:string, $server as xs:string) as item()+ { - let $metadata-file := t-coll:get-metadata-file($collection-uri) - let $format-type := t-coll:get-format-type($metadata-file) - let $sequence := t-coll:make-sequence($collection-uri, $server) - let $annotationCollection-uri := t-coll:make-annotationCollection-uri($server, $collection-uri) + let $metadata-file := tapi-coll:get-metadata-file($collection-uri) + let $format-type := tapi-coll:get-format-type($metadata-file) + let $sequence := tapi-coll:make-sequence($collection-uri, $server) + let $annotationCollection-uri := tapi-coll:make-annotationCollection-uri($server, $collection-uri) return <object> @@ -86,7 +60,7 @@ as item()+ { </object> }; -declare function t-coll:get-aggregation($collection-uri as xs:string) +declare function tapi-coll:get-aggregation($collection-uri as xs:string) as document-node() { doc($commons:agg || $collection-uri || ".xml") }; @@ -102,7 +76,7 @@ as document-node() { : @return A list of ore:aggregates without the manifests to be excluded : :) -declare function t-coll:get-allowed-manifest-uris($aggregation-file as node()) +declare function tapi-coll:get-allowed-manifest-uris($aggregation-file as node()) as xs:string+ { let $not-allowed := ( @@ -113,29 +87,29 @@ as xs:string+ { $aggregate[@rdf:resource != $not-allowed]/@rdf:resource return for $uri in $allowed return - t-coll:remove-textgrid-prefix($uri) + tapi-coll:remove-textgrid-prefix($uri) }; -declare function t-coll:remove-textgrid-prefix($uri as xs:string) +declare function tapi-coll:remove-textgrid-prefix($uri as xs:string) as xs:string { replace($uri, "textgrid:", "") }; -declare function t-coll:get-metadata-file($uri as xs:string) +declare function tapi-coll:get-metadata-file($uri as xs:string) as document-node() { doc($commons:meta || $uri || ".xml") }; -declare function t-coll:make-sequence($collection-uri as xs:string, +declare function tapi-coll:make-sequence($collection-uri as xs:string, $server as xs:string) as element(sequence)+ { - let $aggregation := t-coll:get-aggregation($collection-uri) - let $allowed-manifest-uris := t-coll:get-allowed-manifest-uris($aggregation/*) + let $aggregation := tapi-coll:get-aggregation($collection-uri) + let $allowed-manifest-uris := tapi-coll:get-allowed-manifest-uris($aggregation/*) for $manifest-uri in $allowed-manifest-uris return - let $manifest-metadata := t-coll:get-metadata-file($manifest-uri) - let $id := t-coll:make-id($server, $collection-uri, $manifest-uri) - let $type := t-coll:make-format-type($manifest-metadata) + let $manifest-metadata := tapi-coll:get-metadata-file($manifest-uri) + let $id := tapi-coll:make-id($server, $collection-uri, $manifest-uri) + let $type := tapi-coll:make-format-type($manifest-metadata) return <sequence> <id>{$id}</id> @@ -143,20 +117,20 @@ as element(sequence)+ { </sequence> }; -declare function t-coll:make-id($server as xs:string, +declare function tapi-coll:make-id($server as xs:string, $collection-uri as xs:string, $manifest-uri as xs:string) as xs:string { $server || "/api/textapi/ahikar/" || $collection-uri || "/" || $manifest-uri || "/manifest.json" }; -declare function t-coll:get-format-type($metadata as document-node()) +declare function tapi-coll:get-format-type($metadata as document-node()) as xs:string { $metadata//tgmd:format[1]/string() - => t-coll:make-format-type() + => tapi-coll:make-format-type() }; -declare function t-coll:make-format-type($tgmd-format as xs:string) +declare function tapi-coll:make-format-type($tgmd-format as xs:string) as xs:string { switch ($tgmd-format) case "text/tg.aggregation+xml" return "collection" @@ -164,7 +138,7 @@ as xs:string { default return "manifest" }; -declare function t-coll:make-annotationCollection-uri($server as xs:string, +declare function tapi-coll:make-annotationCollection-uri($server as xs:string, $collection-uri as xs:string) as xs:string { $server || "/api/textapi/ahikar/" || $collection-uri || "/annotationCollection.json" diff --git a/exist-app/modules/tapi-html.xqm b/exist-app/modules/tapi-html.xqm new file mode 100644 index 0000000000000000000000000000000000000000..4fd7d05aec0ccf91e7689178e7329eb05a0680cc --- /dev/null +++ b/exist-app/modules/tapi-html.xqm @@ -0,0 +1,101 @@ +xquery version "3.1"; +(: + : This module is for preparing the HTML serialization of a + : given TEI document or fragment. + :) + +module namespace tapi-html="http://ahikar.sub.uni-goettingen.de/ns/tapi/html"; + +declare namespace tei="http://www.tei-c.org/ns/1.0"; +declare namespace xhtml="http://www.w3.org/1999/xhtml"; + +import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "commons.xqm"; +import module namespace fragment="https://wiki.tei-c.org/index.php?title=Milestone-chunk.xquery" at "fragment.xqm"; + +(:~ + : Initiates the HTML serialization of a given page. + : + : @param $manifest-uri The unprefixed TextGrid URI of a document, e.g. '3rbmb' + : @param $page The page to be rendered. This has to be the string value of a tei:pb/@n in the given document, e.g. '1a' + : @return A div wrapper containing the rendered page + :) +declare function tapi-html:get-html($tei-xml-uri as xs:string, + $page as xs:string) +as element(div) { + let $tei-xml-base-uri := $commons:data || $tei-xml-uri || ".xml" + let $fragment := + if ($page) then + tapi-html:get-page-fragment($tei-xml-base-uri, $page) + else + doc($tei-xml-base-uri)/* + return + tapi-html:get-html-from-fragment($fragment) +}; + + +declare function tapi-html:get-page-fragment($tei-xml-base-uri as xs:string, + $page as xs:string) +as element() { + let $node := doc($tei-xml-base-uri)/* + => tapi-html:add-IDs(), + $start-node := $node//tei:pb[@n = $page and @facs], + $end-node := tapi-html:get-end-node($start-node), + $wrap-in-first-common-ancestor-only := false(), + $include-start-and-end-nodes := false(), + $empty-ancestor-elements-to-include := ("") + return + fragment:get-fragment-from-doc( + $node, + $start-node, + $end-node, + $wrap-in-first-common-ancestor-only, + $include-start-and-end-nodes, + $empty-ancestor-elements-to-include) +}; + + +declare function tapi-html:add-IDs($nodes as node()*) +as node()* { + for $node in $nodes return + typeswitch ($node) + + case text() return + $node + + case comment() return + () + + case processing-instruction() return + $node + + default return + element {QName("http://www.tei-c.org/ns/1.0", local-name($node))} { + attribute id {generate-id($node)}, + $node/@*, + tapi-html:add-IDs($node/node()) + } +}; + + +declare function tapi-html:get-end-node($start-node as element(tei:pb)) +as element() { + let $following-pb := $start-node/following::tei:pb[1][@facs] + return + if($following-pb) then + $following-pb + else + $start-node/following::tei:ab[last()] +}; + + +declare function tapi-html:get-html-from-fragment($fragment as element()) +as element(xhtml:div) { + let $stylesheet := doc("/db/apps/sade_assets/TEI-Stylesheets/html5/html5.xsl") + return + (: this wrapping is necessary in order to correctly set the namespace. + otherwise, error XQST0070 is raised during the tests. :) + element xhtml:div { + attribute class {"tei_body"}, + transform:transform($fragment, $stylesheet, ())/xhtml:body//xhtml:div[@class = "tei_body"]/* + } +}; diff --git a/exist-app/modules/tapi-item.xqm b/exist-app/modules/tapi-item.xqm new file mode 100644 index 0000000000000000000000000000000000000000..f38fb7e7798113f10f9659c3d597c62b6e3ad6e5 --- /dev/null +++ b/exist-app/modules/tapi-item.xqm @@ -0,0 +1,88 @@ +xquery version "3.1"; + +(: + : This module handles calls to the API on item level, e.g. + : + : /textapi/ahikar/3r9ps/3rx15-8a/latest/item.json + :) + +module namespace tapi-item="http://ahikar.sub.uni-goettingen.de/ns/tapi/item"; + +declare namespace tei="http://www.tei-c.org/ns/1.0"; + +import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "commons.xqm"; + + +declare function tapi-item:get-json($collection-uri as xs:string, + $manifest-uri as xs:string, + $page as xs:string, + $server as xs:string) +as element(object) { + <object> + <textapi>{$commons:version}</textapi> + <title>{tapi-item:make-title($manifest-uri)}</title> + <type>page</type> + <n>{$page}</n> + <content>{$server}/api/content/{commons:get-xml-uri($manifest-uri)}-{$page}.html</content> + <content-type>application/xhtml+xml</content-type> + {tapi-item:make-language-elements($manifest-uri)} + <x-langString>{tapi-item:get-language-string($manifest-uri)}</x-langString> + <image> + <id>{tapi-item:make-facsimile-id($manifest-uri, $page, $server)}</id> + </image> + <annotationCollection>{$server}/api/textapi/ahikar/{$collection-uri}/{$manifest-uri}-{$page}/annotationCollection.json</annotationCollection> + </object> +}; + + +declare function tapi-item:make-title($manifest-uri) +as xs:string { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + return + $tei-xml//tei:title[@type = "main"]/string() +}; + + +declare function tapi-item:make-language-elements($manifest-uri as xs:string) +as element()+ { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + let $languages := $tei-xml//tei:language + return + for $lang in $languages return + if ($lang[@xml:base = "https://iso639-3.sil.org/code/"]) then + element lang {$lang/@ident/string()} + else + element langAlt {$lang/@ident/string()} +}; + + +declare function tapi-item:get-language-string($manifest-uri as xs:string) +as xs:string { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + let $langString := + for $lang in $tei-xml//tei:language/text() + order by $lang + return $lang + return + string-join($langString, ", ") +}; + + +declare function tapi-item:make-facsimile-id($manifest-uri as xs:string, + $page as xs:string, + $server as xs:string) +as xs:string { + let $image-uri := tapi-item:get-facsimile-uri-for-page($manifest-uri, $page) + return + $server || "/api/images/" || $image-uri +}; + + +declare function tapi-item:get-facsimile-uri-for-page($manifest-uri as xs:string, + $page as xs:string) +as xs:string { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + return + $tei-xml//tei:pb[@n = $page]/@facs + => substring-after("textgrid:") +}; diff --git a/exist-app/modules/tapi-manifest.xqm b/exist-app/modules/tapi-manifest.xqm new file mode 100644 index 0000000000000000000000000000000000000000..6a3205af5c64468a3e978c61626230e37fba92ba --- /dev/null +++ b/exist-app/modules/tapi-manifest.xqm @@ -0,0 +1,142 @@ +xquery version "3.1"; + +(: + : This module handles calls to the API on manifest level, e.g. + : + : /textapi/ahikar/3r9ps/3rx15/manifest.json + :) + +module namespace tapi-mani="http://ahikar.sub.uni-goettingen.de/ns/tapi/manifest"; + +declare namespace tei="http://www.tei-c.org/ns/1.0"; +declare namespace tgmd="http://textgrid.info/namespaces/metadata/core/2010"; + +import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "commons.xqm"; + + +declare function tapi-mani:get-json($collection-uri as xs:string, + $manifest-uri as xs:string, + $server as xs:string) +as element(object) { + <object> + <textapi>{$commons:version}</textapi> + <id>{$server || "/api/textapi/ahikar/" || $collection-uri || "/" || $manifest-uri || "/manifest.json"}</id> + <label>{tapi-mani:get-manifest-title($manifest-uri)}</label> + { + tapi-mani:make-editors($manifest-uri), + tapi-mani:make-creation-date($manifest-uri), + tapi-mani:make-origin($manifest-uri), + tapi-mani:make-current-location($manifest-uri) + } + <license>CC0-1.0</license> + <annotationCollection>{$server}/api/textapi/ahikar/{$collection-uri}/{$manifest-uri}/annotationCollection.json</annotationCollection> + {tapi-mani:make-sequences($collection-uri, $manifest-uri, $server)} + </object> +}; + + +declare function tapi-mani:make-sequences($collection-uri as xs:string, + $manifest-uri as xs:string, + $server as xs:string) +as element(sequence)+ { + let $valid-pages := tapi-mani:get-valid-page-ids($manifest-uri) + return + for $page in $valid-pages + let $uri := "/api/textapi/ahikar/" || $collection-uri || "/" || $manifest-uri || "-" || $page || "/latest/item.json" + return + <sequence> + <id>{$server}{$uri}</id> + <type>item</type> + </sequence> +}; + +declare function tapi-mani:get-valid-page-ids($manifest-uri as xs:string) +as xs:string+ { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + return + $tei-xml//tei:pb[@facs]/string(@n) +}; + +declare function tapi-mani:get-manifest-title($manifest-uri as xs:string) +as xs:string { + let $metadata-file := tapi-mani:get-metadata-file($manifest-uri) + return + $metadata-file//tgmd:title/string() +}; + +declare function tapi-mani:get-metadata-file($manifest-uri as xs:string) +as document-node() { + doc($commons:tg-collection || "/meta/" || $manifest-uri || ".xml") +}; + + +declare function tapi-mani:make-editors($manifest-uri as xs:string) +as element(x-editor)+ { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + let $editors := $tei-xml//tei:titleStmt//tei:editor + return + if (exists($editors)) then + for $editor in $editors + return + <x-editor> + <role>editor</role> + <name>{$editor/string()}</name> + </x-editor> + else + <x-editor> + <name>none</name> + </x-editor> +}; + + +declare function tapi-mani:make-creation-date($manifest-uri as xs:string) +as element(x-date) { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + let $creation-date := $tei-xml//tei:history//tei:date + let $string := + if ($creation-date) then + $creation-date/string() + else + "unknown" + return + <x-date>{$string}</x-date> +}; + + +declare function tapi-mani:make-origin($manifest-uri as xs:string) as +element(x-origin) { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + let $country := $tei-xml//tei:history//tei:country + let $place := $tei-xml//tei:history//tei:placeName + let $string := + if ($country and $place) then + $place/string() || ", " || $country/string() + else if ($country) then + $country/string() + else if($place) then + $place/string() + else + "unknown" + return + <x-origin>{$string}</x-origin> +}; + + +declare function tapi-mani:make-current-location($manifest-uri as xs:string) as +element(x-location) { + let $tei-xml := commons:get-tei-xml-for-manifest($manifest-uri) + let $institution := $tei-xml//tei:msIdentifier//tei:institution + let $country := $tei-xml//tei:msIdentifier//tei:country + let $string := + if ($country and $institution) then + $institution || ", " || $country + else if ($country) then + $country/string() + else if($institution) then + $institution/string() + else + "unknown" + return + <x-location>{$string}</x-location> + +}; \ No newline at end of file diff --git a/exist-app/modules/tapi-txt.xqm b/exist-app/modules/tapi-txt.xqm new file mode 100644 index 0000000000000000000000000000000000000000..6dd2652fd6b8d7368f70df0f1fc1c0f33861462e --- /dev/null +++ b/exist-app/modules/tapi-txt.xqm @@ -0,0 +1,316 @@ +xquery version "3.1"; + +(:~ + : This module extracts the chunks marked as important for the collation from + : the TEI files and uses them as an input for the plain text creation. These + : serve as a basis for the collation with CollateX in the project's CI/CD + : pipelines. + :) + +module namespace tapi-txt="http://ahikar.sub.uni-goettingen.de/ns/tapi/txt"; + +declare namespace ore="http://www.openarchives.org/ore/terms/"; +declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; +declare namespace tei="http://www.tei-c.org/ns/1.0"; +declare namespace tgmd="http://textgrid.info/namespaces/metadata/core/2010"; + +import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "commons.xqm"; +import module namespace fragment="https://wiki.tei-c.org/index.php?title=Milestone-chunk.xquery" at "fragment.xqm"; + +declare variable $tapi-txt:textgrid := "/db/apps/sade/textgrid"; +declare variable $tapi-txt:data := $tapi-txt:textgrid || "/data"; +declare variable $tapi-txt:txt := $tapi-txt:textgrid || "/txt"; + + +declare function tapi-txt:main() +as xs:string+ { + tapi-txt:create-txt-collection-if-not-available(), + for $text in tapi-txt:get-transcriptions-and-transliterations() return + let $relevant-text := tapi-txt:get-relevant-text($text) + let $file-name := tapi-txt:make-file-name($text) + return + xmldb:store($tapi-txt:txt, $file-name, $relevant-text, "text/plain") +}; + +declare function tapi-txt:create-txt-collection-if-not-available() +as xs:string? { + if (xmldb:collection-available($tapi-txt:txt)) then + () + else + xmldb:create-collection($tapi-txt:textgrid, "txt") +}; + +declare function tapi-txt:get-transcriptions-and-transliterations() +as element(tei:text)+ { + collection($tapi-txt:data)//tei:text[@type = ("transcription", "transliteration")] + [tapi-txt:has-text-milestone(.)] +}; + +declare function tapi-txt:has-text-milestone($text as element(tei:text)) +as xs:boolean { + if ($text//tei:milestone) then + true() + else + false() +}; + +(:~ + : An example for the file name is + : syriac-Brit_Lib_Add_7200-3r131-transcription.txt + :) +declare function tapi-txt:make-file-name($text as element(tei:text)) +as xs:string { + let $lang-prefix := tapi-txt:get-language-prefix($text) + let $title-from-metadata := tapi-txt:create-metadata-title-for-file-name($text) + let $uri-plus-text-type := tapi-txt:make-file-name-suffix($text) + return + $lang-prefix || "-" || $title-from-metadata || "-" || $uri-plus-text-type +}; + +declare function tapi-txt:get-language-prefix($text as element(tei:text)) +as xs:string? { + switch ($text/@type) + case "transcription" return + switch ($text/@xml:lang) + case "karshuni" return "karshuni" + case "ara" return "arabic" + case "syc" return "syriac" + default return () + + (: although the transliteration may have another language than + the transcription, the latter remains decisive for the prefix :) + case "transliteration" return + switch ($text/root()//tei:text[@type = "transcription"]/@xml:lang) + case "ara" return "arabic" + case "karshuni" return "karshuni" + case "syc" return "syriac" + default return () + default return () +}; + +declare function tapi-txt:create-metadata-title-for-file-name($text as element(tei:text)) +as xs:string { + let $base-uri := tapi-txt:get-base-uri($text) + let $metadata := doc($base-uri => replace("/data/", "/meta/")) + return + $metadata//tgmd:title + => replace("[^a-zA-Z0-9]", "_") + => replace("[_]+", "_") +}; + +declare function tapi-txt:get-base-uri($text as element(tei:text)) +as xs:string{ + base-uri($text) +}; + +declare function tapi-txt:make-file-name-suffix($text as element(tei:text)) +as xs:string { + let $base-uri := tapi-txt:get-base-uri($text) + let $file-name := tapi-txt:get-file-name($base-uri) + let $type := $text/@type + return + $file-name || "-" || $type || ".txt" +}; + +declare function tapi-txt:get-file-name($base-uri as xs:string) +as xs:string { + tokenize($base-uri, "/")[last()] + => substring-before(".xml") +}; + +declare function tapi-txt:get-relevant-text($text as element(tei:text)) +as xs:string { + let $milestones := tapi-txt:get-milestones-in-text($text) + let $chunks := tapi-txt:get-chunks($milestones) + let $texts := tapi-txt:get-relevant-text-from-chunks($chunks) + return + string-join($texts, " ") +}; + +declare function tapi-txt:get-milestones-in-text($text as element(tei:text)) +as element(tei:milestone)+ { + $text//tei:milestone +}; + +declare function tapi-txt:get-chunks($milestones as element(tei:milestone)+) +as element(tei:TEI)+ { + for $milestone in $milestones return + tapi-txt:get-chunk($milestone) +}; + +declare function tapi-txt:get-chunk($milestone as element(tei:milestone)) +as element(tei:TEI) { + let $root := $milestone/root() + let $end-of-chunk := tapi-txt:get-end-of-chunk($milestone) + return + fragment:get-fragment-from-doc( + $root, + $milestone, + $end-of-chunk, + false(), + true(), + ("")) +}; + +declare function tapi-txt:get-end-of-chunk($milestone as element(tei:milestone)) +as node() { + if (tapi-txt:has-following-milestone($milestone)) then + tapi-txt:get-next-milestone($milestone) + else + $milestone/ancestor::tei:text[1]/tei:body/child::*[last()] +}; + +declare function tapi-txt:has-following-milestone($milestone as element(tei:milestone)) +as xs:boolean { + if ($milestone/following::tei:milestone[ancestor::tei:text[1] = $milestone/ancestor::tei:text[1]]) then + true() + else + false() +}; + +declare function tapi-txt:get-next-milestone($milestone as element(tei:milestone)) +as element(tei:milestone)? { + $milestone/following::tei:milestone[ancestor::tei:text[1] = $milestone/ancestor::tei:text[1]][1] +}; + +declare function tapi-txt:get-relevant-text-from-chunks($chunks as element(tei:TEI)+) +as xs:string { + let $texts := + for $chunk in $chunks return + tapi-txt:make-plain-text-from-chunk($chunk) + return + string-join($texts, " ") + => normalize-space() +}; + +declare function tapi-txt:make-plain-text-from-chunk($chunk as element(tei:TEI)) +as xs:string { + let $texts := tapi-txt:get-relevant-text-nodes($chunk) + let $prepared-texts := + for $text in $texts return + tapi-txt:prepare-plain-text-creation($text) + return + tapi-txt:format-and-normalize-string($prepared-texts) +}; + +(:~ + : The following nodes shouldn't be considered for the plain text creation: + : * sic (wrong text) + : * surplus (surplus text) + : * supplied (supplied by modern editors) + : * colophons + : * glyphs + : * unclear (text unclear) + : * catchwords (they simply serve to bind the books correctly and reduplicate text) + : * note (they have been added later by another scribe) + :) +declare function tapi-txt:get-relevant-text-nodes($chunk as element(tei:TEI)) +as text()+ { + (($chunk//text() + [not(parent::tei:sic)] + [not(parent::tei:surplus)]) + [not(parent::tei:supplied)]) + [not(parent::tei:*[@type = "colophon"])] + [not(parent::tei:g)] + [not(parent::tei:unclear)] + [not(parent::tei:catchwords)] + [not(parent::tei:note)] +}; + +declare function tapi-txt:prepare-plain-text-creation($text as text()) +as xs:string { + if ($text/preceding-sibling::*[1][self::tei:lb[@break = "no"]]) then + "@" || $text + else + $text +}; + +declare function tapi-txt:format-and-normalize-string($strings as xs:string+) +as xs:string { + string-join($strings, " ") + => replace(" @", "") + => replace("[\p{P}\n+]", "") + => replace("\s+", " ") +}; + + +(:~ + : Returns the tei:text of a document as indicated by the @type parameter. + : + : Due to the structure of the Ahikar project we can pass either an edition or + : an XML file to the API endpoint for plain text creation. + : This function determines the correct file which serves as a basis for the plain text. + : + : @param $document The URI of a resource + : @param $type Indicates the @type of tei:text to be processed + : @return The tei:text element to be serialized as plain text + :) +declare function tapi-txt:get-TEI-text($document-uri as xs:string, + $type as xs:string) +as element(tei:text) { + if (tapi-txt:is-document-tei-xml($document-uri)) then + commons:open-tei-xml($document-uri)//tei:text[@type = $type] + else + tapi-txt:get-tei-xml-uri-from-edition + => tapi-txt:get-text-of-type($type) +}; + + +declare function tapi-txt:is-document-tei-xml($document-uri as xs:string) { + let $format := tapi-txt:get-format($document-uri) + return + if ($format = "text/xml") then + true() + else + false() +}; + + +(:~ + : Returns the TextGrid metadata type of a resource. + : + : @param $uri The URI of the resource + : @return The resource's format as tgmd:format + :) +declare function tapi-txt:get-format($uri as xs:string) as xs:string { + doc($commons:meta || $uri || ".xml")//tgmd:format +}; + + +declare function tapi-txt:get-tei-xml-uri-from-edition($document-uri as xs:string) +as xs:string { + let $aggregates := tapi-txt:get-edition-aggregates-without-uri-namespace($document-uri) + return + tapi-txt:get-tei-xml-from-aggregates($aggregates) +}; + + +declare function tapi-txt:get-edition-aggregates-without-uri-namespace($document-uri as xs:string) +as xs:string+ { + let $edition := commons:get-aggregation($document-uri) + for $agg in $edition//ore:aggregates/@rdf:resource return + replace($agg, "textgrid:", "") +}; + + +declare function tapi-txt:get-tei-xml-from-aggregates($aggregates as xs:string+) +as xs:string { + for $agg in $aggregates return + if (tapi-txt:get-format($agg) = "text/xml") then + $agg + else + () +}; + + +declare function tapi-txt:get-text-of-type($uri as xs:string, + $type as xs:string) +as element(tei:text) { + commons:open-tei-xml($uri)//tei:text[@type = $type] +}; + + +declare function tapi-txt:compress-to-zip() +as xs:base64Binary* { + compression:zip(xs:anyURI($commons:tg-collection || "/txt/"), false()) +}; \ No newline at end of file diff --git a/exist-app/modules/tapi.xqm b/exist-app/modules/tapi.xqm index 9cae4a0ca0a722cfe9bb5d4c5c77d4ba94f05e0b..e0d3aa5ec70548fb3ce028e47f4e0756a2ed2ac4 100644 --- a/exist-app/modules/tapi.xqm +++ b/exist-app/modules/tapi.xqm @@ -13,23 +13,25 @@ xquery version "3.1"; module namespace tapi="http://ahikar.sub.uni-goettingen.de/ns/tapi"; -declare namespace expkg="http://expath.org/ns/pkg"; -declare namespace ore="http://www.openarchives.org/ore/terms/"; declare namespace output="http://www.w3.org/2010/xslt-xquery-serialization"; -declare namespace rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; declare namespace tei="http://www.tei-c.org/ns/1.0"; declare namespace test="http://exist-db.org/xquery/xqsuite"; -declare namespace tgmd="http://textgrid.info/namespaces/metadata/core/2010"; declare namespace xhtml="http://www.w3.org/1999/xhtml"; -import module namespace coll="http://ahikar.sub.uni-goettingen.de/ns/collate" at "collate.xqm"; +import module namespace tapi-coll="http://ahikar.sub.uni-goettingen.de/ns/tapi/collection" at "tapi-collection.xqm"; +import module namespace tapi-item="http://ahikar.sub.uni-goettingen.de/ns/tapi/item" at "tapi-item.xqm"; +import module namespace tapi-mani="http://ahikar.sub.uni-goettingen.de/ns/tapi/manifest" at "tapi-manifest.xqm"; +import module namespace tapi-txt="http://ahikar.sub.uni-goettingen.de/ns/tapi/txt" at "tapi-txt.xqm"; import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "commons.xqm"; -import module namespace fragment="https://wiki.tei-c.org/index.php?title=Milestone-chunk.xquery" at "fragment.xqm"; -import module namespace functx="http://www.functx.com"; import module namespace requestr="http://exquery.org/ns/request"; import module namespace rest="http://exquery.org/ns/restxq"; +import module namespace tapi-html="http://ahikar.sub.uni-goettingen.de/ns/tapi/html" at "tapi-html.xqm"; -declare variable $tapi:server := if(requestr:hostname() = "existdb") then $commons:expath-pkg/*/@name => replace("/$", "") else "http://localhost:8094/exist/restxq"; +declare variable $tapi:server := + if(requestr:hostname() = "existdb") then + $commons:expath-pkg/*/@name => replace("/$", "") + else + "http://localhost:8094/exist/restxq"; (:~ : Shows information about the currently installed application. @@ -41,7 +43,7 @@ declare %rest:HEAD %rest:path("/info") %output:method("json") -function tapi:info-rest() +function tapi:endpoint-info() as item()+ { $commons:responseHeader200, tapi:info() @@ -82,275 +84,66 @@ declare function tapi:remove-whitespaces($doc as document-node()) as document-no (:~ - : Returns information about a given document as specified at - : https://subugoe.pages.gwdg.de/emo/text-api/page/specs/#manifest. - : - : @see https://subugoe.pages.gwdg.de/emo/text-api/page/specs/#manifest - : @param $collection The unprefixed TextGrid URI of a collection, e.g. '3r84g' - : @param $document The unprefixed TextGrid URI of a document, e.g. '3r679' - : @return An object element containing all necessary information about a manifest object + : @see https://subugoe.pages.gwdg.de/emo/text-api/page/specs/#collection + : @see https://subugoe.pages.gwdg.de/emo/text-api/page/specs/#collection-object + : @param $collection-uri The unprefixed TextGrid URI of a collection, e.g. '3r132' + : @return A collection object as JSON :) declare %rest:GET %rest:HEAD - %rest:path("/textapi/ahikar/{$collection}/{$document}/manifest.json") + %rest:path("/textapi/ahikar/{$collection-uri}/collection.json") %output:method("json") -function tapi:manifest-rest($collection as xs:string, $document as xs:string) +function tapi:endpoint-collection($collection-uri as xs:string) as item()+ { $commons:responseHeader200, - tapi:manifest($collection, $document, $tapi:server) -}; - - -(:~ - : Returns information about an edition object (i.e. an aggregation) which holds - : an XML document as well as the facsimiles. - : - : In contrast to the generic TextAPI specs on manifest objects we do not provide an - : ID at this point. One reason is the TextGrid metadata model, the other is FRBR. - : - : @param $collection The URI of the document's parent collection, e.g. '3r9ps' - : @param $document The URI of an edition object, e.g. '3r177' - : @param $server A string indicating the server. This parameter has been introduced to make this function testable and defaults to $tapi:server. - : @return An object element containing all necessary information about a manifest object - :) -declare function tapi:manifest($collection as xs:string, $document as xs:string, -$server as xs:string) -as element(object) { - let $aggNode := doc($commons:agg || $document || ".xml") - let $metaNode := doc($commons:tg-collection || "/meta/" || $document || ".xml") - let $documentUri := $aggNode//ore:aggregates[1]/@rdf:resource => substring-after(":") - let $documentNode := doc($commons:data || $documentUri || ".xml") - let $sequence := - for $page in $documentNode//tei:pb[@facs]/string(@n) - let $uri := "/api/textapi/ahikar/" || $collection || "/" || $document || "-" || $page || "/latest/item.json" - return - <sequence> - <id>{$server}{$uri}</id> - <type>item</type> - </sequence> - let $id := $server || "/api/textapi/ahikar/" || $collection || "/" || $document || "/manifest.json" - - return - <object> - <textapi>{$commons:version}</textapi> - <id>{$id}</id> - <label>{string($metaNode//tgmd:title)}</label> - { - tapi:make-editors($documentNode), - tapi:make-date($documentNode), - tapi:make-origin($documentNode), - tapi:make-location($documentNode) - } - <license>CC0-1.0</license> - <annotationCollection>{$server}/api/textapi/ahikar/{$collection}/{$document}/annotationCollection.json</annotationCollection> - {$sequence} - </object> -}; - - -(:~ - : Creates the necessary information about editors. - : - : @see https://subugoe.pages.gwdg.de/ahiqar/api-documentation/page/text-api-specs/#actor-object - : @param $documentNode The opened TEI file of the current manifest - : @return An x-editor element with all information necessary for an Actor Object. - :) -declare function tapi:make-editors($documentNode as document-node()) as element(x-editor)* { - let $role := "editor" - let $has-editor := exists($documentNode//tei:titleStmt//tei:editor) - return - if ($has-editor) then - for $editor in $documentNode//tei:titleStmt//tei:editor - return - <x-editor> - <role>{$role}</role> - <name>{$editor/string()}</name> - </x-editor> - else - <x-editor> - <name>none</name> - </x-editor> -}; - -(:~ - : Creates the necessary information about a manuscript's origin from the TEI - : header. - : - : @see https://subugoe.pages.gwdg.de/ahiqar/api-documentation/page/text-api-specs/#manifest-object - : @param $documentNode The opened TEI file of the current manifest - : @return An x-origin element containing a descriptive string - :) -declare function tapi:make-origin($documentNode as document-node()) as -element(x-origin)? { - let $country := $documentNode//tei:history//tei:country - let $place := $documentNode//tei:history//tei:placeName - let $string := - if ($country and $place) then - $place/string() || ", " || $country/string() - else if ($country) then - $country/string() - else if($place) then - $place/string() - else - "unknown" - return - <x-origin>{$string}</x-origin> -}; - - -(:~ - : Creates the necessary information about a manuscript's creation date from the - : TEI header. - : - : @see https://subugoe.pages.gwdg.de/ahiqar/api-documentation/page/text-api-specs/#manifest-object - : @param $documentNode The opened TEI file of the current manifest - : @return An x-date element containing a descriptive string - :) -declare function tapi:make-date($documentNode as document-node()) as -element(x-date)? { - let $date := $documentNode//tei:history//tei:date - let $string := - if ($date) then - $date/string() - else - "unknown" - return - <x-date>{$string}</x-date> + tapi-coll:get-json($collection-uri, $tapi:server) }; (:~ - : Creates the necessary information about a manuscript's current location from - : the TEI header. - : - : @see https://subugoe.pages.gwdg.de/ahiqar/api-documentation/page/text-api-specs/#manifest-object - : @param $documentNode The opened TEI file of the current manifest - : @return An x-location element containing a descriptive string + : @see https://subugoe.pages.gwdg.de/emo/text-api/page/specs/#manifest :) -declare function tapi:make-location($documentNode as document-node()) as -element(x-location) { - let $institution := $documentNode//tei:msIdentifier//tei:institution - let $country := $documentNode//tei:msIdentifier//tei:country - let $string := - if ($country and $institution) then - $institution || ", " || $country - else if ($country) then - $country/string() - else if($institution) then - $institution/string() - else - "unknown" - return - <x-location>{$string}</x-location> - +declare + %rest:GET + %rest:HEAD + %rest:path("/textapi/ahikar/{$collection-uri}/{$manifest-uri}/manifest.json") + %output:method("json") +function tapi:endpoint-manifest($collection-uri as xs:string, + $manifest-uri as xs:string) +as item()+ { + $commons:responseHeader200, + tapi-mani:get-json($collection-uri, $manifest-uri, $tapi:server) }; -(:~ - : Returns the API endpoints of all pages of the manuscript. - : Since we also have transliterations, only "original" pages (i.e. the ones - : with a facsimile) are considered for the endpoints. - : - : @param $documentNode The opened TEI file of the current manifest - : @retun A sequence of sequence elements - :) -declare function tapi:make-sequence($documentNode as document-node()) as -element(sequence)+ { - for $page in $documentNode//tei:pb[@facs]/string(@n) - let $uri := "/api/textapi/ahikar/" || $collection || "/" || $document || "-" || $page || "/latest/item.json" - return - <sequence> - <id>{$server}{$uri}</id> - <type>item</type> - </sequence> -}; - (:~ : Returns information about a given page in a document. This is mainly compliant : with the SUB TextAPI, but has the following additions: : * the division number, 'n', is mandatory : * 'image' is mandatory since every page has a facsimile - : - : The parameter $collection is actually not necessary but introduced to keep - : the structure of the API clear. : : Sample call to API: /api/textapi/ahikar/3r17c/3r1pq-147a/latest/item.json : : @see https://subugoe.pages.gwdg.de/emo/text-api/page/specs/#item - : @param $collection The unprefixed TextGrid URI of a collection, e.g. '3r17c' - : @param $document The unprefixed TextGrid URI of a document, e.g. '3r1pq' + : @param $collection-uri The unprefixed TextGrid URI of a collection, e.g. '3r17c' + : @param $manifest-uri The unprefixed TextGrid URI of a document, e.g. '3r1pq' : @param $page A page number as encoded in a tei:pb/@n, e.g. '147a' : @return Information about a page :) declare %rest:GET %rest:HEAD - %rest:path("/textapi/ahikar/{$collection}/{$document}-{$page}/latest/item.json") + %rest:path("/textapi/ahikar/{$collection-uri}/{$manifest-uri}-{$page}/latest/item.json") %output:method("json") -function tapi:item-rest($collection as xs:string, $document as xs:string, -$page as xs:string) as item()+ { +function tapi:endpoint-item($collection-uri as xs:string, + $manifest-uri as xs:string, + $page as xs:string) +as item()+ { $commons:responseHeader200, - tapi:item($collection, $document, $page, $tapi:server) + tapi-item:get-json($collection-uri, $manifest-uri, $page, $tapi:server) }; - -(:~ - : Returns information about a given page. - : - : @param $document The unprefixed TextGrid URI of a collection, e.g. '3r9ps' - : @param $document The unprefixed TextGrid URI of a document, e.g. '3r1pq' - : @param $page A page number as encoded in a tei:pb/@n, e.g. '147a' - : @param $server A string indicating the server. This parameter has been introduced to make this function testable and defaults to $tapi:server. - : @return An object element containing all necessary information about an item - :) -declare function tapi:item($collection as xs:string, $document as xs:string, -$page as xs:string, $server as xs:string) -as element(object) { - let $aggNode := doc($commons:agg || $document || ".xml") - let $teiUri := - if($aggNode) - then $aggNode//ore:aggregates[1]/@rdf:resource => substring-after(":") - else $document - let $image := doc($commons:data || $teiUri || ".xml")//tei:pb[@n = $page]/@facs => substring-after("textgrid:") - - let $xml := doc($commons:data || $teiUri || ".xml") - let $title := $xml//tei:title[@type = "main"]/string() - let $iso-languages := - $xml//tei:language[@xml:base = "https://iso639-3.sil.org/code/"]/@ident/string() - let $alt-languages := - $xml//tei:language[not(@xml:base = "https://iso639-3.sil.org/code/")]/@ident/string() - let $langString := - for $lang in $xml//tei:language/text() - order by $lang - return $lang - let $langString := string-join($langString, ", ") - - return - <object> - <textapi>{$commons:version}</textapi> - <title>{$title}</title> - <type>page</type> - <n>{$page}</n> - <content>{$server}/api/content/{$teiUri}-{$page}.html</content> - <content-type>application/xhtml+xml</content-type> - { - for $lang in $iso-languages return - element lang {$lang} - } - { - for $lang in $alt-languages return - element langAlt {$lang} - } - <x-langString>{$langString}</x-langString> - <image> - <id>{$server}/api/images/{$image}</id> - </image> - <annotationCollection>{$server}/api/textapi/ahikar/{$collection}/{$document}-{$page}/annotationCollection.json</annotationCollection> - </object> -}; - - (:~ : Returns an HTML rendering of a given page. : @@ -360,62 +153,21 @@ as element(object) { : : Sample call to API: /content/3rbmb-1a.html : - : @param $document The unprefixed TextGrid URI of a document, e.g. '3rbmb' + : @param $document The unprefixed TextGrid URI of a TEI/XML, e.g. '3rbmb' : @param $page The page to be rendered. This has to be the string value of a tei:pb/@n in the given document, e.g. '1a' : @return A response header as well as the rendered HTML page :) declare %rest:GET %rest:HEAD - %rest:path("/content/{$document}-{$page}.html") + %rest:path("/content/{$tei-xml-uri}-{$page}.html") %output:method("xml") %output:indent("no") -function tapi:content-rest($document as xs:string, $page as xs:string) +function tapi:endpoint-html($tei-xml-uri as xs:string, + $page as xs:string) as item()+ { $commons:responseHeader200, - tapi:content($document, $page) -}; - - -(:~ - : Initiates the HTML serialization of a given page. - : - : @param $document The unprefixed TextGrid URI of a document, e.g. '3rbmb' - : @param $page The page to be rendered. This has to be the string value of a tei:pb/@n in the given document, e.g. '1a' - : @return A div wrapper containing the rendered page - :) -declare function tapi:content($document as xs:string, $page as xs:string) -as element(div) { - let $documentPath := $commons:data || $document || ".xml" - let $TEI := - if($page) - then - let $node := doc($documentPath)/* => tapi:add-IDs(), - $start-node := $node//tei:pb[@n = $page and @facs], - $end-node := - let $followingPb := $node//tei:pb[@n = $page and @facs]/following::tei:pb[1][@facs] - return - if($followingPb) - then $followingPb - else $node//tei:pb[@n = $page and @facs]/following::tei:ab[last()], - $wrap-in-first-common-ancestor-only := false(), - $include-start-and-end-nodes := false(), - $empty-ancestor-elements-to-include := ("") - return - fragment:get-fragment-from-doc( - $node, - $start-node, - $end-node, - $wrap-in-first-common-ancestor-only, - $include-start-and-end-nodes, - $empty-ancestor-elements-to-include) - else doc($documentPath)/* - let $stylesheet := doc("/db/apps/sade_assets/TEI-Stylesheets/html5/html5.xsl") - let $transform := transform:transform($TEI, $stylesheet, ())/xhtml:body//xhtml:div[@class = "tei_body"] - return - <div> - {$transform} - </div> + tapi-html:get-html($tei-xml-uri, $page) }; @@ -435,7 +187,7 @@ declare %rest:path("/images/{$uri}") %rest:produces("image/jpeg") %output:method("binary") -function tapi:images-rest($uri as xs:string) +function tapi:endpoint-image($uri as xs:string) as item()+ { $commons:responseHeader200, hc:send-request( @@ -458,20 +210,20 @@ as item()+ { declare %rest:GET %rest:HEAD - %rest:path("/content/{$document}.txt") + %rest:path("/content/{$document-uri}.txt") %rest:query-param("type", "{$type}", "transcription") %output:method("text") -function tapi:text-rest($document as xs:string, $type) +function tapi:endpoint-txt($document-uri as xs:string, + $type) as item()+ { - let $text := tapi:get-TEI-text($document, $type) - let $TEI := + let $pseudo-chunk := element tei:TEI { - $text + tapi-txt:get-TEI-text($document-uri, $type) } return ( $commons:responseHeader200, - coll:make-plain-text-from-chunk($TEI) + tapi-txt:make-plain-text-from-chunk($pseudo-chunk) ) }; @@ -486,111 +238,9 @@ declare %rest:HEAD %rest:path("/content/ahikar-plain-text.zip") %output:method("binary") -function tapi:text-rest() as item()+ { - let $prepare := coll:main() +function tapi:endpoint-zip() as item()+ { + let $prepare := tapi-txt:main() return $commons:responseHeader200, - tapi:compress-to-zip() -}; - - -(:~ - : Compressing all manuscripts available to ZIP. - : - : @return the zipped files as xs:base64Binary - :) -declare function tapi:compress-to-zip() -as xs:base64Binary* { - compression:zip(xs:anyURI($commons:tg-collection || "/txt/"), false()) -}; - - -(:~ - : Returns the tei:text of a document as indicated by the @type parameter. - : - : Due to the structure of the Ahikar project we can pass either an edition or - : an XML file to the API endpoint for plain text creation. - : This function determines the correct file which serves as a basis for the plain text. - : - : @param $document The URI of a resource - : @param $type Indicates the @type of tei:text to be processed - : @return The tei:text element to be serialized as plain text - :) -declare function tapi:get-TEI-text($document as xs:string, $type as xs:string) -as element(tei:text) { - let $format := tapi:get-format($document) - return - if ($format = "text/xml") then - doc($commons:data || $document || ".xml")//tei:text[@type = $type] - (: in this case the document is an edition which forces us to pick the - text/xml file belonging to it :) - else - let $xml := tapi:get-tei-file-name-of-edition($document) - return - tapi:get-text-of-type($xml, $type) -}; - -declare function tapi:get-tei-file-name-of-edition($document as xs:string) -as xs:string { - let $aggregates := tapi:get-edition-aggregates-without-uri-namespace($document) - return - tapi:find-xml-in-aggregates($aggregates) -}; - -declare function tapi:get-edition-aggregates-without-uri-namespace($document as xs:string) -as xs:string+ { - let $edition := doc($commons:agg || $document || ".xml") - for $agg in $edition//ore:aggregates/@rdf:resource return - replace($agg, "textgrid:", "") -}; - -declare function tapi:find-xml-in-aggregates($aggregates as xs:string+) -as xs:string { - for $agg in $aggregates return - if (tapi:get-format($agg) = "text/xml") then - $agg - else - () -}; - -declare function tapi:get-text-of-type($uri as xs:string, $type as xs:string) -as element(tei:text) { - doc($commons:data || $uri || ".xml")//tei:text[@type = $type] -}; - -(:~ - : Returns the TextGrid metadata type of a resource. - : - : @param $uri The URI of the resource - : @return The resource's format as tgmd:format - :) -declare function tapi:get-format($uri as xs:string) as xs:string { - doc($commons:meta || $uri || ".xml")//tgmd:format -}; - - -declare function tapi:add-IDs($tei as element(tei:TEI)) as element(tei:TEI) { - tapi:add-IDs-recursion($tei) -}; - -declare function tapi:add-IDs-recursion($nodes as node()*) as node()* { - util:log-system-out($nodes), - for $node in $nodes return - typeswitch ($node) - - case text() return - $node - - case comment() return - () - - case processing-instruction() return - $node - - default return - element {QName("http://www.tei-c.org/ns/1.0", local-name($node))} { - attribute id {generate-id($node)}, - $node/@*, - tapi:add-IDs-recursion($node/node()) - } + tapi-txt:compress-to-zip() }; diff --git a/exist-app/modules/testtrigger.xqm b/exist-app/modules/testtrigger.xqm index afaa51dfb246918b5352ce16e6616fc400062e76..d1004775ac135f92d624632aa41f9d969cbbad90 100644 --- a/exist-app/modules/testtrigger.xqm +++ b/exist-app/modules/testtrigger.xqm @@ -6,7 +6,6 @@ xquery version "3.1"; : since at this point the RESTXQ API isn't fired up yet which causes the tests to throw errors. : : @author Michelle Weidling - : @version 0.1.0 : @since 0.4.0 :) @@ -14,7 +13,14 @@ module namespace testtrigger="http://ahikar.sub.uni-goettingen.de/ns/testtrigger import module namespace rest="http://exquery.org/ns/restxq"; import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; -import module namespace tests="http://ahikar.sub.uni-goettingen.de/ns/tapi/tests" at "../tests.xqm"; + +import module namespace ttt="http://ahikar.sub.uni-goettingen.de/ns/tapi/txt/tests" at "../tests/tapi-txt-tests.xqm"; +import module namespace ct="http://ahikar.sub.uni-goettingen.de/ns/commons-tests" at "../tests/commons-tests.xqm"; +import module namespace tct="http://ahikar.sub.uni-goettingen.de/ns/tapi/collection/tests" at "../tests/tapi-collection-tests.xqm"; +import module namespace thtmlt="http://ahikar.sub.uni-goettingen.de/ns/tapi/html/tests" at "../tests/tapi-html-tests.xqm"; +import module namespace titemt="http://ahikar.sub.uni-goettingen.de/ns/tapi/item/tests" at "../tests/tapi-item-tests.xqm"; +import module namespace tmt="http://ahikar.sub.uni-goettingen.de/ns/tapi/manifest/tests" at "../tests/tapi-manifest-tests.xqm"; +import module namespace tt="http://ahikar.sub.uni-goettingen.de/ns/tapi/tests" at "../tests/tapi-tests.xqm"; (:~ : Triggers the tests for the Ahikar backend. Called by the CI. @@ -33,7 +39,16 @@ as item()? { then error(QName("error://1", "deploy"), "Deploy token incorrect.") else let $sysout := util:log-system-out("TextAPI and package installation done. running tests…") - let $tests := test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/tests")) + let $tests := + ( + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/txt/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/commons-tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/collection/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/manifest/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/item/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/html/tests")) + ) let $fileSeparator := util:system-property("file.separator") let $system-path := system:get-exist-home() || $fileSeparator diff --git a/exist-app/tests-runner.xq b/exist-app/tests-runner.xq deleted file mode 100644 index b8d5b2272cbbeb2ed46a1ec6f5319da9b2c8ebca..0000000000000000000000000000000000000000 --- a/exist-app/tests-runner.xq +++ /dev/null @@ -1,19 +0,0 @@ -xquery version "3.1"; -(:~ - : Script providing access to the test functions (XQSuite) for local unit test - : execution. - :) - -import module namespace tct="http://ahikar.sub.uni-goettingen.de/ns/tapi/collection/tests" at "tests/tapi-collection-tests.xqm"; -import module namespace ttnt="http://ahikar.sub.uni-goettingen.de/ns/tapi/txt/normalization/tests" at "tests/tapi-txt-normalization-tests.xqm"; -import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; -import module namespace tests="http://ahikar.sub.uni-goettingen.de/ns/tapi/tests" at "tests.xqm"; -import module namespace coll-tests="http://ahikar.sub.uni-goettingen.de/ns/coll-tests" at "tests/collate-tests.xqm"; -import module namespace ct="http://ahikar.sub.uni-goettingen.de/ns/commons-tests" at "tests/commons-tests.xqm"; - -(: test API endpoints :) -test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/tests")), -test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/coll-tests")), -test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/commons-tests")), -test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/collection/tests")), -test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/txt/normalization/tests")) \ No newline at end of file diff --git a/exist-app/tests.xqm b/exist-app/tests.xqm deleted file mode 100644 index 754f93272cc0f69c533784f28c41dfe8f0015f75..0000000000000000000000000000000000000000 --- a/exist-app/tests.xqm +++ /dev/null @@ -1,538 +0,0 @@ -xquery version "3.1"; - -(:~ - : Test module for the RESTXQ endpoints of the Ahikar TextAPI. - : - : @author Michelle Weidling - : @version 0.1.0 - :) - -module namespace tests="http://ahikar.sub.uni-goettingen.de/ns/tapi/tests"; - -declare namespace http = "http://expath.org/ns/http-client"; -declare namespace tei="http://www.tei-c.org/ns/1.0"; - -import module namespace anno="http://ahikar.sub.uni-goettingen.de/ns/annotations" at "modules/annotations.xqm"; -import module namespace map="http://www.w3.org/2005/xpath-functions/map"; -import module namespace tapi="http://ahikar.sub.uni-goettingen.de/ns/tapi" at "modules/tapi.xqm"; -import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; - -declare variable $tests:restxq := "http://0.0.0.0:8080/exist/restxq/"; - - -declare - %test:setUp -function tests:_test-setup() as xs:string+ { - xmldb:create-collection("/db", "test-records"), - xmldb:store("/db/test-records", "white-spaces.xml", <record><id>12 34 56 - 78</id></record>), - xmldb:store("/db/test-records", "sample-tei.xml", <text xmlns="http://www.tei-c.org/ns/1.0" type="transcription">test - <note>test2</note> - test3 - <sic>text4</sic> - <placeName>Berlin</placeName> - </text>), - xmldb:store("/db/test-records", "origin-country-only.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> - <history> - <origin> - <country>Iraq</country> - </origin> - </history> - </teiHeader>), - xmldb:store("/db/test-records", "origin-place-only.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> - <history> - <origin> - <placeName>Alqosh</placeName> - </origin> - </history> - </teiHeader>), - xmldb:store("/db/test-records", "header-empty-history-msIdentifier.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> - <msIdentifier/> - <history/> - </teiHeader>), - xmldb:store("/db/test-records", "location-country-only.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> - <msIdentifier> - <settlement> - <country>Great Britain</country> - </settlement> - </msIdentifier> - </teiHeader>), - xmldb:store("/db/test-records", "location-institution-only.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> - <msIdentifier> - <institution>University of Cambridge - Cambridge University Library</institution> - </msIdentifier> - </teiHeader>) -}; - -declare - %test:tearDown -function tests:_test-teardown() as item() { - xmldb:remove("/db/test-records") -}; - -declare - (: check if requests work :) - %test:assertXPath("map:get($result, 'request') => map:get('scheme') = 'http'") - (: check if expathpkg works :) - %test:assertXPath("map:get($result, 'package') => map:get('title') = 'TextAPI for Ahikar'") - (: check if repo.xml works :) - %test:assertXPath("map:get($result, 'meta') => map:get('target') = 'ahikar'") -function tests:api-info() as item() { - let $url := $tests:restxq || "info" - let $req := <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> - return http:send-request($req)[2] => util:base64-decode() => parse-json() -}; - - -declare - (: check if all parts are present. - : no further tests are needed since the content has been tested by testing - : the underlying function. :) - %test:assertXPath("map:contains($result, 'textapi')") - %test:assertXPath("map:contains($result, 'id')") - %test:assertXPath("map:contains($result, 'label')") - %test:assertXPath("map:contains($result, 'x-editor')") - %test:assertXPath("map:contains($result, 'x-date')") - %test:assertXPath("map:contains($result, 'x-origin')") - %test:assertXPath("map:contains($result, 'x-location')") - %test:assertXPath("map:contains($result, 'license')") - %test:assertXPath("map:contains($result, 'sequence')") -function tests:manifest-rest() as item() { - let $url := $tests:restxq || "/textapi/ahikar/ahiqar_collection/ahiqar_agg/manifest.json" - let $req := <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> - return http:send-request($req)[2] => util:base64-decode() => parse-json() -}; - - -declare - (: check if all parts are present. - : no further tests are needed since the content has been tested while testing - : the underlying function. :) - %test:assertXPath("map:contains($result, 'textapi')") - %test:assertXPath("map:contains($result, 'title')") - %test:assertXPath("map:contains($result, 'type')") - %test:assertXPath("map:contains($result, 'n')") - %test:assertXPath("map:contains($result, 'content')") - %test:assertXPath("map:contains($result, 'content-type')") - %test:assertXPath("map:contains($result, 'lang')") - %test:assertXPath("map:contains($result, 'image')") -function tests:item-rest() as item() { - let $url := $tests:restxq || "/textapi/ahikar/ahiqar_collection/ahiqar_agg-82a/latest/item.json" - let $req := <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> - return http:send-request($req)[2] => util:base64-decode() => parse-json() -}; - - -declare - (: check if tei:div is present. - : no further tests are needed since the content has been tested while testing - : the underlying function. :) - %test:assertXPath("$result//*[@class = 'tei_body']") -function tests:content-rest() as document-node() { - let $url := $tests:restxq || "/content/ahiqar_sample-82a.html" - let $req := <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> - return http:send-request($req)[2] -}; - - -declare - (: check if ZIP is present. - : no further tests are needed since the content has been tested while testing - : the underlying function. :) - %test:assertExists - %test:pending -function tests:content-zip() as xs:base64Binary { - let $url := $tests:restxq || "/content/ahikar-plain-text.zip" - let $req := <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> - return http:send-request($req)[2] -}; - - -declare - (: check if txt is present. - : no further tests are needed since the content has been tested while testing - : the underlying function. :) - %test:assertXPath("matches($result, '[\w]')") -function tests:content-txt() as xs:string { - let $url := $tests:restxq || "/textapi/ahikar/ahiqar_collection/ahiqar_sample.txt" - let $req := <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> - return http:send-request($req)[2] -}; - - -(: ************************ - : * UNDERLYING FUNCTIONS * - : ************************ - : all the functions that contribute to but do not define RESTXQ endpoints - :) - - -declare - %test:args("ahiqar_collection", "ahiqar_agg", "http://localhost:8080/exist/restxq") - (: tests if the object is created at all :) - %test:assertXPath("$result//*[local-name(.) = 'label'] = 'Beispieldatei zum Testen' ") - (: tests if the sequence construction works properly :) - %test:assertXPath("$result//*[local-name(.) = 'id'] = 'http://localhost:8080/exist/restxq/api/textapi/ahikar/ahiqar_collection/ahiqar_agg-82a/latest/item.json' ") -function tests:manifest($collection as xs:string, $document as xs:string, -$server as xs:string) as element(object) { - tapi:manifest($collection, $document, $server) -}; - - - -declare - %test:args("ahiqar_collection", "ahiqar_agg", "82a", "http://localhost:8080/exist/restxq") - (: checks if the correct file has been opened :) - %test:assertXPath("$result//*[local-name(.) = 'title'] = 'The Proverbs or History of Aḥīḳar the wise, the scribe of Sanḥērībh, - king of Assyria and Nineveh' ") - (: checks if language assembling works correctly :) - %test:assertXPath("$result//*[local-name(.) = 'lang'] = 'syc' ") - %test:assertXPath("$result//*[local-name(.) = 'langAlt'] = 'karshuni' ") - %test:assertXPath("$result//*[local-name(.) = 'x-langString'][matches(., 'Classical Syriac')]") - (: checks if underlying pages are identified :) - %test:assertXPath("$result//*[local-name(.) = 'content'] = 'http://localhost:8080/exist/restxq/api/content/ahiqar_sample-82a.html' ") - (: checks if images connected to underlying pages are identified :) - %test:assertXPath("$result//*[local-name(.) = 'id'] = 'http://localhost:8080/exist/restxq/api/images/3r1nz' ") -function tests:item($collection as xs:string, $document as xs:string, $page as xs:string, $server as xs:string) -as element(object){ - tapi:item($collection, $document, $page, $server) -}; - - -declare - %test:args("ahiqar_sample", "82a") - (: checks if there is text at all in the result :) - %test:assertXPath("$result//text()[matches(., '[\w]')]") - (: if a div[@class = 'tei_body'] is present, the transformation has been successfull :) - %test:assertXPath("$result//*[@class = 'tei_body']") - (: this is some text on 82a (and thus should be part of the result) :) - %test:assertXPath("$result//* = 'ܘܬܥܐܠܝ ܕܟܪܗ ܐܠܝ ܐܠܐܒܕ. ܘܢܟܬܒ ܟܒܪ'") - (: this is some text on 83a which shouldn't be part of the result :) - %test:assertXPath("not($result//* = 'ܡܢ ܐܠܣܡܐ ܩܐܝܠܐ. ܒܚܝܬ ܐܬܟܠܬ ܐܘܠܐ ܥܠܝ ܐܠܐܨܢܐܡ' )") -function tests:html-creation($document as xs:string, $page as xs:string) as element(div) { - tapi:content($document, $page) -}; - - -declare - %test:args("ahiqar_sample") - %test:assertEquals("text/xml") -function tests:tgmd-format($uri as xs:string) as xs:string { - tapi:get-format($uri) -}; - - -declare - %test:args("ahiqar_sample", "transcription") - %test:assertXPath("$result[local-name(.) = 'text' and @type = 'transcription']") -function tests:get-tei($document as xs:string, $type as xs:string) as element() { - tapi:get-TEI-text($document, $type) -}; - - -declare - %test:assertXPath("$result[local-name(.) = 'x-editor' and name/text() = 'Aly Elrefaei']") -function tests:make-editors() as element()+ { - let $documentNode := doc("/db/apps/sade/textgrid/data/ahiqar_sample.xml") - return - tapi:make-editors($documentNode) -}; - -declare - %test:assertXPath("$result[local-name(.) = 'x-editor' and name/text() = 'none']") -function tests:make-editors-fail-gracefully() as element()+ { - let $documentNode := doc("/db/test-records/sample-tei.xml") - return - tapi:make-editors($documentNode) -}; - - -declare - %test:assertXPath("$result[local-name(.) = 'x-date'][text() = '18.10.1697']") -function tests:make-date() as element() { - let $documentNode := doc("/db/apps/sade/textgrid/data/ahiqar_sample.xml") - return - tapi:make-date($documentNode) -}; - -declare - %test:assertXPath("$result[local-name(.) = 'x-date'][text() = 'unknown']") -function tests:make-date-none() as element() { - let $documentNode := doc("/db/test-records/header-empty-history-msIdentifier.xml") - return - tapi:make-date($documentNode) -}; - - -declare - %test:assertXPath("$result[local-name(.) = 'x-origin'][text() = 'Alqosh, Iraq']") -function tests:make-origin() as element() { - let $documentNode := doc("/db/apps/sade/textgrid/data/ahiqar_sample.xml") - return - tapi:make-origin($documentNode) -}; - -declare - %test:assertXPath("$result[local-name(.) = 'x-origin'][text() = 'Iraq']") -function tests:make-origin-country-only() as element() { - let $documentNode := doc("/db/test-records/origin-country-only.xml") - return - tapi:make-origin($documentNode) -}; - -declare - %test:assertXPath("$result[local-name(.) = 'x-origin'][text() = 'Alqosh']") -function tests:make-origin-place-only() as element() { - let $documentNode := doc("/db/test-records/origin-place-only.xml") - return - tapi:make-origin($documentNode) -}; - -declare - %test:assertXPath("$result[local-name(.) = 'x-origin'][text() = 'unknown']") -function tests:make-origin-none() as element() { - let $documentNode := doc("/db/test-records/header-empty-history-msIdentifier.xml") - return - tapi:make-origin($documentNode) -}; - - -declare - %test:assertXPath("$result[local-name(.) = 'x-location'][text() = 'University of Cambridge - Cambridge University Library, Great Britain']") -function tests:make-location() as element() { - let $documentNode := doc("/db/apps/sade/textgrid/data/ahiqar_sample.xml") - return - tapi:make-location($documentNode) -}; - -declare - %test:assertXPath("$result[local-name(.) = 'x-location'][text() = 'Great Britain']") -function tests:make-location-country-only() as element() { - let $documentNode := doc("/db/test-records/location-country-only.xml") - return - tapi:make-location($documentNode) -}; - -declare - %test:assertXPath("$result[local-name(.) = 'x-location'][text() = 'University of Cambridge - Cambridge University Library']") -function tests:make-location-institution-only() as element() { - let $documentNode := doc("/db/test-records/location-institution-only.xml") - return - tapi:make-location($documentNode) -}; - -declare - %test:assertXPath("$result[local-name(.) = 'x-location'][text() = 'unknown']") -function tests:make-location-none() as element() { - let $documentNode := doc("/db/test-records/header-empty-history-msIdentifier.xml") - return - tapi:make-location($documentNode) -}; - - -declare - %test:assertXPath("$result/string() = '1234 5678'") -function tests:remove-whitespaces() as document-node() { - let $doc := doc("/db/test-records/white-spaces.xml") - return - tapi:remove-whitespaces($doc) -}; - -declare - %test:args("ahiqar_agg") %test:assertEquals("ahiqar_sample") -function tests:get-tei-file-name-of-edition($document as xs:string) { - tapi:get-tei-file-name-of-edition($document) -}; - -declare - %test:args("ahiqar_agg") %test:assertEquals("ahiqar_sample") -function tests:get-edition-aggregates-without-uri-namespace($document as xs:string) { - tapi:get-edition-aggregates-without-uri-namespace($document) -}; - -declare - %test:args("ahiqar_sample") %test:assertEquals("ahiqar_sample") -function tests:find-xml-in-aggregates($aggregates as xs:string+) { - tapi:find-xml-in-aggregates($aggregates) -}; - -declare - %test:args("ahiqar_sample", "transliteration") %test:assertXPath("$result[@type = 'transliteration']") -function tests:get-text-of-type($uri as xs:string, $type as xs:string) { - tapi:get-text-of-type($uri, $type) -}; - -declare - %test:assertTrue -function tests:is-txt-api-available() { - let $url := $tests:restxq || "content/ahiqar_sample.txt" - return - local:is-endpoint-http200($url) -}; - -declare function tests:txt() { - let $url := $tests:restxq || "textapi/ahiqar/ahiqar_collection/ahiqar_sample.txt" - let $req := <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> - return http:send-request($req)[2] => util:base64-decode() -}; - - -(: - : ***************** - : * AnnotationAPI * - : ***************** - :) - -declare - %test:args("ahiqar_sample", "data") - %test:assertXPath("$result//*[local-name(.) = 'TEI']") -function tests:anno-get-document($uri as xs:string, $type as xs:string) as document-node() { - anno:get-document($uri, $type) -}; - - -(:declare:) -(: %test:args("3r679", "114r"):) -(: %test:assertEquals("0"):) -(:function tests:anno-determine-start-index-for-page($uri as xs:string, $page as xs:string) {:) -(: anno:determine-start-index-for-page($uri, $page):) -(:};:) -(::) -(::) -(:declare:) -(: %test:args("3r131"):) -(: %test:assertEquals("16"):) -(:function tests:anno-determine-start-index($uri as xs:string) {:) -(: anno:determine-start-index($uri):) -(:};:) -(::) -(:declare:) -(: %test:args("3r131"):) -(: %test:assertEquals("3r679"):) -(:function tests:anno-get-parent-aggregation($uri as xs:string) {:) -(: anno:get-parent-aggregation($uri):) -(:};:) -(::) -(::) -(:declare:) -(: %test:args("3r131"):) -(: %test:assertEquals("114r", "114v"):) -(:function tests:anno-get-pages-in-TEI($uri as xs:string) {:) -(: anno:get-pages-in-TEI($uri):) -(:};:) -(::) -(::) -(:declare:) -(: %test:args("3r679"):) -(: %test:assertTrue:) -(:function tests:anno-is-resource-edition($uri as xs:string) {:) -(: anno:is-resource-edition($uri):) -(:};:) -(::) -(::) -(:declare:) -(: %test:args("3r131"):) -(: %test:assertTrue:) -(:function tests:anno-is-resource-xml($uri as xs:string) {:) -(: anno:is-resource-xml($uri):) -(:};:) - - -declare - %test:assertEquals("A place's name.") -function tests:anno-get-bodyValue() { - let $annotation := doc("/db/test-records/sample-tei.xml")//tei:placeName - return - anno:get-bodyValue($annotation) -}; - - -declare - %test:args("asdf") - %test:assertFalse -(: %test:args("3r131"):) -(: %test:assertTrue:) -function tests:anno-are-resources-available($resources as xs:string+) { - anno:are-resources-available($resources) -}; - - -(:declare:) -(: %test:args("3r131"):) -(: %test:assertEquals("Simon Birol, Aly Elrefaei"):) -(:function tests:anno-get-creator($uri as xs:string) {:) -(: anno:get-creator($uri):) -(:};:) -(::) -(::) -(:declare:) -(: %test:args("3r131"):) -(: %test:assertEquals("Brit. Lib. Add. 7200"):) -(:function tests:anno-get-metadata-title($uri as xs:string) {:) -(: anno:get-metadata-title($uri):) -(:};:) -(::) -(::) -(:declare:) -(: %test:args("3r679"):) -(: %test:assertEquals("3r676", "3r672"):) -(:function tests:anno-get-prev-xml-uris($uri as xs:string) {:) -(: anno:get-prev-xml-uris($uri):) -(:};:) -(::) -(::) -(:declare:) -(: %test:args("3r679"):) -(: %test:assertEquals("3r676", "3r672"):) -(:function tests:anno-get-xmls-prev-in-collection($uri as xs:string) {:) -(: anno:get-xmls-prev-in-collection($uri):) -(:};:) - - -(:declare:) -(: %test:args("3r679", "114r", "next"):) -(: %test:assertEquals("114v"):) -(:function tests:anno-get-prev-or-next-page($documentURI as xs:string,:) -(:$page as xs:string, $type as xs:string) {:) -(: anno:get-prev-or-next-page($documentURI, $page, $type):) -(:};:) -(::) -(::) -(:declare:) -(: %test:args("3r9ps"):) -(: %test:assertEquals("3r177", "3r178", "3r7vw", "3r7p1", "3r7p9", "3r7sk", "3r7tp", "3r7vd", "3r179", "3r7n0", "3r9vn", "3r9wf", "3rb3z", "3rbm9", "3rbmc", "3rx14", "3vp38"):) -(:function tests:anno-get-uris($documentURI) {:) -(: anno:get-uris($documentURI):) -(:};:) - -declare function local:is-endpoint-http200($url as xs:string) as xs:boolean { - let $http-status := local:get-http-status($url) - return - $http-status = "200" -}; - -declare function local:get-http-status($url as xs:string) as xs:string { - let $req := local:make-request($url) - return - http:send-request($req)[1]/@status -}; - -declare function local:make-request($url as xs:string) { - <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> -}; \ No newline at end of file diff --git a/exist-app/tests/commons-tests.xqm b/exist-app/tests/commons-tests.xqm index 78dc0a5cf0268dda917d48f0c306ea6a60580ebc..1fd683943633f08a2c6822ca4902ef326b91bdeb 100644 --- a/exist-app/tests/commons-tests.xqm +++ b/exist-app/tests/commons-tests.xqm @@ -5,13 +5,36 @@ module namespace ct="http://ahikar.sub.uni-goettingen.de/ns/commons-tests"; declare namespace http = "http://expath.org/ns/http-client"; declare namespace tei="http://www.tei-c.org/ns/1.0"; +import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "../modules/commons.xqm"; import module namespace map="http://www.w3.org/2005/xpath-functions/map"; import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; declare variable $ct:restxq := "http://0.0.0.0:8080/exist/restxq/"; declare - %test:assertTrue -function ct:succes() { - true() -}; \ No newline at end of file + %test:args("ahiqar_agg") %test:assertXPath("$result//@* = 'textgrid:ahiqar_sample'") +function ct:get-aggregation($manifest-uri as xs:string) { + commons:get-aggregation($manifest-uri) +}; + +declare + %test:args("ahiqar_agg") %test:assertEquals("ahiqar_sample") +function ct:get-xml-uri($manifest-uri as xs:string) +as xs:string { + commons:get-xml-uri($manifest-uri) +}; + +declare + %test:args("ahiqar_agg") %test:assertXPath("$result//*[local-name(.) = 'title'] = 'The Proverbs or History of Aḥīḳar the wise, the scribe of Sanḥērībh, + king of Assyria and Nineveh'") +function ct:get-tei-xml-for-manifest($manifest-uri) { + commons:get-tei-xml-for-manifest($manifest-uri) +}; + + +declare + %test:args("ahiqar_sample") %test:assertXPath("$result//*[local-name(.) = 'TEI']") +function ct:open-tei-xml($tei-xml-uri as xs:string) +as document-node() { + commons:open-tei-xml($tei-xml-uri) +}; diff --git a/exist-app/tests/tapi-collection-tests.xqm b/exist-app/tests/tapi-collection-tests.xqm index 00f35f48cfaac90a1ca467b27f263e871b080710..594e835a88ad1d42e44e58a2d3427e402b44e334 100644 --- a/exist-app/tests/tapi-collection-tests.xqm +++ b/exist-app/tests/tapi-collection-tests.xqm @@ -7,11 +7,11 @@ declare namespace tei="http://www.tei-c.org/ns/1.0"; import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "../modules/commons.xqm"; import module namespace map="http://www.w3.org/2005/xpath-functions/map"; +import module namespace tc="http://ahikar.sub.uni-goettingen.de/ns/tests/commons" at "test-commons.xqm"; import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; -import module namespace t-coll="http://ahikar.sub.uni-goettingen.de/ns/tapi/collection" at "../modules/tapi-collection.xqm"; +import module namespace tapi-coll="http://ahikar.sub.uni-goettingen.de/ns/tapi/collection" at "../modules/tapi-collection.xqm"; -declare variable $tct:restxq := "http://0.0.0.0:8080/exist/restxq"; -declare variable $tct:collection-uri := "test-collection.xml"; +declare variable $tct:collection-uri := "testapi-collection.xml"; declare variable $tct:agg1-uri := "test-aggregation-1.xml"; declare variable $tct:agg2-uri := "test-aggregation-2.xml"; @@ -21,7 +21,7 @@ function tct:_test-setup(){ let $collection := <rdf:RDF xmlns:ore="http://www.openarchives.org/ore/terms/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> - <rdf:Description rdf:about="textgrid:test-collection"> + <rdf:Description rdf:about="textgrid:testapi-collection"> <ore:aggregates rdf:resource="textgrid:test-aggregation-1"/> <ore:aggregates rdf:resource="textgrid:test-aggregation-2"/> </rdf:Description> @@ -102,18 +102,10 @@ function tct:_test-teardown() { xmldb:remove($commons:meta, $tct:agg2-uri) }; -declare - %test:assertTrue -function tct:is-endpoint-available() { - let $url := $tct:restxq || "/textapi/ahikar/ahiqar_collection/collection.json" - return - local:is-endpoint-http200($url) -}; - declare %test:args("ahiqar_collection") %test:assertXPath("$result//*[local-name(.) = 'aggregates']") function tct:get-aggregation($uri as xs:string) { - t-coll:get-aggregation($uri) + tapi-coll:get-aggregation($uri) }; declare @@ -129,7 +121,7 @@ function tct:get-allowed-manifest-uris-mock-up-input-included() { </rdf:Description> </rdf:RDF> return - t-coll:get-allowed-manifest-uris($collection-metadata) = "3rx14" + tapi-coll:get-allowed-manifest-uris($collection-metadata) = "3rx14" }; declare @@ -145,7 +137,7 @@ function tct:get-allowed-manifest-uris-mock-up-input-excluded() { </rdf:Description> </rdf:RDF> return - t-coll:get-allowed-manifest-uris($collection-metadata) = "3vp38" + tapi-coll:get-allowed-manifest-uris($collection-metadata) = "3vp38" }; @@ -153,22 +145,22 @@ declare %test:args("ahiqar_collection", "ahiqar_agg") %test:assertEquals("http://0.0.0.0:8080/exist/restxq/api/textapi/ahikar/ahiqar_collection/ahiqar_agg/manifest.json") function tct:make-id($colletion-uri as xs:string, $manifest-uri as xs:string) as xs:string { - t-coll:make-id($tct:restxq, $colletion-uri, $manifest-uri) + tapi-coll:make-id($tc:server, $colletion-uri, $manifest-uri) }; declare %test:assertEquals("ahiqar_agg") function tct:get-allowed-manifest-uris-sample-input() { - let $collection-metadata := t-coll:get-aggregation("ahiqar_collection") + let $collection-metadata := tapi-coll:get-aggregation("ahiqar_collection") return - t-coll:get-allowed-manifest-uris($collection-metadata) + tapi-coll:get-allowed-manifest-uris($collection-metadata) }; declare %test:args("ahiqar_collection") %test:assertXPath("$result[self::document-node()]") function tct:get-metadata-file($uri as xs:string) { - t-coll:get-metadata-file($uri) + tapi-coll:get-metadata-file($uri) }; @@ -176,7 +168,7 @@ declare %test:args("textgrid:1234") %test:assertEquals("1234") %test:args("1234") %test:assertEquals("1234") function tct:remove-textgrid-prefix($uri as xs:string) { - t-coll:remove-textgrid-prefix($uri) + tapi-coll:remove-textgrid-prefix($uri) }; declare @@ -184,32 +176,32 @@ declare %test:args("text/tg.edition+tg.aggregation+xml") %test:assertEquals("manifest") %test:args("test") %test:assertEquals("manifest") function tct:make-format-type($tgmd-format as xs:string) { - t-coll:make-format-type($tgmd-format) + tapi-coll:make-format-type($tgmd-format) }; declare %test:assertEquals("manifest") function tct:get-format-type() { - let $metadata := t-coll:get-metadata-file("ahiqar_agg") + let $metadata := tapi-coll:get-metadata-file("ahiqar_agg") return - t-coll:get-format-type($metadata) + tapi-coll:get-format-type($metadata) }; declare %test:args("ahiqar_collection") %test:assertXPath("$result//type[. = 'manifest']") %test:args("ahiqar_collection") %test:assertXPath("$result//id[matches(., 'ahiqar_agg/manifest.json')]") - %test:args("test-collection") %test:assertXPath("$result//id[matches(., 'test-aggregation-1/manifest.json')]") - %test:args("test-collection") %test:assertXPath("$result//id[matches(., 'test-aggregation-2/manifest.json')]") + %test:args("testapi-collection") %test:assertXPath("$result//id[matches(., 'test-aggregation-1/manifest.json')]") + %test:args("testapi-collection") %test:assertXPath("$result//id[matches(., 'test-aggregation-2/manifest.json')]") function tct:make-sequence($collection-uri as xs:string) { - t-coll:make-sequence($collection-uri, $tct:restxq) + tapi-coll:make-sequence($collection-uri, $tc:server) }; declare %test:args("ahiqar_collection") %test:assertEquals("http://0.0.0.0:8080/exist/restxq/api/textapi/ahikar/ahiqar_collection/annotationCollection.json") function tct:make-annotationCollection-uri($collection-uri as xs:string) as xs:string { - t-coll:make-annotationCollection-uri($tct:restxq, $collection-uri) + tapi-coll:make-annotationCollection-uri($tc:server, $collection-uri) }; @@ -217,44 +209,5 @@ declare %test:args("ahiqar_collection") %test:assertXPath("$result//title = 'The Story and Proverbs of Ahikar the Wise'") %test:args("ahiqar_collection") %test:assertXPath("$result//*/string() = 'http://0.0.0.0:8080/exist/restxq/api/textapi/ahikar/ahiqar_collection/ahiqar_agg/manifest.json' ") function tct:get-json($collection-uri as xs:string) { - t-coll:get-json($collection-uri, $tct:restxq) + tapi-coll:get-json($collection-uri, $tc:server) }; - - -declare - (: check if all parts are present. - : no further tests are needed since the content has been tested while testing - : the underlying function. :) - %test:assertXPath("map:contains($result, 'title')") - %test:assertXPath("map:contains($result, 'collector')") - %test:assertXPath("map:contains($result, 'description')") - %test:assertXPath("map:contains($result, 'sequence')") -function tct:endpoint() -as item() { - let $url := $tct:restxq || "/textapi/ahikar/ahiqar_collection/collection.json" - let $req := <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> - return http:send-request($req)[2] => util:base64-decode() => parse-json() -}; - - - - -declare function local:is-endpoint-http200($url as xs:string) as xs:boolean { - let $http-status := local:get-http-status($url) - return - $http-status = "200" -}; - -declare function local:get-http-status($url as xs:string) as xs:string { - let $req := local:make-request($url) - return - http:send-request($req)[1]/@status -}; - -declare function local:make-request($url as xs:string) { - <http:request href="{$url}" method="get"> - <http:header name="Connection" value="close"/> - </http:request> -}; \ No newline at end of file diff --git a/exist-app/tests/tapi-html-tests.xqm b/exist-app/tests/tapi-html-tests.xqm new file mode 100644 index 0000000000000000000000000000000000000000..c54e4c10e4e0fea6b135226869a49ed4097af7a5 --- /dev/null +++ b/exist-app/tests/tapi-html-tests.xqm @@ -0,0 +1,74 @@ +xquery version "3.1"; + +module namespace thtmlt="http://ahikar.sub.uni-goettingen.de/ns/tapi/html/tests"; + +declare namespace tei="http://www.tei-c.org/ns/1.0"; +declare namespace xhtml="http://www.w3.org/1999/xhtml"; + +import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "../modules/commons.xqm"; +import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; +import module namespace tapi-html="http://ahikar.sub.uni-goettingen.de/ns/tapi/html" at "../modules/tapi-html.xqm"; + + +declare + %test:assertXPath("$result//@id = 'N4'") +function thtmlt:add-IDs() +as node()+ { + let $manifest := doc($commons:data || "ahiqar_sample.xml")/* + return + tapi-html:add-IDs($manifest) +}; + + +declare + %test:args("/db/apps/sade/textgrid/data/ahiqar_sample.xml", "82a") %test:assertXPath("$result[local-name(.) = 'pb']") + %test:args("/db/apps/sade/textgrid/data/ahiqar_sample.xml", "82a") %test:assertXPath("$result/@facs = 'textgrid:3r1p0'") + %test:args("/db/apps/sade/textgrid/data/ahiqar_sample.xml", "82a") %test:assertXPath("$result/@n = '82b'") + %test:args("/db/apps/sade/textgrid/data/ahiqar_sample.xml", "83b") %test:assertXPath("$result[local-name(.) = 'ab']") + %test:args("/db/apps/sade/textgrid/data/ahiqar_sample.xml", "83b") %test:assertXPath("matches($result, 'ܘܗܦܟܬ ܛܥܢܬ ܐܰܒܵܪܐ ܘܠܐ ܐܝܼܩܰܪ ܥܠ')") +function thtmlt:get-end-node($tei-xml-base-uri as xs:string, + $page as xs:string) +as item()+ { + let $node := doc($tei-xml-base-uri)/* + let $start-node := $node//tei:pb[@n = $page and @facs] + return + tapi-html:get-end-node($start-node) +}; + + +declare + %test:args("/db/apps/sade/textgrid/data/ahiqar_sample.xml", "82a") %test:assertXPath("$result//*[local-name(.) = 'add'][@place = 'margin'] = 'حقًا'") +function thtmlt:get-page-fragment($tei-xml-base-uri as xs:string, + $page as xs:string) +as element() { + tapi-html:get-page-fragment($tei-xml-base-uri, $page) +}; + + +declare + %test:args("/db/apps/sade/textgrid/data/ahiqar_sample.xml", "82a") %test:assertXPath("$result//text()[matches(., 'حقًا')]") +function thtmlt:transform-fragment($tei-xml-base-uri as xs:string, + $page as xs:string) +as element(xhtml:div) { + let $fragment := tapi-html:get-page-fragment($tei-xml-base-uri, $page) + return + tapi-html:get-html-from-fragment($fragment) +}; + + +declare + %test:args("ahiqar_sample", "82a") %test:assertXPath("$result//text()[matches(., 'حقًا')]") + %test:args("ahiqar_sample", "82a") + (: checks if there is text at all in the result :) + %test:assertXPath("$result//text()[matches(., '[\w]')]") + (: if a div[@class = 'tei_body'] is present, the transformation has been successfull :) + %test:assertXPath("$result[@class = 'tei_body']") + (: this is some text on 82a (and thus should be part of the result) :) + %test:assertXPath("$result//* = 'ܘܬܥܐܠܝ ܕܟܪܗ ܐܠܝ ܐܠܐܒܕ. ܘܢܟܬܒ ܟܒܪ'") + (: this is some text on 83a which shouldn't be part of the result :) + %test:assertXPath("not($result//* = 'ܡܢ ܐܠܣܡܐ ܩܐܝܠܐ. ܒܚܝܬ ܐܬܟܠܬ ܐܘܠܐ ܥܠܝ ܐܠܐܨܢܐܡ' )") +function thtmlt:get-html($tei-xml-uri as xs:string, + $page as xs:string) +as element(div) { + tapi-html:get-html($tei-xml-uri, $page) +}; diff --git a/exist-app/tests/tapi-item-tests.xqm b/exist-app/tests/tapi-item-tests.xqm new file mode 100644 index 0000000000000000000000000000000000000000..cba63492ea762c3b600d50c601e2ce753261ec8d --- /dev/null +++ b/exist-app/tests/tapi-item-tests.xqm @@ -0,0 +1,74 @@ +xquery version "3.1"; + +module namespace titemt="http://ahikar.sub.uni-goettingen.de/ns/tapi/item/tests"; + +declare namespace http = "http://expath.org/ns/http-client"; +declare namespace tei="http://www.tei-c.org/ns/1.0"; + +import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "../modules/commons.xqm"; +import module namespace map="http://www.w3.org/2005/xpath-functions/map"; +import module namespace tc="http://ahikar.sub.uni-goettingen.de/ns/tests/commons" at "test-commons.xqm"; +import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; +import module namespace tapi-item="http://ahikar.sub.uni-goettingen.de/ns/tapi/item" at "../modules/tapi-item.xqm"; + + +declare + %test:args("ahiqar_agg", "82a") %test:assertEquals("3r1nz") +function titemt:get-facsimile-uri-for-page($manifest-uri as xs:string, + $page as xs:string) +as xs:string { + tapi-item:get-facsimile-uri-for-page($manifest-uri, $page) +}; + +declare + %test:args("ahiqar_agg") %test:assertEquals("Arabic, Classical Syriac, Eastern Syriac, Karshuni, Western Syriac") +function titemt:get-language-string($manifest-uri as xs:string) +as xs:string { + tapi-item:get-language-string($manifest-uri) +}; + +declare + %test:args("ahiqar_agg", "82a") %test:assertEquals("http://0.0.0.0:8080/exist/restxq/api/images/3r1nz") +function titemt:make-facsimile-id($manifest-uri as xs:string, + $page as xs:string) +as xs:string { + tapi-item:make-facsimile-id($manifest-uri, $page, $tc:server) +}; + +declare + %test:args("ahiqar_agg") %test:assertEquals("The Proverbs or History of Aḥīḳar the wise, the scribe of Sanḥērībh, + king of Assyria and Nineveh") +function titemt:make-title($manifest-uri as xs:string) +as xs:string { + tapi-item:make-title($manifest-uri) +}; + + +declare + %test:args("ahiqar_collection", "ahiqar_agg", "82a") + (: checks if the correct file has been opened :) + %test:assertXPath("$result//*[local-name(.) = 'title'] = 'The Proverbs or History of Aḥīḳar the wise, the scribe of Sanḥērībh, + king of Assyria and Nineveh' ") + (: checks if language assembling works correctly :) + %test:assertXPath("$result//*[local-name(.) = 'lang'] = 'syc' ") + %test:assertXPath("$result//*[local-name(.) = 'langAlt'] = 'karshuni' ") + %test:assertXPath("$result//*[local-name(.) = 'x-langString'][matches(., 'Classical Syriac')]") + (: checks if underlying pages are identified :) + %test:assertXPath("$result//*[local-name(.) = 'content'] = 'http://0.0.0.0:8080/exist/restxq/api/content/ahiqar_sample-82a.html' ") + (: checks if images connected to underlying pages are identified :) + %test:assertXPath("$result//*[local-name(.) = 'id'] = 'http://0.0.0.0:8080/exist/restxq/api/images/3r1nz' ") +function titemt:get-json($collection as xs:string, + $document as xs:string, + $page as xs:string) +as element(object){ + tapi-item:get-json($collection, $document, $page, $tc:server) +}; + + +declare + %test:args("ahiqar_agg") %test:assertXPath("count($result) = 5") + %test:args("ahiqar_agg") %test:assertXPath("$result[local-name(.) = ('lang', 'langAlt')]") + %test:args("ahiqar_agg") %test:assertXPath("count($result[local-name(.) = 'lang']) = 2") +function titemt:make-language-elements($manifest-uri as xs:string) { + tapi-item:make-language-elements($manifest-uri) +}; \ No newline at end of file diff --git a/exist-app/tests/tapi-manifest-tests.xqm b/exist-app/tests/tapi-manifest-tests.xqm new file mode 100644 index 0000000000000000000000000000000000000000..1142ebff75a1066903d2a7d6a7448385663231c2 --- /dev/null +++ b/exist-app/tests/tapi-manifest-tests.xqm @@ -0,0 +1,206 @@ +xquery version "3.1"; + +module namespace tmt="http://ahikar.sub.uni-goettingen.de/ns/tapi/manifest/tests"; + +declare namespace http = "http://expath.org/ns/http-client"; +declare namespace tei="http://www.tei-c.org/ns/1.0"; + +import module namespace commons="http://ahikar.sub.uni-goettingen.de/ns/commons" at "../modules/commons.xqm"; +import module namespace map="http://www.w3.org/2005/xpath-functions/map"; +import module namespace tc="http://ahikar.sub.uni-goettingen.de/ns/tests/commons" at "test-commons.xqm"; +import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; +import module namespace tapi-mani="http://ahikar.sub.uni-goettingen.de/ns/tapi/manifest" at "../modules/tapi-manifest.xqm"; + +declare variable $tmt:manifest1 := "test-manifest1.xml"; +declare variable $tmt:manifest2 := "test-manifest2.xml"; +declare variable $tmt:manifest3 := "test-manifest3.xml"; +declare variable $tmt:tei1-uri := "test-tei-1.xml"; +declare variable $tmt:tei2-uri := "test-tei-2.xml"; +declare variable $tmt:tei3-uri := "test-tei-3.xml"; + + + +declare + %test:setUp +function tmt:_test-setup(){ + let $manifest1 := + <rdf:RDF xmlns:ore="http://www.openarchives.org/ore/terms/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <rdf:Description rdf:about="test-aggregation-1"> + <ore:aggregates rdf:resource="textgrid:test-tei-1"/> + </rdf:Description> + </rdf:RDF> + let $manifest2 := + <rdf:RDF xmlns:ore="http://www.openarchives.org/ore/terms/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <rdf:Description rdf:about="test-aggregation-1"> + <ore:aggregates rdf:resource="textgrid:test-tei-2"/> + </rdf:Description> + </rdf:RDF> + let $manifest3 := + <rdf:RDF xmlns:ore="http://www.openarchives.org/ore/terms/" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> + <rdf:Description rdf:about="test-aggregation-1"> + <ore:aggregates rdf:resource="textgrid:test-tei-3"/> + </rdf:Description> + </rdf:RDF> + + + let $tei1 := + <TEI xmlns="http://www.tei-c.org/ns/1.0"> + <teiHeader> + <fileDesc> + <titleStmt> + <title type="main">A Minimal Dummy TEI</title> + </titleStmt> + </fileDesc> + </teiHeader> + </TEI> + + let $tei2 := + <TEI xmlns="http://www.tei-c.org/ns/1.0"> + <teiHeader> + <fileDesc> + <titleStmt> + <title type="main">A Minimal Dummy TEI2</title> + </titleStmt> + <sourceDesc> + <msDesc> + <msIdentifier> + <institution>University of Cambridge - Cambridge University Library</institution> + </msIdentifier> + <history> + <origin> + <country>Iraq</country> + </origin> + </history> + </msDesc> + </sourceDesc> + </fileDesc> + </teiHeader> + </TEI> + + let $tei3 := + <TEI xmlns="http://www.tei-c.org/ns/1.0"> + <teiHeader> + <fileDesc> + <titleStmt> + <title type="main">A Minimal Dummy TEI3</title> + </titleStmt> + <sourceDesc> + <msDesc> + <msIdentifier> + <settlement> + <country>Great Britain</country> + </settlement> + </msIdentifier> + <history> + <origin> + <placeName>Alqosh</placeName> + </origin> + </history> + </msDesc> + </sourceDesc> + </fileDesc> + </teiHeader> + </TEI> + + + return + ( + xmldb:store($commons:agg, $tmt:manifest1, $manifest1), + xmldb:store($commons:agg, $tmt:manifest2, $manifest2), + xmldb:store($commons:agg, $tmt:manifest3, $manifest3), + xmldb:store($commons:data, $tmt:tei1-uri, $tei1), + xmldb:store($commons:data, $tmt:tei2-uri, $tei2), + xmldb:store($commons:data, $tmt:tei3-uri, $tei3) + + ) +}; + +declare + %test:tearDown +function tmt:_test-teardown() { + xmldb:remove($commons:agg, $tmt:manifest1), + xmldb:remove($commons:agg, $tmt:manifest2), + xmldb:remove($commons:agg, $tmt:manifest3), + xmldb:remove($commons:data, $tmt:tei1-uri), + xmldb:remove($commons:data, $tmt:tei2-uri), + xmldb:remove($commons:data, $tmt:tei3-uri) +}; + +declare + %test:args("ahiqar_agg") %test:assertXPath("$result//* = 'textgrid:ahiqar_agg.0'") +function tmt:get-metadata-file($manifest-uri) { + tapi-mani:get-metadata-file($manifest-uri) +}; + + +declare + %test:args("ahiqar_collection", "ahiqar_agg") %test:assertXPath("$result//id[matches(., '/api/textapi/ahikar/ahiqar_collection/ahiqar_agg-82a/latest/item.json')]") +function tmt:make-sequences($collection-uri as xs:string, + $manifest-uri as xs:string) { + tapi-mani:make-sequences($collection-uri, $manifest-uri, $tc:server) +}; + +declare + %test:args("ahiqar_agg") %test:assertXPath("count($result) = 4") +function tmt:get-valid-page-ids($manifest-uri as xs:string) { + tapi-mani:get-valid-page-ids($manifest-uri) +}; + +declare + %test:args("ahiqar_collection", "ahiqar_agg") %test:assertXPath("$result//label = 'Beispieldatei zum Testen'") + %test:args("ahiqar_collection", "ahiqar_agg") %test:assertXPath("$result//id[matches(., '/api/textapi/ahikar/ahiqar_collection/ahiqar_agg/manifest.json')]") +function tmt:get-json($collection-uri as xs:string, + $manifest-uri as xs:string) { + tapi-mani:get-json($collection-uri, $manifest-uri, $tc:server) +}; + +declare + %test:args("ahiqar_agg") %test:assertEquals("Beispieldatei zum Testen") +function tmt:get-manifest-title($manifest-uri as xs:string) { + tapi-mani:get-manifest-title($manifest-uri) +}; + +declare + %test:args("ahiqar_agg") %test:assertXPath("count($result) = 2") + %test:args("ahiqar_agg") %test:assertXPath("$result//name = 'Simon Birol'") + %test:args("test-manifest1") %test:assertXPath("count($result) = 1") + %test:args("test-manifest1") %test:assertXPath("$result//name = 'none'") +function tmt:make-editors($manifest-uri as xs:string) { + tapi-mani:make-editors($manifest-uri) +}; + +declare + %test:args("ahiqar_agg") %test:assertXPath("$result/string() = '18.10.1697'") + %test:args("test-manifest1") %test:assertXPath("$result/string() = 'unknown'") +function tmt:make-creation-date($manifest-uri as xs:string) { + tapi-mani:make-creation-date($manifest-uri) +}; + +declare + %test:args("ahiqar_agg") %test:assertXPath("$result/string() = 'Alqosh, Iraq'") + %test:args("test-manifest1") %test:assertXPath("$result/string() = 'unknown'") + %test:args("test-manifest2") %test:assertXPath("$result/string() = 'Iraq'") + %test:args("test-manifest3") %test:assertXPath("$result/string() = 'Alqosh'") +function tmt:make-origin($manifest-uri as xs:string) { + tapi-mani:make-origin($manifest-uri) +}; + +declare + %test:args("ahiqar_agg") %test:assertXPath("$result/string() = 'University of Cambridge - Cambridge University Library, Great Britain'") + %test:args("test-manifest1") %test:assertXPath("$result/string() = 'unknown'") + %test:args("test-manifest2") %test:assertXPath("$result/string() = 'University of Cambridge - Cambridge University Library'") + %test:args("test-manifest3") %test:assertXPath("$result/string() = 'Great Britain'") +function tmt:make-current-location($manifest-uri as xs:string) { + tapi-mani:make-current-location($manifest-uri) +}; + +declare + %test:args("ahiqar_collection", "ahiqar_agg") %test:assertExists +function tmt:get-json($collection-uri as xs:string, + $manifest-uri as xs:string) { + tapi-mani:get-json($collection-uri, $manifest-uri, $tc:server) +}; + diff --git a/exist-app/tests/tapi-tests.xqm b/exist-app/tests/tapi-tests.xqm new file mode 100644 index 0000000000000000000000000000000000000000..646cb6ff3d7e07c431f82589ba4453209b5396bc --- /dev/null +++ b/exist-app/tests/tapi-tests.xqm @@ -0,0 +1,372 @@ +xquery version "3.1"; + +(:~ + : Test module for the RESTXQ endpoints of the Ahikar TextAPI. + : + : @author Michelle Weidling + : @version 0.1.0 + :) + +module namespace tt="http://ahikar.sub.uni-goettingen.de/ns/tapi/tests"; + +declare namespace http = "http://expath.org/ns/http-client"; +declare namespace tei="http://www.tei-c.org/ns/1.0"; + +import module namespace anno="http://ahikar.sub.uni-goettingen.de/ns/annotations" at "../modules/annotations.xqm"; +import module namespace map="http://www.w3.org/2005/xpath-functions/map"; +import module namespace tapi="http://ahikar.sub.uni-goettingen.de/ns/tapi" at "../modules/tapi.xqm"; +import module namespace tc="http://ahikar.sub.uni-goettingen.de/ns/tests/commons" at "test-commons.xqm"; +import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; + +declare + %test:setUp +function tt:_test-setup() as xs:string+ { + xmldb:create-collection("/db", "test-records"), + xmldb:store("/db/test-records", "white-spaces.xml", <record><id>12 34 56 + 78</id></record>), + xmldb:store("/db/test-records", "sample-tei.xml", <text xmlns="http://www.tei-c.org/ns/1.0" type="transcription">test + <note>test2</note> + test3 + <sic>text4</sic> + <placeName>Berlin</placeName> + </text>), + xmldb:store("/db/test-records", "origin-country-only.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> + <history> + <origin> + <country>Iraq</country> + </origin> + </history> + </teiHeader>), + xmldb:store("/db/test-records", "origin-place-only.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> + <history> + <origin> + <placeName>Alqosh</placeName> + </origin> + </history> + </teiHeader>), + xmldb:store("/db/test-records", "header-empty-history-msIdentifier.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> + <msIdentifier/> + <history/> + </teiHeader>), + xmldb:store("/db/test-records", "location-country-only.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> + <msIdentifier> + <settlement> + <country>Great Britain</country> + </settlement> + </msIdentifier> + </teiHeader>), + xmldb:store("/db/test-records", "location-institution-only.xml", <teiHeader xmlns="http://www.tei-c.org/ns/1.0"> + <msIdentifier> + <institution>University of Cambridge - Cambridge University Library</institution> + </msIdentifier> + </teiHeader>) +}; + +declare + %test:tearDown +function tt:_test-teardown() as item() { + xmldb:remove("/db/test-records") +}; + +declare + (: check if requests work :) + %test:assertXPath("map:get($result, 'request') => map:get('scheme') = 'http'") + (: check if expathpkg works :) + %test:assertXPath("map:get($result, 'package') => map:get('title') = 'TextAPI for Ahikar'") + (: check if repo.xml works :) + %test:assertXPath("map:get($result, 'meta') => map:get('target') = 'ahikar'") +function tt:api-info() as item() { + let $url := $tc:server || "/info" + let $req := tc:make-request($url) + return http:send-request($req)[2] => util:base64-decode() => parse-json() +}; + + +declare + %test:assertTrue +function tt:is-html-api-available() +as xs:boolean { + let $url := $tc:server || "/content/ahiqar_sample-82a.html" + return + tc:is-endpoint-http200($url) +}; + +declare + (: check if tei:div is present. + : no further tests are needed since the content has been tested while testing + : the underlying function. :) + %test:assertXPath("$result//*[@class = 'tei_body']") +function tt:content-rest() as document-node() { + let $url := $tc:server || "/content/ahiqar_sample-82a.html" + let $req := tc:make-request($url) + return http:send-request($req)[2] +}; + + +declare + (: check if ZIP is present. + : no further tests are needed since the content has been tested while testing + : the underlying function. :) + %test:assertExists + %test:pending +function tt:content-zip() as xs:base64Binary { + let $url := $tc:server || "/content/ahikar-plain-text.zip" + let $req := <http:request href="{$url}" method="get"> + <http:header name="Connection" value="close"/> + </http:request> + return http:send-request($req)[2] +}; + + +declare + (: check if txt is present. + : no further tests are needed since the content has been tested while testing + : the underlying function. :) + %test:assertXPath("matches($result, '[\w]')") +function tt:content-txt() as xs:string { + let $url := $tc:server || "/textapi/ahikar/ahiqar_collection/ahiqar_sample.txt" + let $req := <http:request href="{$url}" method="get"> + <http:header name="Connection" value="close"/> + </http:request> + return http:send-request($req)[2] +}; + + +declare + %test:assertTrue +function tt:is-txt-api-available() { + let $url := $tc:server || "/content/ahiqar_sample.txt" + return + tc:is-endpoint-http200($url) +}; + +declare function tt:txt() { + let $url := $tc:server || "textapi/ahiqar/ahiqar_collection/ahiqar_sample.txt" + let $req := tc:make-request($url) + return http:send-request($req)[2] => util:base64-decode() +}; + + +declare + %test:assertXPath("$result/string() = '1234 5678'") +function tt:remove-whitespaces() as document-node() { + let $doc := doc("/db/test-records/white-spaces.xml") + return + tapi:remove-whitespaces($doc) +}; + +declare + %test:assertTrue +function tt:is-collection-endpoint-http200() { + let $url := $tc:server || "/textapi/ahikar/ahiqar_collection/collection.json" + return + tc:is-endpoint-http200($url) +}; + + +declare + (: check if all parts are present. + : no further tests are needed since the content has been tested while testing + : the underlying function. :) + %test:assertXPath("map:contains($result, 'title')") + %test:assertXPath("map:contains($result, 'collector')") + %test:assertXPath("map:contains($result, 'description')") + %test:assertXPath("map:contains($result, 'sequence')") +function tt:endpoint-collection() +as item() { + let $url := $tc:server || "/textapi/ahikar/ahiqar_collection/collection.json" + let $req := <http:request href="{$url}" method="get"> + <http:header name="Connection" value="close"/> + </http:request> + return http:send-request($req)[2] => util:base64-decode() => parse-json() +}; + +declare + %test:assertTrue +function tt:is-manifest-endpoint-http200() { + let $url := $tc:server || "/textapi/ahikar/ahiqar_collection/ahiqar_agg/manifest.json" + return + tc:is-endpoint-http200($url) +}; + +declare + (: check if all parts are present. + : no further tests are needed since the content has been tested while testing + : the underlying function. :) + %test:assertXPath("map:contains($result, 'textapi')") + %test:assertXPath("map:contains($result, 'id')") + %test:assertXPath("map:contains($result, 'label')") + %test:assertXPath("map:contains($result, 'x-editor')") + %test:assertXPath("map:contains($result, 'x-date')") + %test:assertXPath("map:contains($result, 'x-origin')") + %test:assertXPath("map:contains($result, 'x-location')") + %test:assertXPath("map:contains($result, 'license')") + %test:assertXPath("map:contains($result, 'annotationCollection')") + %test:assertXPath("map:contains($result, 'sequence')") +function tt:endpoint-manifest() +as item() { + let $url := $tc:server || "/textapi/ahikar/ahiqar_collection/ahiqar_agg/manifest.json" + let $req := tc:make-request($url) + return + http:send-request($req)[2] + => util:base64-decode() + => parse-json() +}; + +declare + %test:assertTrue +function tt:is-item-endpoint-http200() { + let $url := $tc:server || "/textapi/ahikar/ahiqar_collection/ahiqar_agg-82a/latest/item.json" + return + tc:is-endpoint-http200($url) +}; + +declare + (: check if all parts are present. + : no further tests are needed since the content has been tested while testing + : the underlying function. :) + %test:assertXPath("map:contains($result, 'textapi')") + %test:assertXPath("map:contains($result, 'title')") + %test:assertXPath("map:contains($result, 'type')") + %test:assertXPath("map:contains($result, 'n')") + %test:assertXPath("map:contains($result, 'content')") + %test:assertXPath("map:contains($result, 'content-type')") + %test:assertXPath("map:contains($result, 'lang')") + %test:assertXPath("map:contains($result, 'langAlt')") + %test:assertXPath("map:contains($result, 'image')") +function tt:endpoint-item() as item() { + let $url := $tc:server || "/textapi/ahikar/ahiqar_collection/ahiqar_agg-82a/latest/item.json" + let $req := tc:make-request($url) + return http:send-request($req)[2] + => util:base64-decode() + => parse-json() +}; + + +(: + : ***************** + : * AnnotationAPI * + : ***************** + :) + +declare + %test:args("ahiqar_sample", "data") + %test:assertXPath("$result//*[local-name(.) = 'TEI']") +function tt:anno-get-document($uri as xs:string, $type as xs:string) as document-node() { + anno:get-document($uri, $type) +}; + + +(:declare:) +(: %test:args("3r679", "114r"):) +(: %test:assertEquals("0"):) +(:function tt:anno-determine-start-index-for-page($uri as xs:string, $page as xs:string) {:) +(: anno:determine-start-index-for-page($uri, $page):) +(:};:) +(::) +(::) +(:declare:) +(: %test:args("3r131"):) +(: %test:assertEquals("16"):) +(:function tt:anno-determine-start-index($uri as xs:string) {:) +(: anno:determine-start-index($uri):) +(:};:) +(::) +(:declare:) +(: %test:args("3r131"):) +(: %test:assertEquals("3r679"):) +(:function tt:anno-get-parent-aggregation($uri as xs:string) {:) +(: anno:get-parent-aggregation($uri):) +(:};:) +(::) +(::) +(:declare:) +(: %test:args("3r131"):) +(: %test:assertEquals("114r", "114v"):) +(:function tt:anno-get-pages-in-TEI($uri as xs:string) {:) +(: anno:get-pages-in-TEI($uri):) +(:};:) +(::) +(::) +(:declare:) +(: %test:args("3r679"):) +(: %test:assertTrue:) +(:function tt:anno-is-resource-edition($uri as xs:string) {:) +(: anno:is-resource-edition($uri):) +(:};:) +(::) +(::) +(:declare:) +(: %test:args("3r131"):) +(: %test:assertTrue:) +(:function tt:anno-is-resource-xml($uri as xs:string) {:) +(: anno:is-resource-xml($uri):) +(:};:) + + +declare + %test:assertEquals("A place's name.") +function tt:anno-get-bodyValue() { + let $annotation := doc("/db/test-records/sample-tei.xml")//tei:placeName + return + anno:get-bodyValue($annotation) +}; + + +declare + %test:args("asdf") + %test:assertFalse +(: %test:args("3r131"):) +(: %test:assertTrue:) +function tt:anno-are-resources-available($resources as xs:string+) { + anno:are-resources-available($resources) +}; + + +(:declare:) +(: %test:args("3r131"):) +(: %test:assertEquals("Simon Birol, Aly Elrefaei"):) +(:function tt:anno-get-creator($uri as xs:string) {:) +(: anno:get-creator($uri):) +(:};:) +(::) +(::) +(:declare:) +(: %test:args("3r131"):) +(: %test:assertEquals("Brit. Lib. Add. 7200"):) +(:function tt:anno-get-metadata-title($uri as xs:string) {:) +(: anno:get-metadata-title($uri):) +(:};:) +(::) +(::) +(:declare:) +(: %test:args("3r679"):) +(: %test:assertEquals("3r676", "3r672"):) +(:function tt:anno-get-prev-xml-uris($uri as xs:string) {:) +(: anno:get-prev-xml-uris($uri):) +(:};:) +(::) +(::) +(:declare:) +(: %test:args("3r679"):) +(: %test:assertEquals("3r676", "3r672"):) +(:function tt:anno-get-xmls-prev-in-collection($uri as xs:string) {:) +(: anno:get-xmls-prev-in-collection($uri):) +(:};:) + + +(:declare:) +(: %test:args("3r679", "114r", "next"):) +(: %test:assertEquals("114v"):) +(:function tt:anno-get-prev-or-next-page($documentURI as xs:string,:) +(:$page as xs:string, $type as xs:string) {:) +(: anno:get-prev-or-next-page($documentURI, $page, $type):) +(:};:) +(::) +(::) +(:declare:) +(: %test:args("3r9ps"):) +(: %test:assertEquals("3r177", "3r178", "3r7vw", "3r7p1", "3r7p9", "3r7sk", "3r7tp", "3r7vd", "3r179", "3r7n0", "3r9vn", "3r9wf", "3rb3z", "3rbm9", "3rbmc", "3rx14", "3vp38"):) +(:function tt:anno-get-uris($documentURI) {:) +(: anno:get-uris($documentURI):) +(:};:) diff --git a/exist-app/tests/collate-tests.xqm b/exist-app/tests/tapi-txt-tests.xqm similarity index 62% rename from exist-app/tests/collate-tests.xqm rename to exist-app/tests/tapi-txt-tests.xqm index 7759776092b2ecf0c2257f15eeaa1de459c4d435..eb82e3372d09e22706b46374aea5d2a4334fcab2 100644 --- a/exist-app/tests/collate-tests.xqm +++ b/exist-app/tests/tapi-txt-tests.xqm @@ -1,62 +1,70 @@ xquery version "3.1"; -module namespace coll-tests="http://ahikar.sub.uni-goettingen.de/ns/coll-tests"; +module namespace ttt="http://ahikar.sub.uni-goettingen.de/ns/tapi/txt/tests"; declare namespace tei="http://www.tei-c.org/ns/1.0"; -import module namespace coll="http://ahikar.sub.uni-goettingen.de/ns/collate" at "modules/collate.xqm"; +import module namespace tapi-txt="http://ahikar.sub.uni-goettingen.de/ns/tapi/txt" at "../modules/tapi-txt.xqm"; import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; -declare variable $coll-tests:sample-file := local:open-file("ahiqar_sample"); -declare variable $coll-tests:sample-transliteration := $coll-tests:sample-file//tei:text[@type = "transliteration"]; -declare variable $coll-tests:sample-transcription := $coll-tests:sample-file//tei:text[@type = "transcription"]; +declare variable $ttt:sample-file := local:open-file("ahiqar_sample"); +declare variable $ttt:sample-transliteration := $ttt:sample-file//tei:text[@type = "transliteration"]; +declare variable $ttt:sample-transcription := $ttt:sample-file//tei:text[@type = "transcription"]; + +declare + %test:setUp +function ttt:_test-setup() +as xs:string+ { + tapi-txt:main() +}; + declare %test:args("ahiqar_sample") %test:assertExists %test:args("1234") %test:assertError("org.exist.xquery.XPathException") -function coll-tests:open-file($uri as xs:string) as document-node() { +function ttt:open-file($uri as xs:string) as document-node() { local:open-file($uri) }; declare %test:assertXPath("count($result) = 2") -function coll-tests:get-milestones-in-text() +function ttt:get-milestones-in-text() as element(tei:milestone)* { - coll:get-milestones-in-text($coll-tests:sample-transliteration) + tapi-txt:get-milestones-in-text($ttt:sample-transliteration) }; declare %test:assertExists -function coll-tests:get-next-milestone-succecss() +function ttt:get-next-milestone-succecss() as element(tei:milestone)? { - let $milestone := $coll-tests:sample-transliteration//tei:milestone[1] + let $milestone := $ttt:sample-transliteration//tei:milestone[1] return - coll:get-next-milestone($milestone) + tapi-txt:get-next-milestone($milestone) }; declare %test:assertEmpty -function coll-tests:get-next-milestone-fail() +function ttt:get-next-milestone-fail() as element(tei:milestone)? { - let $milestone := $coll-tests:sample-transliteration//tei:milestone[2] + let $milestone := $ttt:sample-transliteration//tei:milestone[2] return - coll:get-next-milestone($milestone) + tapi-txt:get-next-milestone($milestone) }; declare %test:assertExists %test:assertXPath("$result//*[local-name(.) = 'ab']") -function coll-tests:get-chunk() +function ttt:get-chunk() as element(tei:TEI) { - let $milestone := $coll-tests:sample-transliteration//tei:milestone[1] + let $milestone := $ttt:sample-transliteration//tei:milestone[1] return - coll:get-chunk($milestone) + tapi-txt:get-chunk($milestone) }; declare %test:assertEquals("some text that should be used display some text without a space") -function coll-tests:make-plain-text-from-chunk() +function ttt:make-plain-text-from-chunk() as xs:string { let $chunk := <TEI xmlns="http://www.tei-c.org/ns/1.0"> @@ -90,13 +98,13 @@ as xs:string { </text> </TEI> return - coll:make-plain-text-from-chunk($chunk) + tapi-txt:make-plain-text-from-chunk($chunk) }; declare %test:assertEquals("some text with") -function coll-tests:prepare-plain-text-creation-no-lb() +function ttt:prepare-plain-text-creation-no-lb() as xs:string { let $chunk := <TEI xmlns="http://www.tei-c.org/ns/1.0"> @@ -112,12 +120,12 @@ as xs:string { </TEI> let $text := $chunk//tei:ab/text() return - coll:prepare-plain-text-creation($text) + tapi-txt:prepare-plain-text-creation($text) }; declare %test:assertEquals("@out a space.") -function coll-tests:prepare-plain-text-creation-lb() +function ttt:prepare-plain-text-creation-lb() as xs:string { let $chunk := <TEI xmlns="http://www.tei-c.org/ns/1.0"> @@ -133,12 +141,12 @@ as xs:string { </TEI> let $text := $chunk//tei:ab/text() return - coll:prepare-plain-text-creation($text) + tapi-txt:prepare-plain-text-creation($text) }; declare %test:assertXPath("count($result) = 6") -function coll-tests:get-relevant-text-nodes() +function ttt:get-relevant-text-nodes() as text()+ { let $chunk := <TEI xmlns="http://www.tei-c.org/ns/1.0"> @@ -172,7 +180,7 @@ as text()+ { </text> </TEI> return - coll:get-relevant-text-nodes($chunk) + tapi-txt:get-relevant-text-nodes($chunk) }; declare @@ -182,15 +190,15 @@ declare %test:args("some new lines") %test:assertEquals("some new lines") -function coll-tests:format-and-normalize-string($string as xs:string) +function ttt:format-and-normalize-string($string as xs:string) as xs:string { - coll:format-and-normalize-string($string) + tapi-txt:format-and-normalize-string($string) }; declare %test:assertTrue -function coll-tests:create-txt-collection-if-not-available() { - let $create-collection := coll:create-txt-collection-if-not-available() +function ttt:create-txt-collection-if-not-available() { + let $create-collection := tapi-txt:create-txt-collection-if-not-available() return if (xmldb:collection-available("/db/apps/sade/textgrid/txt/")) then true() @@ -200,22 +208,22 @@ function coll-tests:create-txt-collection-if-not-available() { declare %test:assertXPath("count($result) gt 0") -function coll-tests:get-transcriptions-and-transliterations() +function ttt:get-transcriptions-and-transliterations() as element(tei:text)+ { - coll:get-transcriptions-and-transliterations() + tapi-txt:get-transcriptions-and-transliterations() }; declare %test:args("ara") %test:assertEquals("arabic") %test:args("karshuni") %test:assertEquals("karshuni") %test:args("syc") %test:assertEquals("syriac") -function coll-tests:get-language-prefix-transcriptions($lang as xs:string) +function ttt:get-language-prefix-transcriptions($lang as xs:string) as xs:string { let $text := <text xmlns="http://www.tei-c.org/ns/1.0" type="transcription" xml:lang="{$lang}" /> return - coll:get-language-prefix($text) + tapi-txt:get-language-prefix($text) }; declare @@ -228,7 +236,7 @@ declare %test:args("syriac", "ara") %test:assertEquals("arabic") %test:args("syriac", "karshuni") %test:assertEquals("karshuni") %test:args("syriac", "syc") %test:assertEquals("syriac") -function coll-tests:get-language-prefix-transliteration($lang-transliteration as xs:string, +function ttt:get-language-prefix-transliteration($lang-transliteration as xs:string, $lang-transcription as xs:string) as xs:string { let $TEI := @@ -238,47 +246,47 @@ as xs:string { </TEI> let $text := $TEI/tei:text[1] return - coll:get-language-prefix($text) + tapi-txt:get-language-prefix($text) }; declare %test:assertEquals("/db/apps/sade/textgrid/data/ahiqar_sample.xml") -function coll-tests:get-base-uri() +function ttt:get-base-uri() as xs:string { - coll:get-base-uri($coll-tests:sample-transcription) + tapi-txt:get-base-uri($ttt:sample-transcription) }; declare %test:assertEquals("Beispieldatei_zum_Testen") -function coll-tests:create-metadata-title-for-file-name() +function ttt:create-metadata-title-for-file-name() as xs:string { - coll:create-metadata-title-for-file-name($coll-tests:sample-transcription) + tapi-txt:create-metadata-title-for-file-name($ttt:sample-transcription) }; declare %test:assertEquals("karshuni-Beispieldatei_zum_Testen-ahiqar_sample-transcription.txt") -function coll-tests:make-file-name() +function ttt:make-file-name() as xs:string { - coll:make-file-name($coll-tests:sample-transcription) + tapi-txt:make-file-name($ttt:sample-transcription) }; declare %test:assertEquals("ahiqar_sample-transcription.txt") -function coll-tests:make-file-name-suffix() +function ttt:make-file-name-suffix() as xs:string { - coll:make-file-name-suffix($coll-tests:sample-transcription) + tapi-txt:make-file-name-suffix($ttt:sample-transcription) }; declare %test:args("/db/apps/sade/textgrid/data/ahiqar_sample.xml") %test:assertEquals("ahiqar_sample") -function coll-tests:get-file-name($base-uri as xs:string) +function ttt:get-file-name($base-uri as xs:string) as xs:string { - coll:get-file-name($base-uri) + tapi-txt:get-file-name($base-uri) }; declare %test:assertEquals("text of the first narrative section some sayings") -function coll-tests:get-relevant-text() { +function ttt:get-relevant-text() { let $TEI := <TEI xmlns="http://www.tei-c.org/ns/1.0"> <text> @@ -292,37 +300,37 @@ function coll-tests:get-relevant-text() { </text> </TEI> return - coll:get-relevant-text($TEI/tei:text) + tapi-txt:get-relevant-text($TEI/tei:text) }; declare %test:assertXPath("count($result) = 2") -function coll-tests:get-chunks() { - let $milestones := coll:get-milestones-in-text($coll-tests:sample-transliteration) +function ttt:get-chunks() { + let $milestones := tapi-txt:get-milestones-in-text($ttt:sample-transliteration) return - coll:get-chunks($milestones) + tapi-txt:get-chunks($milestones) }; declare %test:assertXPath("$result[self::*[local-name(.) = 'milestone']]") -function coll-tests:get-end-of-chunk-milestone() { - let $milestone := coll:get-milestones-in-text($coll-tests:sample-transliteration)[1] +function ttt:get-end-of-chunk-milestone() { + let $milestone := tapi-txt:get-milestones-in-text($ttt:sample-transliteration)[1] return - coll:get-end-of-chunk($milestone) + tapi-txt:get-end-of-chunk($milestone) }; declare %test:assertXPath("$result[self::*[local-name(.) = 'ab']]") -function coll-tests:get-end-of-chunk-end-of-text() { - let $milestone := coll:get-milestones-in-text($coll-tests:sample-transliteration)[2] +function ttt:get-end-of-chunk-end-of-text() { + let $milestone := tapi-txt:get-milestones-in-text($ttt:sample-transliteration)[2] return - coll:get-end-of-chunk($milestone) + tapi-txt:get-end-of-chunk($milestone) }; declare %test:assertXPath("$result[self::*/string() = 'the end text']") -function coll-tests:get-end-of-chunk-end-of-text-2() { +function ttt:get-end-of-chunk-end-of-text-2() { let $TEI := <TEI xmlns="http://www.tei-c.org/ns/1.0"> <text> @@ -345,30 +353,30 @@ function coll-tests:get-end-of-chunk-end-of-text-2() { let $milestone := $TEI//tei:text[@type = "transliteration"]//tei:milestone return - coll:get-end-of-chunk($milestone) + tapi-txt:get-end-of-chunk($milestone) }; declare %test:assertTrue -function coll-tests:has-following-milestone-true() +function ttt:has-following-milestone-true() as xs:boolean { - let $milestone := coll:get-milestones-in-text($coll-tests:sample-transliteration)[1] + let $milestone := tapi-txt:get-milestones-in-text($ttt:sample-transliteration)[1] return - coll:has-following-milestone($milestone) + tapi-txt:has-following-milestone($milestone) }; declare %test:assertFalse -function coll-tests:has-following-milestone-false() +function ttt:has-following-milestone-false() as xs:boolean { - let $milestone := coll:get-milestones-in-text($coll-tests:sample-transliteration)[2] + let $milestone := tapi-txt:get-milestones-in-text($ttt:sample-transliteration)[2] return - coll:has-following-milestone($milestone) + tapi-txt:has-following-milestone($milestone) }; declare %test:assertEquals("chunk1 relevant text more relevant text chunk2 relevant text more relevant text") -function coll-tests:get-relevant-text-from-chunks() +function ttt:get-relevant-text-from-chunks() as xs:string { let $chunk1 := <TEI xmlns="http://www.tei-c.org/ns/1.0"> @@ -389,12 +397,12 @@ as xs:string { </text> </TEI> return - coll:get-relevant-text-from-chunks(($chunk1, $chunk2)) + tapi-txt:get-relevant-text-from-chunks(($chunk1, $chunk2)) }; declare %test:assertTrue -function coll-tests:has-text-milestone-succcess() { +function ttt:has-text-milestone-succcess() { let $text:= <text xmlns="http://www.tei-c.org/ns/1.0"> <body> @@ -402,12 +410,12 @@ function coll-tests:has-text-milestone-succcess() { </body> </text> return - coll:has-text-milestone($text) + tapi-txt:has-text-milestone($text) }; declare %test:assertFalse -function coll-tests:has-text-milestones-fail() { +function ttt:has-text-milestones-fail() { let $text:= <text xmlns="http://www.tei-c.org/ns/1.0"> <body> @@ -415,10 +423,79 @@ function coll-tests:has-text-milestones-fail() { </body> </text> return - coll:has-text-milestone($text) + tapi-txt:has-text-milestone($text) }; declare function local:open-file($uri as xs:string) as document-node() { - doc($coll:data || "/" || $uri || ".xml") + doc($tapi-txt:data || "/" || $uri || ".xml") +}; + + +declare + %test:args("ahiqar_sample", "transcription") + %test:assertXPath("$result[local-name(.) = 'text' and @type = 'transcription']") +function ttt:get-tei($document-uri as xs:string, + $type as xs:string) +as element() { + tapi-txt:get-TEI-text($document-uri, $type) +}; + +declare + %test:args("ahiqar_sample") %test:assertEquals("text/xml") + %test:args("ahiqar_agg") %test:assertEquals("text/tg.edition+tg.aggregation+xml") +function ttt:tgmd-format($uri as xs:string) +as xs:string { + tapi-txt:get-format($uri) +}; + + +declare + %test:args("ahiqar_sample", "transcription") + %test:assertXPath("$result[local-name(.) = 'text' and @type = 'transcription']") +function ttt:get-tei($document as xs:string, $type as xs:string) as element() { + tapi-txt:get-TEI-text($document, $type) +}; + + +declare + %test:args("ahiqar_agg") %test:assertEquals("ahiqar_sample") +function ttt:get-tei-xml-uri-from-edition($document as xs:string) { + tapi-txt:get-tei-xml-uri-from-edition($document) +}; + + +declare + %test:args("ahiqar_agg") %test:assertEquals("ahiqar_sample") +function ttt:get-edition-aggregates-without-uri-namespace($document as xs:string) { + tapi-txt:get-edition-aggregates-without-uri-namespace($document) +}; + + +declare + %test:args("ahiqar_sample") %test:assertEquals("ahiqar_sample") +function ttt:get-tei-xml-from-aggregates($aggregates as xs:string+) { + tapi-txt:get-tei-xml-from-aggregates($aggregates) +}; + + +declare + %test:args("ahiqar_sample", "transliteration") %test:assertXPath("$result[@type = 'transliteration']") +function ttt:get-text-of-type($uri as xs:string, $type as xs:string) { + tapi-txt:get-text-of-type($uri, $type) +}; + +declare + %test:args("ahiqar_sample") %test:assertTrue + %test:args("ahiqar_agg") %test:assertFalse +function ttt:is-document-tei-xml($document-uri as xs:string) +as xs:boolean { + tapi-txt:is-document-tei-xml($document-uri) +}; + +declare + %test:assertExists +function ttt:compress-text() +as xs:base64Binary { + tapi-txt:compress-to-zip() }; diff --git a/exist-app/tests/test-commons.xqm b/exist-app/tests/test-commons.xqm new file mode 100644 index 0000000000000000000000000000000000000000..eaa17779835dab0ea4162b1932bebcadad0e7a32 --- /dev/null +++ b/exist-app/tests/test-commons.xqm @@ -0,0 +1,25 @@ +xquery version "3.1"; + +module namespace tc="http://ahikar.sub.uni-goettingen.de/ns/tests/commons"; + +declare namespace http = "http://expath.org/ns/http-client"; + +declare variable $tc:server := "http://0.0.0.0:8080/exist/restxq"; + +declare function tc:is-endpoint-http200($url as xs:string) as xs:boolean { + let $http-status := tc:get-http-status($url) + return + $http-status = "200" +}; + +declare function tc:get-http-status($url as xs:string) as xs:string { + let $req := tc:make-request($url) + return + http:send-request($req)[1]/@status +}; + +declare function tc:make-request($url as xs:string) { + <http:request href="{$url}" method="get"> + <http:header name="Connection" value="close"/> + </http:request> +}; \ No newline at end of file diff --git a/exist-app/tests/tests-runner.xq b/exist-app/tests/tests-runner.xq new file mode 100644 index 0000000000000000000000000000000000000000..0fb6c1e783e038698bca478358af9ded62d046eb --- /dev/null +++ b/exist-app/tests/tests-runner.xq @@ -0,0 +1,34 @@ +xquery version "3.1"; +(:~ + : Script providing access to the test functions (XQSuite) for local unit test + : execution. + : Elevated rights (dba/admin) are required for some tests. + :) + +import module namespace ttt="http://ahikar.sub.uni-goettingen.de/ns/tapi/txt/tests" at "tapi-txt-tests.xqm"; +import module namespace ct="http://ahikar.sub.uni-goettingen.de/ns/commons-tests" at "commons-tests.xqm"; +import module namespace tct="http://ahikar.sub.uni-goettingen.de/ns/tapi/collection/tests" at "tapi-collection-tests.xqm"; +import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql"; +import module namespace thtmlt="http://ahikar.sub.uni-goettingen.de/ns/tapi/html/tests" at "tapi-html-tests.xqm"; +import module namespace titemt="http://ahikar.sub.uni-goettingen.de/ns/tapi/item/tests" at "tapi-item-tests.xqm"; +import module namespace tmt="http://ahikar.sub.uni-goettingen.de/ns/tapi/manifest/tests" at "tapi-manifest-tests.xqm"; +import module namespace tt="http://ahikar.sub.uni-goettingen.de/ns/tapi/tests" at "tapi-tests.xqm"; + + +let $test-results := + ( + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/txt/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/commons-tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/collection/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/manifest/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/item/tests")), + test:suite(util:list-functions("http://ahikar.sub.uni-goettingen.de/ns/tapi/html/tests")) + ) + +for $result in $test-results return + if ($result//@failures = 0 + and $result//@errors = 0) then + "Everything okay: " || $result//@package + else + $result \ No newline at end of file diff --git a/get-unit-test-failures-and-errors.sh b/get-unit-test-failures-and-errors.sh new file mode 100755 index 0000000000000000000000000000000000000000..ee76a04ba95a361415f355a3e3353bb6d2c384bf --- /dev/null +++ b/get-unit-test-failures-and-errors.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +failures=$(xmllint --xpath '/tests/testsuites/testsuite/@failures' exist-app/test/test-results.xml | egrep -o "[0-9]+") +errors=$(xmllint --xpath '/tests/testsuites/testsuite/@errors' exist-app/test/test-results.xml | egrep -o "[0-9]+") + +problem_sum=0 + +for FAILURE in $failures $errors +do + let problem_sum+=$FAILURE +done + +echo $problem_sum