]> gitweb.factorcode.org Git - factor.git/blob - basis/toml/toml-tests.factor
a9075d28b988598f90fa4df2ef893c9431380881
[factor.git] / basis / toml / toml-tests.factor
1 USING: assocs calendar multiline present toml tools.test ;
2
3 ! Example document
4
5 {
6     H{
7         { "title" "TOML Example" }
8         {
9             "owner"
10             H{
11                 { "name" "Tom Preston-Werner" }
12                 { "organization" "GitHub" }
13                 {
14                     "bio"
15                     "GitHub Cofounder & CEO\nLikes tater tots and beer."
16                 }
17                 { "dob"
18                     T{ timestamp
19                         { year 1979 }
20                         { month 5 }
21                         { day 27 }
22                         { hour 7 }
23                         { minute 32 }
24                     }
25                 }
26             }
27         }
28         {
29             "database"
30             H{
31                 { "server" "192.168.1.1" }
32                 { "ports" { 8001 8001 8002 } }
33                 { "connection_max" 5000 }
34                 { "enabled" t }
35             }
36         }
37         {
38             "servers"
39             H{
40                 {
41                     "alpha"
42                     H{
43                         { "ip" "10.0.0.1" }
44                         { "dc" "eqdc10" }
45                     }
46                 }
47                 {
48                     "beta"
49                     H{
50                         { "ip" "10.0.0.2" }
51                         { "dc" "eqdc10" }
52                         { "country" "中国" }
53                     }
54                 }
55             }
56         }
57         {
58             "clients"
59             H{
60                 { "data" { { "gamma" "delta" } { 1 2 } } }
61                 { "hosts" { "alpha" "omega" } }
62             }
63         }
64         {
65             "products"
66             V{
67                 H{
68                     { "name" "Hammer" }
69                     { "sku" 738594937 }
70                 }
71                 H{
72                     { "name" "Nail" }
73                     { "sku" 284758393 }
74                     { "color" "gray" }
75                 }
76             }
77         }
78     }
79 } [
80     [=[
81
82 # This is a TOML document. Boom.
83
84 title = "TOML Example"
85
86 [owner]
87 name = "Tom Preston-Werner"
88 organization = "GitHub"
89 bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
90 dob = 1979-05-27T07:32:00Z # First class dates? Why not?
91
92 [database]
93 server = "192.168.1.1"
94 ports = [ 8001, 8001, 8002 ]
95 connection_max = 5000
96 enabled = true
97
98 [servers]
99
100   # You can indent as you please. Tabs or spaces. TOML don't care.
101   [servers.alpha]
102   ip = "10.0.0.1"
103   dc = "eqdc10"
104
105   [servers.beta]
106   ip = "10.0.0.2"
107   dc = "eqdc10"
108   country = "中国" # This should be parsed as UTF-8
109
110 [clients]
111 data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
112
113 # Line breaks are OK when inside arrays
114 hosts = [
115   "alpha",
116   "omega"
117 ]
118
119 # Products
120
121   [[products]]
122   name = "Hammer"
123   sku = 738594937
124
125   [[products]]
126   name = "Nail"
127   sku = 284758393
128   color = "gray"
129
130     ]=] toml>
131 ] unit-test
132
133 {
134     H{
135         { "deps" H{
136             { "temp_targets" H{ { "case" 72.0 } } } }
137         }
138     }
139 } [
140     "[deps]
141     temp_targets = { case = 72.0 }" toml>
142 ] unit-test
143
144 {
145     H{ { "foo" H{ { "qux" 456 } { "bar" H{ { "baz" 123 } } } } } }
146 } [
147 [=[
148 [foo.bar]
149 baz = 123
150 [foo]
151 qux = 456
152 ]=] toml>
153 ] unit-test
154
155 ! TESTS FROM 1.0.0 SPEC
156
157 ! Comments
158 {
159     H{ { "key" "value" } { "another" "# This is not a comment" } }
160 } [
161     [=[ # This is a full-line comment
162 key = "value"  # This is a comment at the end of a line
163 another = "# This is not a comment"]=] toml>
164 ] unit-test
165
166 ! Key/Value Pairs
167
168 [ [=[ key = # INVALID]=] toml> ] must-fail
169
170 [ [=[ key = 1234abcd ]=] toml> ] must-fail
171
172 [ [=[ first = "Tom" last = "Preston-Werner" # INVALID]=] toml> ] must-fail
173
174 ! Keys
175
176 {
177     H{
178         { "character encoding" "value" }
179         { "quoted \"value\"" "value" }
180         { "ʎǝʞ" "value" }
181         { "key2" "value" }
182         { "127.0.0.1" "value" }
183     }
184 } [
185     [=[
186 "127.0.0.1" = "value"
187 "character encoding" = "value"
188 "ʎǝʞ" = "value"
189 'key2' = "value"
190 'quoted "value"' = "value"
191  ]=] toml>
192 ] unit-test
193
194 [ [=[ = "no key name"  # INVALID]=] toml> ] must-fail
195 { H{ { "" "blank" } } } [ [=[ "" = "blank"     # VALID but discouraged]=] toml> ] unit-test
196 { H{ { "" "blank" } } } [ [=[ '' = "blank"     # VALID but discouraged]=] toml> ] unit-test
197
198 {
199     H{
200         { "physical" H{ { "color" "orange" } { "shape" "round" } } }
201         { "name" "Orange" }
202         { "site" H{ { "google.com" t } } }
203     }
204 } [
205     [=[
206 name = "Orange"
207 physical.color = "orange"
208 physical.shape = "round"
209 site."google.com" = true
210 ]=] toml>
211 ] unit-test
212
213 {
214     H{
215         { "fruit" H{
216                 { "name" "banana" }
217                 { "color" "yellow" }
218                 { "flavor" "banana" }
219             }
220         }
221     }
222 } [
223     [=[
224 fruit.name = "banana"     # this is best practice
225 fruit. color = "yellow"    # same as fruit.color
226 fruit . flavor = "banana"   # same as fruit.flavor]=] toml>
227 ] unit-test
228
229 [ [=[
230 # DO NOT DO THIS
231 name = "Tom"
232 name = "Pradyun"
233 ]=] toml> ] [ duplicate-key? ] must-fail-with
234
235 [ [=[ # THE FOLLOWING IS INVALID
236
237 # This defines the value of fruit.apple to be an integer.
238 fruit.apple = 1
239
240 # But then this treats fruit.apple like it's a table.
241 # You can't turn an integer into a table.
242 fruit.apple.smooth = true]=] toml> ] must-fail
243
244 { H{ { "3" H{ { "14159" "pi" } } } } } [
245     [=[ 3.14159 = "pi" ]=] toml>
246 ] unit-test
247
248 ! Strings
249
250 {
251     H{
252         {
253             "str"
254             "I'm a string. \"You can quote me\". Name\tJosé\nLocation\tSF."
255         }
256     }
257 } [
258     [=[ str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF." ]=]
259     toml>
260 ] unit-test
261
262 { H{ { "str1" "Roses are red\nViolets are blue" } } } [
263     [=[ str1 = """
264 Roses are red
265 Violets are blue"""]=] toml>
266 ] unit-test
267
268 {
269     H{
270         { "str1" "The quick brown fox jumps over the lazy dog." }
271         { "str2" "The quick brown fox jumps over the lazy dog." }
272         { "str3" "The quick brown fox jumps over the lazy dog." }
273     }
274 } [
275     [=[
276 # The following strings are byte-for-byte equivalent:
277 str1 = "The quick brown fox jumps over the lazy dog."
278
279 str2 = """
280 The quick brown \
281
282
283   fox jumps over \
284     the lazy dog."""
285
286 str3 = """\
287        The quick brown \
288        fox jumps over \
289        the lazy dog.\
290        """
291    ]=] toml>
292 ] unit-test
293
294 {
295     H{
296         { "regex" "<\\i\\c*\\s*>" }
297         { "quoted" "Tom \"Dubs\" Preston-Werner" }
298         { "winpath2" "\\\\ServerX\\admin$\\system32\\" }
299         { "winpath" "C:\\Users\\nodejs\\templates" }
300     }
301 } [
302     [=[ # What you see is what you get.
303 winpath  = 'C:\Users\nodejs\templates'
304 winpath2 = '\\ServerX\admin$\system32\'
305 quoted   = 'Tom "Dubs" Preston-Werner'
306 regex    = '<\i\c*\s*>' ]=] toml>
307 ] unit-test
308
309 ! Integer
310
311 {
312     H{
313         { "int1" 99 }
314         { "int2" 42 }
315         { "int3" 0 }
316         { "int4" -17 }
317         { "int5" 1000 }
318         { "int6" 5349221 }
319         { "int7" 5349221 }
320         { "int8" 12345 }
321         { "hex1" 0xdeadbeef }
322         { "hex2" 0xdeadbeef }
323         { "hex3" 0xdeadbeef }
324         { "oct1" 0o01234567 }
325         { "oct2" 0o755 }
326         { "bin1" 0b11010110 }
327     }
328 } [
329     [=[
330 int1 = +99
331 int2 = 42
332 int3 = 0
333 int4 = -17
334 int5 = 1_000
335 int6 = 5_349_221
336 int7 = 53_49_221  # Indian number system grouping
337 int8 = 1_2_3_4_5  # VALID but discouraged
338
339 # hexadecimal with prefix `0x`
340 hex1 = 0xDEADBEEF
341 hex2 = 0xdeadbeef
342 hex3 = 0xdead_beef
343
344 # octal with prefix `0o`
345 oct1 = 0o01234567
346 oct2 = 0o755 # useful for Unix file permissions
347
348 # binary with prefix `0b`
349 bin1 = 0b11010110
350 ]=] toml>
351 ] unit-test
352
353 [ [=[ key = +0o99 ]=] toml> ] must-fail
354
355 ! Floats
356
357 {
358     H{
359         { "flt1" "1.0" }
360         { "flt2" "3.1415" }
361         { "flt3" "-0.01" }
362         { "flt4" "5.0e+22" }
363         { "flt5" "1000000.0" }
364         { "flt6" "-0.02" }
365         { "flt7" "6.626e-34" }
366         { "flt8" "224617.445991228" }
367         { "sf1" "1/0." }
368         { "sf3" "-1/0." }
369         { "sf2" "1/0." }
370         { "sf5" "0/0." }
371         { "sf4" "0/0." }
372         { "sf6" "0/0." }
373     }
374 } [
375     [=[
376 # fractional
377 flt1 = +1.0
378 flt2 = 3.1415
379 flt3 = -0.01
380
381 # exponent
382 flt4 = 5e+22
383 flt5 = 1e06
384 flt6 = -2E-2
385
386 # both
387 flt7 = 6.626e-34
388
389 flt8 = 224_617.445_991_228
390
391 # infinity
392 sf1 = inf  # positive infinity
393 sf2 = +inf # positive infinity
394 sf3 = -inf # negative infinity
395
396 # not a number
397 sf4 = nan  # actual sNaN/qNaN encoding is implementation-specific
398 sf5 = +nan # same as `nan`
399 sf6 = -nan # valid, actual encoding is implementation-specific
400 ]=] toml> [ present ] assoc-map
401 ] unit-test
402
403 [ [=[ invalid_float_1 = .7]=] toml> ] must-fail
404 [ [=[ invalid_float_2 = 7.]=] toml> ] must-fail
405 [ [=[ invalid_float_2 = 3.e+20]=] toml> ] must-fail
406
407 ! Booleans
408
409 { H{ { "bool1" t } { "bool2" f } } } [
410     [=[ bool1 = true
411 bool2 = false]=] toml>
412 ] unit-test
413
414 ! Offset Date-Time
415
416 {
417     H{
418         {
419             "odt4"
420             T{ timestamp
421                 { year 1979 }
422                 { month 5 }
423                 { day 27 }
424                 { hour 7 }
425                 { minute 32 }
426             }
427         }
428         {
429             "odt1"
430             T{ timestamp
431                 { year 1979 }
432                 { month 5 }
433                 { day 27 }
434                 { hour 7 }
435                 { minute 32 }
436             }
437         }
438         {
439             "odt2"
440             T{ timestamp
441                 { year 1979 }
442                 { month 5 }
443                 { day 27 }
444                 { minute 32 }
445                 { gmt-offset T{ duration { hour -7 } } }
446             }
447         }
448         {
449             "odt3"
450             T{ timestamp
451                 { year 1979 }
452                 { month 5 }
453                 { day 27 }
454                 { minute 32 }
455                 { second 999999/1000000 }
456                 { gmt-offset T{ duration { hour -7 } } }
457             }
458         }
459     }
460 } [
461     [=[
462 odt1 = 1979-05-27T07:32:00Z
463 odt2 = 1979-05-27T00:32:00-07:00
464 odt3 = 1979-05-27T00:32:00.999999-07:00
465 odt4 = 1979-05-27 07:32:00Z
466 ]=] toml>
467 ] unit-test
468
469 ! Local Date-Time
470
471 {
472     H{
473         {
474             "ldt1"
475             T{ timestamp
476                 { year 1979 }
477                 { month 5 }
478                 { day 27 }
479                 { hour 7 }
480                 { minute 32 }
481             }
482         }
483         {
484             "ldt2"
485             T{ timestamp
486                 { year 1979 }
487                 { month 5 }
488                 { day 27 }
489                 { minute 32 }
490                 { second 999999/1000000 }
491             }
492         }
493     }
494 } [
495     [=[
496 ldt1 = 1979-05-27T07:32:00
497 ldt2 = 1979-05-27T00:32:00.999999
498 ]=] toml>
499 ] unit-test
500
501 ! Local Date
502
503 { H{ { "ld1" "1979-05-27" } } } [
504     [=[
505 ld1 = 1979-05-27
506 ]=] toml>
507 ] unit-test
508
509 ! Local Time
510
511 { H{ { "lt2" "00:32:00.999999" } { "lt1" "07:32:00" } } } [
512     [=[
513 lt1 = 07:32:00
514 lt2 = 00:32:00.999999
515 ]=] toml>
516 ] unit-test
517
518 ! Array
519
520 {
521     H{
522         { "integers" { 1 2 3 } }
523         { "colors" { "red" "yellow" "green" } }
524         { "nested_arrays_of_ints" { { 1 2 } { 3 4 5 } } }
525         { "nested_mixed_array" { { 1 2 } { "a" "b" "c" } } }
526         { "string_array" { "all" "strings" "are the same" "type" } }
527         { "numbers" { 0.1 0.2 0.5 1 2 5 } }
528         {
529             "contributors"
530             {
531                 "Foo Bar <foo@example.com>"
532                 H{
533                     { "name" "Baz Qux" }
534                     { "email" "bazqux@example.com" }
535                     { "url" "https://example.com/bazqux" }
536                 }
537             }
538         }
539     }
540 } [
541     [=[
542 integers = [ 1, 2, 3 ]
543 colors = [ "red", "yellow", "green" ]
544 nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ]
545 nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ]
546 string_array = [ "all", 'strings', """are the same""", '''type''' ]
547
548 # Mixed-type arrays are allowed
549 numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ]
550 contributors = [
551   "Foo Bar <foo@example.com>",
552   { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" }
553 ]
554 ]=] toml>
555 ] unit-test
556
557 {
558     H{
559         { "integers2" { 1 2 3 } }
560         { "integers3" { 1 2 } }
561     }
562 } [
563     [=[ integers2 = [
564   1, 2, 3
565 ]
566
567 integers3 = [
568   1,
569   2, # this is ok
570 ]]=] toml>
571 ] unit-test
572
573 ! Table
574
575 {
576     H{ { "j" H{ { "ʞ" H{ { "l" H{ { "key1" t } } } } } } } }
577 } [
578     [=[
579 [ j . "ʞ" . 'l' ]
580 key1 = true
581 ]=] toml>
582 ] unit-test
583
584 ! Inline Table
585
586 {
587     H{
588         {
589             "name"
590             H{ { "first" "Tom" } { "last" "Preston-Werner" } }
591         }
592         { "point" H{ { "x" 1 } { "y" 2 } } }
593         { "animal" H{ { "type" H{ { "name" "pug" } } } } }
594     }
595 } [
596     [=[
597 name = { first = "Tom", last = "Preston-Werner" }
598 point = { x = 1, y = 2 }
599 animal = { type.name = "pug" }]=] toml>
600 ] unit-test
601
602 ! Array of Tables
603
604 {
605     H{
606         { "points" {
607                 H{ { "x" 1 } { "y" 2 } { "z" 3 } }
608                 H{ { "x" 7 } { "y" 8 } { "z" 9 } }
609                 H{ { "x" 2 } { "y" 4 } { "z" 8 } }
610             }
611         }
612     }
613 } [
614     [=[ points = [ { x = 1, y = 2, z = 3 },
615            { x = 7, y = 8, z = 9 },
616            { x = 2, y = 4, z = 8 } ] ]=] toml>
617 ] unit-test
618
619 { H{ { "a" { } } } } [ "a=[]" toml> ] unit-test
620 { H{ { "a" { 1 } } } } [ "a=[1]" toml> ] unit-test
621 { H{ { "a" { 1 2 3 } } } } [ "a=[1,2,3]" toml> ] unit-test
622 { H{ { "a" { 1 2 3 } } } } [ "a=[,1,,,,2,,3,,]" toml> ] unit-test
623 { H{ { "a" { 1 2 3 } } } } [ "a=[ # this\n,1,, # is\n,,2, #a\n,3,, # comment \n]" toml> ] unit-test
624
625 ! unreleased
626
627 ! Clarify Unicode and UTF-8 references.
628 ! Relax comment parsing; most control characters are again permitted.
629 ! Allow newline after key/values in inline tables.
630 ! Allow trailing comma in inline tables.
631 ! Clarify where and how dotted keys define tables.
632 ! Add new \e shorthand for the escape character.
633 ! Add \x00 notation to basic strings.
634 ! Seconds in Date-Time and Time values are now optional.
635 ! Allow non-English scripts in unquoted (bare) keys
636 ! Clarify newline normalization in multi-line literal strings.