diff --git a/config.xml b/config.xml
index 3281e2070d699ab412ceaee3c92b7840efd5aa32..cb14b6a55f2998c5632dcfecb91555f86b29f169 100644
--- a/config.xml
+++ b/config.xml
@@ -1,3 +1,4 @@
+
+ dot
+
+
+
\ No newline at end of file
diff --git a/docs/about.md b/docs/about.md
index c2740defa9bfabdab77d7a6dd5196aba32d5d3c7..d23d095fd14a9f75e7a3f3fb4518326802e6fcef 100644
--- a/docs/about.md
+++ b/docs/about.md
@@ -39,6 +39,7 @@ version is a completely rewritten one.
- [Dokuwiki](dokuwikiParser.md)
- multi-language support
- [prepared for optionally prerendering](prerendering.md)
+- create [call graphs](callgraphs.md) of modules
### Third party addons
- SemToNotes
diff --git a/docs/callgraphs.md b/docs/callgraphs.md
new file mode 100644
index 0000000000000000000000000000000000000000..424a241effea70e52b64a07b14452e3d4ba7b8cd
--- /dev/null
+++ b/docs/callgraphs.md
@@ -0,0 +1,66 @@
+# Call graphs (call multigraphs)
+
+This modules examines XQuery modules and creates an SVG representation of their respective call graphs.
+These call graphs are useful as an overview of how the SADE app and project specific extensions work and can be used as illustration of the app's architecture, for improving a module's structure while developing, ...
+
+To meet the different needs of users, three ways of using this module are possible:
+
+You can create the call graph of
+
+* a single module
+* all modules that belong to a collection
+* the whole SADE app
+
+
+
+## Requirements
+Please make sure you have [GraphViz](http://graphviz.org/) installed wherever the database runs (on your computer, on a VM, ...).
+
+
+## Configuration
+For the module to work properly you have to consider on which kind of operating system (Windows, Unix, MacOS, ...) the database runs.
+Simply change the following line in `config.xml` to the command line invocation of `dot` that is used by your OS:
+
+```xml
+\dot
+```
+
+The option defaults to Unix' `dot` command.
+
+
+## How to create call graphs
+Before using the call graph module please make sure you have the module imported with
+
+```
+import module namespace callgraph="https://sade.textgrid.de/ns/callgraph" at "$(path/to/module)/callgraph.xqm";
+```
+
+To generate a call graph all you have to do is calling the function
+
+```
+callgraph:main("/some/input/as/string", "filename/as/string")
+```
+where the first input parameter can be the following:
+
+* the base URI of a single module, e.g. `/db/apps/sade/modules/some-module.xqm`
+* the URI of a collection as path, e.g. `/db/apps/sade/modules/my-project-collection`
+* `full` (generates a call graph for the whole SADE app)
+
+The second parameter is the desired filename __without__ file extension.
+
+The call graph SVG is stored to `/db/apps/sade/modules/callgraph/svg` while the GraphML representation can be found at `/db/apps/sade/modules/callgraph/graphml`.
+
+
+## How it works (in detail)
+Depending on which input option you select (cf. "How to create call graphs" above) one or more modules are examined by eXist-db's `inspect:inspect-module` function which returns some information about the module(s) and its functions.
+
+This information is then converted into a [GraphML](http://graphml.graphdrawing.org/) representation of the module as a directed graph in which all calling and called functions are represented as a `graphml:node` element. In case several modules are inspected duplicates are avoided. The calling/called connection between two functions is denoted by a `graphml:edge` element where the calling function becomes the edge's `@source` and the called one the edge's `@target`.
+
+This GraphML document is then saved to `/db/apps/sade/callgraph/graphml` and serves as input for generating a [DOT](https://graphviz.gitlab.io/_pages/doc/info/lang.html) representation of the graph which in turn is used by `dot` to create an SVG file that is saved to `/db/apps/sade/callgraph/svg`.
+
+
+## Sample output
+
+The following image has been generated by the callgraph-module and illustrates how its modules and functions interact:
+
+
\ No newline at end of file
diff --git a/modules/callgraph/callgraph.xqm b/modules/callgraph/callgraph.xqm
new file mode 100644
index 0000000000000000000000000000000000000000..b7b31ea579af64f6b315aae65a7097cdb3eb5b1f
--- /dev/null
+++ b/modules/callgraph/callgraph.xqm
@@ -0,0 +1,221 @@
+xquery version "3.1";
+
+(:~
+ : This module creates an SVG image of call graph of
+ :
+ : * a given module
+ : * the modules of a given collection
+ : * the modules of the whole SADE app
+ :
+ : A module is defined as a file that ends with '.xqm'.
+ : While the SVG image is stored to /db/apps/sade/modules/callgraph/svg,
+ : the intermediate GraphML representation of the call graph is saved to
+ : /db/apps/sade/modules/callgraph/graphml and could be re-used in other
+ : applications.
+ :
+ : This module was roughly inspired by the graphviz app for eXist-db which can be
+ : found at https://github.com/KitWallace/graphviz.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @see https://github.com/KitWallace/graphviz
+ :
+ : :)
+
+
+module namespace callgraph="https://sade.textgrid.de/ns/callgraph";
+
+import module namespace config="https://sade.textgrid.de/ns/config" at "../config.xqm";
+import module namespace console="http://exist-db.org/xquery/console";
+import module namespace functx="http://www.functx.com";
+import module namespace inspect="http://exist-db.org/xquery/inspection";
+import module namespace inspect2graphml="https://sade.textgrid.de/ns/inspect2graphml" at "inspect2graphml.xqm";
+
+declare namespace graphml="http://graphml.graphdrawing.org/xmlns";
+declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";
+
+declare variable $callgraph:xslt := $config:app-root || "/modules/callgraph/graphml2dot.xsl";
+declare variable $callgraph:colors :=
+ ("#90b0d4", "#e6f2ff", "#eee6ff", "#ffffe6",
+ "#f9ecec", "#bfe0ba", "#bfd2e3", "#dbaddb",
+ "#decbb2", "#e0b7b6", "#d9f09e", "#f5a1a4",
+ "#faf0a5", "#8acca0", "#cfb88c", "#d18ecb");
+
+(:~
+ : Creates an SVG file of one or more modules depending on the given $option.
+ : Possible options are:
+ : * an URI of a single module, e.g. "/db/apps/sade/modules/callgraph/tests/xqm/inspect2graphml-testmodule.xqm"
+ : * a collection URI, e.g. "/db/apps/sade/modules/callgraph/tests/xqm/"
+ : * "full" which will consider all *.xqm in the SADE app
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @param $option Selects the modules which should be displayed in the output SVG file
+ : @param $filename The filename without extension, e.g. "output"
+ : @return Message that indicates a successfull transformation
+ : @error The given option is invalid
+ : @error The given filename is invalid
+ : :)
+declare function callgraph:main($option as xs:string, $filename as xs:string) as xs:string {
+ if(ends-with($option, ".xqm")
+ or $option = "full"
+ or xmldb:collection-available($option)) then
+ let $filename :=
+ if(contains($filename, ".")) then
+ error( QName("https://sade.textgrid.de/ns/app", "CALLGRAPH01"),
+ "Invalid filename '" || $filename || "'. Please enter a filename without file extension.")
+ else
+ $filename
+ let $dot := callgraph:get-dot($option, $filename)
+ let $svg-output := callgraph:get-svg($dot)
+ let $svg := callgraph:clear-svg($svg-output, $filename)
+
+ return "Call graph creation successfull."
+ else
+ error( QName("https://sade.textgrid.de/ns/app", "CALLGRAPH02"),
+ "Invalid option '" || $option || "'. Please enter a base URI, a collection path or 'full' as argument.")
+};
+
+
+(:~
+ : Gets a DOT representation of the given module, the modules of a collection or
+ : all modules of the SADE app.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @see https://en.wikipedia.org/wiki/DOT_(graph_description_language)
+ : @param $option Selects the modules which should be displayed in the output SVG file (cf. callgraph:main)
+ : @return The DOT representation of the call graph
+ : @error GraphML couldn't be transformed to DOT
+ : @error The DOT file is empty
+ : :)
+declare function callgraph:get-dot($option as xs:string, $filename as xs:string)
+as xs:string {
+ let $graphml := inspect2graphml:main($option, $filename)
+ let $dot :=
+ try {
+ (: $graphml[1] is graphml:graphml,
+ $graphml[2] is path to stored XML :)
+ callgraph:transform2dot($graphml[1])
+ => string-join("")
+ } catch * {
+ error( QName("https://sade.textgrid.de/ns/app", "CALLGRAPH03"),
+ "Could not transform GraphML to DOT.")
+ }
+
+ return
+ if(normalize-space($dot) != "") then
+ $dot
+ else
+ error( QName("https://sade.textgrid.de/ns/app", "CALLGRAPH04"),
+ "DOT file is empty.")
+};
+
+
+(:~
+ : Transforms the given GraphML elements to DOT.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @see https://en.wikipedia.org/wiki/DOT_(graph_description_language)
+ : @param $nodes The GraphML nodes generated by inspect2graphml:main
+ : @return The DOT representation of the call graph
+ : :)
+declare function callgraph:transform2dot($nodes as element()*) as node()* {
+ for $node in $nodes return
+ typeswitch ($node)
+
+ case element(graphml:graphml) return
+ (text{"digraph g {"},
+ callgraph:transform2dot($node/node()),
+ text{"}"})
+
+ case element(graphml:graph) return
+ if($node/@id = "base-graph") then
+ callgraph:transform2dot($node/node())
+ else
+ (text{"node [shape=box, style=filled, color="""},
+ text{$callgraph:colors[count($node/preceding::graphml:graph) + 1]},
+ text{"""];"},
+ callgraph:transform2dot($node/node()))
+
+ case element(graphml:node) return
+ if($node/parent::graphml:graph[@id = "base-graph"]) then
+ callgraph:transform2dot($node/node())
+ else
+ (text{""""},
+ text{$node/@id},
+ text{""" [shape=box];"})
+
+ case element(graphml:edge) return
+ (text{""""},
+ text{$node/@source},
+ text{""""},
+ text{" -> "},
+ text{""""},
+ text{$node/@target},
+ text{""";"})
+
+ default return
+ callgraph:transform2dot($node/node())
+};
+
+
+
+(:~
+ : Creates an SVG file based of a given DOT file.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @see https://en.wikipedia.org/wiki/DOT_(graph_description_language)
+ : @param $dot A graph denoted in DOT
+ : @return The lines of the SVG file as element(line)
+ : @error DOT couldn't be transformed to SVG
+ : @error The SVG file is empty
+ : :)
+declare function callgraph:get-svg($dot as xs:string) as element(line)+ {
+ let $conf := $config:app-root || "/config.xml"
+ let $cmd := doc($conf)//*[@key = "dot-cmd"]/string()
+ let $target-dir := doc($conf)//*[@key = "target-dir"]/string()
+ let $options :=
+
+ {$target-dir}
+ {$dot}
+
+ let $output :=
+ try {
+ process:execute(($cmd, "-Tsvg"), $options)
+ } catch * {
+ error( QName("https://sade.textgrid.de/ns/app", "CALLGRAPH05"),
+ "Could not transform the given DOT file to SVG.")
+ }
+ return
+ if($output//stdout/line) then
+ $output
+ else
+ error( QName("https://sade.textgrid.de/ns/app", "CALLGRAPH06"),
+ "SVG output empty.")
+};
+
+
+(:~
+ : Since the output of callgraph:get-svg consists of multiple line elements that
+ : contain the XML representation of the SVG, this function extracts the SVG data
+ : and creates a valid SVG file.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @param $svg Multiple line elements that hold the SVG data
+ : @param $filename The name of the generated SVG file
+ : @return The path to the stored SVG file
+ : :)
+declare function callgraph:clear-svg($svg as element(execution), $filename as
+xs:string) as xs:string {
+ let $lines := $svg//line
+ let $content :=
+ for $line in subsequence($lines, 7) return
+ $line/string()
+ let $cleared-svg := string-join($content, "")
+ return
+ xmldb:store($config:app-root || "/modules/callgraph/svg/", $filename || ".svg", $cleared-svg)
+};
\ No newline at end of file
diff --git a/modules/callgraph/graphml/callgraph-modules-graphml.xml b/modules/callgraph/graphml/callgraph-modules-graphml.xml
new file mode 100644
index 0000000000000000000000000000000000000000..34fee6ea6f4b8031687e01c3da9dec90d5f15ba5
--- /dev/null
+++ b/modules/callgraph/graphml/callgraph-modules-graphml.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/modules/callgraph/inspect2graphml.xqm b/modules/callgraph/inspect2graphml.xqm
new file mode 100644
index 0000000000000000000000000000000000000000..4feceee2d183118bbab2231c944badccf334e22e
--- /dev/null
+++ b/modules/callgraph/inspect2graphml.xqm
@@ -0,0 +1,194 @@
+xquery version "3.1";
+(:~
+ : This module creates a GraphML representation of one or more given modules or
+ : even the whole SADE app. To achieve this we take the information retrieved by
+ : inspect:inspect-module and convert the relevant nodes to GraphML.
+ :
+ : The process was roughly inspired by the graphviz app for eXist-db which can
+ : be found at https://github.com/KitWallace/graphviz.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @see https://github.com/KitWallace/graphviz
+ : @see http://graphml.graphdrawing.org/specification.html
+ :
+ : :)
+
+
+module namespace inspect2graphml="https://sade.textgrid.de/ns/inspect2graphml";
+
+import module namespace config="https://sade.textgrid.de/ns/config" at "../config.xqm";
+import module namespace console="http://exist-db.org/xquery/console";
+import module namespace functx="http://www.functx.com";
+import module namespace inspect="http://exist-db.org/xquery/inspection";
+
+declare namespace graphml="http://graphml.graphdrawing.org/xmlns";
+declare namespace xsi="http://www.w3.org/2001/XMLSchema-instance";
+
+
+(:~
+ : The interface for other modules.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @param $option Selects the modules which should be displayed in the output SVG file (cf. callgraph:main for valid options)
+ : @return The graph representation as element(graphml:graphml)
+ : @return The path to the stored GraphML file
+ : :)
+declare function inspect2graphml:main($option as xs:string, $filename
+as xs:string) as item()+ {
+ let $graphml := inspect2graphml:get-graphml($option)
+ return
+ ($graphml,
+ xmldb:store($config:app-root || "/modules/callgraph/graphml/", $filename || "-graphml.xml", $graphml))
+};
+
+
+(:~
+ : Creates a GraphML representation of one or more given modules or even the
+ : whole SADE app.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @param $option Selects the modules which should be displayed in the output SVG file (cf. callgraph:main for valid options)
+ : :)
+declare function inspect2graphml:get-graphml($option as xs:string) as
+element(graphml:graphml) {
+ let $xqms := inspect2graphml:get-xqms($option)
+ return
+ if(count($xqms) = 1) then
+ element graphml:graphml {
+ attribute xsi:schemaLocation {"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"},
+ let $inspect-result := inspect:inspect-module(xs:anyURI($xqms))
+ let $transformed-subgraph := inspect2graphml:transform($inspect-result, true())
+ return local:sort-edges-and-nodes($transformed-subgraph)
+ }
+
+ else
+ element graphml:graphml {
+ attribute xsi:schemaLocation {"http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"},
+ element graphml:graph {
+ attribute id {"base-graph"},
+ attribute edgedefault {"directed"},
+ for $xqm in $xqms return
+ let $inspect-result := inspect:inspect-module(xs:anyURI($xqm))
+ let $transformed-subgraph := inspect2graphml:transform($inspect-result, false())
+
+ return
+ element graphml:node {
+ attribute id {util:hash($xqm, "md5")},
+ local:sort-edges-and-nodes($transformed-subgraph)
+ }
+ }
+ }
+};
+
+
+(:~
+ : Transforms the relevant nodes that have been generated by inspect:inspect-module
+ : to GraphML elements.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @param $nodes The nodes that are the result of inspect:inspect-module
+ : @param $single-module A flag denoting if the user wants only a single module to be considered. In this case all function elements have to be converted to graphml:node which otherwise would lead to redundancies.
+ : @return The transformed node(s)
+ : :)
+declare function inspect2graphml:transform($nodes as node()*, $single-module as xs:boolean) as node()* {
+ for $node in $nodes return
+ typeswitch ($node)
+
+ case element(module) return
+ element graphml:graph {
+ attribute id {$node/@prefix},
+ attribute edgedefault {"directed"},
+ inspect2graphml:transform($node/node(), $single-module)
+ }
+
+ case element(function) return
+ (local:make-node($node),
+ inspect2graphml:transform($node/node(), $single-module))
+
+ case element(calls) return
+ let $source-function := $node/ancestor::function[1]
+ let $prefix := substring-before($source-function/@name, ":")
+ for $called in $node/function
+ return
+ (element graphml:edge {
+ attribute source {$source-function/@name},
+ attribute target {$called/@name}
+ },
+ if($single-module
+ and not(substring-before($called/@name, ":") = $prefix)) then
+ local:make-node($called)
+ else
+ ())
+
+ default return
+ ()
+};
+
+
+(:~
+ : Gets all relevant *.xqm files.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @param $option Selects the modules which should be displayed in the output SVG file (cf. callgraph:main for valid options)
+ : @return A sequence of module URIs
+ : :)
+declare function inspect2graphml:get-xqms($option as xs:string) as xs:string* {
+ switch ($option)
+ case "full" return (collection($config:app-root)/base-uri())[ends-with(., ".xqm")]
+
+ default return
+ if(ends-with($option, ".xqm")) then
+ $option
+ else
+ for $child in xmldb:get-child-resources($option) return
+ if(contains($child, ".xqm")) then
+ $option || "/" || $child
+ else
+ ()
+};
+
+
+(:~
+ : Creates a graphml:node element.
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @param $node The current result node of inspect:inspect-module
+ : @return A respective graphml:node element
+ : :)
+declare function local:make-node($node as node()) as element(graphml:node) {
+ element graphml:node {
+ attribute id {$node/@name}
+ }
+};
+
+
+(:~
+ : As the output of inspect2graphml:transform mixes up graphml:node and
+ : graphml:edge, this function sorts them: We want all graphml:node to be listed
+ : first, followed by all graphml:edge elements. The order depend on the node ID
+ : and the source and target attribute respectively.
+ :
+ :
+ : @author Michelle Weidling
+ : @since v3.1.0
+ : @param $graph A (sub-)graph with nodes and edges
+ : @return A graph with sorted nodes and edges
+ : :)
+declare function local:sort-edges-and-nodes($graph as element(graphml:graph))
+as element(graphml:graph) {
+ element graphml:graph {
+ $graph/@*,
+ for $node in $graph/graphml:node
+ order by $node/@id/string() ascending
+ return $node,
+ for $edge in $graph/graphml:edge
+ order by $edge/@source, $edge/@target
+ return $edge
+ }
+};
\ No newline at end of file
diff --git a/modules/callgraph/svg/callgraph-modules.svg b/modules/callgraph/svg/callgraph-modules.svg
new file mode 100644
index 0000000000000000000000000000000000000000..b6c898002d4261c258b4c5abb85edf6950e6ccba
--- /dev/null
+++ b/modules/callgraph/svg/callgraph-modules.svg
@@ -0,0 +1,117 @@
+
+
\ No newline at end of file
diff --git a/modules/callgraph/tests/callgraph-test.xq b/modules/callgraph/tests/callgraph-test.xq
new file mode 100644
index 0000000000000000000000000000000000000000..e5bcc0ad2585f0c26f7e070a2d9594612c3367f5
--- /dev/null
+++ b/modules/callgraph/tests/callgraph-test.xq
@@ -0,0 +1,112 @@
+xquery version "3.1";
+
+(: This library module contains XQSuite tests for the callgraph module
+ : stored in callgraph.xqm :)
+
+module namespace callgraph-test = "https://sade.textgrid.de/ns/callgraph-test";
+
+import module namespace callgraph="https://sade.textgrid.de/ns/callgraph" at "../callgraph.xqm";
+
+declare namespace graphml="http://graphml.graphdrawing.org/xmlns";
+declare namespace test="http://exist-db.org/xquery/xqsuite";
+
+declare
+ %test:name("Testing filename error message by error code")
+ %test:args("invalid-filename.svg")
+ %test:assertError("CALLGRAPH01")
+ function callgraph-test:aa-test-error($option as xs:string) {
+ callgraph:main($option, "test-2")
+};
+
+declare
+ %test:name("Testing option error message by error code")
+ %test:args("an invalid option")
+ %test:assertError("CALLGRAPH02")
+ function callgraph-test:aa-test-error($option as xs:string) {
+ callgraph:main($option, "test-2")
+};
+
+declare
+ %test:name("Testing error message by error description")
+ %test:args("an invalid option")
+ %test:assertError("Invalid option 'an invalid option'. Please enter a base URI, a collection path or 'full' as argument.")
+ function callgraph-test:ab-test-error($option as xs:string) {
+ callgraph:main($option, "test-2")
+};
+
+
+declare
+ %test:name("Test DOT output from graphml:graphml")
+ %test:args("")
+ %test:assertEquals("digraph g {", "}")
+ function callgraph-test:transform2dot-001($element as element()) {
+ callgraph:transform2dot($element)
+};
+
+
+declare
+ %test:name("Test DOT output from graphml:graph")
+ %test:args("")
+ %test:assertEmpty
+
+ %test:args("")
+ %test:assertEquals("node [shape=box, style=filled, color=""", "#90b0d4", """];")
+ function callgraph-test:transform2dot-002($element as element()) {
+ callgraph:transform2dot($element)
+};
+
+
+declare
+ %test:name("Test DOT output from graphml:node")
+ %test:args("")
+ %test:assertEquals("node [shape=box, style=filled, color=""", "#90b0d4", """];", """", "some-function", """ [shape=box];")
+
+ %test:args("")
+ %test:assertEmpty
+ function callgraph-test:transform2dot-003($element as element()) {
+ callgraph:transform2dot($element)
+};
+
+
+declare
+ %test:name("Test DOT output from graphml:edge")
+ %test:args("")
+ %test:assertEquals("""", "some-function", """", " -> ", """", "another-function", """;")
+ function callgraph-test:transform2dot-004($element as element()) {
+ callgraph:transform2dot($element)
+};
+
+
+declare
+ %test:name("Testing DOT ouput for a single module")
+ %test:args("/db/apps/sade/modules/callgraph/tests/xqm/inspect2graphml-testmodule.xqm")
+ %test:assertEquals("digraph g {node [shape=box, style=filled, color=""#90b0d4""];""inspect2graphml-testmodule:get-value"" [shape=box];""inspect2graphml-testmodule:main"" [shape=box];""inspect2graphml-testmodule:set-value"" [shape=box];""inspect2graphml-testmodule:main"" -> ""inspect2graphml-testmodule:get-value"";""inspect2graphml-testmodule:main"" -> ""inspect2graphml-testmodule:set-value"";""inspect2graphml-testmodule:set-value"" -> ""inspect2graphml-testmodule:get-value"";}")
+ function callgraph-test:ba-dot($option as xs:string) {
+ callgraph:get-dot($option, "inspect2graphml-testmodule-xqm")
+};
+
+
+declare
+ %test:name("Testing DOT ouput for two modules")
+ %test:args("/db/apps/sade/modules/callgraph/tests/xqm/")
+ %test:assertEquals("digraph g {node [shape=box, style=filled, color=""#90b0d4""];""inspect2graphml-testmodule2:get-value"" [shape=box];""inspect2graphml-testmodule2:main"" [shape=box];""inspect2graphml-testmodule2:set-value"" [shape=box];""inspect2graphml-testmodule2:main"" -> ""inspect2graphml-testmodule2:get-value"";""inspect2graphml-testmodule2:main"" -> ""inspect2graphml-testmodule2:set-value"";""inspect2graphml-testmodule2:main"" -> ""inspect2graphml-testmodule:set-value"";""inspect2graphml-testmodule2:set-value"" -> ""inspect2graphml-testmodule:get-value"";node [shape=box, style=filled, color=""#e6f2ff""];""inspect2graphml-testmodule:get-value"" [shape=box];""inspect2graphml-testmodule:main"" [shape=box];""inspect2graphml-testmodule:set-value"" [shape=box];""inspect2graphml-testmodule:main"" -> ""inspect2graphml-testmodule:get-value"";""inspect2graphml-testmodule:main"" -> ""inspect2graphml-testmodule:set-value"";""inspect2graphml-testmodule:set-value"" -> ""inspect2graphml-testmodule:get-value"";}")
+ function callgraph-test:bb-dot($option as xs:string) {
+ callgraph:get-dot($option, "tests-collection")
+};
+
+declare
+ %test:name("Testing SVG error behavior")
+ %test:args("")
+ %test:assertError("CALLGRAPH06")
+ function callgraph-test:c-svg($dot as xs:string) {
+ callgraph:get-svg($dot)
+};
+
+
+declare
+ %test:name("Testing SVG clearance for a simple module")
+ %test:args("/db/apps/sade/modules/callgraph/tests/xqm/inspect2graphml-testmodule.xqm")
+ %test:assertEquals("Call graph creation successfull.")
+ function callgraph-test:d-svg($option as xs:string) {
+ callgraph:main($option, "inspect2graphml-testmodule-xqm2")
+};
diff --git a/modules/callgraph/tests/inspect2graphml-test.xq b/modules/callgraph/tests/inspect2graphml-test.xq
new file mode 100644
index 0000000000000000000000000000000000000000..394bb532817c2db5740828fea2043bc89a9cf3d9
--- /dev/null
+++ b/modules/callgraph/tests/inspect2graphml-test.xq
@@ -0,0 +1,54 @@
+xquery version "3.1";
+
+(: This library module contains XQSuite tests for the inspect2graphml module
+ : stored in inspect2graphml.xqm :)
+
+module namespace inspect2graphml-test = "https://sade.textgrid.de/ns/inspect2graphml-test";
+
+import module namespace inspect2graphml="https://sade.textgrid.de/ns/inspect2graphml" at "../inspect2graphml.xqm";
+
+declare namespace graphml="http://graphml.graphdrawing.org/xmlns";
+declare namespace test="http://exist-db.org/xquery/xqsuite";
+
+
+declare
+ %test:name("Testing the test")
+ %test:args("some input")
+ %test:assertEmpty
+ function inspect2graphml-test:a-test-the-test($node as text()) {
+ ()
+};
+
+
+declare
+ %test:name("Testing a simple module with module node as input")
+ %test:args("Some Documentation Michelle Weidling 1.0 the name of the current filexs:string The path where the HTML is storedDetermines the directory where an HTML file should be saved. 1.0 Michelle Weidling ")
+ %test:assertEquals("")
+ function inspect2graphml-test:ba-simple-graph($node as element(*)) {
+ inspect2graphml:transform($node, true())
+};
+
+declare
+ %test:name("Testing a simple module with URI as input")
+ %test:args("/db/apps/sade/modules/callgraph/tests/xqm/inspect2graphml-testmodule.xqm")
+ %test:assertEquals("", "/db/apps/sade/modules/callgraph/graphml/inspect2graphml-test-graphml.xml")
+ function inspect2graphml-test:bb-simple-graph($option as xs:string) {
+ inspect2graphml:main($option, "inspect2graphml-test")
+};
+
+
+declare
+ %test:name("Testing two simple modules with collection path as input")
+ %test:args("/db/apps/sade/modules/callgraph/tests/xqm/")
+ %test:assertEquals("", "/db/apps/sade/modules/callgraph/graphml/inspect2graphml-test2-graphml.xml")
+ function inspect2graphml-test:bc-simple-graph($option as xs:string) {
+ inspect2graphml:main($option, "inspect2graphml-test2")
+};
+
+declare
+ %test:name("Testing transformation from GraphML to DOT with one module")
+ %test:args("/db/apps/sade/modules/callgraph/tests/xqm/inspect2graphml-testmodule.xqm")
+ %test:assertEquals("", "/db/apps/sade/modules/callgraph/graphml/inspect2graphml-test3-graphml.xml")
+ function inspect2graphml-test:ca-simple-graphml-to-dot($xqm as xs:string) {
+ inspect2graphml:main($xqm, "inspect2graphml-test3")
+};
diff --git a/modules/callgraph/tests/xqm/inspect2graphml-testmodule.xqm b/modules/callgraph/tests/xqm/inspect2graphml-testmodule.xqm
new file mode 100644
index 0000000000000000000000000000000000000000..219c4fe1cdf56bd2012b1924cd0e938c7f9a2dcb
--- /dev/null
+++ b/modules/callgraph/tests/xqm/inspect2graphml-testmodule.xqm
@@ -0,0 +1,21 @@
+xquery version "3.1";
+
+module namespace inspect2graphml-testmodule="https://sade.textgrid.de/ns/inspect2graphml-test-module";
+
+declare function inspect2graphml-testmodule:main() as xs:boolean {
+ let $url := "some-url"
+ let $url-return := inspect2graphml-testmodule:get-value($url)
+ let $set-value := inspect2graphml-testmodule:set-value($url)
+ return
+ true()
+};
+
+declare function inspect2graphml-testmodule:get-value($url as xs:string) as xs:string {
+ "return value"
+};
+
+declare function inspect2graphml-testmodule:set-value($url as xs:string) as empty-sequence() {
+ let $value := inspect2graphml-testmodule:get-value($url)
+ return
+ ()
+};
\ No newline at end of file
diff --git a/modules/callgraph/tests/xqm/inspect2graphml-testmodule2.xqm b/modules/callgraph/tests/xqm/inspect2graphml-testmodule2.xqm
new file mode 100644
index 0000000000000000000000000000000000000000..193fd8df46ddfec61915f3e8aef09e2511913add
--- /dev/null
+++ b/modules/callgraph/tests/xqm/inspect2graphml-testmodule2.xqm
@@ -0,0 +1,25 @@
+xquery version "3.1";
+
+module namespace inspect2graphml-testmodule2="https://sade.textgrid.de/ns/inspect2graphml-test-module2";
+
+import module namespace inspect2graphml-testmodule="https://sade.textgrid.de/ns/inspect2graphml-test-module" at "inspect2graphml-testmodule.xqm";
+
+
+declare function inspect2graphml-testmodule2:main() as xs:boolean {
+ let $url := "some-url"
+ let $url-return := inspect2graphml-testmodule2:get-value($url)
+ let $set-value1 := inspect2graphml-testmodule2:set-value($url)
+ let $set-value2 := inspect2graphml-testmodule:set-value($url)
+ return
+ true()
+};
+
+declare function inspect2graphml-testmodule2:get-value($url as xs:string) as xs:string {
+ "return value"
+};
+
+declare function inspect2graphml-testmodule2:set-value($url as xs:string) as empty-sequence() {
+ let $value := inspect2graphml-testmodule:get-value($url)
+ return
+ ()
+};
\ No newline at end of file
diff --git a/test.xq b/test.xq
index d9d5568ba83fa424c56c9e6c29a137ea329b5597..93e218b07ef6bd442848f7088df32d6e8aa5dc22 100644
--- a/test.xq
+++ b/test.xq
@@ -2,4 +2,13 @@ xquery version "3.1";
import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql";
import module namespace tests="https://sade.textgrid.de/ns/tests" at "test.xqm";
-test:suite(util:list-functions("https://sade.textgrid.de/ns/tests"))
+(: callgraph :)
+import module namespace callgraph-test = "https://sade.textgrid.de/ns/callgraph-test" at "modules/callgraph/tests/callgraph-test.xq";
+import module namespace inspect2graphml-test = "https://sade.textgrid.de/ns/inspect2graphml-test" at "modules/callgraph/tests/inspect2graphml-test.xq";
+
+
+test:suite(util:list-functions("https://sade.textgrid.de/ns/tests")),
+
+(: * CALLGRAPH * :)
+test:suite(util:list-functions("https://sade.textgrid.de/ns/callgraph-test")),
+test:suite(util:list-functions("https://sade.textgrid.de/ns/inspect2graphml-test"))
\ No newline at end of file
diff --git a/test.xqm b/test.xqm
index 402a2c9c575217654a4a50be8bb51fe0ba082ee4..fbf9a21bcb6cbd4ac476ca9bdf1f76d0e8db6882 100644
--- a/test.xqm
+++ b/test.xqm
@@ -8,7 +8,7 @@ import module namespace multiviewer="https://sade.textgrid.de/ns/multiviewer" at
import module namespace nav="https://sade.textgrid.de/ns/navigation" at "modules/navigation.xqm";
import module namespace tgconnect="https://sade.textgrid.de/ns/connect" at "modules/textgrid/connect.xqm";
-declare namespace test="http://exist-db.org/xquery/xqsuite";
+import module namespace test="http://exist-db.org/xquery/xqsuite" at "resource:org/exist/xquery/lib/xqsuite/xqsuite.xql";
declare variable $tests:node := ;
declare variable $tests:model := map{};