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