1# LYAML binding for Lua 5.1, 5.2, 5.3 & 5.4 2# Copyright (C) 2013-2022 Gary V. Vaughan 3 4specify parsing: 5- it parses empty streams: 6 e = yaml.parser "" 7 expect (e ().type).to_be "STREAM_START" 8 expect (e ().type).to_be "STREAM_END" 9 expect (e ()).to_be (nil) 10 expect (e ()).to_be (nil) 11- it ignores comments: ' 12 e = yaml.parser "# A comment\nnon-comment # trailing comment\n" 13 expect (e ().type).to_be "STREAM_START" 14 expect (e ().type).to_be "DOCUMENT_START" 15 expect (e ().value).to_be "non-comment" 16 expect (e ().type).to_be "DOCUMENT_END"' 17 18- describe STREAM_START: 19 - before: 20 e = yaml.parser "# no BOM" 21 - it is the first event: 22 expect (e ().type).to_be "STREAM_START" 23 - it reports event start marker: 24 expect (e ().start_mark).to_equal {line = 0, column = 0, index = 0} 25 - it reports event end marker: 26 expect (e ().end_mark).to_equal {line = 0, column = 0, index = 0} 27 - it uses UTF-8 by default: 28 expect (e ().encoding).to_be "UTF8" 29 - it recognizes UTF-16 BOM: 30 e = yaml.parser (BOM .. " BOM") 31 expect (e ().encoding).to_match "UTF16[BL]E" 32 33- describe STREAM_END: 34 - before: 35 for t in yaml.parser "nothing to see" do ev = t end 36 - it is the last event: 37 expect (ev.type).to_be "STREAM_END" 38 - it reports event start marker: 39 expect (ev.start_mark).to_equal {line = 1, column = 0, index = 14} 40 - it reports event end marker: 41 expect (ev.end_mark).to_equal {line = 1, column = 0, index = 14} 42 43- describe DOCUMENT_START: 44 - before: 45 e = consume (1, "---") 46 - it recognizes document start marker: 47 expect (filter (e (), "type", "implicit")). 48 to_equal {type = "DOCUMENT_START", implicit = false} 49 - it reports implicit document start: 50 e = consume (1, "foo") 51 expect (e ().implicit).to_be (true) 52 - it reports event start marker: 53 expect (e ().start_mark).to_equal {line = 0, column = 0, index = 0} 54 - it reports event end marker: 55 expect (e ().end_mark).to_equal {line = 0, column = 3, index = 3} 56 57 - context parser directives: 58 - it can recognize document versions: 59 e = consume (1, "%YAML 1.1\n---") 60 expect (e ().version_directive).to_equal {major = 1, minor = 1} 61 - it can diagnose missing document start: 62 e = consume (1, "%YAML 1.1\n") 63 expect (e ()).to_error "expected <document start>" 64 - it can diagnose multiple versions: 65 e = consume (1, "%YAML 1.1\n%YAML 1.1\n---") 66 expect (e ()).to_error "duplicate %YAML directive" 67 - it can diagnose too-new versions: 68 e = consume (1, "%YAML 2.0\n---") 69 expect (e ()).to_error "incompatible YAML document" 70 - it warns of newer minor versions: 71 pending (github_issue "1") 72 e = consume (1, "%YAML 1.9\n---") 73 expect (e ()). 74 to_error "attempting parsing of newer minor document version" 75 76 - it can recognize primary tag handles: 77 e = consume (1, "%TAG ! tag:ben-kiki.org,2000:app/\n---") 78 expect (e ().tag_directives). 79 to_equal {{handle = "!", prefix = "tag:ben-kiki.org,2000:app/"}} 80 - it can recognize secondary tag handles: 81 e = consume (1, "%TAG !! tag:yaml.org,2002:\n---") 82 expect (e ().tag_directives). 83 to_equal {{handle = "!!", prefix = "tag:yaml.org,2002:"}} 84 - it can recognize named tag handles: 85 e = consume (1, "%TAG !o! tag:ben-kiki.org,2000:\n---") 86 expect (e ().tag_directives). 87 to_equal {{handle = "!o!", prefix = "tag:ben-kiki.org,2000:"}} 88 - it can concatenate multiple tag handles: 89 e = consume (1, "%TAG ! !\n" .. 90 "%TAG !! tag:yaml.org,2002:\n" .. 91 "%TAG !o! tag:ben-kiki.org,2000:\n" .. 92 "---") 93 expect (e ().tag_directives).to_contain. 94 all_of {{handle = "!", prefix = "!"}, 95 {handle = "!!", prefix = "tag:yaml.org,2002:"}, 96 {handle = "!o!", prefix = "tag:ben-kiki.org,2000:"}} 97 - it can diagnose missing document start: 98 e = consume (1, "%TAG ! !\n") 99 expect (e ()).to_error "expected <document start>" 100 101- describe DOCUMENT_END: 102 - before: 103 e = consume (3, "foo\n...") 104 - it recognizes the document end marker: 105 expect (filter (e (), "type", "implicit")). 106 to_equal {type = "DOCUMENT_END", implicit = false} 107 - it reports an implicit document end marker: 108 e = consume (3, "foo\n") 109 expect (filter (e (), "type", "implicit")). 110 to_equal {type = "DOCUMENT_END", implicit = true} 111 - it reports event start marker: 112 expect (e ().start_mark).to_equal {line = 1, column = 0, index = 4} 113 - it reports event end marker: 114 expect (e ().end_mark).to_equal {line = 1, column = 3, index = 7} 115 116- describe ALIAS: 117 - before: 118 e = consume (10, "---\n" .. 119 "hr:\n" .. 120 "- Mark McGwire\n" .. 121 "- &SS Sammy Sosa\n" .. 122 "rbi:\n" .. 123 "- *SS\n" .. 124 "- Ken Griffey") 125 - it recognizes an alias event: 126 expect (filter (e (), "type", "anchor")). 127 to_equal {type = "ALIAS", anchor = "SS"} 128 - it reports event start marker: 129 expect (e ().start_mark).to_equal {line = 5, column = 2, index = 47} 130 - it reports event end marker: 131 expect (e ().end_mark).to_equal {line = 5, column = 5, index = 50} 132 133- describe SCALAR: 134 - before: 135 e = consume (6, "---\n" .. 136 "hr:\n" .. 137 "- Mark McGwire\n" .. 138 "- &SS Sammy Sosa\n" .. 139 "rbi:\n" .. 140 "- *SS\n" .. 141 "- Ken Griffey") 142 - it recognizes a scalar event: 143 expect (filter (e (), "type", "value")). 144 to_equal {type = "SCALAR", value = "Sammy Sosa"} 145 - it records anchors: 146 expect (e ().anchor).to_be "SS" 147 - it reports event start marker: 148 expect (e ().start_mark).to_equal {line = 3, column = 2, index = 25} 149 - it reports event end marker: 150 expect (e ().end_mark).to_equal {line = 3, column = 16, index = 39} 151 152 - context with quoting style: 153 - context plain style: 154 - before: 155 e = consume (2, "---\n" .. 156 " Mark McGwire's\n" .. 157 " year was crippled\n" .. 158 " by a knee injury.\n") 159 - it ignores line-breaks and indentation: 160 expect (e ().value). 161 to_be "Mark McGwire's year was crippled by a knee injury." 162 - it recognizes implicit plain style: 163 e = consume (2, "---\n" .. 164 " Mark McGwire's\n" .. 165 " year was crippled\n" .. 166 " by a knee injury.\n") 167 expect (e ().plain_implicit).to_be (true) 168 - it recognizes explicit plain style: 169 e = consume (2, "|\n" .. 170 " Mark McGwire's\n" .. 171 " year was crippled\n" .. 172 " by a knee injury.\n") 173 expect (e ().plain_implicit).to_be (false) 174 - it recognizes implicit quoted style: 175 e = consume (2, "|\n" .. 176 " Mark McGwire's\n" .. 177 " year was crippled\n" .. 178 " by a knee injury.\n") 179 expect (e ().quoted_implicit).to_be (true) 180 - it recognizes explicit quoted style: 181 e = consume (2, "'\n" .. 182 " Mark McGwire's\n" .. 183 " year was crippled\n" .. 184 " by a knee injury.'\n") 185 expect (e ().plain_implicit).to_be (false) 186 - context folded style: 187 - it preserves blank lines and deeper indentation: 188 e = consume (2, ">\n" .. 189 " Sammy Sosa completed another\n" .. 190 " fine season with great stats.\n" .. 191 "\n" .. 192 " 63 Home Runs\n" .. 193 " 0.288 Batting Average\n" .. 194 "\n" .. 195 " What a year!\n") 196 expect (e ().value). 197 to_be ("Sammy Sosa completed another fine season with great stats.\n" .. 198 "\n" .. 199 " 63 Home Runs\n" .. 200 " 0.288 Batting Average\n" .. 201 "\n" .. 202 "What a year!\n") 203 - context literal style: 204 - it removes indentation but preserves all line-breaks: 205 e = consume (2, [[# ASCII Art]] .. "\n" .. 206 [[--- |]] .. "\n" .. 207 [[ \//||\/||]] .. "\n" .. 208 [[ // || ||__]] .. "\n") 209 expect (e ().value). 210 to_be ([[\//||\/||]] .. "\n" .. 211 [[// || ||__]] .. "\n") 212 213 - context single quoted style: 214 - it folds line breaks: 215 e = consume (2, [['This quoted scalar]] .. "\n" .. 216 [[ spans two lines.']]) 217 expect (e ().value). 218 to_be "This quoted scalar spans two lines." 219 - it does not process escape sequences: 220 # Lua [[ quoting makes sure libyaml sees all the quotes. 221 e = consume (2, [['"Howdy!"\t\u263A']]) 222 expect (e ().value).to_be [["Howdy!"\t\u263A]] 223 224 # Note that we have to single quote the Lua snippets to prevent 225 # libyaml from interpreting the bytes as the spec file is read, so 226 # that the raw strings get correctly passed to the Lua compiler. 227 - context double quoted style: 228 - it folds line breaks: ' 229 e = consume (4, [[quoted: "This quoted scalar]] .. "\n" .. 230 [[ spans two lines\n"]]) 231 expect (e ().value). 232 to_be "This quoted scalar spans two lines\n"' 233 - it recognizes unicode escape sequences: ' 234 e = consume (4, [[unicode: "Sosa did fine.\u263A"]]) 235 expect (e ().value).to_be "Sosa did fine.\226\152\186"' 236 - it recognizes control escape sequences: ' 237 e = consume (4, [[control: "\b1998\t1999\t2000\n"]]) 238 expect (e ().value).to_be "\b1998\t1999\t2000\n"' 239 - it recognizes hexadecimal escape sequences: ' 240 e = consume (4, [[hexesc: "\x41\x42\x43 is ABC"]]) 241 expect (e ().value).to_be "ABC is ABC"' 242 243 - context indentation determines scope: ' 244 e = consume (4, "name: Mark McGwire\n" .. 245 "accomplishment: >\n" .. 246 " Mark set a major league\n" .. 247 " home run record in 1998.\n" .. 248 "stats: |\n" .. 249 " 65 Home Runs\n" .. 250 " 0.278 Batting Average\n") 251 expect (e ().value).to_be "Mark McGwire" 252 expect (e ().value).to_be "accomplishment" 253 expect (e ().value). 254 to_be "Mark set a major league home run record in 1998.\n" 255 expect (e ().value).to_be "stats" 256 expect (e ().value).to_be "65 Home Runs\n0.278 Batting Average\n"' 257 258 - context with tag: 259 - it recognizes local tags: ' 260 e = consume (4, "application specific tag: !something |\n" .. 261 " The semantics of the tag\n" .. 262 " above may be different for\n" .. 263 " different documents.") 264 expect (e ().tag).to_be "!something"' 265 - it recognizes global tags: ' 266 e = consume (4, "picture: !!binary |\n" .. 267 " R0lGODlhDAAMAIQAAP//9/X\n" .. 268 " 17unp5WZmZgAAAOfn515eXv\n" .. 269 " Pz7Y6OjuDg4J+fn5OTk6enp\n" .. 270 " 56enmleECcgggoBADs=") 271 expect (e ().tag).to_be "tag:yaml.org,2002:binary"' 272 - it resolves %TAG declarations: ' 273 e = consume (5, "%TAG ! tag:clarkevans.com,2002:\n" .. 274 "---\n" .. 275 "shape:\n" .. 276 "- !circle\n" .. 277 " center: &ORIGIN {x: 73, y: 129}\n" .. 278 " radius: 7") 279 expect (e ().tag).to_be "tag:clarkevans.com,2002:circle"' 280 281- describe SEQUENCE_START: 282 - before: ' 283 e = consume (4, "fubar: &FOO\n" .. 284 " - foo\n" .. 285 " - bar\n")' 286 - it recognizes a sequence start event: 287 expect (e ().type).to_be "SEQUENCE_START" 288 - it records anchors: 289 expect (e ().anchor).to_be "FOO" 290 - it reports event start marker: 291 expect (e ().start_mark).to_equal {line = 0, column = 7, index = 7} 292 - it reports event end marker: 293 expect (e ().end_mark).to_equal {line = 1, column = 2, index = 14} 294 295 - context with tag: 296 - it recognizes local tags: ' 297 e = consume (2, "--- !something\n" .. 298 "- foo\n") 299 expect (filter (e (), "type", "tag")). 300 to_equal {type = "SEQUENCE_START", tag = "!something"}' 301 - it recognizes global tags: ' 302 e = consume (2, "--- !!omap\n" .. 303 "- Mark McGwire: 65\n" .. 304 "- Sammy Sosa: 63\n" .. 305 "- Ken Griffy: 58\n") 306 expect (filter (e (), "type", "tag")). 307 to_equal {type = "SEQUENCE_START", 308 tag = "tag:yaml.org,2002:omap"}' 309 - it resolves %TAG declarations: ' 310 e = consume (2, "%TAG ! tag:clarkevans.com,2002:\n" .. 311 "--- !shape\n" .. 312 "- !circle\n" .. 313 " center: &ORIGIN {x: 73, y: 129}\n" .. 314 " radius: 7\n") 315 expect (filter (e (), "type", "tag")). 316 to_equal {type = "SEQUENCE_START", 317 tag = "tag:clarkevans.com,2002:shape"}' 318 319 - context with style: 320 - it recognizes block style: 321 e = consume (2, "- first\n- second") 322 expect (filter (e (), "type", "style")). 323 to_equal {type = "SEQUENCE_START", style = "BLOCK"} 324 - it recognizes flow style: 325 e = consume (2, "[first, second]") 326 expect (filter (e (), "type", "style")). 327 to_equal {type = "SEQUENCE_START", style = "FLOW"} 328 329- describe SEQUENCE_END: 330 - before: 331 e = consume (5, "- foo\n- bar\n") 332 - it recognizes a sequence end event: 333 expect (e ().type).to_equal "SEQUENCE_END" 334 - it reports event start marker: 335 expect (e ().start_mark).to_equal {line = 2, column = 0, index = 12} 336 - it reports event end marker: 337 expect (e ().end_mark).to_equal {line = 2, column = 0, index = 12} 338 339- describe MAPPING_START: 340 - before: 'e = consume (3, "- &FUBAR\n foo: bar\n")' 341 - it recognizes a mapping start event: 342 expect (e ().type).to_be "MAPPING_START" 343 - it records anchors: 344 expect (e ().anchor).to_be "FUBAR" 345 - it reports event start marker: 346 expect (e ().start_mark).to_equal {line = 0, column = 2, index = 2} 347 - it reports event end marker: 348 expect (e ().end_mark).to_equal {line = 1, column = 2, index = 11} 349 350 - context with tag: 351 - it recognizes local tags: ' 352 e = consume (2, "--- !something\nfoo: bar\n") 353 expect (filter (e (), "type", "tag")). 354 to_equal {type = "MAPPING_START", tag = "!something"}' 355 - it recognizes global tags: ' 356 e = consume (2, "--- !!set\n" .. 357 "? Mark McGwire\n" .. 358 "? Sammy Sosa\n" .. 359 "? Ken Griffy\n") 360 expect (filter (e (), "type", "tag")). 361 to_equal {type = "MAPPING_START", 362 tag = "tag:yaml.org,2002:set"}' 363 - it resolves %TAG declarations: ' 364 e = consume (3, "%TAG ! tag:clarkevans.com,2002:\n" .. 365 "--- !shape\n" .. 366 "- !circle\n" .. 367 " center: &ORIGIN {x: 73, y: 129}\n" .. 368 " radius: 7\n") 369 expect (filter (e (), "type", "tag")). 370 to_equal {type = "MAPPING_START", 371 tag = "tag:clarkevans.com,2002:circle"}' 372 373 - context with style: 374 - it recognizes block style: ' 375 e = consume (2, "foo: bar\nbaz:\n quux") 376 expect (filter (e (), "type", "style")). 377 to_equal {type = "MAPPING_START", style = "BLOCK"}' 378 - it recognizes flow style: ' 379 e = consume (2, "{foo: bar, baz: quux}") 380 expect (filter (e (), "type", "style")). 381 to_equal {type = "MAPPING_START", style = "FLOW"}' 382 383 384- describe MAPPING_END: 385 - before: 'e = consume (5, "foo: bar\n")' 386 - it recognizes the mapping end event: 387 expect (e ().type).to_equal "MAPPING_END" 388 - it reports event start marker: 389 expect (e ().start_mark).to_equal {line = 1, column = 0, index = 9} 390 - it reports event end marker: 391 expect (e ().end_mark).to_equal {line = 1, column = 0, index = 9} 392