| 1 | |
| 2 | |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 |
|
| 19 | (define-module (test-toml)
|
| 20 | #:use-module (guix build toml)
|
| 21 | #:use-module (guix tests)
|
| 22 | #:use-module (srfi srfi-19) |
| 23 | #:use-module (srfi srfi-64)
|
| 24 | #:use-module (ice-9 match))
|
| 25 |
|
| 26 | |
| 27 | (module-set! (resolve-module '(guix build toml))
|
| 28 | 'raise (@ (srfi srfi-34) raise))
|
| 29 |
|
| 30 | (test-begin "toml")
|
| 31 |
|
| 32 | |
| 33 |
|
| 34 | (test-error "parse-toml: Unspecified key"
|
| 35 | &file-not-consumed
|
| 36 | (parse-toml "key = # INVALID"))
|
| 37 |
|
| 38 | (test-error "parse-toml: Missing EOL"
|
| 39 | &file-not-consumed
|
| 40 | (parse-toml "first = \"Tom\" last = \"Preston-Werner\" # INVALID"))
|
| 41 |
|
| 42 | (test-equal "parse-toml: Bare keys"
|
| 43 | '(("key" . "value") ("bare_key" . "value") ("bare-key" . "value") ("1234" . "value"))
|
| 44 | (parse-toml "key = \"value\"
|
| 45 | bare_key = \"value\"
|
| 46 | bare-key = \"value\"
|
| 47 | 1234 = \"value\""))
|
| 48 |
|
| 49 | (test-equal "parse-toml: Quoted keys"
|
| 50 | '(("127.0.0.1" . "value")
|
| 51 | ("character encoding" . "value")
|
| 52 | ("ʎǝʞ" . "value")
|
| 53 | ("key2" . "value")
|
| 54 | ("quoted \"value\"" . "value"))
|
| 55 | (parse-toml "\"127.0.0.1\" = \"value\"
|
| 56 | \"character encoding\" = \"value\"
|
| 57 | \"ʎǝʞ\" = \"value\"
|
| 58 | 'key2' = \"value\"
|
| 59 | 'quoted \"value\"' = \"value\""))
|
| 60 |
|
| 61 | (test-equal "parse-toml: Quoted keys with escapes"
|
| 62 | '(("key \\ with \n escapes" . "value")
|
| 63 | ("key" ("with \t escapes" ("and \n dots" . "value"))))
|
| 64 | (parse-toml "\"key \\\\ with \\n escapes\" = \"value\"
|
| 65 | key.\"with \\t escapes\".\"and \\n dots\" = \"value\""))
|
| 66 |
|
| 67 | (test-error "parse-toml: No key"
|
| 68 | &file-not-consumed
|
| 69 | (parse-toml "= \"no key name\""))
|
| 70 |
|
| 71 | (test-equal "parse-toml: Empty key"
|
| 72 | '(("" . "blank"))
|
| 73 | (parse-toml "\"\" = \"blank\""))
|
| 74 |
|
| 75 | (test-equal "parse-toml: Dotted keys"
|
| 76 | '(("name" . "Orange")
|
| 77 | ("physical" ("color" . "orange")
|
| 78 | ("shape" . "round"))
|
| 79 | ("site" ("google.com" . #t)))
|
| 80 | (parse-toml "name = \"Orange\"
|
| 81 | physical.color = \"orange\"
|
| 82 | physical.shape = \"round\"
|
| 83 | site.\"google.com\" = true"))
|
| 84 |
|
| 85 | (test-equal "parse-toml: Dotted keys with whitespace"
|
| 86 | '(("fruit" ("name" . "banana") ("color" . "yellow") ("flavor" . "banana")))
|
| 87 | (parse-toml "fruit.name = \"banana\" # this is best practice
|
| 88 | fruit. color = \"yellow\" # same as fruit.color
|
| 89 | fruit . flavor = \"banana\" # same as fruit.flavor"))
|
| 90 |
|
| 91 | (test-error "parse-toml: Multiple keys"
|
| 92 | &already-defined
|
| 93 | (parse-toml "name = \"Tom\"
|
| 94 | name = \"Pradyun\""))
|
| 95 |
|
| 96 | (test-equal "parse-toml: Implicit tables"
|
| 97 | '(("fruit" ("apple" ("smooth" . #t)) ("orange" . 2)))
|
| 98 | (parse-toml "fruit.apple.smooth = true
|
| 99 | fruit.orange = 2"))
|
| 100 |
|
| 101 | (test-error "parse-toml: Write to value"
|
| 102 | &already-defined
|
| 103 | (parse-toml "fruit.apple = 1
|
| 104 | fruit.apple.smooth = true"))
|
| 105 |
|
| 106 | (test-equal "parse-toml: String"
|
| 107 | '(("str" . "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."))
|
| 108 | (parse-toml "str = \"I'm a string. \\\"You can quote me\\\". Name\\tJos\\xE9\\nLocation\\tSF.\""))
|
| 109 |
|
| 110 | (test-equal "parse-toml: Empty string"
|
| 111 | '(("str1" . "")
|
| 112 | ("str2" . "")
|
| 113 | ("str3" . "")
|
| 114 | ("str4" . ""))
|
| 115 | (parse-toml "str1 = \"\"
|
| 116 | str2 = ''
|
| 117 | str3 = \"\"\"\"\"\"
|
| 118 | str4 = ''''''"))
|
| 119 |
|
| 120 | (test-equal "parse-toml: Multi-line basic strings"
|
| 121 | '(("str1" . "Roses are red\nViolets are blue")
|
| 122 | ("str2" . "The quick brown fox jumps over the lazy dog.")
|
| 123 | ("str3" . "The quick brown fox jumps over the lazy dog.")
|
| 124 | ("str4" . "Here are two quotation marks: \"\". Simple enough.")
|
| 125 | ("str5" . "Here are three quotation marks: \"\"\".")
|
| 126 | ("str6" . "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\".")
|
| 127 | ("str7" . "\"This,\" she said, \"is just a pointless statement.\""))
|
| 128 | (parse-toml "str1 = \"\"\"
|
| 129 | Roses are red
|
| 130 | Violets are blue\"\"\"
|
| 131 |
|
| 132 | str2 = \"\"\"
|
| 133 | The quick brown \\
|
| 134 |
|
| 135 |
|
| 136 | fox jumps over \\
|
| 137 | the lazy dog.\"\"\"
|
| 138 |
|
| 139 | str3 = \"\"\"\\
|
| 140 | The quick brown \\
|
| 141 | fox jumps over \\
|
| 142 | the lazy dog.\\
|
| 143 | \"\"\"
|
| 144 |
|
| 145 | str4 = \"\"\"Here are two quotation marks: \"\". Simple enough.\"\"\"
|
| 146 | # str5 = \"\"\"Here are three quotation marks: \"\"\".\"\"\" # INVALID
|
| 147 | str5 = \"\"\"Here are three quotation marks: \"\"\\\".\"\"\"
|
| 148 | str6 = \"\"\"Here are fifteen quotation marks: \"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\"\"\"\\\".\"\"\"
|
| 149 |
|
| 150 | # \"This,\" she said, \"is just a pointless statement.\"
|
| 151 | str7 = \"\"\"\"This,\" she said, \"is just a pointless statement.\"\"\"\""))
|
| 152 |
|
| 153 | (test-equal "parse-toml: Literal string"
|
| 154 | '(("winpath" . "C:\\Users\\nodejs\\templates")
|
| 155 | ("winpath2" . "\\\\ServerX\\admin$\\system32\\")
|
| 156 | ("quoted" . "Tom \"Dubs\" Preston-Werner")
|
| 157 | ("regex" . "<\\i\\c*\\s*>"))
|
| 158 | (parse-toml "winpath = 'C:\\Users\\nodejs\\templates'
|
| 159 | winpath2 = '\\\\ServerX\\admin$\\system32\\'
|
| 160 | quoted = 'Tom \"Dubs\" Preston-Werner'
|
| 161 | regex = '<\\i\\c*\\s*>'"))
|
| 162 |
|
| 163 | (test-equal "parse-toml: Multi-line literal strings"
|
| 164 | '(("regex2" . "I [dw]on't need \\d{2} apples")
|
| 165 | ("lines" . "The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n")
|
| 166 | ("quot15" . "Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"")
|
| 167 | ("apos15" . "Here are fifteen apostrophes: '''''''''''''''")
|
| 168 | ("str" . "'That,' she said, 'is still pointless.'"))
|
| 169 | (parse-toml "regex2 = '''I [dw]on't need \\d{2} apples'''
|
| 170 | lines = '''
|
| 171 | The first newline is
|
| 172 | trimmed in raw strings.
|
| 173 | All other whitespace
|
| 174 | is preserved.
|
| 175 | '''
|
| 176 | quot15 = '''Here are fifteen quotation marks: \"\"\"\"\"\"\"\"\"\"\"\"\"\"\"'''
|
| 177 |
|
| 178 | # apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID
|
| 179 | apos15 = \"Here are fifteen apostrophes: '''''''''''''''\"
|
| 180 |
|
| 181 | # 'That,' she said, 'is still pointless.'
|
| 182 | str = ''''That,' she said, 'is still pointless.''''"))
|
| 183 |
|
| 184 | (test-equal "parse-toml: Decimal integer"
|
| 185 | '(("int1" . 99) ("int2" . 42) ("int3" . 0) ("int4" . -17))
|
| 186 | (parse-toml "int1 = +99
|
| 187 | int2 = 42
|
| 188 | int3 = 0
|
| 189 | int4 = -17"))
|
| 190 |
|
| 191 | (test-equal "parse-toml: Decimal integer underscores"
|
| 192 | '(("int5" . 1000) ("int6" . 5349221) ("int7" . 5349221) ("int8" . 12345))
|
| 193 | (parse-toml "int5 = 1_000
|
| 194 | int6 = 5_349_221
|
| 195 | int7 = 53_49_221 # Indian number system grouping
|
| 196 | int8 = 1_2_3_4_5 # VALID but discouraged"))
|
| 197 |
|
| 198 | (test-equal "parse-toml: Hexadecimal"
|
| 199 | `(("hex1" . ,#xdeadbeef) ("hex2" . ,#xdeadbeef) ("hex3" . ,#xdeadbeef))
|
| 200 | (parse-toml "hex1 = 0xDEADBEEF
|
| 201 | hex2 = 0xdeadbeef
|
| 202 | hex3 = 0xdead_beef"))
|
| 203 |
|
| 204 | (test-equal "parse-toml: Octal"
|
| 205 | `(("oct1" . ,#o01234567) ("oct2" . #o755))
|
| 206 | (parse-toml "oct1 = 0o01234567
|
| 207 | oct2 = 0o755"))
|
| 208 |
|
| 209 | (test-equal "parse-toml: Binary"
|
| 210 | `(("bin1" . ,#b11010110))
|
| 211 | (parse-toml "bin1 = 0b11010110"))
|
| 212 |
|
| 213 | (test-equal "parse-toml: Float"
|
| 214 | '(("flt1" . 1.0)
|
| 215 | ("flt2" . 3.1415)
|
| 216 | ("flt3" . -0.01)
|
| 217 | ("flt4" . 5e+22)
|
| 218 | ("flt5" . 1e06)
|
| 219 | ("flt6" . -2e-2)
|
| 220 | ("flt7" . 6.626e-34)
|
| 221 | ("flt8" . 224617.445991228))
|
| 222 | (parse-toml "# fractional
|
| 223 | flt1 = +1.0
|
| 224 | flt2 = 3.1415
|
| 225 | flt3 = -0.01
|
| 226 |
|
| 227 | # exponent
|
| 228 | flt4 = 5e+22
|
| 229 | flt5 = 1e06
|
| 230 | flt6 = -2E-2
|
| 231 |
|
| 232 | # both
|
| 233 | flt7 = 6.626e-34
|
| 234 |
|
| 235 | flt8 = 224_617.445_991_228"))
|
| 236 |
|
| 237 | (test-equal "parse-toml: Float"
|
| 238 | '(("sf1" . +inf.0)
|
| 239 | ("sf2" . +inf.0)
|
| 240 | ("sf3" . -inf.0)
|
| 241 | ("sf4" . +nan.0)
|
| 242 | ("sf5" . +nan.0)
|
| 243 | ("sf6" . -nan.0))
|
| 244 | (parse-toml "# infinity
|
| 245 | sf1 = inf # positive infinity
|
| 246 | sf2 = +inf # positive infinity
|
| 247 | sf3 = -inf # negative infinity
|
| 248 |
|
| 249 | # not a number
|
| 250 | sf4 = nan # actual sNaN/qNaN encoding is implementation-specific
|
| 251 | sf5 = +nan # same as `nan`
|
| 252 | sf6 = -nan # valid, actual encoding is implementation-specific"))
|
| 253 |
|
| 254 | (test-equal "parse-toml: Boolean"
|
| 255 | '(("bool1" . #t)
|
| 256 | ("bool2" . #f))
|
| 257 | (parse-toml "bool1 = true
|
| 258 | bool2 = false"))
|
| 259 |
|
| 260 | (test-equal "parse-toml: Offset date-time"
|
| 261 | `(("odt1" . ,(make-date #f 0 32 7 27 5 1979 0))
|
| 262 | ("odt2" . ,(make-date #f 0 32 0 27 5 1979 (* -7 60 60)))
|
| 263 | ("odt3" . ,(make-date 999999 0 32 0 27 5 1979 (* 7 60 60)))
|
| 264 | ("odt4" . ,(make-date #f 0 32 7 27 5 1979 0))
|
| 265 | ("odt5" . ,(make-date #f 0 32 7 27 5 1979 0)))
|
| 266 | (parse-toml "odt1 = 1979-05-27T07:32:00Z
|
| 267 | odt2 = 1979-05-27T00:32:00-07:00
|
| 268 | odt3 = 1979-05-27T00:32:00.999999+07:00
|
| 269 | odt4 = 1979-05-27 07:32:00Z
|
| 270 | odt5 = 1979-05-27 07:32:00z"))
|
| 271 |
|
| 272 | (test-equal "parse-toml: Local date-time"
|
| 273 | `(("ldt1" . ,(make-date #f 0 32 7 27 5 1979 #f))
|
| 274 | ("ldt2" . ,(make-date 999999 0 32 0 27 5 1979 #f)))
|
| 275 | (parse-toml "ldt1 = 1979-05-27T07:32:00
|
| 276 | ldt2 = 1979-05-27T00:32:00.999999"))
|
| 277 |
|
| 278 | (test-equal "parse-toml: Local date"
|
| 279 | `(("ld1" . ,(make-date #f #f #f #f 27 5 1979 #f)))
|
| 280 | (parse-toml "ld1 = 1979-05-27"))
|
| 281 |
|
| 282 | (test-equal "parse-toml: Local time"
|
| 283 | `(("lt1" . ,(make-date #f 0 32 7 #f #f #f #f))
|
| 284 | ("lt2" . ,(make-date 999999 0 32 0 #f #f #f #f)))
|
| 285 | (parse-toml "lt1 = 07:32:00
|
| 286 | lt2 = 00:32:00.999999"))
|
| 287 |
|
| 288 | (test-equal "parse-toml: Arrays"
|
| 289 | '(("integers" 1 2 3)
|
| 290 | ("colors" "red" "yellow" "green")
|
| 291 | ("nested_arrays_of_ints" (1 2) (3 4 5))
|
| 292 | ("nested_mixed_array" (1 2) ("a" "b" "c"))
|
| 293 | ("string_array" "all" "strings")
|
| 294 | ("numbers" 0.1 0.2 0.5 1 2 5)
|
| 295 | ("contributors" "Foo Bar <[email protected]>" (("name" . "Baz Qux") ("email" . "[email protected]") ("url" . "https://example.com/bazqux")))
|
| 296 | ("integers2" 1 2 3)
|
| 297 | ("integers3" 1 2))
|
| 298 | (parse-toml "integers = [ 1, 2, 3 ]
|
| 299 | colors = [ \"red\", \"yellow\", \"green\" ]
|
| 300 | nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
|
| 301 | nested_mixed_array = [ [ 1, 2 ], [\"a\", \"b\", \"c\"] ]
|
| 302 | string_array = [ \"all\", 'strings' ]
|
| 303 |
|
| 304 | # Mixed-type arrays are allowed
|
| 305 | numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
|
| 306 | contributors = [
|
| 307 | \"Foo Bar <[email protected]>\",
|
| 308 | { name = \"Baz Qux\", email = \"[email protected]\", url = \"https://example.com/bazqux\" }
|
| 309 | ]
|
| 310 |
|
| 311 | integers2 = [
|
| 312 | 1, 2, 3
|
| 313 | ]
|
| 314 |
|
| 315 | integers3 = [
|
| 316 | 1,
|
| 317 | 2, # this is ok
|
| 318 | ]"))
|
| 319 |
|
| 320 | (test-equal "parse-toml: Arrays of empty strings"
|
| 321 | '(("empty1" "")
|
| 322 | ("empty2" "" "")
|
| 323 | ("empty3" "" "" "")
|
| 324 | ("emptyraw1" "")
|
| 325 | ("emptyraw2" "" "")
|
| 326 | ("emptyraw3" "" "" "")
|
| 327 | ("emptyml1" "")
|
| 328 | ("emptyml2" "" "")
|
| 329 | ("emptyml3" "" "" "")
|
| 330 | ("emptyrawml1" "")
|
| 331 | ("emptyrawml2" "" "")
|
| 332 | ("emptyrawml3" "" "" ""))
|
| 333 | (parse-toml "empty1 = [ \"\" ]
|
| 334 | empty2 = [ \"\", \"\" ]
|
| 335 | empty3 = [ \"\", \"\", \"\" ]
|
| 336 | emptyraw1 = [ '' ]
|
| 337 | emptyraw2 = [ '', '' ]
|
| 338 | emptyraw3 = [ '', '', '' ]
|
| 339 | emptyml1 = [ \"\"\"\"\"\" ]
|
| 340 | emptyml2 = [ \"\"\"\"\"\", \"\"\"\"\"\" ]
|
| 341 | emptyml3 = [ \"\"\"\"\"\", \"\"\"\"\"\", \"\"\"\"\"\" ]
|
| 342 | emptyrawml1 = [ '''''' ]
|
| 343 | emptyrawml2 = [ '''''', '''''' ]
|
| 344 | emptyrawml3 = [ '''''', '''''', '''''' ]
|
| 345 | "))
|
| 346 |
|
| 347 | (test-equal "parse-toml: Tables"
|
| 348 | '(("table-1" ("key1" . "some string")
|
| 349 | ("key2" . 123))
|
| 350 | ("table-2" ("key1" . "another string")
|
| 351 | ("key2" . 456)))
|
| 352 | (parse-toml "[table-1]
|
| 353 | key1 = \"some string\"
|
| 354 | key2 = 123
|
| 355 |
|
| 356 | [table-2]
|
| 357 | key1 = \"another string\"
|
| 358 | key2 = 456"))
|
| 359 |
|
| 360 |
|
| 361 | (test-equal "parse-toml: Dotted table"
|
| 362 | '(("dog" ("tater.man" ("type" ("name" . "pug")))))
|
| 363 | (parse-toml "[dog.\"tater.man\"]
|
| 364 | type.name = \"pug\""))
|
| 365 |
|
| 366 |
|
| 367 | (test-equal "parse-toml: Dotted table with whitespace"
|
| 368 | '(("a" ("b" ("c" ("x" . 1))))
|
| 369 | ("d" ("e" ("f" ("x" . 1))))
|
| 370 | ("g" ("h" ("i" ("x" . 1))))
|
| 371 | ("j" ("ʞ" ("l" ("x" . 1)))))
|
| 372 | (parse-toml "[a.b.c] # this is best practice
|
| 373 | x=1
|
| 374 | [ d.e.f ] # same as [d.e.f]
|
| 375 | x=1
|
| 376 | [ g . h . i ] # same as [g.h.i]
|
| 377 | x=1
|
| 378 | [ j . \"ʞ\" . 'l' ] # same as [j.\"ʞ\".'l']
|
| 379 | x=1"))
|
| 380 |
|
| 381 | |
| 382 | (test-equal "parse-toml: Multiple tables"
|
| 383 | '(("fruit" ("apple" . "red") ("orange" . "orange")))
|
| 384 | (parse-toml "[fruit]
|
| 385 | apple = \"red\"
|
| 386 |
|
| 387 | [fruit]
|
| 388 | orange = \"orange\""))
|
| 389 |
|
| 390 | (test-error "parse-toml: Assignment to non-table"
|
| 391 | #t
|
| 392 | (parse-toml "[fruit]
|
| 393 | apple = \"red\"
|
| 394 |
|
| 395 | [fruit.apple]
|
| 396 | texture = \"smooth\""))
|
| 397 |
|
| 398 | (test-equal "parse-toml: Dotted keys create tables"
|
| 399 | '(("fruit" ("apple" ("color" . "red") ("taste" ("sweet" . #t)))))
|
| 400 | (parse-toml "fruit.apple.color = \"red\"
|
| 401 | fruit.apple.taste.sweet = true"))
|
| 402 |
|
| 403 | (test-equal "parse-toml: Inline tables"
|
| 404 | '(("name" ("first" . "Tom") ("last" . "Preston-Werner"))
|
| 405 | ("point" ("x" . 1) ("y" . 2))
|
| 406 | ("animal" ("type" ("name" . "pug")))
|
| 407 | ("contact" . (("personal" . (("name" . "Donald Duck")
|
| 408 | ("email" . "[email protected]")))
|
| 409 | ("work" . (("name" . "Coin cleaner")
|
| 410 | ("email" . "[email protected]"))))))
|
| 411 | (parse-toml "name = { first = \"Tom\", last = \"Preston-Werner\" }
|
| 412 | point = { x = 1, y = 2 }
|
| 413 | animal = { type.name = \"pug\" }
|
| 414 | contact = {
|
| 415 | personal = {
|
| 416 | name = \"Donald Duck\",
|
| 417 | email = \"[email protected]\",
|
| 418 | },
|
| 419 | work = {
|
| 420 | name = \"Coin cleaner\",
|
| 421 | email = \"[email protected]\",
|
| 422 | },
|
| 423 | }"))
|
| 424 |
|
| 425 | (test-equal "parse-toml: Empty inline table"
|
| 426 | '(("name")
|
| 427 | ("point")
|
| 428 | ("animal"))
|
| 429 | (parse-toml "name = {}
|
| 430 | point = { }
|
| 431 | animal = { }"))
|
| 432 |
|
| 433 | (test-error "parse-toml: Invalid assignment to inline table"
|
| 434 | #t
|
| 435 | (parse-toml "[product]
|
| 436 | type = { name = \"Nail\" }
|
| 437 | type.edible = false # INVALID"))
|
| 438 |
|
| 439 | |
| 440 | (test-expect-fail 1)
|
| 441 | (test-error "parse-toml: Invalid assignment to implicit table"
|
| 442 | #t
|
| 443 | (parse-toml "[product]
|
| 444 | type.name = \"Nail\"
|
| 445 | type = { edible = false } # INVALID"))
|
| 446 |
|
| 447 | |
| 448 | (test-expect-fail 1)
|
| 449 | (test-equal "parse-toml: Array of tables"
|
| 450 | '(("products" (("name" . "Hammer") ("sku" . 738594937))
|
| 451 | ()
|
| 452 | (("name" . "Nail") ("sku" . 284758393) ("color" . "gray"))))
|
| 453 | (parse-toml "[[products]]
|
| 454 | name = \"Hammer\"
|
| 455 | sku = 738594937
|
| 456 |
|
| 457 | [[products]] # empty table within the array
|
| 458 |
|
| 459 | [[products]]
|
| 460 | name = \"Nail\"
|
| 461 | sku = 284758393
|
| 462 |
|
| 463 | color = \"gray\""))
|
| 464 |
|
| 465 | |
| 466 | (test-expect-fail 1)
|
| 467 | (test-equal "parse-toml: Array of tables"
|
| 468 | '(("fruits" . ((("name" . "apple")
|
| 469 | ("physical" . (("color" . "red")
|
| 470 | ("shape" . "round")))
|
| 471 | ("varieties" . ((("name" . "red delicious"))
|
| 472 | (("name" . "granny smith")))))
|
| 473 | (("name" . "banana")
|
| 474 | ("varieties" . ((("name" . "plantain"))))))))
|
| 475 | (parse-toml "[[fruits]]
|
| 476 | name = \"apple\"
|
| 477 |
|
| 478 | [fruits.physical] # subtable
|
| 479 | color = \"red\"
|
| 480 | shape = \"round\"
|
| 481 |
|
| 482 | [[fruits.varieties]] # nested array of tables
|
| 483 | name = \"red delicious\"
|
| 484 |
|
| 485 | [[fruits.varieties]]
|
| 486 | name = \"granny smith\"
|
| 487 |
|
| 488 |
|
| 489 | [[fruits]]
|
| 490 | name = \"banana\"
|
| 491 |
|
| 492 | [[fruits.varieties]]
|
| 493 | name = \"plantain\""))
|
| 494 |
|
| 495 | |
| 496 | (test-expect-fail 1)
|
| 497 | (test-error "parse-toml: Assignment to statically defined array"
|
| 498 | #t
|
| 499 | (parse-toml "fruits = []
|
| 500 |
|
| 501 | [[fruits]]
|
| 502 | x=1"))
|
| 503 |
|
| 504 | (test-end "toml")
|
| 505 |
|