AtlatestRepositorysigil-yaml
sigil-yaml / tree / testtest-yaml.sgl
1
;;; Test suite for (sigil yaml)3
(import (sigil test)4
(sigil yaml)5
(sigil math))7
;; ============================================================8
;; Scalar Type Resolution9
;; ============================================================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 Mappings85
;; ============================================================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 colon103
;; Actually "key:" at end of line should give null104
(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 Sequences119
;; ============================================================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 Nesting144
;; ============================================================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 Collections162
;; ============================================================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 Scalars195
;; ============================================================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
;; Comments220
;; ============================================================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-Document237
;; ============================================================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 Aliases254
;; ============================================================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 Style268
;; ============================================================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 Style310
;; ============================================================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 Tests343
;; ============================================================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 Cases370
;; ============================================================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\""))))