Skip to content

Commit 5c5bccc

Browse files
joewizclaude
andcommitted
[feature] Relocate file:sync tests for util:file-sync
The old file module's sync tests (sync.xqm, sync-serialize.xqm, syncmod.xqm) plus their helper/fixtures resources have been adapted to test util:file-sync instead of file:sync. Key changes: - file:sync() calls → util:file-sync() - Old file module functions → EXPath file module equivalents (file:mkdirs→create-dir, file:serialize-binary→write-binary, etc.) - XML result namespace: file:sync/update/delete → util:sync/update/delete - file:list XML output → EXPath string-based list with separator stripping All 108 tests pass (106 pass + 2 pending/skipped). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent eec9ee5 commit 5c5bccc

File tree

5 files changed

+1325
-0
lines changed

5 files changed

+1325
-0
lines changed
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
(:
2+
: eXist-db Open Source Native XML Database
3+
: Copyright (C) 2001 The eXist-db Authors
4+
:
5+
: info@exist-db.org
6+
: http://www.exist-db.org
7+
:
8+
: This library is free software; you can redistribute it and/or
9+
: modify it under the terms of the GNU Lesser General Public
10+
: License as published by the Free Software Foundation; either
11+
: version 2.1 of the License, or (at your option) any later version.
12+
:
13+
: This library is distributed in the hope that it will be useful,
14+
: but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
: Lesser General Public License for more details.
17+
:
18+
: You should have received a copy of the GNU Lesser General Public
19+
: License along with this library; if not, write to the Free Software
20+
: Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
:)
22+
xquery version "3.1";
23+
24+
module namespace fixtures="http://exist-db.org/xquery/test/util/fixtures";
25+
26+
(: simple xml :)
27+
28+
declare variable $fixtures:XML := document {<foo><bar/></foo>};
29+
30+
declare variable $fixtures:SIMPLE_XML_INDENTED :=
31+
"<foo>" || $fixtures:NL ||
32+
" <bar/>" || $fixtures:NL ||
33+
"</foo>"
34+
;
35+
36+
declare variable $fixtures:SIMPLE_XML_UNINDENTED := "<foo><bar/></foo>";
37+
38+
(: more complex xml :)
39+
40+
declare variable $fixtures:COMPLEX_XML :=
41+
<root>
42+
<item>This is a very long line. Certainly longer than eighty characters. It is here to see what happens to lines longer than a certain limit. Let's see.</item>
43+
<empty-item></empty-item>
44+
<unary />
45+
<item>
46+
47+
MIXED CONTENT&#10;
48+
<nested
49+
attr = "with lots of whitespace"
50+
/>
51+
The next word <hi>is</hi> highlighted.
52+
</item>
53+
<p/>
54+
</root>
55+
;
56+
57+
(: FIXME(JL) cannot use StringConstructor here because that will cause all comparisons to fail on Windows :)
58+
(: see https://github.com/eXist-db/exist/issues/4301 :)
59+
declare variable $fixtures:COMPLEX_XML_INDENTED :=
60+
"<root>" || $fixtures:NL ||
61+
" <item>This is a very long line. Certainly longer than eighty characters. It is here to see what happens to lines longer than a certain limit. Let's see.</item>" || $fixtures:NL ||
62+
" <empty-item/>" || $fixtures:NL ||
63+
" <unary/>" || $fixtures:NL ||
64+
" <item>" || $fixtures:NL ||
65+
$fixtures:NL ||
66+
" MIXED CONTENT" || $fixtures:NL ||
67+
$fixtures:NL ||
68+
" <nested attr=""with lots of whitespace""/>" || $fixtures:NL ||
69+
" The next word <hi>is</hi> highlighted." || $fixtures:NL ||
70+
" </item>" || $fixtures:NL ||
71+
" <p/>" || $fixtures:NL ||
72+
"</root>"
73+
;
74+
75+
declare variable $fixtures:COMPLEX_XML_UNINDENTED :=
76+
"<root>" ||
77+
"<item>This is a very long line. Certainly longer than eighty characters. It is here to see what happens to lines longer than a certain limit. Let's see.</item>" ||
78+
"<empty-item/>" ||
79+
"<unary/>" ||
80+
"<item>" || $fixtures:NL ||
81+
$fixtures:NL ||
82+
" MIXED CONTENT" || $fixtures:NL ||
83+
$fixtures:NL ||
84+
" <nested attr=""with lots of whitespace""/>" || $fixtures:NL ||
85+
" The next word <hi>is</hi> highlighted." || $fixtures:NL ||
86+
" </item>" ||
87+
"<p/>" ||
88+
"</root>"
89+
;
90+
91+
92+
declare variable $fixtures:TXT :=
93+
``[12 12
94+
This is just a Text
95+
]``
96+
;
97+
98+
declare variable $fixtures:XQY := "xquery version ""3.1""; 0 to 9";
99+
declare variable $fixtures:BIN := "To bin or not to bin...";
100+
101+
(: other constants :)
102+
103+
declare variable $fixtures:XML_DECLARATION := '<?xml version="1.0" encoding="UTF-8"?>';
104+
declare variable $fixtures:NL := "&#10;";
105+
106+
(: modification dates :)
107+
108+
declare variable $fixtures:now := current-dateTime();
109+
declare variable $fixtures:mod-date := $fixtures:now;
110+
declare variable $fixtures:mod-date-2 := $fixtures:now + xs:dayTimeDuration('PT2H');
111+
112+
(: collections :)
113+
114+
declare variable $fixtures:collection-name := "file-module-test";
115+
declare variable $fixtures:child-collection-name := "data";
116+
declare variable $fixtures:collection := "/db/" || $fixtures:collection-name;
117+
declare variable $fixtures:child-collection := $fixtures:collection || "/" || $fixtures:child-collection-name;
118+
119+
(: file sync results :)
120+
121+
declare variable $fixtures:ALL-UPDATED := ("test-text.txt", "test-query.xq", "bin", "test-data.xml");
122+
123+
declare variable $fixtures:ROOT-FS := ("bin", "test-text.txt", "test-query.xq", "data");
124+
125+
declare variable $fixtures:EXTRA-DATA := ("test", ".env");
126+
127+
declare variable $fixtures:ROOT-FS-EXTRA := ("test", "bin", ".env", "test-text.txt", "test-query.xq", "data");
Lines changed: 231 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,231 @@
1+
(:
2+
: eXist-db Open Source Native XML Database
3+
: Copyright (C) 2001 The eXist-db Authors
4+
:
5+
: info@exist-db.org
6+
: http://www.exist-db.org
7+
:
8+
: This library is free software; you can redistribute it and/or
9+
: modify it under the terms of the GNU Lesser General Public
10+
: License as published by the Free Software Foundation; either
11+
: version 2.1 of the License, or (at your option) any later version.
12+
:
13+
: This library is distributed in the hope that it will be useful,
14+
: but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16+
: Lesser General Public License for more details.
17+
:
18+
: You should have received a copy of the GNU Lesser General Public
19+
: License along with this library; if not, write to the Free Software
20+
: Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
:)
22+
xquery version "3.1";
23+
24+
module namespace helper="http://exist-db.org/xquery/test/util/helper";
25+
import module namespace fixtures="http://exist-db.org/xquery/test/util/fixtures" at "fixtures.xqm";
26+
import module namespace file="http://expath.org/ns/file";
27+
import module namespace xmldb="http://exist-db.org/xquery/xmldb";
28+
import module namespace util="http://exist-db.org/xquery/util";
29+
30+
declare namespace utilns="http://exist-db.org/xquery/util";
31+
32+
declare variable $helper:error := xs:QName("helper:assert-sync-error");
33+
34+
declare variable $helper:path-separator := util:system-property("file.separator");
35+
36+
(:
37+
/db
38+
/file-module-test
39+
/data
40+
test-data.xml
41+
test-text.txt
42+
test-query.xq
43+
bin
44+
:)
45+
declare function helper:setup-db() as empty-sequence() {
46+
let $_ := (
47+
xmldb:create-collection("/db", $fixtures:collection-name),
48+
helper:create-db-resource($fixtures:collection, "test-text.txt", $fixtures:TXT),
49+
helper:create-db-resource($fixtures:collection, "test-query.xq", $fixtures:XQY),
50+
helper:create-db-resource($fixtures:collection, "bin", $fixtures:BIN),
51+
52+
xmldb:create-collection($fixtures:collection, $fixtures:child-collection-name),
53+
helper:create-db-resource($fixtures:child-collection, "test-data.xml", $fixtures:XML)
54+
)
55+
return ()
56+
};
57+
58+
declare function helper:clear-db() {
59+
xmldb:remove($fixtures:collection)
60+
};
61+
62+
declare function helper:create-db-resource($collection as xs:string, $resource as xs:string, $content as item()) as empty-sequence() {
63+
let $_ := xmldb:store($collection, $resource, $content)
64+
return ()
65+
};
66+
67+
declare function helper:modify-db-resource($collection as xs:string, $resource as xs:string) as empty-sequence() {
68+
let $_ := xmldb:touch($collection, $resource, $fixtures:mod-date-2)
69+
return ()
70+
};
71+
72+
declare function helper:clear-suite-fs ($suite as xs:string) as empty-sequence() {
73+
let $dir :=
74+
helper:glue-path((
75+
util:system-property("java.io.tmpdir"),
76+
$suite
77+
))
78+
return
79+
if (file:exists($dir)) then
80+
let $_ := file:delete($dir, true())
81+
return ()
82+
else ()
83+
};
84+
85+
declare function helper:clear-fs ($directory as xs:string) as empty-sequence() {
86+
if (file:exists($directory)) then
87+
let $_ := file:delete($directory, true())
88+
return ()
89+
else ()
90+
};
91+
92+
declare function helper:get-test-directory ($suite as xs:string) as xs:string {
93+
helper:glue-path((
94+
util:system-property("java.io.tmpdir"),
95+
$suite,
96+
util:uuid()
97+
))
98+
};
99+
100+
declare function helper:glue-path ($parts as xs:string+) as xs:string {
101+
string-join($parts, $helper:path-separator)
102+
};
103+
104+
(:
105+
: clear FS state and simulate additional data on the file system in a specific directory
106+
: @returns given directory to allow use in pipeline (chain of arrow operators)
107+
:)
108+
declare function helper:setup-fs-extra ($directory as xs:string) as xs:string {
109+
let $_ := file:create-dir($directory)
110+
let $_ := file:create-dir(helper:glue-path(($directory, "test")))
111+
let $_ := (
112+
file:write-binary(
113+
helper:glue-path(($directory, ".env")),
114+
util:string-to-binary("SERVER_SECRET=123!")),
115+
file:write-binary(
116+
helper:glue-path(($directory, "test", "three.s")),
117+
util:string-to-binary("..."))
118+
)
119+
return $directory
120+
};
121+
122+
declare function helper:get-deleted-from-sync-result ($result as element(utilns:sync)) as xs:string* {
123+
$result//utilns:delete/@name/string()
124+
};
125+
126+
declare function helper:get-dir-from-sync-result ($result as element(utilns:sync)) as xs:string* {
127+
$result/@utilns:dir/string()
128+
};
129+
130+
declare function helper:get-updated-from-sync-result ($result as element(utilns:sync)) as xs:string* {
131+
$result//utilns:update/@name/string()
132+
};
133+
134+
declare function helper:list-files-and-directories ($directory as xs:string) as xs:string* {
135+
(: EXPath file:list returns relative path strings, directories end with separator :)
136+
for $entry in file:list($directory)
137+
return
138+
(: strip trailing separator from directory names :)
139+
if (ends-with($entry, file:dir-separator()))
140+
then substring($entry, 1, string-length($entry) - string-length(file:dir-separator()))
141+
else $entry
142+
};
143+
144+
declare function helper:sync-with-options ($directory as xs:string, $options as item()?) as element(utilns:sync) {
145+
util:file-sync($fixtures:collection, $directory, $options)/*
146+
};
147+
148+
declare function helper:assert-sync-result (
149+
$result as document-node(element(utilns:sync)),
150+
$expected as map(xs:string, xs:string*)
151+
) as xs:boolean {
152+
helper:assert-permutation-of(
153+
$expected?updated,
154+
helper:get-updated-from-sync-result($result/*),
155+
"updated"
156+
)
157+
and
158+
helper:assert-permutation-of(
159+
$expected?deleted,
160+
helper:get-deleted-from-sync-result($result/*),
161+
"deleted"
162+
)
163+
and
164+
helper:assert-permutation-of(
165+
$expected?fs,
166+
helper:get-dir-from-sync-result($result/*)
167+
=> helper:list-files-and-directories(),
168+
"filesystem"
169+
)
170+
};
171+
172+
declare function helper:assert-permutation-of(
173+
$expected as xs:anyAtomicType*,
174+
$actual as xs:anyAtomicType*,
175+
$label as xs:string
176+
) as xs:boolean {
177+
let $test := fold-left(
178+
$expected,
179+
[true(), $actual],
180+
helper:permutation-reducer#2
181+
)
182+
183+
return
184+
if (empty($expected) and not(empty($actual)))
185+
then error($helper:error,
186+
"Assertion failed (" || $label || "): expected empty sequence" ||
187+
" but got (" || string-join($actual, ", ") || ")")
188+
else if (not($test?1 or exists($test?2)))
189+
then error($helper:error,
190+
"Assertion failed (" || $label || "): expected permutation of " ||
191+
"(" || string-join($expected, ", ") || ")" ||
192+
" but got (" || string-join($actual, ", ") || ")")
193+
else true()
194+
};
195+
196+
declare function helper:permutation-reducer ($result, $next) as array(*) {
197+
let $first-index := index-of($result?2, $next)[1]
198+
return [
199+
$result?1 and $first-index > 0,
200+
helper:maybe-remove-item-at-index($result?2, $first-index)
201+
]
202+
};
203+
204+
declare function helper:maybe-remove-item-at-index($sequence as xs:anyAtomicType*, $index as xs:integer?) as xs:anyAtomicType* {
205+
if ($index = 1)
206+
then subsequence($sequence, 2)
207+
else if ($index > 1)
208+
then (
209+
subsequence($sequence, 1, $index - 1),
210+
subsequence($sequence, $index + 1)
211+
)
212+
else $sequence (: do nothing - will be handled later :)
213+
};
214+
215+
declare function helper:assert-file-contents($expected as xs:string, $path-parts as xs:string+) as xs:boolean {
216+
let $path := helper:glue-path($path-parts)
217+
let $actual := file:read-text($path)
218+
219+
return
220+
if (
221+
exists($actual) and
222+
count($actual) = 1 and
223+
$actual eq $expected)
224+
then true()
225+
else error(
226+
$helper:error,
227+
"File Content Assertion failed:&#10;expected file " || $path || "&#10;" ||
228+
"to contain string&#10;" || "<[" || $expected || "]>" ||
229+
" but was&#10;<[" || $actual || "]>"
230+
)
231+
};

0 commit comments

Comments
 (0)