Skip to content

Commit 5576d80

Browse files
committed
Merge branch 'jonesyface-alt-report-formats' into develop
2 parents 47a898c + 26baee3 commit 5576d80

File tree

6 files changed

+165
-27
lines changed

6 files changed

+165
-27
lines changed

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ mlAppName=marklogic-unit-test-testapp
66
mlHost=localhost
77
mlUsername=admin
88
mlPassword=admin
9-
mlRestPort=8090
9+
mlRestPort=8030
1010
mlContentForestsPerHost=1
1111

1212
# Load both the ml-unit-test framework code and some test modules

src/main/ml-modules/root/test/default.xqy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ declare function local:run() {
3434
if ($suite) then
3535
let $result := helper:run-suite($suite, $tests, $run-suite-teardown, $run-teardown, $calculate-coverage)
3636
return
37-
if ($format eq "junit") then
38-
helper:format-junit($result)
37+
if ($format) then
38+
helper:format($result, $format, $suite)
3939
else
4040
$result
4141
else ()
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
<!--
2+
Convert default ml-unit-test report XML output to valid JUnit report XML
3+
-->
4+
<xsl:stylesheet version="2.0"
5+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
6+
xmlns:t="http://marklogic.com/roxy/test"
7+
xmlns:error="http://marklogic.com/xdmp/error"
8+
exclude-result-prefixes="#all">
9+
<xsl:output method="xml" encoding="utf-8" indent="yes"/>
10+
11+
<!-- Required inputs -->
12+
<xsl:param name="hostname"/>
13+
<xsl:param name="timestamp"/>
14+
15+
<!-- Output all text nodes, elements and attributes -->
16+
<xsl:template match="@*|node()">
17+
<xsl:copy>
18+
<xsl:apply-templates select="@*|node()" />
19+
</xsl:copy>
20+
</xsl:template>
21+
22+
<!-- Output test suites -->
23+
<xsl:template match="t:suite">
24+
<testsuite errors="0" failures="{@failed}" hostname="{$hostname}" name="{@name}" tests="{@total}" time="{@time}" timestamp="{$timestamp}">
25+
<xsl:apply-templates/>
26+
</testsuite>
27+
</xsl:template>
28+
29+
<!-- Output test cases within test suites -->
30+
<xsl:template match="t:test">
31+
<testcase classname="{@name}" name="{@name}" time="{@time}">
32+
<xsl:apply-templates/>
33+
</testcase>
34+
</xsl:template>
35+
36+
<!-- Output test case failures -->
37+
<xsl:template match="t:result[@type = 'fail']">
38+
<failure type="{error:error/error:name/string()}" message="{error:error/error:message/string()}">
39+
<xsl:apply-templates mode="serialize"/>
40+
</failure>
41+
</xsl:template>
42+
43+
<!-- Prevent output test case successes -->
44+
<xsl:template match="t:result[@type = 'success']"/>
45+
46+
<!-- Serialize error stack output so document is valid JUnit XML -->
47+
<xsl:template match="*" mode="serialize">
48+
<xsl:text>&lt;</xsl:text>
49+
<xsl:value-of select="name()"/>
50+
<xsl:apply-templates select="@*" mode="serialize" />
51+
<xsl:if test="name() = 'error:error'">
52+
<xsl:for-each select="namespace::*">
53+
<xsl:text> </xsl:text>
54+
<xsl:value-of select="name()"/>
55+
<xsl:text>="</xsl:text>
56+
<xsl:value-of select="."/>
57+
<xsl:text>"</xsl:text>
58+
</xsl:for-each>
59+
</xsl:if>
60+
<xsl:choose>
61+
<xsl:when test="node()">
62+
<xsl:text>&gt;</xsl:text>
63+
<xsl:apply-templates mode="serialize" />
64+
<xsl:text>&lt;/</xsl:text>
65+
<xsl:value-of select="name()"/>
66+
<xsl:text>&gt;</xsl:text>
67+
</xsl:when>
68+
<xsl:otherwise>
69+
<xsl:text> /&gt;</xsl:text>
70+
</xsl:otherwise>
71+
</xsl:choose>
72+
</xsl:template>
73+
74+
<xsl:template match="@*" mode="serialize">
75+
<xsl:text> </xsl:text>
76+
<xsl:value-of select="name()"/>
77+
<xsl:text>="</xsl:text>
78+
<xsl:value-of select="."/>
79+
<xsl:text>"</xsl:text>
80+
</xsl:template>
81+
82+
<xsl:template match="text()" mode="serialize">
83+
<xsl:value-of select="."/>
84+
</xsl:template>
85+
86+
</xsl:stylesheet>

src/main/ml-modules/root/test/test-controller.xqy

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,11 @@ import module namespace helper = "http://marklogic.com/roxy/test-helper" at "/te
1414
declare namespace t="http://marklogic.com/roxy/test";
1515

1616
declare variable $FS-PATH as xs:string := if (xdmp:platform() eq "winnt") then "\" else "/";
17-
17+
declare variable $XSL-PATTERN as xs:string := "\.xslt?$";
1818
declare variable $TEST-SUITES-ROOT := "/test/suites/";
19+
declare variable $db-id as xs:unsignedLong := xdmp:modules-database();
20+
declare variable $root as xs:string := xdmp:modules-root();
21+
1922

2023
(:
2124
: Returns a list of the available tests. This list is magically computed based on the modules
@@ -29,45 +32,67 @@ declare function list()
2932
)
3033
return
3134
element t:tests {
32-
let $db-id as xs:unsignedLong := xdmp:modules-database()
33-
let $root as xs:string := xdmp:modules-root()
3435
let $suites as xs:string* :=
3536
if ($db-id = 0) then
3637
xdmp:filesystem-directory(fn:concat($root, $FS-PATH, "test/suites"))/dir:entry[dir:type = "directory" and fn:not(dir:filename = $suite-ignore-list)]/dir:filename
3738
else
38-
let $uris := helper:list-from-database($db-id, $root, ())
39+
let $uris := helper:list-from-database($db-id, $root, (), 'suites')
3940
return
4041
fn:distinct-values(
4142
for $uri in $uris
4243
let $path := fn:replace(cvt:basepath($uri), fn:concat($root, "test/suites/?"), "")
4344
where $path ne "" and fn:not(fn:contains($path, "/")) and fn:not($path = $suite-ignore-list)
4445
return
4546
$path)
46-
for $suite as xs:string in $suites
47-
let $tests as xs:string* :=
47+
let $main-formats as xs:string* :=
4848
if ($db-id = 0) then
49-
xdmp:filesystem-directory(fn:concat($root, $FS-PATH, "test/suites/", $suite))/dir:entry[dir:type = "file" and fn:not(dir:filename = $test-ignore-list)]/dir:filename[fn:ends-with(., ".xqy") or fn:ends-with(., ".sjs")]
49+
xdmp:filesystem-directory(fn:concat($root, $FS-PATH, "test/formats"))/dir:entry[dir:type = "file" and fn:not(dir:filename = $test-ignore-list)]/dir:filename[fn:matches(., $XSL-PATTERN)]
5050
else
51-
let $uris := helper:list-from-database($db-id, $root, fn:concat($suite, '/'))
51+
let $uris := helper:list-from-database($db-id, $root, (), 'formats')
5252
return
5353
fn:distinct-values(
5454
for $uri in $uris
55-
let $path := fn:replace($uri, fn:concat($root, "test/suites/", $suite, "/"), "")
56-
where $path ne "" and fn:not(fn:contains($path, "/")) and fn:not($path = $test-ignore-list) and (fn:ends-with($path, ".xqy") or fn:ends-with($path, ".sjs"))
55+
let $path := fn:replace($uri, fn:concat($root, "test/formats/"), "")
56+
where $path ne "" and fn:not(fn:contains($path, "/")) and fn:not($path = $test-ignore-list) and (fn:matches($path, $XSL-PATTERN))
5757
return
5858
$path)
59-
where $tests
60-
return
61-
element t:suite {
62-
attribute path {$suite},
63-
element t:tests {
64-
for $test in $tests
59+
return (
60+
for $suite as xs:string in $suites
61+
let $tests as xs:string* :=
62+
if ($db-id = 0) then
63+
xdmp:filesystem-directory(fn:concat($root, $FS-PATH, "test/suites/", $suite))/dir:entry[dir:type = "file" and fn:not(dir:filename = $test-ignore-list)]/dir:filename[fn:ends-with(., ".xqy") or fn:ends-with(., ".sjs")]
64+
else
65+
let $uris := helper:list-from-database(
66+
$db-id, $root, fn:concat($suite, '/'), 'suites')
67+
return
68+
fn:distinct-values(
69+
for $uri in $uris
70+
let $path := fn:replace($uri, fn:concat($root, "test/suites/", $suite, "/"), "")
71+
where $path ne "" and fn:not(fn:contains($path, "/")) and fn:not($path = $test-ignore-list) and (fn:ends-with($path, ".xqy") or fn:ends-with($path, ".sjs"))
72+
return
73+
$path)
74+
where $tests
75+
return
76+
element t:suite {
77+
attribute path {$suite},
78+
element t:tests {
79+
for $test in $tests
80+
return
81+
element t:test {
82+
attribute path {$test}
83+
}
84+
}
85+
},
86+
if ($main-formats) then
87+
element t:formats {
88+
for $main-format in $main-formats
6589
return
66-
element t:test {
67-
attribute path {$test}
90+
element t:format {
91+
attribute path {$main-format}
6892
}
6993
}
70-
}
94+
else ()
95+
)
7196
}
7297
};
7398

@@ -98,7 +123,7 @@ declare function run-suite(
98123
$run-suite-teardown as xs:boolean,
99124
$run-teardown as xs:boolean)
100125
{
101-
run-suite($suite, $tests, $run-suite-teardown, $run-teardown, fn:false())
126+
run-suite($suite, $tests, $run-suite-teardown, $run-teardown, fn:false())
102127
};
103128

104129
(:~
@@ -205,6 +230,32 @@ declare function run(
205230
};
206231

207232

233+
declare function format($result as element(), $format as xs:string, $suite as xs:string)
234+
{
235+
if ($format eq "junit") then
236+
format-junit($suite)
237+
else
238+
let $format-uris :=
239+
if ($db-id = 0) then
240+
xdmp:filesystem-directory(fn:concat($root, $FS-PATH, "test/formats"))/dir:entry[dir:type = "file"]/dir:filename[fn:matches(., $XSL-PATTERN)]
241+
else
242+
helper:list-from-database($db-id, $root, (), 'formats')
243+
let $xsl-match :=
244+
for $uri in $format-uris
245+
return
246+
if (fn:matches(fn:tokenize($uri, '/')[fn:last()], '^' || $format || $XSL-PATTERN)) then $uri
247+
else ()
248+
return
249+
if ($xsl-match) then
250+
let $xsl := $xsl-match[1]
251+
let $params := map:map()
252+
let $_ := map:put($params, "hostname", fn:tokenize(xdmp:get-request-header("Host"), ":")[1])
253+
let $_ := map:put($params, "timestamp", fn:current-dateTime())
254+
return xdmp:xslt-invoke($xsl, $result, $params)/element()
255+
else $result
256+
};
257+
258+
208259
declare function format-junit($suite as element())
209260
{
210261
element testsuite {

src/main/ml-modules/root/test/test-helper.xqy

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -556,7 +556,8 @@ declare function helper:log($items as item()*)
556556
declare function helper:list-from-database(
557557
$database as xs:unsignedLong,
558558
$root as xs:string,
559-
$suite as xs:string?)
559+
$suite as xs:string?,
560+
$file-type as xs:string)
560561
as xs:string*
561562
{
562563
xdmp:eval(
@@ -567,7 +568,7 @@ as xs:string*
567568
if ($ex/error:code ne "XDMP-URILXCNNOTFOUND") then xdmp:rethrow()
568569
else xdmp:directory($PATH, "infinity")/xdmp:node-uri(.) }',
569570
(xs:QName('PATH'),
570-
fn:concat($root, 'test/suites/', ($suite, '')[1])),
571+
fn:concat($root, 'test/', $file-type, '/', ($suite, '')[1])),
571572
<options xmlns="xdmp:eval"><database>{$database}</database></options>)
572573
};
573574

src/main/ml-modules/services/ml-unit-test.xqy

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ declare private function run($params as map:map)
3838
if ($suite) then
3939
let $result := helper:run-suite($suite, $tests, $run-suite-teardown, $run-teardown)
4040
return
41-
if ($format eq "junit") then
42-
helper:format-junit($result)
41+
if ($format) then
42+
helper:format($result, $format, $suite)
4343
else
4444
$result
4545
else ()

0 commit comments

Comments
 (0)