AtlatestRepositorysigil-yaml

sigil-yaml / tree / testtest-yaml.sgl

1;;; Test suite for (sigil yaml)
2
3(import (sigil test)
4 (sigil yaml)
5 (sigil math))
6
7;; ============================================================
8;; Scalar Type Resolution
9;; ============================================================
11(test-group "yaml-decode - null"
12 (test "null keyword"
13 (assert-equal 'null (yaml-decode "null")))
14 (test "Null keyword"
15 (assert-equal 'null (yaml-decode "Null")))
16 (test "NULL keyword"
17 (assert-equal 'null (yaml-decode "NULL")))
18 (test "tilde is null"
19 (assert-equal 'null (yaml-decode "~")))
20 (test "empty string is null"
21 (assert-equal 'null (yaml-decode ""))))
23(test-group "yaml-decode - booleans"
24 (test "true"
25 (assert-equal #t (yaml-decode "true")))
26 (test "True"
27 (assert-equal #t (yaml-decode "True")))
28 (test "TRUE"
29 (assert-equal #t (yaml-decode "TRUE")))
30 (test "false"
31 (assert-equal #f (yaml-decode "false")))
32 (test "False"
33 (assert-equal #f (yaml-decode "False")))
34 (test "FALSE"
35 (assert-equal #f (yaml-decode "FALSE"))))
37(test-group "yaml-decode - integers"
38 (test "positive integer"
39 (assert-equal 42 (yaml-decode "42")))
40 (test "negative integer"
41 (assert-equal -7 (yaml-decode "-7")))
42 (test "zero"
43 (assert-equal 0 (yaml-decode "0")))
44 (test "hex integer"
45 (assert-equal 255 (yaml-decode "0xFF")))
46 (test "octal integer"
47 (assert-equal 8 (yaml-decode "0o10"))))
49(test-group "yaml-decode - floats"
50 (test "simple float"
51 (assert-equal 3.14 (yaml-decode "3.14")))
52 (test "negative float"
53 (assert-equal -2.5 (yaml-decode "-2.5")))
54 (test "positive infinity"
55 (assert-true (infinite? (yaml-decode ".inf")))
56 (assert-true (> (yaml-decode ".inf") 0)))
57 (test "negative infinity"
58 (assert-true (infinite? (yaml-decode "-.inf")))
59 (assert-true (< (yaml-decode "-.inf") 0)))
60 (test "nan"
61 (assert-true (nan? (yaml-decode ".nan")))))
63(test-group "yaml-decode - strings"
64 (test "plain string"
65 (assert-equal "hello" (yaml-decode "hello")))
66 (test "string with spaces"
67 (assert-equal "hello world" (yaml-decode "hello world")))
68 (test "double-quoted string"
69 (assert-equal "hello" (yaml-decode "\"hello\"")))
70 (test "single-quoted string"
71 (assert-equal "hello" (yaml-decode "'hello'")))
72 (test "double-quoted with escapes"
73 (assert-equal "line1\nline2" (yaml-decode "\"line1\\nline2\"")))
74 (test "double-quoted with tab"
75 (assert-equal "a\tb" (yaml-decode "\"a\\tb\"")))
76 (test "single-quoted with escaped quote"
77 (assert-equal "it's" (yaml-decode "'it''s'")))
78 (test "double-quoted preserves special chars"
79 (assert-equal "true" (yaml-decode "\"true\"")))
80 (test "single-quoted preserves special chars"
81 (assert-equal "null" (yaml-decode "'null'"))))
83;; ============================================================
84;; Block Mappings
85;; ============================================================
87(test-group "yaml-decode - block mappings"
88 (test "simple mapping"
89 (assert-equal #{ name: "Alice" age: 30 }
90 (yaml-decode "name: Alice\nage: 30")))
92 (test "mapping with string values"
93 (assert-equal #{ first: "John" last: "Doe" }
94 (yaml-decode "first: John\nlast: Doe")))
96 (test "mapping with mixed types"
97 (assert-equal #{ name: "Alice" age: 30 active: #t }
98 (yaml-decode "name: Alice\nage: 30\nactive: true")))
100 (test "mapping with null value"
101 (assert-equal #{ key: "null" }
102 ;; Bare "key:" with no value after colon
103 ;; Actually "key:" at end of line should give null
104 (yaml-decode "key: 'null'")))
106 (test "mapping with empty value"
107 (assert-true (yaml-null? (dict-ref (yaml-decode "key:") key:))))
109 (test "nested mapping"
110 (assert-equal #{ outer: #{ inner: 42 } }
111 (yaml-decode "outer:\n inner: 42")))
113 (test "deeply nested mapping"
114 (assert-equal #{ a: #{ b: #{ c: "deep" } } }
115 (yaml-decode "a:\n b:\n c: deep"))))
117;; ============================================================
118;; Block Sequences
119;; ============================================================
121(test-group "yaml-decode - block sequences"
122 (test "simple sequence"
123 (assert-equal '("apple" "banana" "cherry")
124 (yaml-decode "- apple\n- banana\n- cherry")))
126 (test "sequence of integers"
127 (assert-equal '(1 2 3)
128 (yaml-decode "- 1\n- 2\n- 3")))
130 (test "sequence with mixed types"
131 (assert-equal '("hello" 42 #t)
132 (yaml-decode "- hello\n- 42\n- true")))
134 (test "nested sequence"
135 (assert-equal '(("a" "b") ("c" "d"))
136 (yaml-decode "- - a\n - b\n- - c\n - d")))
138 (test "sequence of mappings"
139 (assert-equal (list #{ name: "Alice" } #{ name: "Bob" })
140 (yaml-decode "- name: Alice\n- name: Bob"))))
142;; ============================================================
143;; Mixed Nesting
144;; ============================================================
146(test-group "yaml-decode - mixed nesting"
147 (test "mapping with sequence value"
148 (assert-equal #{ items: '(1 2 3) }
149 (yaml-decode "items:\n - 1\n - 2\n - 3")))
151 (test "mapping with nested sequence of mappings"
152 (assert-equal #{ users: (list #{ name: "Alice" age: 30 } #{ name: "Bob" age: 25 }) }
153 (yaml-decode "users:\n - name: Alice\n age: 30\n - name: Bob\n age: 25")))
155 (test "sequence of mappings with nested values"
156 (assert-equal (list #{ name: "server1" ports: '(80 443) }
157 #{ name: "server2" ports: '(8080) })
158 (yaml-decode "- name: server1\n ports:\n - 80\n - 443\n- name: server2\n ports:\n - 8080"))))
160;; ============================================================
161;; Flow Collections
162;; ============================================================
164(test-group "yaml-decode - flow collections"
165 (test "flow sequence"
166 (assert-equal '(1 2 3)
167 (yaml-decode "[1, 2, 3]")))
169 (test "flow mapping"
170 (assert-equal #{ a: 1 b: 2 }
171 (yaml-decode "{a: 1, b: 2}")))
173 (test "nested flow"
174 (assert-equal #{ a: '(1 2) b: #{ c: 3 } }
175 (yaml-decode "{a: [1, 2], b: {c: 3}}")))
177 (test "flow in block mapping"
178 (assert-equal #{ items: '(1 2 3) }
179 (yaml-decode "items: [1, 2, 3]")))
181 (test "flow mapping in block"
182 (assert-equal #{ point: #{ x: 10 y: 20 } }
183 (yaml-decode "point: {x: 10, y: 20}")))
185 (test "empty flow sequence"
186 (assert-equal '()
187 (yaml-decode "[]")))
189 (test "empty flow mapping"
190 (assert-equal #{}
191 (yaml-decode "{}"))))
193;; ============================================================
194;; Block Scalars
195;; ============================================================
197(test-group "yaml-decode - block scalars"
198 (test "literal block scalar"
199 (assert-equal "line1\nline2\nline3\n"
200 (dict-ref (yaml-decode "text: |\n line1\n line2\n line3") text:)))
202 (test "folded block scalar"
203 (assert-equal "line1 line2 line3\n"
204 (dict-ref (yaml-decode "text: >\n line1\n line2\n line3") text:)))
206 (test "literal with strip chomping"
207 (assert-equal "line1\nline2"
208 (dict-ref (yaml-decode "text: |-\n line1\n line2") text:)))
210 (test "literal with keep chomping"
211 (assert-equal "line1\nline2\n\n"
212 (dict-ref (yaml-decode "text: |+\n line1\n line2\n\nnext: val") text:)))
214 (test "folded with paragraph break"
215 (assert-equal "first second\n\nthird fourth\n"
216 (dict-ref (yaml-decode "text: >\n first\n second\n\n third\n fourth") text:))))
218;; ============================================================
219;; Comments
220;; ============================================================
222(test-group "yaml-decode - comments"
223 (test "full-line comment"
224 (assert-equal #{ name: "Alice" }
225 (yaml-decode "# This is a comment\nname: Alice")))
227 (test "inline comment"
228 (assert-equal #{ name: "Alice" }
229 (yaml-decode "name: Alice # a comment")))
231 (test "comment between entries"
232 (assert-equal #{ a: 1 b: 2 }
233 (yaml-decode "a: 1\n# separator\nb: 2"))))
235;; ============================================================
236;; Multi-Document
237;; ============================================================
239(test-group "yaml-decode - multi-document"
240 (test "single document with marker"
241 (assert-equal #{ a: 1 }
242 (yaml-decode "---\na: 1")))
244 (test "yaml-read-all with multiple docs"
245 (assert-equal (list #{ a: 1 } #{ b: 2 })
246 (yaml-decode-all "---\na: 1\n---\nb: 2")))
248 (test "document end marker"
249 (assert-equal (list #{ a: 1 })
250 (yaml-decode-all "---\na: 1\n..."))))
252;; ============================================================
253;; Anchors and Aliases
254;; ============================================================
256(test-group "yaml-decode - anchors and aliases"
257 (test "simple anchor and alias"
258 (let ((result (yaml-decode "anchor: &val Alice\nref: *val")))
259 (assert-equal "Alice" (dict-ref result anchor:))
260 (assert-equal "Alice" (dict-ref result ref:))))
262 (test "anchor on mapping value"
263 (let ((result (yaml-decode "defaults: &def\n color: red\n size: large\ncustom:\n color: blue\n size: large")))
264 (assert-equal "red" (dict-ref (dict-ref result defaults:) color:)))))
266;; ============================================================
267;; Writer - Block Style
268;; ============================================================
270(test-group "yaml-encode - scalars"
271 (test "encode string"
272 (assert-equal "hello\n" (yaml-encode "hello")))
273 (test "encode integer"
274 (assert-equal "42\n" (yaml-encode 42)))
275 (test "encode float"
276 (assert-equal "3.14\n" (yaml-encode 3.14)))
277 (test "encode true"
278 (assert-equal "true\n" (yaml-encode #t)))
279 (test "encode false"
280 (assert-equal "false\n" (yaml-encode #f)))
281 (test "encode null"
282 (assert-equal "null\n" (yaml-encode 'null)))
283 (test "encode string that needs quoting"
284 (assert-equal "\"true\"\n" (yaml-encode "true")))
285 (test "encode empty string"
286 (assert-equal "\"\"\n" (yaml-encode ""))))
288(test-group "yaml-encode - block mappings"
289 (test "simple mapping"
290 (assert-equal "name: Alice\n"
291 (yaml-encode #{ name: "Alice" })))
293 (test "nested mapping"
294 (assert-equal "outer:\n inner: 42\n"
295 (yaml-encode #{ outer: #{ inner: 42 } })))
297 (test "empty mapping"
298 (assert-equal "{}\n" (yaml-encode #{}))))
300(test-group "yaml-encode - block sequences"
301 (test "simple sequence"
302 (assert-equal "- 1\n- 2\n- 3\n"
303 (yaml-encode '(1 2 3))))
305 (test "empty list"
306 (assert-equal "[]\n" (yaml-encode '()))))
308;; ============================================================
309;; Writer - Flow Style
310;; ============================================================
312(test-group "yaml-encode - flow style"
313 (test "flow mapping"
314 (assert-equal "{a: 1, b: 2}"
315 (yaml-encode #{ a: 1 b: 2 } flow: #t)))
317 (test "flow sequence"
318 (assert-equal "[1, 2, 3]"
319 (yaml-encode '(1 2 3) flow: #t)))
321 (test "flow nested"
322 (assert-equal "{items: [1, 2, 3]}"
323 (yaml-encode #{ items: '(1 2 3) } flow: #t))))
325;; ============================================================
326;; yaml-null?
327;; ============================================================
329(test-group "yaml-null?"
330 (test "null symbol is null"
331 (assert-true (yaml-null? 'null)))
332 (test "false is not null"
333 (assert-false (yaml-null? #f)))
334 (test "empty list is not null"
335 (assert-false (yaml-null? '())))
336 (test "decoded null is null"
337 (assert-true (yaml-null? (yaml-decode "null"))))
338 (test "decoded tilde is null"
339 (assert-true (yaml-null? (yaml-decode "~")))))
341;; ============================================================
342;; Round-Trip Tests
343;; ============================================================
345(test-group "yaml round-trip"
346 (test "simple mapping round-trip"
347 (let* ((original #{ name: "Alice" age: 30 })
348 (encoded (yaml-encode original))
349 (decoded (yaml-decode encoded)))
350 (assert-equal "Alice" (dict-ref decoded name:))
351 (assert-equal 30 (dict-ref decoded age:))))
353 (test "sequence round-trip"
354 (let* ((original '(1 2 3))
355 (encoded (yaml-encode original))
356 (decoded (yaml-decode encoded)))
357 (assert-equal original decoded)))
359 (test "nested structure round-trip"
360 (let* ((original #{ users: (list #{ name: "Alice" } #{ name: "Bob" }) })
361 (encoded (yaml-encode original))
362 (decoded (yaml-decode encoded)))
363 (assert-equal "Alice"
364 (dict-ref (car (dict-ref decoded users:)) name:))
365 (assert-equal "Bob"
366 (dict-ref (cadr (dict-ref decoded users:)) name:)))))
368;; ============================================================
369;; Edge Cases
370;; ============================================================
372(test-group "yaml-decode - edge cases"
373 (test "empty document"
374 (assert-equal 'null (yaml-decode "")))
376 (test "comment-only document"
377 (assert-equal 'null (yaml-decode "# just a comment")))
379 (test "quoted key in mapping"
380 (assert-equal #{ key: "value" }
381 (yaml-decode "\"key\": value")))
383 (test "colon in value"
384 (assert-equal #{ url: "http://example.com" }
385 (yaml-decode "url: http://example.com")))
387 (test "mapping key with quoted value"
388 (assert-equal #{ greeting: "hello world" }
389 (yaml-decode "greeting: \"hello world\""))))