Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/lyaml/spec/lib_lyaml_spec.yaml
178469 views
1
# LYAML binding for Lua 5.1, 5.2, 5.3 & 5.4
2
# Copyright (C) 2013-2022 Gary V. Vaughan
3
4
before: |
5
lyaml = require "lyaml"
6
7
-- Always use the new multi-doc capable API.
8
lyaml.legacy = lyaml.load
9
lyaml.load = function (stream) return lyaml.legacy (stream, true) end
10
11
specify lyaml:
12
- describe dumping:
13
- context streams:
14
- it writes an empty stream:
15
expect (lyaml.dump {}).to_equal ""
16
17
- context documents:
18
- it writes an empty document:
19
expect (lyaml.dump {""}).to_match "^%-%-%-%s*''\n%.%.%.%s*$"
20
- it writes consecutive documents:
21
expect (lyaml.dump {"one", "two"}).
22
to_match "^%-%-%-%s+one%s*\n%.%.%.%s*\n%-%-%-%s+two%s*\n%.%.%.%s*$"
23
24
- context scalars:
25
- it writes null:
26
expect (lyaml.dump {lyaml.null}).to_be "--- ~\n...\n"
27
expect (lyaml.dump {"~"}).to_be "--- '~'\n...\n"
28
- it writes booleans:
29
expect (lyaml.dump {"true"}).to_be "--- 'true'\n...\n"
30
expect (lyaml.dump {"yes"}).to_be "--- 'yes'\n...\n"
31
expect (lyaml.dump {"false"}).to_be "--- 'false'\n...\n"
32
expect (lyaml.dump {"no"}).to_be "--- 'no'\n...\n"
33
expect (lyaml.dump {true}).to_be "--- true\n...\n"
34
expect (lyaml.dump {false}).to_be "--- false\n...\n"
35
- it writes numbers:
36
expect (lyaml.dump {"123"}).to_be "--- '123'\n...\n"
37
expect (lyaml.dump {"12.3"}).to_be "--- '12.3'\n...\n"
38
expect (lyaml.dump {"0/0"}).to_be "--- 0/0\n...\n"
39
expect (lyaml.dump {123}).to_be "--- 123\n...\n"
40
expect (lyaml.dump {12.3}).to_be "--- 12.3\n...\n"
41
expect (lyaml.dump {0/0}).to_be "--- .nan\n...\n"
42
expect (lyaml.dump {math.huge}).to_be "--- .inf\n...\n"
43
expect (lyaml.dump {-math.huge}).to_be "--- -.inf\n...\n"
44
- it writes strings:
45
expect (lyaml.dump {"a string"}).to_be "--- a string\n...\n"
46
expect (lyaml.dump {"'a string'"}).to_be "--- '''a string'''\n...\n"
47
expect (lyaml.dump {"a\nmultiline\nstring"}).to_be "--- |-\n a\n multiline\n string\n...\n"
48
expect (lyaml.dump {""}).to_be "--- ''\n...\n"
49
50
- context sequences:
51
- it writes a sequence:
52
expect (lyaml.dump {{1, 2, 3}}).to_contain "- 1\n- 2\n- 3"
53
54
- context mappings:
55
- it writes a mapping: |
56
expect (lyaml.dump {{a=1, b=2, c=3, d=""}}).
57
to_contain.all_of {"a: 1", "b: 2", "c: 3", "d: ''"}
58
- it writes a mapping of mixed keys: |
59
expect (lyaml.dump {{[1]=1, [2]=2, three="three", four="4", [5]="five"}}).
60
to_contain.all_of {"1: 1", "2: 2", "three: three", "four: '4'", "5: five"}
61
- it writes a mapping of integer keys starting at two: |
62
expect (lyaml.dump {{[2]=2, [3]=3, [4]=4}}).
63
to_contain.all_of {"2: 2", "3: 3", "4: 4"}
64
- it writes a mapping of mixed keys starting at one: |
65
expect (lyaml.dump {{[1]=1, [2]=2, [3]=3, foo="bar"}}).
66
to_contain.all_of {"1: 1", "2: 2", "3: 3", "foo: bar"}
67
- it writes a mapping of mixed keys starting at two: |
68
expect (lyaml.dump {{[2]=2, [3]=3, [4]=4, foo="bar"}}).
69
to_contain.all_of {"2: 2", "3: 3", "4: 4", "foo: bar"}
70
- it writes a table containing nils (jumps in index) as mapping: |
71
expect (lyaml.dump {{1, 2, nil, 3, 4}}).
72
to_contain.all_of {"1: 1", "2: 2", "4: 3", "5: 4"}
73
74
- context anchors and aliases:
75
- before:
76
anchors = {
77
MAP = {["Mark McGwire"] = 65, ["Sammy Sosa"] = 63},
78
SEQ = {"Mark McGwire", "Sammy Sosa"},
79
}
80
- it writes scalar anchors: '
81
anchors = { SS = "Sammy Sosa" }
82
expect (lyaml.dump ({{{anchor = anchors.SS}, {alias = anchors.SS}}}, anchors)).
83
to_contain "- anchor: &SS Sammy Sosa\n- alias: *SS\n"'
84
- it writes sequence anchors: '
85
expect (lyaml.dump ({{{anchor = anchors.SEQ}, {alias = anchors.SEQ}}}, anchors)).
86
to_contain "\n- anchor: &SEQ\n - Mark McGwire\n - Sammy Sosa\n- alias: *SEQ\n"'
87
- it writes mapping anchors: '
88
expect (lyaml.dump ({{{anchor = anchors.MAP}, {alias = anchors.MAP}}}, anchors)).
89
to_match "\n%- anchor: &MAP\n %w+ %w+: %d+\n %w+ %w+: %d+\n%- alias: %*MAP\n"'
90
91
92
- describe loading:
93
- before:
94
fn = lyaml.load
95
96
- it loads an empty stream:
97
expect (fn "").to_equal {}
98
- it ignores comments: '
99
expect (fn "# A comment\nnon-comment # trailing comment\n").
100
to_equal { "non-comment" }'
101
- it diagnoses unexpected events: '
102
expect (fn "...").to_error "1:1: did not find expected node content"
103
expect (fn "---\n...\ngarbage\n").
104
to_error "2:1: did not find expected <document start>"
105
expect (fn " *ALIAS").
106
to_error "1:2: invalid reference: ALIAS"'
107
108
- context documents:
109
- it lyaml.loads an empty document:
110
expect (fn "---").to_equal {lyaml.null}
111
expect (fn "---\n").to_equal {lyaml.null}
112
expect (fn "---\n...").to_equal {lyaml.null}
113
expect (fn "---\n...\n").to_equal {lyaml.null}
114
- it lyaml.loads multiple documents:
115
expect (fn "one\n---\ntwo").to_equal {"one", "two"}
116
expect (fn "---\none\n---\ntwo").to_equal {"one", "two"}
117
expect (fn "one\n...\n---\ntwo\n...").to_equal {"one", "two"}
118
expect (fn "---\none\n...\n---\ntwo\n...").to_equal {"one", "two"}
119
- it reports an empty document:
120
expect (fn "---\n---\ntwo\n---").
121
to_equal {lyaml.null, "two", lyaml.null}
122
expect (fn "---\n...\n---\ntwo\n---").
123
to_equal {lyaml.null, "two", lyaml.null}
124
expect (fn "---\n...\n---\ntwo\n...\n---").
125
to_equal {lyaml.null, "two", lyaml.null}
126
expect (fn "---\n...\n---\ntwo\n...\n---\n...").
127
to_equal {lyaml.null, "two", lyaml.null}
128
129
- context version directive:
130
- it recognizes version number:
131
expect (fn "%YAML 1.1\n---").to_equal {lyaml.null}
132
- it diagneses missing document start:
133
expect (fn "%YAML 1.1").
134
to_error "expected <document start>"
135
- it diagnoses unsupported version:
136
expect (fn "%YAML 2.0\n---").
137
to_error "incompatible YAML document"
138
139
- context tag directive:
140
- it recognizes primary tag directive: '
141
expect (fn ("%TAG ! tag:yaml.org,2002:\n" ..
142
"---\n" ..
143
"!bool N")).to_equal {false}'
144
- it recognizes secondary tag directive: '
145
expect (fn ("%TAG !! tag:ben-kiki.org,2000:\n" ..
146
"---\n" ..
147
"!!bool untrue")).to_equal {"untrue"}'
148
- it recognizes named tag directive: '
149
expect (fn ("%TAG !bkk! tag:ben-kiki.org,2000:\n" ..
150
"---\n" ..
151
"!bkk!bool untrue")).to_equal {"untrue"}'
152
- it diagnoses undefined tag handles: '
153
expect (fn ("!bkk!bool untrue")).
154
to_error "undefined tag handle"'
155
156
- context scalars:
157
- it recognizes null: '
158
expect (fn "~").to_equal {lyaml.null}
159
expect (fn "foo: ").to_equal {{foo = lyaml.null}}
160
expect (fn "foo: ~").to_equal {{foo = lyaml.null}}
161
expect (fn "foo: !!null").to_equal {{foo = lyaml.null}}
162
expect (fn "foo: null").to_equal {{foo = lyaml.null}}
163
expect (fn "foo: Null").to_equal {{foo = lyaml.null}}
164
expect (fn "foo: NULL").to_equal {{foo = lyaml.null}}'
165
- it recognizes booleans: '
166
expect (fn "true").to_equal {true}
167
expect (fn "false").to_equal {false}
168
expect (fn "yes").to_equal {true}
169
expect (fn "no").to_equal {false}'
170
- it loads bare y and n as strings:
171
expect (fn "y").to_equal {"y"}
172
expect (fn "n").to_equal {"n"}
173
- it recognizes integers:
174
expect (fn "0b001010011010").to_equal {666}
175
expect (fn "0b0010_1001_1010").to_equal {666}
176
expect (fn "+0b001_010_011_010").to_equal {666}
177
expect (fn "-0b0010_1001_1010").to_equal {-666}
178
expect (fn "0_1232").to_equal {666}
179
expect (fn "-01232").to_equal {-666}
180
expect (fn "666").to_equal {666}
181
expect (fn "0x29a").to_equal {666}
182
expect (fn "-0x29a").to_equal {-666}
183
expect (fn "12_345_678").to_equal {12345678}
184
expect (fn "11:6").to_equal {666}
185
- it recognizes floats:
186
expect (fn "12.3").to_equal {12.3}
187
expect (fn "685.230_15e+03").to_equal {685230.15}
188
expect (fn "685_230.15e+03").to_equal {685230150.0}
189
expect (fn "12_345_678.9").to_equal {12345678.9}
190
expect (fn "11:6.777").to_equal {666.777}
191
expect (fn ".Inf").to_equal {math.huge}
192
expect (fn "-.inf").to_equal {-math.huge}
193
nant = fn ".NaN"
194
expect (nant[1]).not_to_equal (nant[1])
195
- it recognizes strings:
196
expect (fn "a string").to_equal {"a string"}
197
expect (fn "'''a string'''").to_equal {"'a string'"}
198
expect (fn "|-\n a\n multiline\n string").to_equal {"a\nmultiline\nstring"}
199
expect (fn "'yes'").to_equal {"yes"}
200
expect (fn "''").to_equal {""}
201
expect (fn '""').to_equal {""}
202
203
- context global tags:
204
- it recognizes !!null:
205
expect (fn "!!null").to_equal {lyaml.null}
206
- it recognizes !!bool: |
207
expect (fn '!!bool "true"').to_equal {true}
208
expect (fn '!!bool true').to_equal {true}
209
expect (fn '!!bool True').to_equal {true}
210
expect (fn '!!bool TRUE').to_equal {true}
211
expect (fn "!!bool 'false'").to_equal {false}
212
expect (fn '!!bool false').to_equal {false}
213
expect (fn '!!bool False').to_equal {false}
214
expect (fn '!!bool FALSE').to_equal {false}
215
expect (fn '!!bool "yes"').to_equal {true}
216
expect (fn "!!bool 'Yes'").to_equal {true}
217
expect (fn '!!bool YES').to_equal {true}
218
expect (fn '!!bool no').to_equal {false}
219
expect (fn "!!bool 'No'").to_equal {false}
220
expect (fn '!!bool "NO"').to_equal {false}
221
expect (fn '!!bool garbage').
222
to_raise "invalid 'tag:yaml.org,2002:bool' value: 'garbage'"
223
- it loads explicit y and n as booleans:
224
expect (fn '!!bool Y').to_equal {true}
225
expect (fn '!!bool y').to_equal {true}
226
expect (fn '!!bool N').to_equal {false}
227
expect (fn '!!bool n').to_equal {false}
228
- it recognizes !!float: |
229
expect (fn '!!float 42').to_equal {42.0}
230
expect (fn '!!float "42"').to_equal {42.0}
231
expect (fn '!!float +42').to_equal {42.0}
232
expect (fn '!!float 12.3').to_equal {12.3}
233
expect (fn '!!float -3.141592').to_equal {-3.141592}
234
expect (fn '!!float 685_230.15e+03').to_equal {685230150.0}
235
expect (fn '!!float +685.230_15e+03').to_equal {685230.15}
236
expect (fn '!!float 12_345_678.9').to_equal {12345678.9}
237
expect (fn '!!float -0:3:11:6.777').to_equal {-11466.777}
238
expect (fn '!!float .Inf').to_equal {math.huge}
239
expect (fn '!!float -.inf').to_equal {-math.huge}
240
nant = fn '!!float .NaN'
241
expect (nant[1]).not_to_equal (nant[1])
242
expect (fn '!!float garbage').
243
to_raise "invalid 'tag:yaml.org,2002:float' value: 'garbage'"
244
- it recognizes !!int: |
245
expect (fn '!!int 0b0010_1001_1010').to_equal {666}
246
expect (fn '!!int "+0b001_010_011_010"').to_equal {666}
247
expect (fn '!!int -0b0010_1001_1010').to_equal {-666}
248
expect (fn '!!int 0_1232').to_equal {666}
249
expect (fn '!!int "-01232"').to_equal {-666}
250
expect (fn '!!int 666').to_equal {666}
251
expect (fn '!!int 0668').to_equal {668}
252
expect (fn '!!int "0x29a"').to_equal {666}
253
expect (fn '!!int -0x29a').to_equal {-666}
254
expect (fn '!!int 12_345_678').to_equal {12345678}
255
expect (fn '!!int 11:6').to_equal {666}
256
expect (fn '!!int 12.3').
257
to_raise "invalid 'tag:yaml.org,2002:int' value: '12.3'"
258
expect (fn '!!int garbage').
259
to_raise "invalid 'tag:yaml.org,2002:int' value: 'garbage'"
260
261
- context sequences:
262
- it recognizes block sequences:
263
expect (fn "- ~\n- \n- true\n- 42").
264
to_equal {{lyaml.null, lyaml.null, true, 42}}
265
- it recognizes flow sequences:
266
expect (fn "[~, true, 42]").
267
to_equal {{lyaml.null, true, 42}}
268
269
- context anchors and aliases:
270
- it resolves scalar anchors: '
271
expect (fn "anchor: &SS Sammy Sosa\nalias: *SS").
272
to_equal {{anchor = "Sammy Sosa", alias = "Sammy Sosa"}}'
273
- it resolves sequence anchors: '
274
expect (fn "anchor: &SEQ [Mark McGwire, Sammy Sosa]\nalias: *SEQ").
275
to_equal {{anchor = {"Mark McGwire", "Sammy Sosa"},
276
alias = {"Mark McGwire", "Sammy Sosa"}}}'
277
- it resolves mapping anchors: '
278
expect (fn "anchor: &MAP {Mark McGwire: 65, Sammy Sosa: 63}\nalias: *MAP").
279
to_equal {{anchor = {["Mark McGwire"] = 65, ["Sammy Sosa"] = 63},
280
alias = {["Mark McGwire"] = 65, ["Sammy Sosa"] = 63}}}'
281
282
- context a map:
283
- it recognizes block mapping: |
284
expect (fn "'null': ~\nboolean: yes\nnumber: 3.14").
285
to_equal {{null = lyaml.null, boolean = true, number = 3.14}}
286
- it recognizes flow mapping: |
287
expect (fn "{null: null, boolean: yes, number: 3.14}").
288
to_equal {{[lyaml.null] = lyaml.null, boolean = true, number = 3.14}}
289
- context with merge keys:
290
- before: |
291
merge = {x=1, y=2}
292
override = {x=0, z=2}
293
bogus = true
294
YAML = "- &MERGE {x: 1, y: 2}\n" ..
295
"- &OVERRIDE {x: 0, z: 2}\n" ..
296
"- &BOGUS true\n"
297
- it diagnoses invalid merge events: |
298
expect (fn "-\n !!merge : x\n z: 3").
299
to_raise "invalid 'tag:yaml.org,2002:merge' merge event: x"
300
expect (fn "-\n << : x\n z: 3").
301
to_raise "invalid '<<' merge event: x"
302
- it diagnoses invalid merge alias types: |
303
expect (fn (YAML .. "-\n !!merge : *BOGUS")).
304
to_raise "invalid 'tag:yaml.org,2002:merge' merge event: true"
305
expect (fn (YAML .. "-\n << : *BOGUS")).
306
to_raise "invalid '<<' merge event: true"
307
- it diagnoses invalid merge sequence elements: |
308
expect (fn (YAML .. '-\n !!merge : [*MERGE, OVERRIDE]')).
309
to_raise "invalid 'tag:yaml.org,2002:merge' sequence element 2: OVERRIDE"
310
expect (fn (YAML .. '-\n <<: [*MERGE, OVERRIDE]')).
311
to_raise "invalid '<<' sequence element 2: OVERRIDE"
312
- it diagnoses invalid merge sequence alias tyes: |
313
expect (fn (YAML .. '-\n !!merge : [*MERGE, *BOGUS]')).
314
to_raise "invalid 'tag:yaml.org,2002:merge' sequence element 2: true"
315
expect (fn (YAML .. '-\n <<: [*MERGE, *BOGUS]')).
316
to_raise "invalid '<<' sequence element 2: true"
317
- it supports merging bare maps: |
318
expect (fn ("-\n !!merge : {x: 1, y: 2}\n z: 3")).
319
to_equal {{{x=1, y=2, z=3}}}
320
expect (fn "-\n <<: {x: 1, y: 2}\n z: 3").
321
to_equal {{{x=1, y=2, z=3}}}
322
- it supports merging map aliases: |
323
expect (fn (YAML .. "-\n !!merge : *MERGE\n z: 3")).
324
to_equal {{merge, override, bogus, {x=1, y=2, z=3}}}
325
expect (fn (YAML .. "-\n <<: *MERGE\n z: 3")).
326
to_equal {{merge, override, bogus, {x=1, y=2, z=3}}}
327
- it merges sequence of bare maps with decreasing precedence: |
328
expect (fn "-\n !!merge : [{x: 1, y: 2}, {x: 0, z: 2}]\n z: 3").
329
to_equal {{{x=1, y=2, z=3}}}
330
expect (fn "-\n <<: [{x: 1, y: 2}, {x: 0, z: 2}]\n z: 3").
331
to_equal {{{x=1, y=2, z=3}}}
332
- it merges sequence of aliases with decreasing precedence: |
333
expect (fn (YAML .. "-\n !!merge : [*MERGE, *OVERRIDE]\n z: 3")).
334
to_equal {{merge, override, bogus, {x=1, y=2, z=3}}}
335
expect (fn (YAML .. "-\n <<: [*MERGE, *OVERRIDE]\n z: 3")).
336
to_equal {{merge, override, bogus, {x=1, y=2, z=3}}}
337
- it merges a sequence alias with decreasing precedence: |
338
seq = {merge, override}
339
r = {{merge, override, bogus, seq, {x=1, y=2, z=3}}}
340
expect (fn (YAML .. "- &SEQ [*MERGE, *OVERRIDE]\n" ..
341
"-\n !!merge : *SEQ\n z: 3")).to_equal (r)
342
expect (fn (YAML .. "- &SEQ [*MERGE, *OVERRIDE]\n" ..
343
"-\n <<: *SEQ\n z: 3")).to_equal (r)
344
345