diff options
| author | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:44:05 +0300 |
|---|---|---|
| committer | Mehmet Samet Duman <yongdohyun@projecttick.org> | 2026-04-02 18:44:05 +0300 |
| commit | 0b24459ac12b6cf9fd5a401d647796ca254a8fa8 (patch) | |
| tree | f2fd66e2476976a51e2a51330fd95dc6e87b24c1 /tomlplusplus/tests/conformance_burntsushi_valid.cpp | |
| parent | b85e90fc3480da0e6a48da73201a0b22488cc650 (diff) | |
| parent | 1c8b7466e4946fcc3bf20484c0e1d001202cca5a (diff) | |
| download | Project-Tick-0b24459ac12b6cf9fd5a401d647796ca254a8fa8.tar.gz Project-Tick-0b24459ac12b6cf9fd5a401d647796ca254a8fa8.zip | |
Add 'tomlplusplus/' from commit '1c8b7466e4946fcc3bf20484c0e1d001202cca5a'
git-subtree-dir: tomlplusplus
git-subtree-mainline: b85e90fc3480da0e6a48da73201a0b22488cc650
git-subtree-split: 1c8b7466e4946fcc3bf20484c0e1d001202cca5a
Diffstat (limited to 'tomlplusplus/tests/conformance_burntsushi_valid.cpp')
| -rw-r--r-- | tomlplusplus/tests/conformance_burntsushi_valid.cpp | 4734 |
1 files changed, 4734 insertions, 0 deletions
diff --git a/tomlplusplus/tests/conformance_burntsushi_valid.cpp b/tomlplusplus/tests/conformance_burntsushi_valid.cpp new file mode 100644 index 0000000000..14520d6177 --- /dev/null +++ b/tomlplusplus/tests/conformance_burntsushi_valid.cpp @@ -0,0 +1,4734 @@ +// This file is a part of toml++ and is subject to the the terms of the MIT license. +// Copyright (c) Mark Gillard <mark.gillard@outlook.com.au> +// See https://github.com/marzer/tomlplusplus/blob/master/LICENSE for the full license text. +// SPDX-License-Identifier: MIT +//----- +// this file was generated by generate_conformance_tests.py - do not modify it directly + +#include "tests.hpp" + +namespace +{ + static constexpr auto array_array = R"(ints = [1, 2, 3, ] +floats = [1.1, 2.1, 3.1] +strings = ["a", "b", "c"] +dates = [ + 1987-07-05T17:45:00Z, + 1979-05-27T07:32:00Z, + 2006-06-01T11:00:00Z, +] +comments = [ + 1, + 2, #this is ok +])"sv; + static constexpr auto array_bool = R"(a = [true, false])"sv; + static constexpr auto array_empty = R"(thevoid = [[[[[]]]]])"sv; + static constexpr auto array_hetergeneous = R"(mixed = [[1, 2], ["a", "b"], [1.1, 2.1]])"sv; + static constexpr auto array_mixed_int_array = R"(arrays-and-ints = [1, ["Arrays are not integers."]])"sv; + static constexpr auto array_mixed_int_float = R"(ints-and-floats = [1, 1.1])"sv; + static constexpr auto array_mixed_int_string = R"(strings-and-ints = ["hi", 42])"sv; + static constexpr auto array_mixed_string_table = R"(contributors = [ + "Foo Bar <foo@example.com>", + { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" } +] + +# Start with a table as the first element. This tests a case that some libraries +# might have where they will check if the first entry is a table/map/hash/assoc +# array and then encode it as a table array. This was a reasonable thing to do +# before TOML 1.0 since arrays could only contain one type, but now it's no +# longer. +mixed = [{k="a"}, "b", 1])"sv; + static constexpr auto array_nested_double = R"(nest = [ + [ + ["a"], + [1, 2, [3]] + ] +])"sv; + static constexpr auto array_nested_inline_table = R"(a = [ { b = {} } ])"sv; + static constexpr auto array_nested = R"(nest = [["a"], ["b"]])"sv; + static constexpr auto array_nospaces = R"(ints = [1,2,3])"sv; + static constexpr auto array_string_quote_comma_2 = R"(title = [ " \", ",])"sv; + static constexpr auto array_string_quote_comma = R"(title = [ +"Client: \"XXXX\", Job: XXXX", +"Code: XXXX" +])"sv; + static constexpr auto array_string_with_comma_2 = R"(title = [ +"""Client: XXXX, +Job: XXXX""", +"Code: XXXX" +])"sv; + static constexpr auto array_string_with_comma = R"(title = [ +"Client: XXXX, Job: XXXX", +"Code: XXXX" +])"sv; + static constexpr auto array_strings = R"(string_array = [ "all", 'strings', """are the same""", '''type'''])"sv; + static constexpr auto array_table_array_string_backslash = R"(foo = [ { bar="\"{{baz}}\""} ])"sv; + + static constexpr auto bool_bool = R"(t = true +f = false)"sv; + + static constexpr auto comment_after_literal_no_ws = R"(inf=inf#infinity +nan=nan#not a number +true=true#true +false=false#false)"sv; + static constexpr auto comment_at_eof = R"(# This is a full-line comment +key = "value" # This is a comment at the end of a line)"sv; + static constexpr auto comment_at_eof2 = R"(# This is a full-line comment +key = "value" # This is a comment at the end of a line)"sv; + static constexpr auto comment_everywhere = R"(# Top comment. + # Top comment. +# Top comment. + +# [no-extraneous-groups-please] + +[group] # Comment +answer = 42 # Comment +# no-extraneous-keys-please = 999 +# Inbetween comment. +more = [ # Comment + # What about multiple # comments? + # Can you handle it? + # + # Evil. +# Evil. + 42, 42, # Comments within arrays are fun. + # What about multiple # comments? + # Can you handle it? + # + # Evil. +# Evil. +# ] Did I fool you? +] # Hopefully not. + +# Make sure the space between the datetime and "#" isn't lexed. +dt = 1979-05-27T07:32:12-07:00 # c +d = 1979-05-27 # Comment)"sv; + static constexpr auto comment_noeol = R"(# single comment without any eol characters)"sv; + static constexpr auto comment_tricky = R"([section]#attached comment +#[notsection] +one = "11"#cmt +two = "22#" +three = '#' + +four = """# no comment +# nor this +#also not comment"""#is_comment + +five = 5.5#66 +six = 6#7 +8 = "eight" +#nine = 99 +ten = 10e2#1 +eleven = 1.11e1#23 + +["hash#tag"] +"#!" = "hash bang" +arr3 = [ "#", '#', """###""" ] +arr4 = [ 1,# 9, 9, +2#,9 +,#9 +3#] +,4] +arr5 = [[[[#["#"], +["#"]]]]#] +] +tbl1 = { "#" = '}#'}#}})"sv; + +#if UNICODE_LITERALS_OK + + static constexpr auto comment_nonascii = R"(# ~ ÿ 𐀀 )"sv; + +#endif // UNICODE_LITERALS_OK + + static constexpr auto datetime_datetime = R"(space = 1987-07-05 17:45:00Z +lower = 1987-07-05t17:45:00z)"sv; + static constexpr auto datetime_local_date = R"(bestdayever = 1987-07-05)"sv; + static constexpr auto datetime_local_time = R"(besttimeever = 17:45:00 +milliseconds = 10:32:00.555)"sv; + static constexpr auto datetime_local = R"(local = 1987-07-05T17:45:00 +milli = 1977-12-21T10:32:00.555 +space = 1987-07-05 17:45:00)"sv; + static constexpr auto datetime_milliseconds = R"(utc1 = 1987-07-05T17:45:56.123Z +utc2 = 1987-07-05T17:45:56.6Z +wita1 = 1987-07-05T17:45:56.123+08:00 +wita2 = 1987-07-05T17:45:56.6+08:00)"sv; + static constexpr auto datetime_timezone = R"(utc = 1987-07-05T17:45:56Z +pdt = 1987-07-05T17:45:56-05:00 +nzst = 1987-07-05T17:45:56+12:00 +nzdt = 1987-07-05T17:45:56+13:00 # DST)"sv; + +#if TOML_LANG_UNRELEASED + + static constexpr auto datetime_no_seconds = R"(# Seconds are optional in date-time and time. +without-seconds-1 = 13:37 +without-seconds-2 = 1979-05-27 07:32Z +without-seconds-3 = 1979-05-27 07:32-07:00 +without-seconds-4 = 1979-05-27T07:32)"sv; + +#endif // TOML_LANG_UNRELEASED + + static constexpr auto empty_file = R"()"sv; + + static constexpr auto example = R"(best-day-ever = 1987-07-05T17:45:00Z + +[numtheory] +boring = false +perfection = [6, 28, 496])"sv; + + static constexpr auto float_exponent = R"(lower = 3e2 +upper = 3E2 +neg = 3e-2 +pos = 3E+2 +zero = 3e0 +pointlower = 3.1e2 +pointupper = 3.1E2 +minustenth = -1E-1)"sv; + static constexpr auto float_float = R"(pi = 3.14 +pospi = +3.14 +negpi = -3.14 +zero-intpart = 0.123)"sv; + static constexpr auto float_inf_and_nan = + R"(# We don't encode +nan and -nan back with the signs; many languages don't +# support a sign on NaN (it doesn't really make much sense). +nan = nan +nan_neg = -nan +nan_plus = +nan +infinity = inf +infinity_neg = -inf +infinity_plus = +inf)"sv; + static constexpr auto float_long = R"(longpi = 3.141592653589793 +neglongpi = -3.141592653589793)"sv; + static constexpr auto float_underscore = R"(before = 3_141.5927 +after = 3141.592_7 +exponent = 3e1_4)"sv; + static constexpr auto float_zero = R"(zero = 0.0 +signed-pos = +0.0 +signed-neg = -0.0 +exponent = 0e0 +exponent-two-0 = 0e00 +exponent-signed-pos = +0e0 +exponent-signed-neg = -0e0)"sv; + + static constexpr auto implicit_and_explicit_after = R"([a.b.c] +answer = 42 + +[a] +better = 43)"sv; + static constexpr auto implicit_and_explicit_before = R"([a] +better = 43 + +[a.b.c] +answer = 42)"sv; + static constexpr auto implicit_groups = R"([a.b.c] +answer = 42)"sv; + + static constexpr auto inline_table_array = R"(people = [{first_name = "Bruce", last_name = "Springsteen"}, + {first_name = "Eric", last_name = "Clapton"}, + {first_name = "Bob", last_name = "Seger"}])"sv; + static constexpr auto inline_table_bool = R"(a = {a = true, b = false})"sv; + static constexpr auto inline_table_empty = R"(empty1 = {} +empty2 = { } +empty_in_array = [ { not_empty = 1 }, {} ] +empty_in_array2 = [{},{not_empty=1}] +many_empty = [{},{},{}] +nested_empty = {"empty"={}})"sv; + static constexpr auto inline_table_end_in_bool = + R"(black = { python=">3.6", version=">=18.9b0", allow_prereleases=true })"sv; + static constexpr auto inline_table_inline_table = R"(name = { first = "Tom", last = "Preston-Werner" } +point = { x = 1, y = 2 } +simple = { a = 1 } +str-key = { "a" = 1 } +table-array = [{ "a" = 1 }, { "b" = 2 }])"sv; + static constexpr auto inline_table_multiline = R"(tbl_multiline = { a = 1, b = """ +multiline +""", c = """and yet +another line""", d = 4 })"sv; + static constexpr auto inline_table_nest = R"(tbl_tbl_empty = { tbl_0 = {} } +tbl_tbl_val = { tbl_1 = { one = 1 } } +tbl_arr_tbl = { arr_tbl = [ { one = 1 } ] } +arr_tbl_tbl = [ { tbl = { one = 1 } } ] + +# Array-of-array-of-table is interesting because it can only +# be represented in inline form. +arr_arr_tbl_empty = [ [ {} ] ] +arr_arr_tbl_val = [ [ { one = 1 } ] ] +arr_arr_tbls = [ [ { one = 1 }, { two = 2 } ] ])"sv; + +#if !TOML_MSVC + + static constexpr auto inline_table_key_dotted = R"(inline = {a.b = 42} + +many.dots.here.dot.dot.dot = {a.b.c = 1, a.b.d = 2} + +a = { a.b = 1 } +b = { "a"."b" = 1 } +c = { a . b = 1 } +d = { 'a' . "b" = 1 } +e = {a.b=1} + +[tbl] +a.b.c = {d.e=1} + +[tbl.x] +a.b.c = {d.e=1} + +[[arr]] +t = {a.b=1} +T = {a.b=1} + +[[arr]] +t = {a.b=2} +T = {a.b=2})"sv; + +#endif // !TOML_MSVC + +#if TOML_LANG_UNRELEASED + + static constexpr auto inline_table_newline = R"(# TOML 1.1 supports newlines in inline tables and trailing commas. + +trailing-comma-1 = { + c = 1, +} +trailing-comma-2 = { c = 1, } + +tbl-1 = { + hello = "world", + 1 = 2, + arr = [1, + 2, + 3, + ], + tbl = { + k = 1, + } +} + +tbl-2 = { + k = """ + Hello + """ +})"sv; + +#endif // TOML_LANG_UNRELEASED + + static constexpr auto integer_integer = R"(answer = 42 +posanswer = +42 +neganswer = -42 +zero = 0)"sv; + static constexpr auto integer_literals = R"(bin1 = 0b11010110 +bin2 = 0b1_0_1 + +oct1 = 0o01234567 +oct2 = 0o755 +oct3 = 0o7_6_5 + +hex1 = 0xDEADBEEF +hex2 = 0xdeadbeef +hex3 = 0xdead_beef +hex4 = 0x00987)"sv; + static constexpr auto integer_long = R"(int64-max = 9223372036854775807 +int64-max-neg = -9223372036854775808)"sv; + static constexpr auto integer_underscore = R"(kilo = 1_000 +x = 1_1_1_1)"sv; + static constexpr auto integer_zero = R"(d1 = 0 +d2 = +0 +d3 = -0 + +h1 = 0x0 +h2 = 0x00 +h3 = 0x00000 + +o1 = 0o0 +a2 = 0o00 +a3 = 0o00000 + +b1 = 0b0 +b2 = 0b00 +b3 = 0b00000)"sv; + +#if UNICODE_LITERALS_OK + + static constexpr auto key_case_sensitive = R"(sectioN = "NN" + +[section] +name = "lower" +NAME = "upper" +Name = "capitalized" + +[Section] +name = "different section!!" +"μ" = "greek small letter mu" +"Μ" = "greek capital letter MU" +M = "latin letter M")"sv; + static constexpr auto key_escapes = R"("\n" = "newline" +"\u00c0" = "latin capital letter A with grave" +"\"" = "just a quote" + +["backsp\b\b"] + +["\"quoted\""] +quote = true + +["a.b"."\u00c0"])"sv; + static constexpr auto key_quoted_unicode = R"( +"\u0000" = "null" +'\u0000' = "different key" +"\u0008 \u000c \U00000041 \u007f \u0080 \u00ff \ud7ff \ue000 \uffff \U00010000 \U0010ffff" = "escaped key" + +"~ ÿ 𐀀 " = "basic key" +'l ~ ÿ 𐀀 ' = "literal key")"sv; + +#endif // UNICODE_LITERALS_OK + + static constexpr auto key_dotted_empty = R"(''.x = "empty.x" +x."" = "x.empty" +[a] +"".'' = "empty.empty")"sv; + static constexpr auto key_dotted = R"(# Note: this file contains literal tab characters. + +name.first = "Arthur" +"name".'last' = "Dent" + +many.dots.here.dot.dot.dot = 42 + +# Space are ignored, and key parts can be quoted. +count.a = 1 +count . b = 2 +"count"."c" = 3 +"count" . "d" = 4 +'count'.'e' = 5 +'count' . 'f' = 6 +"count".'g' = 7 +"count" . 'h' = 8 +count.'i' = 9 +count . 'j' = 10 +"count".k = 11 +"count" . l = 12 + +[tbl] +a.b.c = 42.666 + +[a.few.dots] +polka.dot = "again?" +polka.dance-with = "Dot" + +[[arr]] +a.b.c=1 +a.b.d=2 + +[[arr]] +a.b.c=3 +a.b.d=4)"sv; + static constexpr auto key_empty = R"("" = "blank")"sv; + static constexpr auto key_equals_nospace = R"(answer=42)"sv; + static constexpr auto key_numeric_dotted = R"(1.2 = 3)"sv; + static constexpr auto key_numeric = R"(1 = 1)"sv; + static constexpr auto key_quoted_dots = R"(plain = 1 +"with.dot" = 2 + +[plain_table] +plain = 3 +"with.dot" = 4 + +[table.withdot] +plain = 5 +"key.with.dots" = 6)"sv; + static constexpr auto key_space = R"(# Keep whitespace inside quotes keys at all positions. +"a b" = 1 +" c d " = 2 + +[ " tbl " ] +"\ttab\ttab\t" = "tab")"sv; + static constexpr auto key_special_chars = R"("=~!@$^&*()_+-`1234567890[]|/?><.,;:'=" = 1)"sv; + static constexpr auto key_special_word = R"(false = false +true = 1 +inf = 100000000 +nan = "ceci n'est pas un nombre")"sv; + +#if TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK + + static constexpr auto key_unicode = R"(# TOML 1.1 supports Unicode for bare keys. + +€ = 'Euro' +😂 = "rofl" +ab = "zwj" +ÅÅ = "U+00C5 U+0041 U+030A" + +[中文] +中文 = {中文 = "Chinese language"} + +[[tiếng-Việt]] +tiəŋ˧˦.viət̚˧˨ʔ = "north" + +[[tiếng-Việt]] +tiəŋ˦˧˥.viək̚˨˩ʔ = "central")"sv; + +#endif // TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK + + static constexpr auto newline_crlf = "os = \"DOS\"\r\n" + "newline = \"crlf\""sv; + static constexpr auto newline_lf = R"(os = "unix" +newline = "lf")"sv; + + static constexpr auto spec_array_0 = R"(integers = [ 1, 2, 3 ] +colors = [ "red", "yellow", "green" ] +nested_arrays_of_ints = [ [ 1, 2 ], [3, 4, 5] ] +nested_mixed_array = [ [ 1, 2 ], ["a", "b", "c"] ] +string_array = [ "all", 'strings', """are the same""", '''type''' ] + +# Mixed-type arrays are allowed +numbers = [ 0.1, 0.2, 0.5, 1, 2, 5 ] +contributors = [ + "Foo Bar <foo@example.com>", + { name = "Baz Qux", email = "bazqux@example.com", url = "https://example.com/bazqux" } +])"sv; + static constexpr auto spec_array_1 = R"(integers2 = [ + 1, 2, 3 +] + +integers3 = [ + 1, + 2, # this is ok +])"sv; + static constexpr auto spec_array_of_tables_0 = R"([[products]] +name = "Hammer" +sku = 738594937 + +[[products]] # empty table within the array + +[[products]] +name = "Nail" +sku = 284758393 + +color = "gray")"sv; + static constexpr auto spec_array_of_tables_1 = R"([[fruits]] +name = "apple" + +[fruits.physical] # subtable +color = "red" +shape = "round" + +[[fruits.varieties]] # nested array of tables +name = "red delicious" + +[[fruits.varieties]] +name = "granny smith" + + +[[fruits]] +name = "banana" + +[[fruits.varieties]] +name = "plantain")"sv; + static constexpr auto spec_array_of_tables_2 = R"(points = [ { x = 1, y = 2, z = 3 }, + { x = 7, y = 8, z = 9 }, + { x = 2, y = 4, z = 8 } ])"sv; + static constexpr auto spec_boolean_0 = R"(bool1 = true +bool2 = false)"sv; + static constexpr auto spec_comment_0 = R"(# This is a full-line comment +key = "value" # This is a comment at the end of a line +another = "# This is not a comment")"sv; + static constexpr auto spec_float_0 = R"(# fractional +flt1 = +1.0 +flt2 = 3.1415 +flt3 = -0.01 + +# exponent +flt4 = 5e+22 +flt5 = 1e06 +flt6 = -2E-2 + +# both +flt7 = 6.626e-34)"sv; + static constexpr auto spec_float_1 = R"(flt8 = 224_617.445_991_228)"sv; + static constexpr auto spec_float_2 = R"(# infinity +sf1 = inf # positive infinity +sf2 = +inf # positive infinity +sf3 = -inf # negative infinity + +# not a number +sf4 = nan # actual sNaN/qNaN encoding is implementation-specific +sf5 = +nan # same as `nan` +sf6 = -nan # valid, actual encoding is implementation-specific)"sv; + static constexpr auto spec_inline_table_0 = R"(name = { first = "Tom", last = "Preston-Werner" } +point = { x = 1, y = 2 } +animal = { type.name = "pug" })"sv; + static constexpr auto spec_inline_table_1 = R"([name] +first = "Tom" +last = "Preston-Werner" + +[point] +x = 1 +y = 2 + +[animal] +type.name = "pug")"sv; + static constexpr auto spec_inline_table_2 = R"([product] +type = { name = "Nail" } +# type.edible = false # INVALID)"sv; + static constexpr auto spec_inline_table_3 = R"([product] +type.name = "Nail" +# type = { edible = false } # INVALID)"sv; + static constexpr auto spec_integer_0 = R"(int1 = +99 +int2 = 42 +int3 = 0 +int4 = -17)"sv; + static constexpr auto spec_integer_1 = R"(int5 = 1_000 +int6 = 5_349_221 +int7 = 53_49_221 # Indian number system grouping +int8 = 1_2_3_4_5 # VALID but discouraged)"sv; + static constexpr auto spec_integer_2 = R"(# hexadecimal with prefix `0x` +hex1 = 0xDEADBEEF +hex2 = 0xdeadbeef +hex3 = 0xdead_beef + +# octal with prefix `0o` +oct1 = 0o01234567 +oct2 = 0o755 # useful for Unix file permissions + +# binary with prefix `0b` +bin1 = 0b11010110)"sv; + static constexpr auto spec_key_value_pair_0 = R"(key = "value")"sv; + static constexpr auto spec_keys_0 = R"(key = "value" +bare_key = "value" +bare-key = "value" +1234 = "value")"sv; + static constexpr auto spec_keys_3 = R"(name = "Orange" +physical.color = "orange" +physical.shape = "round" +site."google.com" = true)"sv; + static constexpr auto spec_keys_4 = R"(fruit.name = "banana" # this is best practice +fruit. color = "yellow" # same as fruit.color +fruit . flavor = "banana" # same as fruit.flavor)"sv; + static constexpr auto spec_keys_5 = R"(# VALID BUT DISCOURAGED + +apple.type = "fruit" +orange.type = "fruit" + +apple.skin = "thin" +orange.skin = "thick" + +apple.color = "red" +orange.color = "orange")"sv; + static constexpr auto spec_keys_6 = R"(# RECOMMENDED + +apple.type = "fruit" +apple.skin = "thin" +apple.color = "red" + +orange.type = "fruit" +orange.skin = "thick" +orange.color = "orange")"sv; + static constexpr auto spec_keys_7 = R"(3.14159 = "pi")"sv; + static constexpr auto spec_local_date_0 = R"(ld1 = 1979-05-27)"sv; + static constexpr auto spec_local_date_time_0 = R"(ldt1 = 1979-05-27T07:32:00 +ldt2 = 1979-05-27T00:32:00.999999)"sv; + static constexpr auto spec_local_time_0 = R"(lt1 = 07:32:00 +lt2 = 00:32:00.999999)"sv; + static constexpr auto spec_offset_date_time_0 = R"(odt1 = 1979-05-27T07:32:00Z +odt2 = 1979-05-27T00:32:00-07:00 +odt3 = 1979-05-27T00:32:00.999999-07:00)"sv; + static constexpr auto spec_offset_date_time_1 = R"(odt4 = 1979-05-27 07:32:00Z)"sv; + static constexpr auto spec_string_1 = R"(str1 = """ +Roses are red +Violets are blue""")"sv; + static constexpr auto spec_string_2 = + R"(# On a Unix system, the above multi-line string will most likely be the same as: +str2 = "Roses are red\nViolets are blue" + +# On a Windows system, it will most likely be equivalent to: +str3 = "Roses are red\r\nViolets are blue")"sv; + static constexpr auto spec_string_3 = R"(# The following strings are byte-for-byte equivalent: +str1 = "The quick brown fox jumps over the lazy dog." + +str2 = """ +The quick brown \ + + + fox jumps over \ + the lazy dog.""" + +str3 = """\ + The quick brown \ + fox jumps over \ + the lazy dog.\ + """)"sv; + static constexpr auto spec_string_4 = R"(str4 = """Here are two quotation marks: "". Simple enough.""" +# str5 = """Here are three quotation marks: """.""" # INVALID +str5 = """Here are three quotation marks: ""\".""" +str6 = """Here are fifteen quotation marks: ""\"""\"""\"""\"""\".""" + +# "This," she said, "is just a pointless statement." +str7 = """"This," she said, "is just a pointless statement."""")"sv; + static constexpr auto spec_string_5 = R"(# What you see is what you get. +winpath = 'C:\Users\nodejs\templates' +winpath2 = '\\ServerX\admin$\system32\' +quoted = 'Tom "Dubs" Preston-Werner' +regex = '<\i\c*\s*>')"sv; + static constexpr auto spec_string_6 = R"(regex2 = '''I [dw]on't need \d{2} apples''' +lines = ''' +The first newline is +trimmed in raw strings. + All other whitespace + is preserved. +''')"sv; + static constexpr auto spec_string_7 = R"(quot15 = '''Here are fifteen quotation marks: """""""""""""""''' + +# apos15 = '''Here are fifteen apostrophes: '''''''''''''''''' # INVALID +apos15 = "Here are fifteen apostrophes: '''''''''''''''" + +# 'That,' she said, 'is still pointless.' +str = ''''That,' she said, 'is still pointless.'''')"sv; + static constexpr auto spec_table_0 = R"([table])"sv; + static constexpr auto spec_table_1 = R"([table-1] +key1 = "some string" +key2 = 123 + +[table-2] +key1 = "another string" +key2 = 456)"sv; + static constexpr auto spec_table_2 = R"([dog."tater.man"] +type.name = "pug")"sv; + static constexpr auto spec_table_4 = R"(# [x] you +# [x.y] don't +# [x.y.z] need these +[x.y.z.w] # for this to work + +[x] # defining a super-table afterward is ok)"sv; + static constexpr auto spec_table_5 = R"(# VALID BUT DISCOURAGED +[fruit.apple] +[animal] +[fruit.orange])"sv; + static constexpr auto spec_table_6 = R"(# RECOMMENDED +[fruit.apple] +[fruit.orange] +[animal])"sv; + static constexpr auto spec_table_7 = R"(# Top-level table begins. +name = "Fido" +breed = "pug" + +# Top-level table ends. +[owner] +name = "Regina Dogman" +member_since = 1999-08-04)"sv; + static constexpr auto spec_table_8 = R"(fruit.apple.color = "red" +# Defines a table named fruit +# Defines a table named fruit.apple + +fruit.apple.taste.sweet = true +# Defines a table named fruit.apple.taste +# fruit and fruit.apple were already created)"sv; + static constexpr auto spec_table_9 = R"([fruit] +apple.color = "red" +apple.taste.sweet = true + +# [fruit.apple] # INVALID +# [fruit.apple.taste] # INVALID + +[fruit.apple.texture] # you can add sub-tables +smooth = true)"sv; + static constexpr auto spec_example_1_compact = R"(#Useless spaces eliminated. +title="TOML Example" +[owner] +name="Lance Uppercut" +dob=1979-05-27T07:32:00-08:00#First class dates +[database] +server="192.168.1.1" +ports=[8001,8001,8002] +connection_max=5000 +enabled=true +[servers] +[servers.alpha] +ip="10.0.0.1" +dc="eqdc10" +[servers.beta] +ip="10.0.0.2" +dc="eqdc10" +[clients] +data=[["gamma","delta"],[1,2]] +hosts=[ +"alpha", +"omega" +])"sv; + static constexpr auto spec_example_1 = R"(# This is a TOML document. Boom. + +title = "TOML Example" + +[owner] +name = "Lance Uppercut" +dob = 1979-05-27T07:32:00-08:00 # First class dates? Why not? + +[database] +server = "192.168.1.1" +ports = [ 8001, 8001, 8002 ] +connection_max = 5000 +enabled = true + +[servers] + + # You can indent as you please. Tabs or spaces. TOML don't care. + [servers.alpha] + ip = "10.0.0.1" + dc = "eqdc10" + + [servers.beta] + ip = "10.0.0.2" + dc = "eqdc10" + +[clients] +data = [ ["gamma", "delta"], [1, 2] ] + +# Line breaks are OK when inside arrays +hosts = [ + "alpha", + "omega" +])"sv; + +#if UNICODE_LITERALS_OK + + static constexpr auto spec_keys_1 = R"("127.0.0.1" = "value" +"character encoding" = "value" +"ʎǝʞ" = "value" +'key2' = "value" +'quoted "value"' = "value")"sv; + static constexpr auto spec_string_0 = + R"(str = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF.")"sv; + static constexpr auto spec_table_3 = R"([a.b.c] # this is best practice +[ d.e.f ] # same as [d.e.f] +[ g . h . i ] # same as [g.h.i] +[ j . "ʞ" . 'l' ] # same as [j."ʞ".'l'])"sv; + +#endif // UNICODE_LITERALS_OK + + static constexpr auto string_double_quote_escape = R"(test = "\"one\"")"sv; + static constexpr auto string_empty = R"(answer = "")"sv; + static constexpr auto string_escaped_escape = R"(answer = "\\x64")"sv; + static constexpr auto string_escapes = R"(backspace = "This string has a \b backspace character." +tab = "This string has a \t tab character." +newline = "This string has a \n new line character." +formfeed = "This string has a \f form feed character." +carriage = "This string has a \r carriage return character." +quote = "This string has a \" quote character." +backslash = "This string has a \\ backslash character." +notunicode1 = "This string does not have a unicode \\u escape." +notunicode2 = "This string does not have a unicode \u005Cu escape." +notunicode3 = "This string does not have a unicode \\u0075 escape." +notunicode4 = "This string does not have a unicode \\\u0075 escape." +delete = "This string has a \u007F delete control code." +unitseparator = "This string has a \u001F unit separator control code.")"sv; + static constexpr auto string_multiline_escaped_crlf = + "# The following line should be an unescaped backslash followed by a Windows\r\n" + "# newline sequence (\"\\r\\n\")\r\n" + "0=\"\"\"\\\r\n" + "\"\"\""sv; + static constexpr auto string_multiline_quotes = + R"(# Make sure that quotes inside multiline strings are allowed, including right +# after the opening '''/""" and before the closing '''/""" + +lit_one = ''''one quote'''' +lit_two = '''''two quotes''''' +lit_one_space = ''' 'one quote' ''' +lit_two_space = ''' ''two quotes'' ''' + +one = """"one quote"""" +two = """""two quotes""""" +one_space = """ "one quote" """ +two_space = """ ""two quotes"" """ + +mismatch1 = """aaa'''bbb""" +mismatch2 = '''aaa"""bbb''' + +# Three opening """, then one escaped ", then two "" (allowed), and then three +# closing """ +escaped = """lol\"""""")"sv; + static constexpr auto string_multiline = + "# NOTE: this file includes some literal tab characters.\n" + "\n" + "multiline_empty_one = \"\"\"\"\"\"\n" + "\n" + "# A newline immediately following the opening delimiter will be trimmed.\n" + "multiline_empty_two = \"\"\"\n" + "\"\"\"\n" + "\n" + "# \\ at the end of line trims newlines as well; note that last \\ is followed by\n" + "# two spaces, which are ignored.\n" + "multiline_empty_three = \"\"\"\\\n" + " \"\"\"\n" + "multiline_empty_four = \"\"\"\\\n" + " \\\n" + " \\ \n" + " \"\"\"\n" + "\n" + "equivalent_one = \"The quick brown fox jumps over the lazy dog.\"\n" + "equivalent_two = \"\"\"\n" + "The quick brown \\\n" + "\n" + "\n" + " fox jumps over \\\n" + " the lazy dog.\"\"\"\n" + "\n" + "equivalent_three = \"\"\"\\\n" + " The quick brown \\\n" + " fox jumps over \\\n" + " the lazy dog.\\\n" + " \"\"\"\n" + "\n" + "whitespace-after-bs = \"\"\"\\\n" + " The quick brown \\\n" + " fox jumps over \\ \n" + " the lazy dog.\\ \n" + " \"\"\"\n" + "\n" + "no-space = \"\"\"a\\\n" + " b\"\"\"\n" + "\n" + "# Has tab character.\n" + "keep-ws-before = \"\"\"a \\\n" + " b\"\"\"\n" + "\n" + "escape-bs-1 = \"\"\"a \\\\\n" + "b\"\"\"\n" + "\n" + "escape-bs-2 = \"\"\"a \\\\\\\n" + "b\"\"\"\n" + "\n" + "escape-bs-3 = \"\"\"a \\\\\\\\\n" + " b\"\"\""sv; + static constexpr auto string_nl = R"(nl_mid = "val\nue" +nl_end = """value\n""" + +lit_nl_end = '''value\n''' +lit_nl_mid = 'val\nue' +lit_nl_uni = 'val\ue')"sv; + static constexpr auto string_raw_multiline = R"(# Single ' should be allowed. +oneline = '''This string has a ' quote character.''' + +# A newline immediately following the opening delimiter will be trimmed. +firstnl = ''' +This string has a ' quote character.''' + +# All other whitespace and newline characters remain intact. +multiline = ''' +This string +has ' a quote character +and more than +one newline +in it.''' + +# Tab character in literal string does not need to be escaped +multiline_with_tab = '''First line + Followed by a tab''')"sv; + static constexpr auto string_raw = R"(backspace = 'This string has a \b backspace character.' +tab = 'This string has a \t tab character.' +unescaped_tab = 'This string has an unescaped tab character.' +newline = 'This string has a \n new line character.' +formfeed = 'This string has a \f form feed character.' +carriage = 'This string has a \r carriage return character.' +slash = 'This string has a \/ slash character.' +backslash = 'This string has a \\ backslash character.')"sv; + static constexpr auto string_simple = R"(answer = "You are not drinking enough whisky.")"sv; + static constexpr auto string_with_pound = R"(pound = "We see no # comments here." +poundcomment = "But there are # some comments here." # Did I # mess you up?)"sv; + +#if TOML_LANG_UNRELEASED + + static constexpr auto string_escape_esc = R"(esc = "\e There is no escape! \e")"sv; + +#endif // TOML_LANG_UNRELEASED + +#if UNICODE_LITERALS_OK + + static constexpr auto string_escape_tricky = R"(end_esc = "String does not end here\" but ends here\\" +lit_end_esc = 'String ends here\' + +multiline_unicode = """ +\u00a0""" + +multiline_not_unicode = """ +\\u0041""" + +multiline_end_esc = """When will it end? \"""...""\" should be here\"""" + +lit_multiline_not_unicode = ''' +\u007f''' + +lit_multiline_end = '''There is no escape\''')"sv; + static constexpr auto string_quoted_unicode = R"( +escaped_string = "\u0000 \u0008 \u000c \U00000041 \u007f \u0080 \u00ff \ud7ff \ue000 \uffff \U00010000 \U0010ffff" +not_escaped_string = '\u0000 \u0008 \u000c \U00000041 \u007f \u0080 \u00ff \ud7ff \ue000 \uffff \U00010000 \U0010ffff' + +basic_string = "~ ÿ 𐀀 " +literal_string = '~ ÿ 𐀀 ')"sv; + static constexpr auto string_unicode_escape = R"(answer4 = "\u03B4" +answer8 = "\U000003B4")"sv; + static constexpr auto string_unicode_literal = R"(answer = "δ")"sv; + +#endif // UNICODE_LITERALS_OK + +#if TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK + + static constexpr auto string_hex_escape = R"(# \x for the first 255 codepoints + +whitespace = "\x20 \x09 \x1b \x0d\x0a" +bs = "\x7f" +nul = "\x00" +hello = "\x68\x65\x6c\x6c\x6f\x0a" +higher-than-127 = "S\xf8rmirb\xe6ren" + +multiline = """ +\x20 \x09 \x1b \x0d\x0a +\x7f +\x00 +\x68\x65\x6c\x6c\x6f\x0a +\x53\xF8\x72\x6D\x69\x72\x62\xE6\x72\x65\x6E +""" + +# Not inside literals. +literal = '\x20 \x09 \x0d\x0a' +multiline-literal = ''' +\x20 \x09 \x0d\x0a +''')"sv; + +#endif // TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK + + static constexpr auto table_array_implicit_and_explicit_after = R"([[a.b]] +x = 1 + +[a] +y = 2)"sv; + static constexpr auto table_array_implicit = R"([[albums.songs]] +name = "Glory Days")"sv; + static constexpr auto table_array_many = R"([[people]] +first_name = "Bruce" +last_name = "Springsteen" + +[[people]] +first_name = "Eric" +last_name = "Clapton" + +[[people]] +first_name = "Bob" +last_name = "Seger")"sv; + static constexpr auto table_array_nest = R"([[albums]] +name = "Born to Run" + + [[albums.songs]] + name = "Jungleland" + + [[albums.songs]] + name = "Meeting Across the River" + +[[albums]] +name = "Born in the USA" + + [[albums.songs]] + name = "Glory Days" + + [[albums.songs]] + name = "Dancing in the Dark")"sv; + static constexpr auto table_array_one = R"([[people]] +first_name = "Bruce" +last_name = "Springsteen")"sv; + static constexpr auto table_array_table_array = R"([[a]] + [[a.b]] + [a.b.c] + d = "val0" + [[a.b]] + [a.b.c] + d = "val1")"sv; + static constexpr auto table_array_within_dotted = R"([fruit] +apple.color = "red" + +[[fruit.apple.seeds]] +size = 2)"sv; + static constexpr auto table_empty_name = R"([''] +x = 1 + +["".a] +x = 2 + +[a.''] +x = 3)"sv; + static constexpr auto table_empty = R"([a])"sv; + static constexpr auto table_keyword = R"([true] + +[false] + +[inf] + +[nan])"sv; + static constexpr auto table_no_eol = R"([table])"sv; + static constexpr auto table_sub_empty = R"([a] +[a.b])"sv; + static constexpr auto table_sub = R"([a] +key = 1 + +# a.extend is a key inside the "a" table. +[a.extend] +key = 2 + +[a.extend.more] +key = 3)"sv; + static constexpr auto table_whitespace = R"(["valid key"])"sv; + static constexpr auto table_with_literal_string = R"(['a'] +[a.'"b"'] +[a.'"b"'.c] +answer = 42 )"sv; + static constexpr auto table_with_pound = R"(["key#group"] +answer = 42)"sv; + static constexpr auto table_with_single_quotes = R"(['a'] +[a.'b'] +[a.'b'.c] +answer = 42 )"sv; + static constexpr auto table_without_super = R"(# [x] you +# [x.y] don't +# [x.y.z] need these +[x.y.z.w] # for this to work +[x] # defining a super-table afterwards is ok)"sv; + +#if UNICODE_LITERALS_OK + + static constexpr auto table_names = R"([a.b.c] +[a."b.c"] +[a.'d.e'] +[a.' x '] +[ d.e.f ] +[ g . h . i ] +[ j . "ʞ" . 'l' ] + +[x.1.2])"sv; + +#endif // UNICODE_LITERALS_OK +} + +TEST_CASE("conformance - burntsushi/valid") +{ + SECTION("array-array") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_array, + [](toml::table&& tbl) // array-array + { + const auto expected = toml::table{ + { R"(comments)"sv, + toml::array{ + 1, + 2, + } }, + { R"(dates)"sv, + toml::array{ + toml::date_time{ { 1987, 7, 5 }, { 17, 45 }, { 0, 0 } }, + toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } }, + toml::date_time{ { 2006, 6, 1 }, { 11, 0 }, { 0, 0 } }, + } }, + { R"(floats)"sv, + toml::array{ + 1.1, + 2.1, + 3.1, + } }, + { R"(ints)"sv, + toml::array{ + 1, + 2, + 3, + } }, + { R"(strings)"sv, + toml::array{ + R"(a)"sv, + R"(b)"sv, + R"(c)"sv, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-bool") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_bool, + [](toml::table&& tbl) // array-bool + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::array{ + true, + false, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-empty") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_empty, + [](toml::table&& tbl) // array-empty + { + const auto expected = toml::table{ + { R"(thevoid)"sv, + toml::array{ + toml::inserter{ toml::array{ + toml::inserter{ toml::array{ + toml::inserter{ toml::array{ + toml::inserter{ toml::array{} }, + } }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-hetergeneous") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_hetergeneous, + [](toml::table&& tbl) // array-hetergeneous + { + const auto expected = toml::table{ + { R"(mixed)"sv, + toml::array{ + toml::array{ + 1, + 2, + }, + toml::array{ + R"(a)"sv, + R"(b)"sv, + }, + toml::array{ + 1.1, + 2.1, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-mixed-int-array") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_mixed_int_array, + [](toml::table&& tbl) // array-mixed-int-array + { + const auto expected = toml::table{ + { R"(arrays-and-ints)"sv, + toml::array{ + 1, + toml::array{ + R"(Arrays are not integers.)"sv, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-mixed-int-float") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_mixed_int_float, + [](toml::table&& tbl) // array-mixed-int-float + { + const auto expected = toml::table{ + { R"(ints-and-floats)"sv, + toml::array{ + 1, + 1.1, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-mixed-int-string") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_mixed_int_string, + [](toml::table&& tbl) // array-mixed-int-string + { + const auto expected = toml::table{ + { R"(strings-and-ints)"sv, + toml::array{ + R"(hi)"sv, + 42, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-mixed-string-table") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_mixed_string_table, + [](toml::table&& tbl) // array-mixed-string-table + { + const auto expected = toml::table{ + { R"(contributors)"sv, + toml::array{ + R"(Foo Bar <foo@example.com>)"sv, + toml::table{ + { R"(email)"sv, R"(bazqux@example.com)"sv }, + { R"(name)"sv, R"(Baz Qux)"sv }, + { R"(url)"sv, R"(https://example.com/bazqux)"sv }, + }, + } }, + { R"(mixed)"sv, + toml::array{ + toml::table{ + { R"(k)"sv, R"(a)"sv }, + }, + R"(b)"sv, + 1, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-nested-double") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_nested_double, + [](toml::table&& tbl) // array-nested-double + { + const auto expected = toml::table{ + { R"(nest)"sv, + toml::array{ + toml::inserter{ toml::array{ + toml::array{ + R"(a)"sv, + }, + toml::array{ + 1, + 2, + toml::array{ + 3, + }, + }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-nested-inline-table") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_nested_inline_table, + [](toml::table&& tbl) // array-nested-inline-table + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::array{ + toml::table{ + { R"(b)"sv, toml::table{} }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-nested") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_nested, + [](toml::table&& tbl) // array-nested + { + const auto expected = toml::table{ + { R"(nest)"sv, + toml::array{ + toml::array{ + R"(a)"sv, + }, + toml::array{ + R"(b)"sv, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-nospaces") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_nospaces, + [](toml::table&& tbl) // array-nospaces + { + const auto expected = toml::table{ + { R"(ints)"sv, + toml::array{ + 1, + 2, + 3, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-string-quote-comma-2") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_string_quote_comma_2, + [](toml::table&& tbl) // array-string-quote-comma-2 + { + const auto expected = toml::table{ + { R"(title)"sv, + toml::array{ + R"( ", )"sv, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-string-quote-comma") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_string_quote_comma, + [](toml::table&& tbl) // array-string-quote-comma + { + const auto expected = toml::table{ + { R"(title)"sv, + toml::array{ + R"(Client: "XXXX", Job: XXXX)"sv, + R"(Code: XXXX)"sv, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-string-with-comma-2") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_string_with_comma_2, + [](toml::table&& tbl) // array-string-with-comma-2 + { + const auto expected = toml::table{ + { R"(title)"sv, + toml::array{ + R"(Client: XXXX, +Job: XXXX)"sv, + R"(Code: XXXX)"sv, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-string-with-comma") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_string_with_comma, + [](toml::table&& tbl) // array-string-with-comma + { + const auto expected = toml::table{ + { R"(title)"sv, + toml::array{ + R"(Client: XXXX, Job: XXXX)"sv, + R"(Code: XXXX)"sv, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-strings") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_strings, + [](toml::table&& tbl) // array-strings + { + const auto expected = toml::table{ + { R"(string_array)"sv, + toml::array{ + R"(all)"sv, + R"(strings)"sv, + R"(are the same)"sv, + R"(type)"sv, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("array-table-array-string-backslash") + { + parsing_should_succeed(FILE_LINE_ARGS, + array_table_array_string_backslash, + [](toml::table&& tbl) // array-table-array-string-backslash + { + const auto expected = toml::table{ + { R"(foo)"sv, + toml::array{ + toml::table{ + { R"(bar)"sv, R"("{{baz}}")"sv }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("bool-bool") + { + parsing_should_succeed(FILE_LINE_ARGS, + bool_bool, + [](toml::table&& tbl) // bool-bool + { + const auto expected = toml::table{ + { R"(f)"sv, false }, + { R"(t)"sv, true }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("comment-after-literal-no-ws") + { + parsing_should_succeed(FILE_LINE_ARGS, + comment_after_literal_no_ws, + [](toml::table&& tbl) // comment-after-literal-no-ws + { + const auto expected = toml::table{ + { R"(false)"sv, false }, + { R"(inf)"sv, std::numeric_limits<double>::infinity() }, + { R"(nan)"sv, std::numeric_limits<double>::quiet_NaN() }, + { R"(true)"sv, true }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("comment-at-eof") + { + parsing_should_succeed(FILE_LINE_ARGS, + comment_at_eof, + [](toml::table&& tbl) // comment-at-eof + { + const auto expected = toml::table{ + { R"(key)"sv, R"(value)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("comment-at-eof2") + { + parsing_should_succeed(FILE_LINE_ARGS, + comment_at_eof2, + [](toml::table&& tbl) // comment-at-eof2 + { + const auto expected = toml::table{ + { R"(key)"sv, R"(value)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("comment-everywhere") + { + parsing_should_succeed( + FILE_LINE_ARGS, + comment_everywhere, + [](toml::table&& tbl) // comment-everywhere + { + const auto expected = toml::table{ + { R"(group)"sv, + toml::table{ + { R"(answer)"sv, 42 }, + { R"(d)"sv, toml::date{ 1979, 5, 27 } }, + { R"(dt)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32, 12 }, { -7, 0 } } }, + { R"(more)"sv, + toml::array{ + 42, + 42, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("comment-noeol") + { + parsing_should_succeed(FILE_LINE_ARGS, + comment_noeol, + [](toml::table&& tbl) // comment-noeol + { + const auto expected = toml::table{}; + REQUIRE(tbl == expected); + }); + } + + SECTION("comment-tricky") + { + parsing_should_succeed(FILE_LINE_ARGS, + comment_tricky, + [](toml::table&& tbl) // comment-tricky + { + const auto expected = toml::table{ + { R"(hash#tag)"sv, + toml::table{ + { R"(#!)"sv, R"(hash bang)"sv }, + { R"(arr3)"sv, + toml::array{ + R"(#)"sv, + R"(#)"sv, + R"(###)"sv, + } }, + { R"(arr4)"sv, + toml::array{ + 1, + 2, + 3, + 4, + } }, + { R"(arr5)"sv, + toml::array{ + toml::inserter{ toml::array{ + toml::inserter{ toml::array{ + toml::inserter{ toml::array{ + toml::inserter{ toml::array{ + R"(#)"sv, + } }, + } }, + } }, + } }, + } }, + { R"(tbl1)"sv, + toml::table{ + { R"(#)"sv, R"(}#)"sv }, + } }, + } }, + { R"(section)"sv, + toml::table{ + { R"(8)"sv, R"(eight)"sv }, + { R"(eleven)"sv, 11.1 }, + { R"(five)"sv, 5.5 }, + { R"(four)"sv, R"(# no comment +# nor this +#also not comment)"sv }, + { R"(one)"sv, R"(11)"sv }, + { R"(six)"sv, 6 }, + { R"(ten)"sv, 1000.0 }, + { R"(three)"sv, R"(#)"sv }, + { R"(two)"sv, R"(22#)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + +#if UNICODE_LITERALS_OK + + SECTION("comment-nonascii") + { + parsing_should_succeed(FILE_LINE_ARGS, + comment_nonascii, + [](toml::table&& tbl) // comment-nonascii + { + const auto expected = toml::table{}; + REQUIRE(tbl == expected); + }); + } + +#endif // UNICODE_LITERALS_OK + + SECTION("datetime-datetime") + { + parsing_should_succeed(FILE_LINE_ARGS, + datetime_datetime, + [](toml::table&& tbl) // datetime-datetime + { + const auto expected = toml::table{ + { R"(lower)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 }, { 0, 0 } } }, + { R"(space)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 }, { 0, 0 } } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("datetime-local-date") + { + parsing_should_succeed(FILE_LINE_ARGS, + datetime_local_date, + [](toml::table&& tbl) // datetime-local-date + { + const auto expected = toml::table{ + { R"(bestdayever)"sv, toml::date{ 1987, 7, 5 } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("datetime-local-time") + { + parsing_should_succeed(FILE_LINE_ARGS, + datetime_local_time, + [](toml::table&& tbl) // datetime-local-time + { + const auto expected = toml::table{ + { R"(besttimeever)"sv, toml::time{ 17, 45 } }, + { R"(milliseconds)"sv, toml::time{ 10, 32, 0, 555000000 } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("datetime-local") + { + parsing_should_succeed(FILE_LINE_ARGS, + datetime_local, + [](toml::table&& tbl) // datetime-local + { + const auto expected = toml::table{ + { R"(local)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 } } }, + { R"(milli)"sv, toml::date_time{ { 1977, 12, 21 }, { 10, 32, 0, 555000000 } } }, + { R"(space)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 } } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("datetime-milliseconds") + { + parsing_should_succeed( + FILE_LINE_ARGS, + datetime_milliseconds, + [](toml::table&& tbl) // datetime-milliseconds + { + const auto expected = toml::table{ + { R"(utc1)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56, 123000000 }, { 0, 0 } } }, + { R"(utc2)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56, 600000000 }, { 0, 0 } } }, + { R"(wita1)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56, 123000000 }, { 8, 0 } } }, + { R"(wita2)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56, 600000000 }, { 8, 0 } } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("datetime-timezone") + { + parsing_should_succeed(FILE_LINE_ARGS, + datetime_timezone, + [](toml::table&& tbl) // datetime-timezone + { + const auto expected = toml::table{ + { R"(nzdt)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56 }, { 13, 0 } } }, + { R"(nzst)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56 }, { 12, 0 } } }, + { R"(pdt)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56 }, { -5, 0 } } }, + { R"(utc)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45, 56 }, { 0, 0 } } }, + }; + REQUIRE(tbl == expected); + }); + } + +#if TOML_LANG_UNRELEASED + + SECTION("datetime-no-seconds") + { + parsing_should_succeed( + FILE_LINE_ARGS, + datetime_no_seconds, + [](toml::table&& tbl) // datetime-no-seconds + { + const auto expected = toml::table{ + { R"(without-seconds-1)"sv, toml::time{ 13, 37 } }, + { R"(without-seconds-2)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } } }, + { R"(without-seconds-3)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { -7, 0 } } }, + { R"(without-seconds-4)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 } } }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // TOML_LANG_UNRELEASED + + SECTION("empty-file") + { + parsing_should_succeed(FILE_LINE_ARGS, + empty_file, + [](toml::table&& tbl) // empty-file + { + const auto expected = toml::table{}; + REQUIRE(tbl == expected); + }); + } + + SECTION("example") + { + parsing_should_succeed( + FILE_LINE_ARGS, + example, + [](toml::table&& tbl) // example + { + const auto expected = toml::table{ + { R"(best-day-ever)"sv, toml::date_time{ { 1987, 7, 5 }, { 17, 45 }, { 0, 0 } } }, + { R"(numtheory)"sv, + toml::table{ + { R"(boring)"sv, false }, + { R"(perfection)"sv, + toml::array{ + 6, + 28, + 496, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("float-exponent") + { + parsing_should_succeed(FILE_LINE_ARGS, + float_exponent, + [](toml::table&& tbl) // float-exponent + { + const auto expected = toml::table{ + { R"(lower)"sv, 300.0 }, { R"(minustenth)"sv, -0.1 }, + { R"(neg)"sv, 0.03 }, { R"(pointlower)"sv, 310.0 }, + { R"(pointupper)"sv, 310.0 }, { R"(pos)"sv, 300.0 }, + { R"(upper)"sv, 300.0 }, { R"(zero)"sv, 3.0 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("float-float") + { + parsing_should_succeed(FILE_LINE_ARGS, + float_float, + [](toml::table&& tbl) // float-float + { + const auto expected = toml::table{ + { R"(negpi)"sv, -3.14 }, + { R"(pi)"sv, 3.14 }, + { R"(pospi)"sv, 3.14 }, + { R"(zero-intpart)"sv, 0.123 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("float-inf-and-nan") + { + parsing_should_succeed(FILE_LINE_ARGS, + float_inf_and_nan, + [](toml::table&& tbl) // float-inf-and-nan + { + const auto expected = toml::table{ + { R"(infinity)"sv, std::numeric_limits<double>::infinity() }, + { R"(infinity_neg)"sv, -std::numeric_limits<double>::infinity() }, + { R"(infinity_plus)"sv, std::numeric_limits<double>::infinity() }, + { R"(nan)"sv, std::numeric_limits<double>::quiet_NaN() }, + { R"(nan_neg)"sv, std::numeric_limits<double>::quiet_NaN() }, + { R"(nan_plus)"sv, std::numeric_limits<double>::quiet_NaN() }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("float-long") + { + parsing_should_succeed(FILE_LINE_ARGS, + float_long, + [](toml::table&& tbl) // float-long + { + const auto expected = toml::table{ + { R"(longpi)"sv, 3.141592653589793 }, + { R"(neglongpi)"sv, -3.141592653589793 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("float-underscore") + { + parsing_should_succeed(FILE_LINE_ARGS, + float_underscore, + [](toml::table&& tbl) // float-underscore + { + const auto expected = toml::table{ + { R"(after)"sv, 3141.5927 }, + { R"(before)"sv, 3141.5927 }, + { R"(exponent)"sv, 300000000000000.0 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("float-zero") + { + parsing_should_succeed(FILE_LINE_ARGS, + float_zero, + [](toml::table&& tbl) // float-zero + { + const auto expected = toml::table{ + { R"(exponent)"sv, 0.0 }, + { R"(exponent-signed-neg)"sv, -0.0 }, + { R"(exponent-signed-pos)"sv, 0.0 }, + { R"(exponent-two-0)"sv, 0.0 }, + { R"(signed-neg)"sv, -0.0 }, + { R"(signed-pos)"sv, 0.0 }, + { R"(zero)"sv, 0.0 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("implicit-and-explicit-after") + { + parsing_should_succeed(FILE_LINE_ARGS, + implicit_and_explicit_after, + [](toml::table&& tbl) // implicit-and-explicit-after + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(answer)"sv, 42 }, + } }, + } }, + { R"(better)"sv, 43 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("implicit-and-explicit-before") + { + parsing_should_succeed(FILE_LINE_ARGS, + implicit_and_explicit_before, + [](toml::table&& tbl) // implicit-and-explicit-before + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(answer)"sv, 42 }, + } }, + } }, + { R"(better)"sv, 43 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("implicit-groups") + { + parsing_should_succeed(FILE_LINE_ARGS, + implicit_groups, + [](toml::table&& tbl) // implicit-groups + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(answer)"sv, 42 }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("inline-table-array") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_array, + [](toml::table&& tbl) // inline-table-array + { + const auto expected = toml::table{ + { R"(people)"sv, + toml::array{ + toml::table{ + { R"(first_name)"sv, R"(Bruce)"sv }, + { R"(last_name)"sv, R"(Springsteen)"sv }, + }, + toml::table{ + { R"(first_name)"sv, R"(Eric)"sv }, + { R"(last_name)"sv, R"(Clapton)"sv }, + }, + toml::table{ + { R"(first_name)"sv, R"(Bob)"sv }, + { R"(last_name)"sv, R"(Seger)"sv }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("inline-table-bool") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_bool, + [](toml::table&& tbl) // inline-table-bool + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(a)"sv, true }, + { R"(b)"sv, false }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("inline-table-empty") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_empty, + [](toml::table&& tbl) // inline-table-empty + { + const auto expected = toml::table{ + { R"(empty1)"sv, toml::table{} }, + { R"(empty2)"sv, toml::table{} }, + { R"(empty_in_array)"sv, + toml::array{ + toml::table{ + { R"(not_empty)"sv, 1 }, + }, + toml::table{}, + } }, + { R"(empty_in_array2)"sv, + toml::array{ + toml::table{}, + toml::table{ + { R"(not_empty)"sv, 1 }, + }, + } }, + { R"(many_empty)"sv, + toml::array{ + toml::table{}, + toml::table{}, + toml::table{}, + } }, + { R"(nested_empty)"sv, + toml::table{ + { R"(empty)"sv, toml::table{} }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("inline-table-end-in-bool") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_end_in_bool, + [](toml::table&& tbl) // inline-table-end-in-bool + { + const auto expected = toml::table{ + { R"(black)"sv, + toml::table{ + { R"(allow_prereleases)"sv, true }, + { R"(python)"sv, R"(>3.6)"sv }, + { R"(version)"sv, R"(>=18.9b0)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("inline-table-inline-table") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_inline_table, + [](toml::table&& tbl) // inline-table-inline-table + { + const auto expected = toml::table{ + { R"(name)"sv, + toml::table{ + { R"(first)"sv, R"(Tom)"sv }, + { R"(last)"sv, R"(Preston-Werner)"sv }, + } }, + { R"(point)"sv, + toml::table{ + { R"(x)"sv, 1 }, + { R"(y)"sv, 2 }, + } }, + { R"(simple)"sv, + toml::table{ + { R"(a)"sv, 1 }, + } }, + { R"(str-key)"sv, + toml::table{ + { R"(a)"sv, 1 }, + } }, + { R"(table-array)"sv, + toml::array{ + toml::table{ + { R"(a)"sv, 1 }, + }, + toml::table{ + { R"(b)"sv, 2 }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("inline-table-multiline") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_multiline, + [](toml::table&& tbl) // inline-table-multiline + { + const auto expected = toml::table{ + { R"(tbl_multiline)"sv, + toml::table{ + { R"(a)"sv, 1 }, + { R"(b)"sv, R"(multiline +)"sv }, + { R"(c)"sv, R"(and yet +another line)"sv }, + { R"(d)"sv, 4 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("inline-table-nest") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_nest, + [](toml::table&& tbl) // inline-table-nest + { + const auto expected = toml::table{ + { R"(arr_arr_tbl_empty)"sv, + toml::array{ + toml::inserter{ toml::array{ + toml::table{}, + } }, + } }, + { R"(arr_arr_tbl_val)"sv, + toml::array{ + toml::inserter{ toml::array{ + toml::table{ + { R"(one)"sv, 1 }, + }, + } }, + } }, + { R"(arr_arr_tbls)"sv, + toml::array{ + toml::inserter{ toml::array{ + toml::table{ + { R"(one)"sv, 1 }, + }, + toml::table{ + { R"(two)"sv, 2 }, + }, + } }, + } }, + { R"(arr_tbl_tbl)"sv, + toml::array{ + toml::table{ + { R"(tbl)"sv, + toml::table{ + { R"(one)"sv, 1 }, + } }, + }, + } }, + { R"(tbl_arr_tbl)"sv, + toml::table{ + { R"(arr_tbl)"sv, + toml::array{ + toml::table{ + { R"(one)"sv, 1 }, + }, + } }, + } }, + { R"(tbl_tbl_empty)"sv, + toml::table{ + { R"(tbl_0)"sv, toml::table{} }, + } }, + { R"(tbl_tbl_val)"sv, + toml::table{ + { R"(tbl_1)"sv, + toml::table{ + { R"(one)"sv, 1 }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + +#if !TOML_MSVC + + SECTION("inline-table-key-dotted") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_key_dotted, + [](toml::table&& tbl) // inline-table-key-dotted + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 1 }, + } }, + } }, + { R"(arr)"sv, + toml::array{ + toml::table{ + { R"(T)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 1 }, + } }, + } }, + { R"(t)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 1 }, + } }, + } }, + }, + toml::table{ + { R"(T)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 2 }, + } }, + } }, + { R"(t)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 2 }, + } }, + } }, + }, + } }, + { R"(b)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 1 }, + } }, + } }, + { R"(c)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 1 }, + } }, + } }, + { R"(d)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 1 }, + } }, + } }, + { R"(e)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 1 }, + } }, + } }, + { R"(inline)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, 42 }, + } }, + } }, + { R"(many)"sv, + toml::table{ + { R"(dots)"sv, + toml::table{ + { R"(here)"sv, + toml::table{ + { R"(dot)"sv, + toml::table{ + { R"(dot)"sv, + toml::table{ + { R"(dot)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, 1 }, + { R"(d)"sv, 2 }, + } }, + } }, + } }, + } }, + } }, + } }, + } }, + } }, + { R"(tbl)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(d)"sv, + toml::table{ + { R"(e)"sv, 1 }, + } }, + } }, + } }, + } }, + { R"(x)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(d)"sv, + toml::table{ + { R"(e)"sv, 1 }, + } }, + } }, + } }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // !TOML_MSVC + +#if TOML_LANG_UNRELEASED + + SECTION("inline-table-newline") + { + parsing_should_succeed(FILE_LINE_ARGS, + inline_table_newline, + [](toml::table&& tbl) // inline-table-newline + { + const auto expected = toml::table{ + { R"(tbl-1)"sv, + toml::table{ + { R"(1)"sv, 2 }, + { R"(arr)"sv, + toml::array{ + 1, + 2, + 3, + } }, + { R"(hello)"sv, R"(world)"sv }, + { R"(tbl)"sv, + toml::table{ + { R"(k)"sv, 1 }, + } }, + } }, + { R"(tbl-2)"sv, + toml::table{ + { R"(k)"sv, R"( Hello + )"sv }, + } }, + { R"(trailing-comma-1)"sv, + toml::table{ + { R"(c)"sv, 1 }, + } }, + { R"(trailing-comma-2)"sv, + toml::table{ + { R"(c)"sv, 1 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // TOML_LANG_UNRELEASED + + SECTION("integer-integer") + { + parsing_should_succeed(FILE_LINE_ARGS, + integer_integer, + [](toml::table&& tbl) // integer-integer + { + const auto expected = toml::table{ + { R"(answer)"sv, 42 }, + { R"(neganswer)"sv, -42 }, + { R"(posanswer)"sv, 42 }, + { R"(zero)"sv, 0 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("integer-literals") + { + parsing_should_succeed( + FILE_LINE_ARGS, + integer_literals, + [](toml::table&& tbl) // integer-literals + { + const auto expected = toml::table{ + { R"(bin1)"sv, 214 }, { R"(bin2)"sv, 5 }, { R"(hex1)"sv, 3735928559 }, + { R"(hex2)"sv, 3735928559 }, { R"(hex3)"sv, 3735928559 }, { R"(hex4)"sv, 2439 }, + { R"(oct1)"sv, 342391 }, { R"(oct2)"sv, 493 }, { R"(oct3)"sv, 501 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("integer-long") + { + parsing_should_succeed(FILE_LINE_ARGS, + integer_long, + [](toml::table&& tbl) // integer-long + { + const auto expected = toml::table{ + { R"(int64-max)"sv, std::numeric_limits<int64_t>::max() }, + { R"(int64-max-neg)"sv, std::numeric_limits<int64_t>::min() }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("integer-underscore") + { + parsing_should_succeed(FILE_LINE_ARGS, + integer_underscore, + [](toml::table&& tbl) // integer-underscore + { + const auto expected = toml::table{ + { R"(kilo)"sv, 1000 }, + { R"(x)"sv, 1111 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("integer-zero") + { + parsing_should_succeed(FILE_LINE_ARGS, + integer_zero, + [](toml::table&& tbl) // integer-zero + { + const auto expected = toml::table{ + { R"(a2)"sv, 0 }, { R"(a3)"sv, 0 }, { R"(b1)"sv, 0 }, { R"(b2)"sv, 0 }, + { R"(b3)"sv, 0 }, { R"(d1)"sv, 0 }, { R"(d2)"sv, 0 }, { R"(d3)"sv, 0 }, + { R"(h1)"sv, 0 }, { R"(h2)"sv, 0 }, { R"(h3)"sv, 0 }, { R"(o1)"sv, 0 }, + }; + REQUIRE(tbl == expected); + }); + } + +#if UNICODE_LITERALS_OK + + SECTION("key-case-sensitive") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_case_sensitive, + [](toml::table&& tbl) // key-case-sensitive + { + const auto expected = toml::table{ + { R"(Section)"sv, + toml::table{ + { R"(M)"sv, R"(latin letter M)"sv }, + { R"(name)"sv, R"(different section!!)"sv }, + { R"(Μ)"sv, R"(greek capital letter MU)"sv }, + { R"(μ)"sv, R"(greek small letter mu)"sv }, + } }, + { R"(sectioN)"sv, R"(NN)"sv }, + { R"(section)"sv, + toml::table{ + { R"(NAME)"sv, R"(upper)"sv }, + { R"(Name)"sv, R"(capitalized)"sv }, + { R"(name)"sv, R"(lower)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-escapes") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_escapes, + [](toml::table&& tbl) // key-escapes + { + const auto expected = toml::table{ + { R"( +)"sv, + R"(newline)"sv }, + { R"(")"sv, R"(just a quote)"sv }, + { R"("quoted")"sv, + toml::table{ + { R"(quote)"sv, true }, + } }, + { R"(a.b)"sv, + toml::table{ + { R"(À)"sv, toml::table{} }, + } }, + { "backsp\x08\x08"sv, toml::table{} }, + { R"(À)"sv, R"(latin capital letter A with grave)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-quoted-unicode") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_quoted_unicode, + [](toml::table&& tbl) // key-quoted-unicode + { + const auto expected = toml::table{ + { "\x00"sv, R"(null)"sv }, + { R"(\u0000)"sv, R"(different key)"sv }, + { "\x08 \f A \x7F ÿ 𐀀 "sv, R"(escaped key)"sv }, + { R"(~ ÿ 𐀀 )"sv, R"(basic key)"sv }, + { R"(l ~ ÿ 𐀀 )"sv, R"(literal key)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // UNICODE_LITERALS_OK + + SECTION("key-dotted-empty") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_dotted_empty, + [](toml::table&& tbl) // key-dotted-empty + { + const auto expected = toml::table{ + { ""sv, + toml::table{ + { R"(x)"sv, R"(empty.x)"sv }, + } }, + { R"(a)"sv, + toml::table{ + { ""sv, + toml::table{ + { ""sv, R"(empty.empty)"sv }, + } }, + } }, + { R"(x)"sv, + toml::table{ + { ""sv, R"(x.empty)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-dotted") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_dotted, + [](toml::table&& tbl) // key-dotted + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(few)"sv, + toml::table{ + { R"(dots)"sv, + toml::table{ + { R"(polka)"sv, + toml::table{ + { R"(dance-with)"sv, R"(Dot)"sv }, + { R"(dot)"sv, R"(again?)"sv }, + } }, + } }, + } }, + } }, + { R"(arr)"sv, + toml::array{ + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, 1 }, + { R"(d)"sv, 2 }, + } }, + } }, + }, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, 3 }, + { R"(d)"sv, 4 }, + } }, + } }, + }, + } }, + { R"(count)"sv, + toml::table{ + { R"(a)"sv, 1 }, + { R"(b)"sv, 2 }, + { R"(c)"sv, 3 }, + { R"(d)"sv, 4 }, + { R"(e)"sv, 5 }, + { R"(f)"sv, 6 }, + { R"(g)"sv, 7 }, + { R"(h)"sv, 8 }, + { R"(i)"sv, 9 }, + { R"(j)"sv, 10 }, + { R"(k)"sv, 11 }, + { R"(l)"sv, 12 }, + } }, + { R"(many)"sv, + toml::table{ + { R"(dots)"sv, + toml::table{ + { R"(here)"sv, + toml::table{ + { R"(dot)"sv, + toml::table{ + { R"(dot)"sv, + toml::table{ + { R"(dot)"sv, 42 }, + } }, + } }, + } }, + } }, + } }, + { R"(name)"sv, + toml::table{ + { R"(first)"sv, R"(Arthur)"sv }, + { R"(last)"sv, R"(Dent)"sv }, + } }, + { R"(tbl)"sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, 42.666 }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-empty") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_empty, + [](toml::table&& tbl) // key-empty + { + const auto expected = toml::table{ + { ""sv, R"(blank)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-equals-nospace") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_equals_nospace, + [](toml::table&& tbl) // key-equals-nospace + { + const auto expected = toml::table{ + { R"(answer)"sv, 42 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-numeric-dotted") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_numeric_dotted, + [](toml::table&& tbl) // key-numeric-dotted + { + const auto expected = toml::table{ + { R"(1)"sv, + toml::table{ + { R"(2)"sv, 3 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-numeric") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_numeric, + [](toml::table&& tbl) // key-numeric + { + const auto expected = toml::table{ + { R"(1)"sv, 1 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-quoted-dots") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_quoted_dots, + [](toml::table&& tbl) // key-quoted-dots + { + const auto expected = toml::table{ + { R"(plain)"sv, 1 }, + { R"(plain_table)"sv, + toml::table{ + { R"(plain)"sv, 3 }, + { R"(with.dot)"sv, 4 }, + } }, + { R"(table)"sv, + toml::table{ + { R"(withdot)"sv, + toml::table{ + { R"(key.with.dots)"sv, 6 }, + { R"(plain)"sv, 5 }, + } }, + } }, + { R"(with.dot)"sv, 2 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-space") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_space, + [](toml::table&& tbl) // key-space + { + const auto expected = toml::table{ + { R"( c d )"sv, 2 }, + { R"( tbl )"sv, + toml::table{ + { R"( tab tab )"sv, R"(tab)"sv }, + } }, + { R"(a b)"sv, 1 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-special-chars") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_special_chars, + [](toml::table&& tbl) // key-special-chars + { + const auto expected = toml::table{ + { R"(=~!@$^&*()_+-`1234567890[]|/?><.,;:'=)"sv, 1 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("key-special-word") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_special_word, + [](toml::table&& tbl) // key-special-word + { + const auto expected = toml::table{ + { R"(false)"sv, false }, + { R"(inf)"sv, 100000000 }, + { R"(nan)"sv, R"(ceci n'est pas un nombre)"sv }, + { R"(true)"sv, 1 }, + }; + REQUIRE(tbl == expected); + }); + } + +#if TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK + + SECTION("key-unicode") + { + parsing_should_succeed(FILE_LINE_ARGS, + key_unicode, + [](toml::table&& tbl) // key-unicode + { + const auto expected = toml::table{ + { R"(ab)"sv, R"(zwj)"sv }, + { R"(tiếng-Việt)"sv, + toml::array{ + toml::table{ + { R"(tiəŋ˧˦)"sv, + toml::table{ + { R"(viət̚˧˨ʔ)"sv, R"(north)"sv }, + } }, + }, + toml::table{ + { R"(tiəŋ˦˧˥)"sv, + toml::table{ + { R"(viək̚˨˩ʔ)"sv, R"(central)"sv }, + } }, + }, + } }, + { R"(ÅÅ)"sv, R"(U+00C5 U+0041 U+030A)"sv }, + { R"(€)"sv, R"(Euro)"sv }, + { R"(中文)"sv, + toml::table{ + { R"(中文)"sv, + toml::table{ + { R"(中文)"sv, R"(Chinese language)"sv }, + } }, + } }, + { R"(😂)"sv, R"(rofl)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK + + SECTION("newline-crlf") + { + parsing_should_succeed(FILE_LINE_ARGS, + newline_crlf, + [](toml::table&& tbl) // newline-crlf + { + const auto expected = toml::table{ + { R"(newline)"sv, R"(crlf)"sv }, + { R"(os)"sv, R"(DOS)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("newline-lf") + { + parsing_should_succeed(FILE_LINE_ARGS, + newline_lf, + [](toml::table&& tbl) // newline-lf + { + const auto expected = toml::table{ + { R"(newline)"sv, R"(lf)"sv }, + { R"(os)"sv, R"(unix)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-array-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_array_0, + [](toml::table&& tbl) // spec-array-0 + { + const auto expected = toml::table{ + { R"(colors)"sv, + toml::array{ + R"(red)"sv, + R"(yellow)"sv, + R"(green)"sv, + } }, + { R"(contributors)"sv, + toml::array{ + R"(Foo Bar <foo@example.com>)"sv, + toml::table{ + { R"(email)"sv, R"(bazqux@example.com)"sv }, + { R"(name)"sv, R"(Baz Qux)"sv }, + { R"(url)"sv, R"(https://example.com/bazqux)"sv }, + }, + } }, + { R"(integers)"sv, + toml::array{ + 1, + 2, + 3, + } }, + { R"(nested_arrays_of_ints)"sv, + toml::array{ + toml::array{ + 1, + 2, + }, + toml::array{ + 3, + 4, + 5, + }, + } }, + { R"(nested_mixed_array)"sv, + toml::array{ + toml::array{ + 1, + 2, + }, + toml::array{ + R"(a)"sv, + R"(b)"sv, + R"(c)"sv, + }, + } }, + { R"(numbers)"sv, + toml::array{ + 0.1, + 0.2, + 0.5, + 1, + 2, + 5, + } }, + { R"(string_array)"sv, + toml::array{ + R"(all)"sv, + R"(strings)"sv, + R"(are the same)"sv, + R"(type)"sv, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-array-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_array_1, + [](toml::table&& tbl) // spec-array-1 + { + const auto expected = toml::table{ + { R"(integers2)"sv, + toml::array{ + 1, + 2, + 3, + } }, + { R"(integers3)"sv, + toml::array{ + 1, + 2, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-array-of-tables-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_array_of_tables_0, + [](toml::table&& tbl) // spec-array-of-tables-0 + { + const auto expected = toml::table{ + { R"(products)"sv, + toml::array{ + toml::table{ + { R"(name)"sv, R"(Hammer)"sv }, + { R"(sku)"sv, 738594937 }, + }, + toml::table{}, + toml::table{ + { R"(color)"sv, R"(gray)"sv }, + { R"(name)"sv, R"(Nail)"sv }, + { R"(sku)"sv, 284758393 }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-array-of-tables-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_array_of_tables_1, + [](toml::table&& tbl) // spec-array-of-tables-1 + { + const auto expected = toml::table{ + { R"(fruits)"sv, + toml::array{ + toml::table{ + { R"(name)"sv, R"(apple)"sv }, + { R"(physical)"sv, + toml::table{ + { R"(color)"sv, R"(red)"sv }, + { R"(shape)"sv, R"(round)"sv }, + } }, + { R"(varieties)"sv, + toml::array{ + toml::table{ + { R"(name)"sv, R"(red delicious)"sv }, + }, + toml::table{ + { R"(name)"sv, R"(granny smith)"sv }, + }, + } }, + }, + toml::table{ + { R"(name)"sv, R"(banana)"sv }, + { R"(varieties)"sv, + toml::array{ + toml::table{ + { R"(name)"sv, R"(plantain)"sv }, + }, + } }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-array-of-tables-2") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_array_of_tables_2, + [](toml::table&& tbl) // spec-array-of-tables-2 + { + const auto expected = toml::table{ + { R"(points)"sv, + toml::array{ + toml::table{ + { R"(x)"sv, 1 }, + { R"(y)"sv, 2 }, + { R"(z)"sv, 3 }, + }, + toml::table{ + { R"(x)"sv, 7 }, + { R"(y)"sv, 8 }, + { R"(z)"sv, 9 }, + }, + toml::table{ + { R"(x)"sv, 2 }, + { R"(y)"sv, 4 }, + { R"(z)"sv, 8 }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-boolean-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_boolean_0, + [](toml::table&& tbl) // spec-boolean-0 + { + const auto expected = toml::table{ + { R"(bool1)"sv, true }, + { R"(bool2)"sv, false }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-comment-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_comment_0, + [](toml::table&& tbl) // spec-comment-0 + { + const auto expected = toml::table{ + { R"(another)"sv, R"(# This is not a comment)"sv }, + { R"(key)"sv, R"(value)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-float-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_float_0, + [](toml::table&& tbl) // spec-float-0 + { + const auto expected = toml::table{ + { R"(flt1)"sv, 1.0 }, { R"(flt2)"sv, 3.1415 }, { R"(flt3)"sv, -0.01 }, + { R"(flt4)"sv, 5e+22 }, { R"(flt5)"sv, 1000000.0 }, { R"(flt6)"sv, -0.02 }, + { R"(flt7)"sv, 6.626e-34 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-float-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_float_1, + [](toml::table&& tbl) // spec-float-1 + { + const auto expected = toml::table{ + { R"(flt8)"sv, 224617.445991228 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-float-2") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_float_2, + [](toml::table&& tbl) // spec-float-2 + { + const auto expected = toml::table{ + { R"(sf1)"sv, std::numeric_limits<double>::infinity() }, + { R"(sf2)"sv, std::numeric_limits<double>::infinity() }, + { R"(sf3)"sv, -std::numeric_limits<double>::infinity() }, + { R"(sf4)"sv, std::numeric_limits<double>::quiet_NaN() }, + { R"(sf5)"sv, std::numeric_limits<double>::quiet_NaN() }, + { R"(sf6)"sv, std::numeric_limits<double>::quiet_NaN() }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-inline-table-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_inline_table_0, + [](toml::table&& tbl) // spec-inline-table-0 + { + const auto expected = toml::table{ + { R"(animal)"sv, + toml::table{ + { R"(type)"sv, + toml::table{ + { R"(name)"sv, R"(pug)"sv }, + } }, + } }, + { R"(name)"sv, + toml::table{ + { R"(first)"sv, R"(Tom)"sv }, + { R"(last)"sv, R"(Preston-Werner)"sv }, + } }, + { R"(point)"sv, + toml::table{ + { R"(x)"sv, 1 }, + { R"(y)"sv, 2 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-inline-table-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_inline_table_1, + [](toml::table&& tbl) // spec-inline-table-1 + { + const auto expected = toml::table{ + { R"(animal)"sv, + toml::table{ + { R"(type)"sv, + toml::table{ + { R"(name)"sv, R"(pug)"sv }, + } }, + } }, + { R"(name)"sv, + toml::table{ + { R"(first)"sv, R"(Tom)"sv }, + { R"(last)"sv, R"(Preston-Werner)"sv }, + } }, + { R"(point)"sv, + toml::table{ + { R"(x)"sv, 1 }, + { R"(y)"sv, 2 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-inline-table-2") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_inline_table_2, + [](toml::table&& tbl) // spec-inline-table-2 + { + const auto expected = toml::table{ + { R"(product)"sv, + toml::table{ + { R"(type)"sv, + toml::table{ + { R"(name)"sv, R"(Nail)"sv }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-inline-table-3") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_inline_table_3, + [](toml::table&& tbl) // spec-inline-table-3 + { + const auto expected = toml::table{ + { R"(product)"sv, + toml::table{ + { R"(type)"sv, + toml::table{ + { R"(name)"sv, R"(Nail)"sv }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-integer-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_integer_0, + [](toml::table&& tbl) // spec-integer-0 + { + const auto expected = toml::table{ + { R"(int1)"sv, 99 }, + { R"(int2)"sv, 42 }, + { R"(int3)"sv, 0 }, + { R"(int4)"sv, -17 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-integer-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_integer_1, + [](toml::table&& tbl) // spec-integer-1 + { + const auto expected = toml::table{ + { R"(int5)"sv, 1000 }, + { R"(int6)"sv, 5349221 }, + { R"(int7)"sv, 5349221 }, + { R"(int8)"sv, 12345 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-integer-2") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_integer_2, + [](toml::table&& tbl) // spec-integer-2 + { + const auto expected = toml::table{ + { R"(bin1)"sv, 214 }, { R"(hex1)"sv, 3735928559 }, + { R"(hex2)"sv, 3735928559 }, { R"(hex3)"sv, 3735928559 }, + { R"(oct1)"sv, 342391 }, { R"(oct2)"sv, 493 }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-key-value-pair-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_key_value_pair_0, + [](toml::table&& tbl) // spec-key-value-pair-0 + { + const auto expected = toml::table{ + { R"(key)"sv, R"(value)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-keys-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_keys_0, + [](toml::table&& tbl) // spec-keys-0 + { + const auto expected = toml::table{ + { R"(1234)"sv, R"(value)"sv }, + { R"(bare-key)"sv, R"(value)"sv }, + { R"(bare_key)"sv, R"(value)"sv }, + { R"(key)"sv, R"(value)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-keys-3") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_keys_3, + [](toml::table&& tbl) // spec-keys-3 + { + const auto expected = toml::table{ + { R"(name)"sv, R"(Orange)"sv }, + { R"(physical)"sv, + toml::table{ + { R"(color)"sv, R"(orange)"sv }, + { R"(shape)"sv, R"(round)"sv }, + } }, + { R"(site)"sv, + toml::table{ + { R"(google.com)"sv, true }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-keys-4") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_keys_4, + [](toml::table&& tbl) // spec-keys-4 + { + const auto expected = toml::table{ + { R"(fruit)"sv, + toml::table{ + { R"(color)"sv, R"(yellow)"sv }, + { R"(flavor)"sv, R"(banana)"sv }, + { R"(name)"sv, R"(banana)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-keys-5") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_keys_5, + [](toml::table&& tbl) // spec-keys-5 + { + const auto expected = toml::table{ + { R"(apple)"sv, + toml::table{ + { R"(color)"sv, R"(red)"sv }, + { R"(skin)"sv, R"(thin)"sv }, + { R"(type)"sv, R"(fruit)"sv }, + } }, + { R"(orange)"sv, + toml::table{ + { R"(color)"sv, R"(orange)"sv }, + { R"(skin)"sv, R"(thick)"sv }, + { R"(type)"sv, R"(fruit)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-keys-6") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_keys_6, + [](toml::table&& tbl) // spec-keys-6 + { + const auto expected = toml::table{ + { R"(apple)"sv, + toml::table{ + { R"(color)"sv, R"(red)"sv }, + { R"(skin)"sv, R"(thin)"sv }, + { R"(type)"sv, R"(fruit)"sv }, + } }, + { R"(orange)"sv, + toml::table{ + { R"(color)"sv, R"(orange)"sv }, + { R"(skin)"sv, R"(thick)"sv }, + { R"(type)"sv, R"(fruit)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-keys-7") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_keys_7, + [](toml::table&& tbl) // spec-keys-7 + { + const auto expected = toml::table{ + { R"(3)"sv, + toml::table{ + { R"(14159)"sv, R"(pi)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-local-date-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_local_date_0, + [](toml::table&& tbl) // spec-local-date-0 + { + const auto expected = toml::table{ + { R"(ld1)"sv, toml::date{ 1979, 5, 27 } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-local-date-time-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_local_date_time_0, + [](toml::table&& tbl) // spec-local-date-time-0 + { + const auto expected = toml::table{ + { R"(ldt1)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 } } }, + { R"(ldt2)"sv, toml::date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000 } } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-local-time-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_local_time_0, + [](toml::table&& tbl) // spec-local-time-0 + { + const auto expected = toml::table{ + { R"(lt1)"sv, toml::time{ 7, 32 } }, + { R"(lt2)"sv, toml::time{ 0, 32, 0, 999999000 } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-offset-date-time-0") + { + parsing_should_succeed( + FILE_LINE_ARGS, + spec_offset_date_time_0, + [](toml::table&& tbl) // spec-offset-date-time-0 + { + const auto expected = toml::table{ + { R"(odt1)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } } }, + { R"(odt2)"sv, toml::date_time{ { 1979, 5, 27 }, { 0, 32 }, { -7, 0 } } }, + { R"(odt3)"sv, toml::date_time{ { 1979, 5, 27 }, { 0, 32, 0, 999999000 }, { -7, 0 } } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-offset-date-time-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_offset_date_time_1, + [](toml::table&& tbl) // spec-offset-date-time-1 + { + const auto expected = toml::table{ + { R"(odt4)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { 0, 0 } } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-string-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_string_1, + [](toml::table&& tbl) // spec-string-1 + { + const auto expected = toml::table{ + { R"(str1)"sv, R"(Roses are red +Violets are blue)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-string-2") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_string_2, + [](toml::table&& tbl) // spec-string-2 + { + const auto expected = toml::table{ + { R"(str2)"sv, R"(Roses are red +Violets are blue)"sv }, + { R"(str3)"sv, + "Roses are red\r\n" + "Violets are blue"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-string-3") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_string_3, + [](toml::table&& tbl) // spec-string-3 + { + const auto expected = toml::table{ + { R"(str1)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv }, + { R"(str2)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv }, + { R"(str3)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-string-4") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_string_4, + [](toml::table&& tbl) // spec-string-4 + { + const auto expected = toml::table{ + { R"(str4)"sv, R"(Here are two quotation marks: "". Simple enough.)"sv }, + { R"(str5)"sv, R"(Here are three quotation marks: """.)"sv }, + { R"(str6)"sv, R"(Here are fifteen quotation marks: """"""""""""""".)"sv }, + { R"(str7)"sv, R"("This," she said, "is just a pointless statement.")"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-string-5") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_string_5, + [](toml::table&& tbl) // spec-string-5 + { + const auto expected = toml::table{ + { R"(quoted)"sv, R"(Tom "Dubs" Preston-Werner)"sv }, + { R"(regex)"sv, R"(<\i\c*\s*>)"sv }, + { R"(winpath)"sv, R"(C:\Users\nodejs\templates)"sv }, + { R"(winpath2)"sv, R"(\\ServerX\admin$\system32\)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-string-6") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_string_6, + [](toml::table&& tbl) // spec-string-6 + { + const auto expected = toml::table{ + { R"(lines)"sv, R"(The first newline is +trimmed in raw strings. + All other whitespace + is preserved. +)"sv }, + { R"(regex2)"sv, R"(I [dw]on't need \d{2} apples)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-string-7") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_string_7, + [](toml::table&& tbl) // spec-string-7 + { + const auto expected = toml::table{ + { R"(apos15)"sv, R"(Here are fifteen apostrophes: ''''''''''''''')"sv }, + { R"(quot15)"sv, R"(Here are fifteen quotation marks: """"""""""""""")"sv }, + { R"(str)"sv, R"('That,' she said, 'is still pointless.')"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_0, + [](toml::table&& tbl) // spec-table-0 + { + const auto expected = toml::table{ + { R"(table)"sv, toml::table{} }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_1, + [](toml::table&& tbl) // spec-table-1 + { + const auto expected = toml::table{ + { R"(table-1)"sv, + toml::table{ + { R"(key1)"sv, R"(some string)"sv }, + { R"(key2)"sv, 123 }, + } }, + { R"(table-2)"sv, + toml::table{ + { R"(key1)"sv, R"(another string)"sv }, + { R"(key2)"sv, 456 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-2") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_2, + [](toml::table&& tbl) // spec-table-2 + { + const auto expected = toml::table{ + { R"(dog)"sv, + toml::table{ + { R"(tater.man)"sv, + toml::table{ + { R"(type)"sv, + toml::table{ + { R"(name)"sv, R"(pug)"sv }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-4") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_4, + [](toml::table&& tbl) // spec-table-4 + { + const auto expected = toml::table{ + { R"(x)"sv, + toml::table{ + { R"(y)"sv, + toml::table{ + { R"(z)"sv, + toml::table{ + { R"(w)"sv, toml::table{} }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-5") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_5, + [](toml::table&& tbl) // spec-table-5 + { + const auto expected = toml::table{ + { R"(animal)"sv, toml::table{} }, + { R"(fruit)"sv, + toml::table{ + { R"(apple)"sv, toml::table{} }, + { R"(orange)"sv, toml::table{} }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-6") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_6, + [](toml::table&& tbl) // spec-table-6 + { + const auto expected = toml::table{ + { R"(animal)"sv, toml::table{} }, + { R"(fruit)"sv, + toml::table{ + { R"(apple)"sv, toml::table{} }, + { R"(orange)"sv, toml::table{} }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-7") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_7, + [](toml::table&& tbl) // spec-table-7 + { + const auto expected = toml::table{ + { R"(breed)"sv, R"(pug)"sv }, + { R"(name)"sv, R"(Fido)"sv }, + { R"(owner)"sv, + toml::table{ + { R"(member_since)"sv, toml::date{ 1999, 8, 4 } }, + { R"(name)"sv, R"(Regina Dogman)"sv }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-8") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_8, + [](toml::table&& tbl) // spec-table-8 + { + const auto expected = toml::table{ + { R"(fruit)"sv, + toml::table{ + { R"(apple)"sv, + toml::table{ + { R"(color)"sv, R"(red)"sv }, + { R"(taste)"sv, + toml::table{ + { R"(sweet)"sv, true }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-9") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_9, + [](toml::table&& tbl) // spec-table-9 + { + const auto expected = toml::table{ + { R"(fruit)"sv, + toml::table{ + { R"(apple)"sv, + toml::table{ + { R"(color)"sv, R"(red)"sv }, + { R"(taste)"sv, + toml::table{ + { R"(sweet)"sv, true }, + } }, + { R"(texture)"sv, + toml::table{ + { R"(smooth)"sv, true }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-example-1-compact") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_example_1_compact, + [](toml::table&& tbl) // spec-example-1-compact + { + const auto expected = toml::table{ + { R"(clients)"sv, + toml::table{ + { R"(data)"sv, + toml::array{ + toml::array{ + R"(gamma)"sv, + R"(delta)"sv, + }, + toml::array{ + 1, + 2, + }, + } }, + { R"(hosts)"sv, + toml::array{ + R"(alpha)"sv, + R"(omega)"sv, + } }, + } }, + { R"(database)"sv, + toml::table{ + { R"(connection_max)"sv, 5000 }, + { R"(enabled)"sv, true }, + { R"(ports)"sv, + toml::array{ + 8001, + 8001, + 8002, + } }, + { R"(server)"sv, R"(192.168.1.1)"sv }, + } }, + { R"(owner)"sv, + toml::table{ + { R"(dob)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { -8, 0 } } }, + { R"(name)"sv, R"(Lance Uppercut)"sv }, + } }, + { R"(servers)"sv, + toml::table{ + { R"(alpha)"sv, + toml::table{ + { R"(dc)"sv, R"(eqdc10)"sv }, + { R"(ip)"sv, R"(10.0.0.1)"sv }, + } }, + { R"(beta)"sv, + toml::table{ + { R"(dc)"sv, R"(eqdc10)"sv }, + { R"(ip)"sv, R"(10.0.0.2)"sv }, + } }, + } }, + { R"(title)"sv, R"(TOML Example)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-example-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_example_1, + [](toml::table&& tbl) // spec-example-1 + { + const auto expected = toml::table{ + { R"(clients)"sv, + toml::table{ + { R"(data)"sv, + toml::array{ + toml::array{ + R"(gamma)"sv, + R"(delta)"sv, + }, + toml::array{ + 1, + 2, + }, + } }, + { R"(hosts)"sv, + toml::array{ + R"(alpha)"sv, + R"(omega)"sv, + } }, + } }, + { R"(database)"sv, + toml::table{ + { R"(connection_max)"sv, 5000 }, + { R"(enabled)"sv, true }, + { R"(ports)"sv, + toml::array{ + 8001, + 8001, + 8002, + } }, + { R"(server)"sv, R"(192.168.1.1)"sv }, + } }, + { R"(owner)"sv, + toml::table{ + { R"(dob)"sv, toml::date_time{ { 1979, 5, 27 }, { 7, 32 }, { -8, 0 } } }, + { R"(name)"sv, R"(Lance Uppercut)"sv }, + } }, + { R"(servers)"sv, + toml::table{ + { R"(alpha)"sv, + toml::table{ + { R"(dc)"sv, R"(eqdc10)"sv }, + { R"(ip)"sv, R"(10.0.0.1)"sv }, + } }, + { R"(beta)"sv, + toml::table{ + { R"(dc)"sv, R"(eqdc10)"sv }, + { R"(ip)"sv, R"(10.0.0.2)"sv }, + } }, + } }, + { R"(title)"sv, R"(TOML Example)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + +#if UNICODE_LITERALS_OK + + SECTION("spec-keys-1") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_keys_1, + [](toml::table&& tbl) // spec-keys-1 + { + const auto expected = toml::table{ + { R"(127.0.0.1)"sv, R"(value)"sv }, { R"(character encoding)"sv, R"(value)"sv }, + { R"(key2)"sv, R"(value)"sv }, { R"(quoted "value")"sv, R"(value)"sv }, + { R"(ʎǝʞ)"sv, R"(value)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-string-0") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_string_0, + [](toml::table&& tbl) // spec-string-0 + { + const auto expected = toml::table{ + { R"(str)"sv, R"(I'm a string. "You can quote me". Name José +Location SF.)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("spec-table-3") + { + parsing_should_succeed(FILE_LINE_ARGS, + spec_table_3, + [](toml::table&& tbl) // spec-table-3 + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, toml::table{} }, + } }, + } }, + { R"(d)"sv, + toml::table{ + { R"(e)"sv, + toml::table{ + { R"(f)"sv, toml::table{} }, + } }, + } }, + { R"(g)"sv, + toml::table{ + { R"(h)"sv, + toml::table{ + { R"(i)"sv, toml::table{} }, + } }, + } }, + { R"(j)"sv, + toml::table{ + { R"(ʞ)"sv, + toml::table{ + { R"(l)"sv, toml::table{} }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // UNICODE_LITERALS_OK + + SECTION("string-double-quote-escape") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_double_quote_escape, + [](toml::table&& tbl) // string-double-quote-escape + { + const auto expected = toml::table{ + { R"(test)"sv, R"("one")"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-empty") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_empty, + [](toml::table&& tbl) // string-empty + { + const auto expected = toml::table{ + { R"(answer)"sv, ""sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-escaped-escape") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_escaped_escape, + [](toml::table&& tbl) // string-escaped-escape + { + const auto expected = toml::table{ + { R"(answer)"sv, R"(\x64)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-escapes") + { + parsing_should_succeed( + FILE_LINE_ARGS, + string_escapes, + [](toml::table&& tbl) // string-escapes + { + const auto expected = toml::table{ + { R"(backslash)"sv, R"(This string has a \ backslash character.)"sv }, + { R"(backspace)"sv, "This string has a \x08 backspace character."sv }, + { R"(carriage)"sv, "This string has a \r carriage return character."sv }, + { R"(delete)"sv, "This string has a \x7F delete control code."sv }, + { R"(formfeed)"sv, "This string has a \f form feed character."sv }, + { R"(newline)"sv, R"(This string has a + new line character.)"sv }, + { R"(notunicode1)"sv, R"(This string does not have a unicode \u escape.)"sv }, + { R"(notunicode2)"sv, R"(This string does not have a unicode \u escape.)"sv }, + { R"(notunicode3)"sv, R"(This string does not have a unicode \u0075 escape.)"sv }, + { R"(notunicode4)"sv, R"(This string does not have a unicode \u escape.)"sv }, + { R"(quote)"sv, R"(This string has a " quote character.)"sv }, + { R"(tab)"sv, R"(This string has a tab character.)"sv }, + { R"(unitseparator)"sv, "This string has a \x1F unit separator control code."sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-multiline-escaped-crlf") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_multiline_escaped_crlf, + [](toml::table&& tbl) // string-multiline-escaped-crlf + { + const auto expected = toml::table{ + { R"(0)"sv, ""sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-multiline-quotes") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_multiline_quotes, + [](toml::table&& tbl) // string-multiline-quotes + { + const auto expected = toml::table{ + { R"(escaped)"sv, R"(lol""")"sv }, + { R"(lit_one)"sv, R"('one quote')"sv }, + { R"(lit_one_space)"sv, R"( 'one quote' )"sv }, + { R"(lit_two)"sv, R"(''two quotes'')"sv }, + { R"(lit_two_space)"sv, R"( ''two quotes'' )"sv }, + { R"(mismatch1)"sv, R"(aaa'''bbb)"sv }, + { R"(mismatch2)"sv, R"(aaa"""bbb)"sv }, + { R"(one)"sv, R"("one quote")"sv }, + { R"(one_space)"sv, R"( "one quote" )"sv }, + { R"(two)"sv, R"(""two quotes"")"sv }, + { R"(two_space)"sv, R"( ""two quotes"" )"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-multiline") + { + parsing_should_succeed( + FILE_LINE_ARGS, + string_multiline, + [](toml::table&& tbl) // string-multiline + { + const auto expected = toml::table{ + { R"(equivalent_one)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv }, + { R"(equivalent_three)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv }, + { R"(equivalent_two)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv }, + { R"(escape-bs-1)"sv, R"(a \ +b)"sv }, + { R"(escape-bs-2)"sv, R"(a \b)"sv }, + { R"(escape-bs-3)"sv, R"(a \\ + b)"sv }, + { R"(keep-ws-before)"sv, R"(a b)"sv }, + { R"(multiline_empty_four)"sv, ""sv }, + { R"(multiline_empty_one)"sv, ""sv }, + { R"(multiline_empty_three)"sv, ""sv }, + { R"(multiline_empty_two)"sv, ""sv }, + { R"(no-space)"sv, R"(ab)"sv }, + { R"(whitespace-after-bs)"sv, R"(The quick brown fox jumps over the lazy dog.)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-nl") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_nl, + [](toml::table&& tbl) // string-nl + { + const auto expected = toml::table{ + { R"(lit_nl_end)"sv, R"(value\n)"sv }, + { R"(lit_nl_mid)"sv, R"(val\nue)"sv }, + { R"(lit_nl_uni)"sv, R"(val\ue)"sv }, + { R"(nl_end)"sv, R"(value +)"sv }, + { R"(nl_mid)"sv, R"(val +ue)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-raw-multiline") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_raw_multiline, + [](toml::table&& tbl) // string-raw-multiline + { + const auto expected = toml::table{ + { R"(firstnl)"sv, R"(This string has a ' quote character.)"sv }, + { R"(multiline)"sv, R"(This string +has ' a quote character +and more than +one newline +in it.)"sv }, + { R"(multiline_with_tab)"sv, R"(First line + Followed by a tab)"sv }, + { R"(oneline)"sv, R"(This string has a ' quote character.)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-raw") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_raw, + [](toml::table&& tbl) // string-raw + { + const auto expected = toml::table{ + { R"(backslash)"sv, R"(This string has a \\ backslash character.)"sv }, + { R"(backspace)"sv, R"(This string has a \b backspace character.)"sv }, + { R"(carriage)"sv, R"(This string has a \r carriage return character.)"sv }, + { R"(formfeed)"sv, R"(This string has a \f form feed character.)"sv }, + { R"(newline)"sv, R"(This string has a \n new line character.)"sv }, + { R"(slash)"sv, R"(This string has a \/ slash character.)"sv }, + { R"(tab)"sv, R"(This string has a \t tab character.)"sv }, + { R"(unescaped_tab)"sv, R"(This string has an unescaped tab character.)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-simple") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_simple, + [](toml::table&& tbl) // string-simple + { + const auto expected = toml::table{ + { R"(answer)"sv, R"(You are not drinking enough whisky.)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-with-pound") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_with_pound, + [](toml::table&& tbl) // string-with-pound + { + const auto expected = toml::table{ + { R"(pound)"sv, R"(We see no # comments here.)"sv }, + { R"(poundcomment)"sv, R"(But there are # some comments here.)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + +#if TOML_LANG_UNRELEASED + + SECTION("string-escape-esc") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_escape_esc, + [](toml::table&& tbl) // string-escape-esc + { + const auto expected = toml::table{ + { R"(esc)"sv, "\x1B There is no escape! \x1B"sv }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // TOML_LANG_UNRELEASED + +#if UNICODE_LITERALS_OK + + SECTION("string-escape-tricky") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_escape_tricky, + [](toml::table&& tbl) // string-escape-tricky + { + const auto expected = toml::table{ + { R"(end_esc)"sv, R"(String does not end here" but ends here\)"sv }, + { R"(lit_end_esc)"sv, R"(String ends here\)"sv }, + { R"(lit_multiline_end)"sv, R"(There is no escape\)"sv }, + { R"(lit_multiline_not_unicode)"sv, R"(\u007f)"sv }, + { R"(multiline_end_esc)"sv, R"(When will it end? """...""" should be here")"sv }, + { R"(multiline_not_unicode)"sv, R"(\u0041)"sv }, + { R"(multiline_unicode)"sv, R"( )"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-quoted-unicode") + { + parsing_should_succeed( + FILE_LINE_ARGS, + string_quoted_unicode, + [](toml::table&& tbl) // string-quoted-unicode + { + const auto expected = toml::table{ + { R"(escaped_string)"sv, "\x00 \x08 \f A \x7F ÿ 𐀀 "sv }, + { R"(not_escaped_string)"sv, + R"(\u0000 \u0008 \u000c \U00000041 \u007f \u0080 \u00ff \ud7ff \ue000 \uffff \U00010000 \U0010ffff)"sv }, + { R"(basic_string)"sv, R"(~ ÿ 𐀀 )"sv }, + { R"(literal_string)"sv, R"(~ ÿ 𐀀 )"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-unicode-escape") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_unicode_escape, + [](toml::table&& tbl) // string-unicode-escape + { + const auto expected = toml::table{ + { R"(answer4)"sv, R"(δ)"sv }, + { R"(answer8)"sv, R"(δ)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("string-unicode-literal") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_unicode_literal, + [](toml::table&& tbl) // string-unicode-literal + { + const auto expected = toml::table{ + { R"(answer)"sv, R"(δ)"sv }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // UNICODE_LITERALS_OK + +#if TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK + + SECTION("string-hex-escape") + { + parsing_should_succeed(FILE_LINE_ARGS, + string_hex_escape, + [](toml::table&& tbl) // string-hex-escape + { + const auto expected = toml::table{ + { R"(bs)"sv, "\x7F"sv }, + { R"(hello)"sv, R"(hello +)"sv }, + { R"(higher-than-127)"sv, R"(Sørmirbæren)"sv }, + { R"(literal)"sv, R"(\x20 \x09 \x0d\x0a)"sv }, + { R"(multiline)"sv, + " \x1B \r\n" + "\n" + "\x7F\n" + "\x00\n" + "hello\n" + "\n" + "Sørmirbæren\n" + ""sv }, + { R"(multiline-literal)"sv, R"(\x20 \x09 \x0d\x0a +)"sv }, + { R"(nul)"sv, "\x00"sv }, + { R"(whitespace)"sv, + " \x1B \r\n" + ""sv }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // TOML_LANG_UNRELEASED && UNICODE_LITERALS_OK + + SECTION("table-array-implicit-and-explicit-after") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_array_implicit_and_explicit_after, + [](toml::table&& tbl) // table-array-implicit-and-explicit-after + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::array{ + toml::table{ + { R"(x)"sv, 1 }, + }, + } }, + { R"(y)"sv, 2 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-array-implicit") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_array_implicit, + [](toml::table&& tbl) // table-array-implicit + { + const auto expected = toml::table{ + { R"(albums)"sv, + toml::table{ + { R"(songs)"sv, + toml::array{ + toml::table{ + { R"(name)"sv, R"(Glory Days)"sv }, + }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-array-many") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_array_many, + [](toml::table&& tbl) // table-array-many + { + const auto expected = toml::table{ + { R"(people)"sv, + toml::array{ + toml::table{ + { R"(first_name)"sv, R"(Bruce)"sv }, + { R"(last_name)"sv, R"(Springsteen)"sv }, + }, + toml::table{ + { R"(first_name)"sv, R"(Eric)"sv }, + { R"(last_name)"sv, R"(Clapton)"sv }, + }, + toml::table{ + { R"(first_name)"sv, R"(Bob)"sv }, + { R"(last_name)"sv, R"(Seger)"sv }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-array-nest") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_array_nest, + [](toml::table&& tbl) // table-array-nest + { + const auto expected = toml::table{ + { R"(albums)"sv, + toml::array{ + toml::table{ + { R"(name)"sv, R"(Born to Run)"sv }, + { R"(songs)"sv, + toml::array{ + toml::table{ + { R"(name)"sv, R"(Jungleland)"sv }, + }, + toml::table{ + { R"(name)"sv, R"(Meeting Across the River)"sv }, + }, + } }, + }, + toml::table{ + { R"(name)"sv, R"(Born in the USA)"sv }, + { R"(songs)"sv, + toml::array{ + toml::table{ + { R"(name)"sv, R"(Glory Days)"sv }, + }, + toml::table{ + { R"(name)"sv, R"(Dancing in the Dark)"sv }, + }, + } }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-array-one") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_array_one, + [](toml::table&& tbl) // table-array-one + { + const auto expected = toml::table{ + { R"(people)"sv, + toml::array{ + toml::table{ + { R"(first_name)"sv, R"(Bruce)"sv }, + { R"(last_name)"sv, R"(Springsteen)"sv }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-array-table-array") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_array_table_array, + [](toml::table&& tbl) // table-array-table-array + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::array{ + toml::table{ + { R"(b)"sv, + toml::array{ + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(d)"sv, R"(val0)"sv }, + } }, + }, + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(d)"sv, R"(val1)"sv }, + } }, + }, + } }, + }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-array-within-dotted") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_array_within_dotted, + [](toml::table&& tbl) // table-array-within-dotted + { + const auto expected = toml::table{ + { R"(fruit)"sv, + toml::table{ + { R"(apple)"sv, + toml::table{ + { R"(color)"sv, R"(red)"sv }, + { R"(seeds)"sv, + toml::array{ + toml::table{ + { R"(size)"sv, 2 }, + }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-empty-name") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_empty_name, + [](toml::table&& tbl) // table-empty-name + { + const auto expected = toml::table{ + { ""sv, + toml::table{ + { R"(a)"sv, + toml::table{ + { R"(x)"sv, 2 }, + } }, + { R"(x)"sv, 1 }, + } }, + { R"(a)"sv, + toml::table{ + { ""sv, + toml::table{ + { R"(x)"sv, 3 }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-empty") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_empty, + [](toml::table&& tbl) // table-empty + { + const auto expected = toml::table{ + { R"(a)"sv, toml::table{} }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-keyword") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_keyword, + [](toml::table&& tbl) // table-keyword + { + const auto expected = toml::table{ + { R"(false)"sv, toml::table{} }, + { R"(inf)"sv, toml::table{} }, + { R"(nan)"sv, toml::table{} }, + { R"(true)"sv, toml::table{} }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-no-eol") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_no_eol, + [](toml::table&& tbl) // table-no-eol + { + const auto expected = toml::table{ + { R"(table)"sv, toml::table{} }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-sub-empty") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_sub_empty, + [](toml::table&& tbl) // table-sub-empty + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, toml::table{} }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-sub") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_sub, + [](toml::table&& tbl) // table-sub + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(extend)"sv, + toml::table{ + { R"(key)"sv, 2 }, + { R"(more)"sv, + toml::table{ + { R"(key)"sv, 3 }, + } }, + } }, + { R"(key)"sv, 1 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-whitespace") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_whitespace, + [](toml::table&& tbl) // table-whitespace + { + const auto expected = toml::table{ + { R"(valid key)"sv, toml::table{} }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-with-literal-string") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_with_literal_string, + [](toml::table&& tbl) // table-with-literal-string + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"("b")"sv, + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(answer)"sv, 42 }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-with-pound") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_with_pound, + [](toml::table&& tbl) // table-with-pound + { + const auto expected = toml::table{ + { R"(key#group)"sv, + toml::table{ + { R"(answer)"sv, 42 }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-with-single-quotes") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_with_single_quotes, + [](toml::table&& tbl) // table-with-single-quotes + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"(b)"sv, + toml::table{ + { R"(c)"sv, + toml::table{ + { R"(answer)"sv, 42 }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + + SECTION("table-without-super") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_without_super, + [](toml::table&& tbl) // table-without-super + { + const auto expected = toml::table{ + { R"(x)"sv, + toml::table{ + { R"(y)"sv, + toml::table{ + { R"(z)"sv, + toml::table{ + { R"(w)"sv, toml::table{} }, + } }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + +#if UNICODE_LITERALS_OK + + SECTION("table-names") + { + parsing_should_succeed(FILE_LINE_ARGS, + table_names, + [](toml::table&& tbl) // table-names + { + const auto expected = toml::table{ + { R"(a)"sv, + toml::table{ + { R"( x )"sv, toml::table{} }, + { R"(b)"sv, + toml::table{ + { R"(c)"sv, toml::table{} }, + } }, + { R"(b.c)"sv, toml::table{} }, + { R"(d.e)"sv, toml::table{} }, + } }, + { R"(d)"sv, + toml::table{ + { R"(e)"sv, + toml::table{ + { R"(f)"sv, toml::table{} }, + } }, + } }, + { R"(g)"sv, + toml::table{ + { R"(h)"sv, + toml::table{ + { R"(i)"sv, toml::table{} }, + } }, + } }, + { R"(j)"sv, + toml::table{ + { R"(ʞ)"sv, + toml::table{ + { R"(l)"sv, toml::table{} }, + } }, + } }, + { R"(x)"sv, + toml::table{ + { R"(1)"sv, + toml::table{ + { R"(2)"sv, toml::table{} }, + } }, + } }, + }; + REQUIRE(tbl == expected); + }); + } + +#endif // UNICODE_LITERALS_OK +} |
