aboutsummaryrefslogtreecommitdiff
path: root/test-suite/tests/valid
diff options
context:
space:
mode:
Diffstat (limited to 'test-suite/tests/valid')
-rw-r--r--test-suite/tests/valid/array-empty.json11
-rw-r--r--test-suite/tests/valid/array-empty.toml1
-rw-r--r--test-suite/tests/valid/array-nospaces.json10
-rw-r--r--test-suite/tests/valid/array-nospaces.toml1
-rw-r--r--test-suite/tests/valid/arrays-hetergeneous.json19
-rw-r--r--test-suite/tests/valid/arrays-hetergeneous.toml1
-rw-r--r--test-suite/tests/valid/arrays-nested.json13
-rw-r--r--test-suite/tests/valid/arrays-nested.toml1
-rw-r--r--test-suite/tests/valid/arrays.json34
-rw-r--r--test-suite/tests/valid/arrays.toml8
-rw-r--r--test-suite/tests/valid/bool.json4
-rw-r--r--test-suite/tests/valid/bool.toml2
-rw-r--r--test-suite/tests/valid/comments-everywhere.json12
-rw-r--r--test-suite/tests/valid/comments-everywhere.toml24
-rw-r--r--test-suite/tests/valid/datetime-truncate.json6
-rw-r--r--test-suite/tests/valid/datetime-truncate.toml1
-rw-r--r--test-suite/tests/valid/datetime.json3
-rw-r--r--test-suite/tests/valid/datetime.toml1
-rw-r--r--test-suite/tests/valid/empty.json1
-rw-r--r--test-suite/tests/valid/empty.toml0
-rw-r--r--test-suite/tests/valid/example-bom.toml5
-rw-r--r--test-suite/tests/valid/example-v0.3.0.json1
-rw-r--r--test-suite/tests/valid/example-v0.3.0.toml182
-rw-r--r--test-suite/tests/valid/example-v0.4.0.json1
-rw-r--r--test-suite/tests/valid/example-v0.4.0.toml235
-rw-r--r--test-suite/tests/valid/example.json14
-rw-r--r--test-suite/tests/valid/example.toml5
-rw-r--r--test-suite/tests/valid/example2.json1
-rw-r--r--test-suite/tests/valid/example2.toml47
-rw-r--r--test-suite/tests/valid/float.json4
-rw-r--r--test-suite/tests/valid/float.toml2
-rw-r--r--test-suite/tests/valid/hard_example.json1
-rw-r--r--test-suite/tests/valid/hard_example.toml33
-rw-r--r--test-suite/tests/valid/implicit-and-explicit-after.json10
-rw-r--r--test-suite/tests/valid/implicit-and-explicit-after.toml5
-rw-r--r--test-suite/tests/valid/implicit-and-explicit-before.json10
-rw-r--r--test-suite/tests/valid/implicit-and-explicit-before.toml5
-rw-r--r--test-suite/tests/valid/implicit-groups.json9
-rw-r--r--test-suite/tests/valid/implicit-groups.toml2
-rw-r--r--test-suite/tests/valid/integer.json4
-rw-r--r--test-suite/tests/valid/integer.toml2
-rw-r--r--test-suite/tests/valid/key-equals-nospace.json3
-rw-r--r--test-suite/tests/valid/key-equals-nospace.toml1
-rw-r--r--test-suite/tests/valid/key-quote-newline.json3
-rw-r--r--test-suite/tests/valid/key-quote-newline.toml1
-rw-r--r--test-suite/tests/valid/key-space.json3
-rw-r--r--test-suite/tests/valid/key-space.toml1
-rw-r--r--test-suite/tests/valid/key-special-chars.json5
-rw-r--r--test-suite/tests/valid/key-special-chars.toml1
-rw-r--r--test-suite/tests/valid/key-with-pound.json3
-rw-r--r--test-suite/tests/valid/key-with-pound.toml1
-rw-r--r--test-suite/tests/valid/long-float.json4
-rw-r--r--test-suite/tests/valid/long-float.toml2
-rw-r--r--test-suite/tests/valid/long-integer.json4
-rw-r--r--test-suite/tests/valid/long-integer.toml2
-rw-r--r--test-suite/tests/valid/multiline-string.json30
-rw-r--r--test-suite/tests/valid/multiline-string.toml23
-rw-r--r--test-suite/tests/valid/raw-multiline-string.json14
-rw-r--r--test-suite/tests/valid/raw-multiline-string.toml9
-rw-r--r--test-suite/tests/valid/raw-string.json30
-rw-r--r--test-suite/tests/valid/raw-string.toml7
-rw-r--r--test-suite/tests/valid/string-empty.json6
-rw-r--r--test-suite/tests/valid/string-empty.toml1
-rw-r--r--test-suite/tests/valid/string-escapes.json50
-rw-r--r--test-suite/tests/valid/string-escapes.toml12
-rw-r--r--test-suite/tests/valid/string-simple.json6
-rw-r--r--test-suite/tests/valid/string-simple.toml1
-rw-r--r--test-suite/tests/valid/string-with-pound.json7
-rw-r--r--test-suite/tests/valid/string-with-pound.toml2
-rw-r--r--test-suite/tests/valid/table-array-implicit.json7
-rw-r--r--test-suite/tests/valid/table-array-implicit.toml2
-rw-r--r--test-suite/tests/valid/table-array-many.json16
-rw-r--r--test-suite/tests/valid/table-array-many.toml11
-rw-r--r--test-suite/tests/valid/table-array-nest-no-keys.json14
-rw-r--r--test-suite/tests/valid/table-array-nest-no-keys.toml6
-rw-r--r--test-suite/tests/valid/table-array-nest.json18
-rw-r--r--test-suite/tests/valid/table-array-nest.toml17
-rw-r--r--test-suite/tests/valid/table-array-one.json8
-rw-r--r--test-suite/tests/valid/table-array-one.toml3
-rw-r--r--test-suite/tests/valid/table-empty.json3
-rw-r--r--test-suite/tests/valid/table-empty.toml1
-rw-r--r--test-suite/tests/valid/table-multi-empty.json5
-rw-r--r--test-suite/tests/valid/table-multi-empty.toml5
-rw-r--r--test-suite/tests/valid/table-sub-empty.json3
-rw-r--r--test-suite/tests/valid/table-sub-empty.toml2
-rw-r--r--test-suite/tests/valid/table-whitespace.json3
-rw-r--r--test-suite/tests/valid/table-whitespace.toml1
-rw-r--r--test-suite/tests/valid/table-with-pound.json5
-rw-r--r--test-suite/tests/valid/table-with-pound.toml2
-rw-r--r--test-suite/tests/valid/unicode-escape.json5
-rw-r--r--test-suite/tests/valid/unicode-escape.toml3
-rw-r--r--test-suite/tests/valid/unicode-literal.json3
-rw-r--r--test-suite/tests/valid/unicode-literal.toml1
93 files changed, 1107 insertions, 0 deletions
diff --git a/test-suite/tests/valid/array-empty.json b/test-suite/tests/valid/array-empty.json
new file mode 100644
index 0000000..2fbf256
--- /dev/null
+++ b/test-suite/tests/valid/array-empty.json
@@ -0,0 +1,11 @@
+{
+ "thevoid": { "type": "array", "value": [
+ {"type": "array", "value": [
+ {"type": "array", "value": [
+ {"type": "array", "value": [
+ {"type": "array", "value": []}
+ ]}
+ ]}
+ ]}
+ ]}
+}
diff --git a/test-suite/tests/valid/array-empty.toml b/test-suite/tests/valid/array-empty.toml
new file mode 100644
index 0000000..fa58dc6
--- /dev/null
+++ b/test-suite/tests/valid/array-empty.toml
@@ -0,0 +1 @@
+thevoid = [[[[[]]]]]
diff --git a/test-suite/tests/valid/array-nospaces.json b/test-suite/tests/valid/array-nospaces.json
new file mode 100644
index 0000000..1833d61
--- /dev/null
+++ b/test-suite/tests/valid/array-nospaces.json
@@ -0,0 +1,10 @@
+{
+ "ints": {
+ "type": "array",
+ "value": [
+ {"type": "integer", "value": "1"},
+ {"type": "integer", "value": "2"},
+ {"type": "integer", "value": "3"}
+ ]
+ }
+}
diff --git a/test-suite/tests/valid/array-nospaces.toml b/test-suite/tests/valid/array-nospaces.toml
new file mode 100644
index 0000000..6618936
--- /dev/null
+++ b/test-suite/tests/valid/array-nospaces.toml
@@ -0,0 +1 @@
+ints = [1,2,3]
diff --git a/test-suite/tests/valid/arrays-hetergeneous.json b/test-suite/tests/valid/arrays-hetergeneous.json
new file mode 100644
index 0000000..478fa5c
--- /dev/null
+++ b/test-suite/tests/valid/arrays-hetergeneous.json
@@ -0,0 +1,19 @@
+{
+ "mixed": {
+ "type": "array",
+ "value": [
+ {"type": "array", "value": [
+ {"type": "integer", "value": "1"},
+ {"type": "integer", "value": "2"}
+ ]},
+ {"type": "array", "value": [
+ {"type": "string", "value": "a"},
+ {"type": "string", "value": "b"}
+ ]},
+ {"type": "array", "value": [
+ {"type": "float", "value": "1.1"},
+ {"type": "float", "value": "2.1"}
+ ]}
+ ]
+ }
+}
diff --git a/test-suite/tests/valid/arrays-hetergeneous.toml b/test-suite/tests/valid/arrays-hetergeneous.toml
new file mode 100644
index 0000000..a246fcf
--- /dev/null
+++ b/test-suite/tests/valid/arrays-hetergeneous.toml
@@ -0,0 +1 @@
+mixed = [[1, 2], ["a", "b"], [1.1, 2.1]]
diff --git a/test-suite/tests/valid/arrays-nested.json b/test-suite/tests/valid/arrays-nested.json
new file mode 100644
index 0000000..d21920c
--- /dev/null
+++ b/test-suite/tests/valid/arrays-nested.json
@@ -0,0 +1,13 @@
+{
+ "nest": {
+ "type": "array",
+ "value": [
+ {"type": "array", "value": [
+ {"type": "string", "value": "a"}
+ ]},
+ {"type": "array", "value": [
+ {"type": "string", "value": "b"}
+ ]}
+ ]
+ }
+}
diff --git a/test-suite/tests/valid/arrays-nested.toml b/test-suite/tests/valid/arrays-nested.toml
new file mode 100644
index 0000000..ce33022
--- /dev/null
+++ b/test-suite/tests/valid/arrays-nested.toml
@@ -0,0 +1 @@
+nest = [["a"], ["b"]]
diff --git a/test-suite/tests/valid/arrays.json b/test-suite/tests/valid/arrays.json
new file mode 100644
index 0000000..58aedbc
--- /dev/null
+++ b/test-suite/tests/valid/arrays.json
@@ -0,0 +1,34 @@
+{
+ "ints": {
+ "type": "array",
+ "value": [
+ {"type": "integer", "value": "1"},
+ {"type": "integer", "value": "2"},
+ {"type": "integer", "value": "3"}
+ ]
+ },
+ "floats": {
+ "type": "array",
+ "value": [
+ {"type": "float", "value": "1.1"},
+ {"type": "float", "value": "2.1"},
+ {"type": "float", "value": "3.1"}
+ ]
+ },
+ "strings": {
+ "type": "array",
+ "value": [
+ {"type": "string", "value": "a"},
+ {"type": "string", "value": "b"},
+ {"type": "string", "value": "c"}
+ ]
+ },
+ "dates": {
+ "type": "array",
+ "value": [
+ {"type": "datetime", "value": "1987-07-05T17:45:00Z"},
+ {"type": "datetime", "value": "1979-05-27T07:32:00Z"},
+ {"type": "datetime", "value": "2006-06-01T11:00:00Z"}
+ ]
+ }
+}
diff --git a/test-suite/tests/valid/arrays.toml b/test-suite/tests/valid/arrays.toml
new file mode 100644
index 0000000..c435f57
--- /dev/null
+++ b/test-suite/tests/valid/arrays.toml
@@ -0,0 +1,8 @@
+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,
+]
diff --git a/test-suite/tests/valid/bool.json b/test-suite/tests/valid/bool.json
new file mode 100644
index 0000000..ae368e9
--- /dev/null
+++ b/test-suite/tests/valid/bool.json
@@ -0,0 +1,4 @@
+{
+ "f": {"type": "bool", "value": "false"},
+ "t": {"type": "bool", "value": "true"}
+}
diff --git a/test-suite/tests/valid/bool.toml b/test-suite/tests/valid/bool.toml
new file mode 100644
index 0000000..a8a829b
--- /dev/null
+++ b/test-suite/tests/valid/bool.toml
@@ -0,0 +1,2 @@
+t = true
+f = false
diff --git a/test-suite/tests/valid/comments-everywhere.json b/test-suite/tests/valid/comments-everywhere.json
new file mode 100644
index 0000000..e69a2e9
--- /dev/null
+++ b/test-suite/tests/valid/comments-everywhere.json
@@ -0,0 +1,12 @@
+{
+ "group": {
+ "answer": {"type": "integer", "value": "42"},
+ "more": {
+ "type": "array",
+ "value": [
+ {"type": "integer", "value": "42"},
+ {"type": "integer", "value": "42"}
+ ]
+ }
+ }
+}
diff --git a/test-suite/tests/valid/comments-everywhere.toml b/test-suite/tests/valid/comments-everywhere.toml
new file mode 100644
index 0000000..3dca74c
--- /dev/null
+++ b/test-suite/tests/valid/comments-everywhere.toml
@@ -0,0 +1,24 @@
+# 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.
diff --git a/test-suite/tests/valid/datetime-truncate.json b/test-suite/tests/valid/datetime-truncate.json
new file mode 100644
index 0000000..8c512e1
--- /dev/null
+++ b/test-suite/tests/valid/datetime-truncate.json
@@ -0,0 +1,6 @@
+{
+ "bestdayever": {
+ "type": "datetime",
+ "value": "1987-07-05T17:45:00.123456789Z"
+ }
+}
diff --git a/test-suite/tests/valid/datetime-truncate.toml b/test-suite/tests/valid/datetime-truncate.toml
new file mode 100644
index 0000000..05de841
--- /dev/null
+++ b/test-suite/tests/valid/datetime-truncate.toml
@@ -0,0 +1 @@
+bestdayever = 1987-07-05T17:45:00.123456789012345Z
diff --git a/test-suite/tests/valid/datetime.json b/test-suite/tests/valid/datetime.json
new file mode 100644
index 0000000..2ca93ce
--- /dev/null
+++ b/test-suite/tests/valid/datetime.json
@@ -0,0 +1,3 @@
+{
+ "bestdayever": {"type": "datetime", "value": "1987-07-05T17:45:00Z"}
+}
diff --git a/test-suite/tests/valid/datetime.toml b/test-suite/tests/valid/datetime.toml
new file mode 100644
index 0000000..2e99340
--- /dev/null
+++ b/test-suite/tests/valid/datetime.toml
@@ -0,0 +1 @@
+bestdayever = 1987-07-05T17:45:00Z
diff --git a/test-suite/tests/valid/empty.json b/test-suite/tests/valid/empty.json
new file mode 100644
index 0000000..0967ef4
--- /dev/null
+++ b/test-suite/tests/valid/empty.json
@@ -0,0 +1 @@
+{}
diff --git a/test-suite/tests/valid/empty.toml b/test-suite/tests/valid/empty.toml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/test-suite/tests/valid/empty.toml
diff --git a/test-suite/tests/valid/example-bom.toml b/test-suite/tests/valid/example-bom.toml
new file mode 100644
index 0000000..fb5ac81
--- /dev/null
+++ b/test-suite/tests/valid/example-bom.toml
@@ -0,0 +1,5 @@
+best-day-ever = 1987-07-05T17:45:00Z
+
+[numtheory]
+boring = false
+perfection = [6, 28, 496]
diff --git a/test-suite/tests/valid/example-v0.3.0.json b/test-suite/tests/valid/example-v0.3.0.json
new file mode 100644
index 0000000..1d9dcb5
--- /dev/null
+++ b/test-suite/tests/valid/example-v0.3.0.json
@@ -0,0 +1 @@
+{"Array":{"key1":{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"},{"type":"integer","value":"3"}]},"key2":{"type":"array","value":[{"type":"string","value":"red"},{"type":"string","value":"yellow"},{"type":"string","value":"green"}]},"key3":{"type":"array","value":[{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"}]},{"type":"array","value":[{"type":"integer","value":"3"},{"type":"integer","value":"4"},{"type":"integer","value":"5"}]}]},"key4":{"type":"array","value":[{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"}]},{"type":"array","value":[{"type":"string","value":"a"},{"type":"string","value":"b"},{"type":"string","value":"c"}]}]},"key5":{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"},{"type":"integer","value":"3"}]},"key6":{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"}]}},"Booleans":{"False":{"type":"bool","value":"false"},"True":{"type":"bool","value":"true"}},"Datetime":{"key1":{"type":"datetime","value":"1979-05-27T07:32:00Z"}},"Float":{"both":{},"exponent":{},"fractional":{"key1":{"type":"float","value":"1.0"},"key2":{"type":"float","value":"3.1415"},"key3":{"type":"float","value":"-0.01"}}},"Integer":{"key1":{"type":"integer","value":"99"},"key2":{"type":"integer","value":"42"},"key3":{"type":"integer","value":"0"},"key4":{"type":"integer","value":"-17"}},"String":{"Literal":{"Multiline":{"lines":{"type":"string","value":"The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n"},"regex2":{"type":"string","value":"I [dw]on't need \\d{2} apples"}},"quoted":{"type":"string","value":"Tom \"Dubs\" Preston-Werner"},"regex":{"type":"string","value":"\u003c\\i\\c*\\s*\u003e"},"winpath":{"type":"string","value":"C:\\Users\\nodejs\\templates"},"winpath2":{"type":"string","value":"\\\\ServerX\\admin$\\system32\\"}},"Multiline":{"key1":{"type":"string","value":"One\nTwo"},"key2":{"type":"string","value":"One\nTwo"},"key3":{"type":"string","value":"One\nTwo"}},"Multilined":{"Singleline":{"key1":{"type":"string","value":"The quick brown fox jumps over the lazy dog."},"key2":{"type":"string","value":"The quick brown fox jumps over the lazy dog."},"key3":{"type":"string","value":"The quick brown fox jumps over the lazy dog."}}},"basic":{"type":"string","value":"I'm a string. \"You can quote me\". Name\u0009José\nLocation\u0009SF."}},"Table":{"key":{"type":"string","value":"value"}},"dog":{"tater":{"type":{"type":"string","value":"pug"}}},"fruit":[{"name":{"type":"string","value":"apple"},"physical":{"color":{"type":"string","value":"red"},"shape":{"type":"string","value":"round"}},"variety":[{"name":{"type":"string","value":"red delicious"}},{"name":{"type":"string","value":"granny smith"}}]},{"name":{"type":"string","value":"banana"},"variety":[{"name":{"type":"string","value":"plantain"}}]}],"products":[{"name":{"type":"string","value":"Hammer"},"sku":{"type":"integer","value":"738594937"}},{},{"color":{"type":"string","value":"gray"},"name":{"type":"string","value":"Nail"},"sku":{"type":"integer","value":"284758393"}}],"x":{"y":{"z":{"w":{}}}}}
diff --git a/test-suite/tests/valid/example-v0.3.0.toml b/test-suite/tests/valid/example-v0.3.0.toml
new file mode 100644
index 0000000..76aacc3
--- /dev/null
+++ b/test-suite/tests/valid/example-v0.3.0.toml
@@ -0,0 +1,182 @@
+# Comment
+# I am a comment. Hear me roar. Roar.
+
+# Table
+# Tables (also known as hash tables or dictionaries) are collections of key/value pairs.
+# They appear in square brackets on a line by themselves.
+
+[Table]
+
+key = "value" # Yeah, you can do this.
+
+# Nested tables are denoted by table names with dots in them. Name your tables whatever crap you please, just don't use #, ., [ or ].
+
+[dog.tater]
+type = "pug"
+
+# You don't need to specify all the super-tables if you don't want to. TOML knows how to do it for you.
+
+# [x] you
+# [x.y] don't
+# [x.y.z] need these
+[x.y.z.w] # for this to work
+
+# String
+# There are four ways to express strings: basic, multi-line basic, literal, and multi-line literal.
+# All strings must contain only valid UTF-8 characters.
+
+[String]
+basic = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
+
+[String.Multiline]
+
+# The following strings are byte-for-byte equivalent:
+key1 = "One\nTwo"
+key2 = """One\nTwo"""
+key3 = """
+One
+Two"""
+
+[String.Multilined.Singleline]
+
+# The following strings are byte-for-byte equivalent:
+key1 = "The quick brown fox jumps over the lazy dog."
+
+key2 = """
+The quick brown \
+
+
+ fox jumps over \
+ the lazy dog."""
+
+key3 = """\
+ The quick brown \
+ fox jumps over \
+ the lazy dog.\
+ """
+
+[String.Literal]
+
+# 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*>'
+
+
+[String.Literal.Multiline]
+
+regex2 = '''I [dw]on't need \d{2} apples'''
+lines = '''
+The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+'''
+
+# Integer
+# Integers are whole numbers. Positive numbers may be prefixed with a plus sign.
+# Negative numbers are prefixed with a minus sign.
+
+[Integer]
+key1 = +99
+key2 = 42
+key3 = 0
+key4 = -17
+
+# Float
+# A float consists of an integer part (which may be prefixed with a plus or minus sign)
+# followed by a fractional part and/or an exponent part.
+
+[Float.fractional]
+
+# fractional
+key1 = +1.0
+key2 = 3.1415
+key3 = -0.01
+
+[Float.exponent]
+
+# exponent
+#key1 = 5e+22
+#key2 = 1e6
+#key3 = -2E-2
+
+[Float.both]
+
+# both
+#key = 6.626e-34
+
+# Boolean
+# Booleans are just the tokens you're used to. Always lowercase.
+
+[Booleans]
+True = true
+False = false
+
+# Datetime
+# Datetimes are RFC 3339 dates.
+
+[Datetime]
+key1 = 1979-05-27T07:32:00Z
+#key2 = 1979-05-27T00:32:00-07:00
+#key3 = 1979-05-27T00:32:00.999999-07:00
+
+# Array
+# Arrays are square brackets with other primitives inside. Whitespace is ignored. Elements are separated by commas. Data types may not be mixed.
+
+[Array]
+key1 = [ 1, 2, 3 ]
+key2 = [ "red", "yellow", "green" ]
+key3 = [ [ 1, 2 ], [3, 4, 5] ]
+key4 = [ [ 1, 2 ], ["a", "b", "c"] ] # this is ok
+
+#Arrays can also be multiline. So in addition to ignoring whitespace, arrays also ignore newlines between the brackets.
+# Terminating commas are ok before the closing bracket.
+
+key5 = [
+ 1, 2, 3
+]
+key6 = [
+ 1,
+ 2, # this is ok
+]
+
+# Array of Tables
+# These can be expressed by using a table name in double brackets.
+# Each table with the same double bracketed name will be an element in the array.
+# The tables are inserted in the order encountered.
+
+[[products]]
+name = "Hammer"
+sku = 738594937
+
+[[products]]
+
+[[products]]
+name = "Nail"
+sku = 284758393
+color = "gray"
+
+
+# You can create nested arrays of tables as well.
+
+[[fruit]]
+ name = "apple"
+
+ [fruit.physical]
+ color = "red"
+ shape = "round"
+
+ [[fruit.variety]]
+ name = "red delicious"
+
+ [[fruit.variety]]
+ name = "granny smith"
+
+[[fruit]]
+ name = "banana"
+
+ [[fruit.variety]]
+ name = "plantain"
+
diff --git a/test-suite/tests/valid/example-v0.4.0.json b/test-suite/tests/valid/example-v0.4.0.json
new file mode 100644
index 0000000..d5cac34
--- /dev/null
+++ b/test-suite/tests/valid/example-v0.4.0.json
@@ -0,0 +1 @@
+{"array":{"key1":{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"},{"type":"integer","value":"3"}]},"key2":{"type":"array","value":[{"type":"string","value":"red"},{"type":"string","value":"yellow"},{"type":"string","value":"green"}]},"key3":{"type":"array","value":[{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"}]},{"type":"array","value":[{"type":"integer","value":"3"},{"type":"integer","value":"4"},{"type":"integer","value":"5"}]}]},"key4":{"type":"array","value":[{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"}]},{"type":"array","value":[{"type":"string","value":"a"},{"type":"string","value":"b"},{"type":"string","value":"c"}]}]},"key5":{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"},{"type":"integer","value":"3"}]},"key6":{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"}]}},"boolean":{"False":{"type":"bool","value":"false"},"True":{"type":"bool","value":"true"}},"datetime":{},"float":{"both":{},"exponent":{},"fractional":{"key1":{"type":"float","value":"1.0"},"key2":{"type":"float","value":"3.1415"},"key3":{"type":"float","value":"-0.01"}},"underscores":{}},"fruit":[{"name":{"type":"string","value":"apple"},"physical":{"color":{"type":"string","value":"red"},"shape":{"type":"string","value":"round"}},"variety":[{"name":{"type":"string","value":"red delicious"}},{"name":{"type":"string","value":"granny smith"}}]},{"name":{"type":"string","value":"banana"},"variety":[{"name":{"type":"string","value":"plantain"}}]}],"integer":{"key1":{"type":"integer","value":"99"},"key2":{"type":"integer","value":"42"},"key3":{"type":"integer","value":"0"},"key4":{"type":"integer","value":"-17"},"underscores":{"key1":{"type":"integer","value":"1000"},"key2":{"type":"integer","value":"5349221"},"key3":{"type":"integer","value":"12345"}}},"products":[{"name":{"type":"string","value":"Hammer"},"sku":{"type":"integer","value":"738594937"}},{},{"color":{"type":"string","value":"gray"},"name":{"type":"string","value":"Nail"},"sku":{"type":"integer","value":"284758393"}}],"string":{"basic":{"basic":{"type":"string","value":"I'm a string. \"You can quote me\". Name\u0009José\nLocation\u0009SF."}},"literal":{"multiline":{"lines":{"type":"string","value":"The first newline is\ntrimmed in raw strings.\n All other whitespace\n is preserved.\n"},"regex2":{"type":"string","value":"I [dw]on't need \\d{2} apples"}},"quoted":{"type":"string","value":"Tom \"Dubs\" Preston-Werner"},"regex":{"type":"string","value":"\u003c\\i\\c*\\s*\u003e"},"winpath":{"type":"string","value":"C:\\Users\\nodejs\\templates"},"winpath2":{"type":"string","value":"\\\\ServerX\\admin$\\system32\\"}},"multiline":{"continued":{"key1":{"type":"string","value":"The quick brown fox jumps over the lazy dog."},"key2":{"type":"string","value":"The quick brown fox jumps over the lazy dog."},"key3":{"type":"string","value":"The quick brown fox jumps over the lazy dog."}},"key1":{"type":"string","value":"One\nTwo"},"key2":{"type":"string","value":"One\nTwo"},"key3":{"type":"string","value":"One\nTwo"}}},"table":{"inline":{"name":{"first":{"type":"string","value":"Tom"},"last":{"type":"string","value":"Preston-Werner"}},"point":{"x":{"type":"integer","value":"1"},"y":{"type":"integer","value":"2"}}},"key":{"type":"string","value":"value"},"subtable":{"key":{"type":"string","value":"another value"}}},"x":{"y":{"z":{"w":{}}}}}
diff --git a/test-suite/tests/valid/example-v0.4.0.toml b/test-suite/tests/valid/example-v0.4.0.toml
new file mode 100644
index 0000000..ffbcce0
--- /dev/null
+++ b/test-suite/tests/valid/example-v0.4.0.toml
@@ -0,0 +1,235 @@
+################################################################################
+## Comment
+
+# Speak your mind with the hash symbol. They go from the symbol to the end of
+# the line.
+
+
+################################################################################
+## Table
+
+# Tables (also known as hash tables or dictionaries) are collections of
+# key/value pairs. They appear in square brackets on a line by themselves.
+
+[table]
+
+key = "value" # Yeah, you can do this.
+
+# Nested tables are denoted by table names with dots in them. Name your tables
+# whatever crap you please, just don't use #, ., [ or ].
+
+[table.subtable]
+
+key = "another value"
+
+# You don't need to specify all the super-tables if you don't want to. TOML
+# knows how to do it for you.
+
+# [x] you
+# [x.y] don't
+# [x.y.z] need these
+[x.y.z.w] # for this to work
+
+
+################################################################################
+## Inline Table
+
+# Inline tables provide a more compact syntax for expressing tables. They are
+# especially useful for grouped data that can otherwise quickly become verbose.
+# Inline tables are enclosed in curly braces `{` and `}`. No newlines are
+# allowed between the curly braces unless they are valid within a value.
+
+[table.inline]
+
+name = { first = "Tom", last = "Preston-Werner" }
+point = { x = 1, y = 2 }
+
+
+################################################################################
+## String
+
+# There are four ways to express strings: basic, multi-line basic, literal, and
+# multi-line literal. All strings must contain only valid UTF-8 characters.
+
+[string.basic]
+
+basic = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
+
+[string.multiline]
+
+# The following strings are byte-for-byte equivalent:
+key1 = "One\nTwo"
+key2 = """One\nTwo"""
+key3 = """
+One
+Two"""
+
+[string.multiline.continued]
+
+# The following strings are byte-for-byte equivalent:
+key1 = "The quick brown fox jumps over the lazy dog."
+
+key2 = """
+The quick brown \
+
+
+ fox jumps over \
+ the lazy dog."""
+
+key3 = """\
+ The quick brown \
+ fox jumps over \
+ the lazy dog.\
+ """
+
+[string.literal]
+
+# 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*>'
+
+
+[string.literal.multiline]
+
+regex2 = '''I [dw]on't need \d{2} apples'''
+lines = '''
+The first newline is
+trimmed in raw strings.
+ All other whitespace
+ is preserved.
+'''
+
+
+################################################################################
+## Integer
+
+# Integers are whole numbers. Positive numbers may be prefixed with a plus sign.
+# Negative numbers are prefixed with a minus sign.
+
+[integer]
+
+key1 = +99
+key2 = 42
+key3 = 0
+key4 = -17
+
+[integer.underscores]
+
+# For large numbers, you may use underscores to enhance readability. Each
+# underscore must be surrounded by at least one digit.
+key1 = 1_000
+key2 = 5_349_221
+key3 = 1_2_3_4_5 # valid but inadvisable
+
+
+################################################################################
+## Float
+
+# A float consists of an integer part (which may be prefixed with a plus or
+# minus sign) followed by a fractional part and/or an exponent part.
+
+[float.fractional]
+
+key1 = +1.0
+key2 = 3.1415
+key3 = -0.01
+
+[float.exponent]
+
+[float.both]
+
+[float.underscores]
+
+
+################################################################################
+## Boolean
+
+# Booleans are just the tokens you're used to. Always lowercase.
+
+[boolean]
+
+True = true
+False = false
+
+
+################################################################################
+## Datetime
+
+# Datetimes are RFC 3339 dates.
+
+[datetime]
+
+#key1 = 1979-05-27T07:32:00Z
+#key2 = 1979-05-27T00:32:00-07:00
+#key3 = 1979-05-27T00:32:00.999999-07:00
+
+
+################################################################################
+## Array
+
+# Arrays are square brackets with other primitives inside. Whitespace is
+# ignored. Elements are separated by commas. Data types may not be mixed.
+
+[array]
+
+key1 = [ 1, 2, 3 ]
+key2 = [ "red", "yellow", "green" ]
+key3 = [ [ 1, 2 ], [3, 4, 5] ]
+key4 = [ [ 1, 2 ], ["a", "b", "c"] ] # this is ok
+
+# Arrays can also be multiline. So in addition to ignoring whitespace, arrays
+# also ignore newlines between the brackets. Terminating commas are ok before
+# the closing bracket.
+
+key5 = [
+ 1, 2, 3
+]
+key6 = [
+ 1,
+ 2, # this is ok
+]
+
+
+################################################################################
+## Array of Tables
+
+# These can be expressed by using a table name in double brackets. Each table
+# with the same double bracketed name will be an element in the array. The
+# tables are inserted in the order encountered.
+
+[[products]]
+
+name = "Hammer"
+sku = 738594937
+
+[[products]]
+
+[[products]]
+
+name = "Nail"
+sku = 284758393
+color = "gray"
+
+
+# You can create nested arrays of tables as well.
+
+[[fruit]]
+ name = "apple"
+
+ [fruit.physical]
+ color = "red"
+ shape = "round"
+
+ [[fruit.variety]]
+ name = "red delicious"
+
+ [[fruit.variety]]
+ name = "granny smith"
+
+[[fruit]]
+ name = "banana"
+
+ [[fruit.variety]]
+ name = "plantain"
diff --git a/test-suite/tests/valid/example.json b/test-suite/tests/valid/example.json
new file mode 100644
index 0000000..48aa907
--- /dev/null
+++ b/test-suite/tests/valid/example.json
@@ -0,0 +1,14 @@
+{
+ "best-day-ever": {"type": "datetime", "value": "1987-07-05T17:45:00Z"},
+ "numtheory": {
+ "boring": {"type": "bool", "value": "false"},
+ "perfection": {
+ "type": "array",
+ "value": [
+ {"type": "integer", "value": "6"},
+ {"type": "integer", "value": "28"},
+ {"type": "integer", "value": "496"}
+ ]
+ }
+ }
+}
diff --git a/test-suite/tests/valid/example.toml b/test-suite/tests/valid/example.toml
new file mode 100644
index 0000000..8cb02e0
--- /dev/null
+++ b/test-suite/tests/valid/example.toml
@@ -0,0 +1,5 @@
+best-day-ever = 1987-07-05T17:45:00Z
+
+[numtheory]
+boring = false
+perfection = [6, 28, 496]
diff --git a/test-suite/tests/valid/example2.json b/test-suite/tests/valid/example2.json
new file mode 100644
index 0000000..3249a97
--- /dev/null
+++ b/test-suite/tests/valid/example2.json
@@ -0,0 +1 @@
+{"clients":{"data":{"type":"array","value":[{"type":"array","value":[{"type":"string","value":"gamma"},{"type":"string","value":"delta"}]},{"type":"array","value":[{"type":"integer","value":"1"},{"type":"integer","value":"2"}]}]},"hosts":{"type":"array","value":[{"type":"string","value":"alpha"},{"type":"string","value":"omega"}]}},"database":{"connection_max":{"type":"integer","value":"5000"},"enabled":{"type":"bool","value":"true"},"ports":{"type":"array","value":[{"type":"integer","value":"8001"},{"type":"integer","value":"8001"},{"type":"integer","value":"8002"}]},"server":{"type":"string","value":"192.168.1.1"}},"owner":{"bio":{"type":"string","value":"GitHub Cofounder \u0026 CEO\nLikes tater tots and beer."},"dob":{"type":"datetime","value":"1979-05-27T07:32:00Z"},"name":{"type":"string","value":"Tom Preston-Werner"},"organization":{"type":"string","value":"GitHub"}},"products":[{"name":{"type":"string","value":"Hammer"},"sku":{"type":"integer","value":"738594937"}},{"color":{"type":"string","value":"gray"},"name":{"type":"string","value":"Nail"},"sku":{"type":"integer","value":"284758393"}}],"servers":{"alpha":{"dc":{"type":"string","value":"eqdc10"},"ip":{"type":"string","value":"10.0.0.1"}},"beta":{"country":{"type":"string","value":"中国"},"dc":{"type":"string","value":"eqdc10"},"ip":{"type":"string","value":"10.0.0.2"}}},"title":{"type":"string","value":"TOML Example"}}
diff --git a/test-suite/tests/valid/example2.toml b/test-suite/tests/valid/example2.toml
new file mode 100644
index 0000000..bc12c99
--- /dev/null
+++ b/test-suite/tests/valid/example2.toml
@@ -0,0 +1,47 @@
+# This is a TOML document. Boom.
+
+title = "TOML Example"
+
+[owner]
+name = "Tom Preston-Werner"
+organization = "GitHub"
+bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
+dob = 1979-05-27T07:32:00Z # 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"
+ country = "中国" # This should be parsed as UTF-8
+
+[clients]
+data = [ ["gamma", "delta"], [1, 2] ] # just an update to make sure parsers support it
+
+# Line breaks are OK when inside arrays
+hosts = [
+ "alpha",
+ "omega"
+]
+
+# Products
+
+ [[products]]
+ name = "Hammer"
+ sku = 738594937
+
+ [[products]]
+ name = "Nail"
+ sku = 284758393
+ color = "gray"
diff --git a/test-suite/tests/valid/float.json b/test-suite/tests/valid/float.json
new file mode 100644
index 0000000..b8a2e97
--- /dev/null
+++ b/test-suite/tests/valid/float.json
@@ -0,0 +1,4 @@
+{
+ "pi": {"type": "float", "value": "3.14"},
+ "negpi": {"type": "float", "value": "-3.14"}
+}
diff --git a/test-suite/tests/valid/float.toml b/test-suite/tests/valid/float.toml
new file mode 100644
index 0000000..7c528d2
--- /dev/null
+++ b/test-suite/tests/valid/float.toml
@@ -0,0 +1,2 @@
+pi = 3.14
+negpi = -3.14
diff --git a/test-suite/tests/valid/hard_example.json b/test-suite/tests/valid/hard_example.json
new file mode 100644
index 0000000..9762e58
--- /dev/null
+++ b/test-suite/tests/valid/hard_example.json
@@ -0,0 +1 @@
+{"the":{"hard":{"another_test_string":{"type":"string","value":" Same thing, but with a string #"},"bit#":{"multi_line_array":{"type":"array","value":[{"type":"string","value":"]"}]},"what?":{"type":"string","value":"You don't think some user won't do that?"}},"harder_test_string":{"type":"string","value":" And when \"'s are in the string, along with # \""},"test_array":{"type":"array","value":[{"type":"string","value":"] "},{"type":"string","value":" # "}]},"test_array2":{"type":"array","value":[{"type":"string","value":"Test #11 ]proved that"},{"type":"string","value":"Experiment #9 was a success"}]}},"test_string":{"type":"string","value":"You'll hate me after this - #"}}}
diff --git a/test-suite/tests/valid/hard_example.toml b/test-suite/tests/valid/hard_example.toml
new file mode 100644
index 0000000..38856c8
--- /dev/null
+++ b/test-suite/tests/valid/hard_example.toml
@@ -0,0 +1,33 @@
+# Test file for TOML
+# Only this one tries to emulate a TOML file written by a user of the kind of parser writers probably hate
+# This part you'll really hate
+
+[the]
+test_string = "You'll hate me after this - #" # " Annoying, isn't it?
+
+ [the.hard]
+ test_array = [ "] ", " # "] # ] There you go, parse this!
+ test_array2 = [ "Test #11 ]proved that", "Experiment #9 was a success" ]
+ # You didn't think it'd as easy as chucking out the last #, did you?
+ another_test_string = " Same thing, but with a string #"
+ harder_test_string = " And when \"'s are in the string, along with # \"" # "and comments are there too"
+ # Things will get harder
+
+ [the.hard."bit#"]
+ "what?" = "You don't think some user won't do that?"
+ multi_line_array = [
+ "]",
+ # ] Oh yes I did
+ ]
+
+# Each of the following keygroups/key value pairs should produce an error. Uncomment to them to test
+
+#[error] if you didn't catch this, your parser is broken
+#string = "Anything other than tabs, spaces and newline after a keygroup or key value pair has ended should produce an error unless it is a comment" like this
+#array = [
+# "This might most likely happen in multiline arrays",
+# Like here,
+# "or here,
+# and here"
+# ] End of array comment, forgot the #
+#number = 3.14 pi <--again forgot the #
diff --git a/test-suite/tests/valid/implicit-and-explicit-after.json b/test-suite/tests/valid/implicit-and-explicit-after.json
new file mode 100644
index 0000000..374bd09
--- /dev/null
+++ b/test-suite/tests/valid/implicit-and-explicit-after.json
@@ -0,0 +1,10 @@
+{
+ "a": {
+ "better": {"type": "integer", "value": "43"},
+ "b": {
+ "c": {
+ "answer": {"type": "integer", "value": "42"}
+ }
+ }
+ }
+}
diff --git a/test-suite/tests/valid/implicit-and-explicit-after.toml b/test-suite/tests/valid/implicit-and-explicit-after.toml
new file mode 100644
index 0000000..c0e8865
--- /dev/null
+++ b/test-suite/tests/valid/implicit-and-explicit-after.toml
@@ -0,0 +1,5 @@
+[a.b.c]
+answer = 42
+
+[a]
+better = 43
diff --git a/test-suite/tests/valid/implicit-and-explicit-before.json b/test-suite/tests/valid/implicit-and-explicit-before.json
new file mode 100644
index 0000000..374bd09
--- /dev/null
+++ b/test-suite/tests/valid/implicit-and-explicit-before.json
@@ -0,0 +1,10 @@
+{
+ "a": {
+ "better": {"type": "integer", "value": "43"},
+ "b": {
+ "c": {
+ "answer": {"type": "integer", "value": "42"}
+ }
+ }
+ }
+}
diff --git a/test-suite/tests/valid/implicit-and-explicit-before.toml b/test-suite/tests/valid/implicit-and-explicit-before.toml
new file mode 100644
index 0000000..eee68ff
--- /dev/null
+++ b/test-suite/tests/valid/implicit-and-explicit-before.toml
@@ -0,0 +1,5 @@
+[a]
+better = 43
+
+[a.b.c]
+answer = 42
diff --git a/test-suite/tests/valid/implicit-groups.json b/test-suite/tests/valid/implicit-groups.json
new file mode 100644
index 0000000..fbae7fc
--- /dev/null
+++ b/test-suite/tests/valid/implicit-groups.json
@@ -0,0 +1,9 @@
+{
+ "a": {
+ "b": {
+ "c": {
+ "answer": {"type": "integer", "value": "42"}
+ }
+ }
+ }
+}
diff --git a/test-suite/tests/valid/implicit-groups.toml b/test-suite/tests/valid/implicit-groups.toml
new file mode 100644
index 0000000..b6333e4
--- /dev/null
+++ b/test-suite/tests/valid/implicit-groups.toml
@@ -0,0 +1,2 @@
+[a.b.c]
+answer = 42
diff --git a/test-suite/tests/valid/integer.json b/test-suite/tests/valid/integer.json
new file mode 100644
index 0000000..61985a1
--- /dev/null
+++ b/test-suite/tests/valid/integer.json
@@ -0,0 +1,4 @@
+{
+ "answer": {"type": "integer", "value": "42"},
+ "neganswer": {"type": "integer", "value": "-42"}
+}
diff --git a/test-suite/tests/valid/integer.toml b/test-suite/tests/valid/integer.toml
new file mode 100644
index 0000000..c4f6297
--- /dev/null
+++ b/test-suite/tests/valid/integer.toml
@@ -0,0 +1,2 @@
+answer = 42
+neganswer = -42
diff --git a/test-suite/tests/valid/key-equals-nospace.json b/test-suite/tests/valid/key-equals-nospace.json
new file mode 100644
index 0000000..1f8709a
--- /dev/null
+++ b/test-suite/tests/valid/key-equals-nospace.json
@@ -0,0 +1,3 @@
+{
+ "answer": {"type": "integer", "value": "42"}
+}
diff --git a/test-suite/tests/valid/key-equals-nospace.toml b/test-suite/tests/valid/key-equals-nospace.toml
new file mode 100644
index 0000000..560901c
--- /dev/null
+++ b/test-suite/tests/valid/key-equals-nospace.toml
@@ -0,0 +1 @@
+answer=42
diff --git a/test-suite/tests/valid/key-quote-newline.json b/test-suite/tests/valid/key-quote-newline.json
new file mode 100644
index 0000000..12473e4
--- /dev/null
+++ b/test-suite/tests/valid/key-quote-newline.json
@@ -0,0 +1,3 @@
+{
+ "\n": {"type": "integer", "value": "1"}
+}
diff --git a/test-suite/tests/valid/key-quote-newline.toml b/test-suite/tests/valid/key-quote-newline.toml
new file mode 100644
index 0000000..a2639bf
--- /dev/null
+++ b/test-suite/tests/valid/key-quote-newline.toml
@@ -0,0 +1 @@
+"\n" = 1
diff --git a/test-suite/tests/valid/key-space.json b/test-suite/tests/valid/key-space.json
new file mode 100644
index 0000000..9d1f769
--- /dev/null
+++ b/test-suite/tests/valid/key-space.json
@@ -0,0 +1,3 @@
+{
+ "a b": {"type": "integer", "value": "1"}
+}
diff --git a/test-suite/tests/valid/key-space.toml b/test-suite/tests/valid/key-space.toml
new file mode 100644
index 0000000..f4f36c4
--- /dev/null
+++ b/test-suite/tests/valid/key-space.toml
@@ -0,0 +1 @@
+"a b" = 1
diff --git a/test-suite/tests/valid/key-special-chars.json b/test-suite/tests/valid/key-special-chars.json
new file mode 100644
index 0000000..6550ebd
--- /dev/null
+++ b/test-suite/tests/valid/key-special-chars.json
@@ -0,0 +1,5 @@
+{
+ "~!@#$^&*()_+-`1234567890[]\\|/?><.,;:'": {
+ "type": "integer", "value": "1"
+ }
+}
diff --git a/test-suite/tests/valid/key-special-chars.toml b/test-suite/tests/valid/key-special-chars.toml
new file mode 100644
index 0000000..dc43625
--- /dev/null
+++ b/test-suite/tests/valid/key-special-chars.toml
@@ -0,0 +1 @@
+"~!@#$^&*()_+-`1234567890[]\\|/?><.,;:'" = 1
diff --git a/test-suite/tests/valid/key-with-pound.json b/test-suite/tests/valid/key-with-pound.json
new file mode 100644
index 0000000..ee39e1d
--- /dev/null
+++ b/test-suite/tests/valid/key-with-pound.json
@@ -0,0 +1,3 @@
+{
+ "key#name": {"type": "integer", "value": "5"}
+}
diff --git a/test-suite/tests/valid/key-with-pound.toml b/test-suite/tests/valid/key-with-pound.toml
new file mode 100644
index 0000000..65b766f
--- /dev/null
+++ b/test-suite/tests/valid/key-with-pound.toml
@@ -0,0 +1 @@
+"key#name" = 5
diff --git a/test-suite/tests/valid/long-float.json b/test-suite/tests/valid/long-float.json
new file mode 100644
index 0000000..8ceed47
--- /dev/null
+++ b/test-suite/tests/valid/long-float.json
@@ -0,0 +1,4 @@
+{
+ "longpi": {"type": "float", "value": "3.141592653589793"},
+ "neglongpi": {"type": "float", "value": "-3.141592653589793"}
+}
diff --git a/test-suite/tests/valid/long-float.toml b/test-suite/tests/valid/long-float.toml
new file mode 100644
index 0000000..9558ae4
--- /dev/null
+++ b/test-suite/tests/valid/long-float.toml
@@ -0,0 +1,2 @@
+longpi = 3.141592653589793
+neglongpi = -3.141592653589793
diff --git a/test-suite/tests/valid/long-integer.json b/test-suite/tests/valid/long-integer.json
new file mode 100644
index 0000000..16c331e
--- /dev/null
+++ b/test-suite/tests/valid/long-integer.json
@@ -0,0 +1,4 @@
+{
+ "answer": {"type": "integer", "value": "9223372036854775807"},
+ "neganswer": {"type": "integer", "value": "-9223372036854775808"}
+}
diff --git a/test-suite/tests/valid/long-integer.toml b/test-suite/tests/valid/long-integer.toml
new file mode 100644
index 0000000..424a13a
--- /dev/null
+++ b/test-suite/tests/valid/long-integer.toml
@@ -0,0 +1,2 @@
+answer = 9223372036854775807
+neganswer = -9223372036854775808
diff --git a/test-suite/tests/valid/multiline-string.json b/test-suite/tests/valid/multiline-string.json
new file mode 100644
index 0000000..075bf50
--- /dev/null
+++ b/test-suite/tests/valid/multiline-string.json
@@ -0,0 +1,30 @@
+{
+ "multiline_empty_one": {
+ "type": "string",
+ "value": ""
+ },
+ "multiline_empty_two": {
+ "type": "string",
+ "value": ""
+ },
+ "multiline_empty_three": {
+ "type": "string",
+ "value": ""
+ },
+ "multiline_empty_four": {
+ "type": "string",
+ "value": ""
+ },
+ "equivalent_one": {
+ "type": "string",
+ "value": "The quick brown fox jumps over the lazy dog."
+ },
+ "equivalent_two": {
+ "type": "string",
+ "value": "The quick brown fox jumps over the lazy dog."
+ },
+ "equivalent_three": {
+ "type": "string",
+ "value": "The quick brown fox jumps over the lazy dog."
+ }
+}
diff --git a/test-suite/tests/valid/multiline-string.toml b/test-suite/tests/valid/multiline-string.toml
new file mode 100644
index 0000000..15b1143
--- /dev/null
+++ b/test-suite/tests/valid/multiline-string.toml
@@ -0,0 +1,23 @@
+multiline_empty_one = """"""
+multiline_empty_two = """
+"""
+multiline_empty_three = """\
+ """
+multiline_empty_four = """\
+ \
+ \
+ """
+
+equivalent_one = "The quick brown fox jumps over the lazy dog."
+equivalent_two = """
+The quick brown \
+
+
+ fox jumps over \
+ the lazy dog."""
+
+equivalent_three = """\
+ The quick brown \
+ fox jumps over \
+ the lazy dog.\
+ """
diff --git a/test-suite/tests/valid/raw-multiline-string.json b/test-suite/tests/valid/raw-multiline-string.json
new file mode 100644
index 0000000..b43cce5
--- /dev/null
+++ b/test-suite/tests/valid/raw-multiline-string.json
@@ -0,0 +1,14 @@
+{
+ "oneline": {
+ "type": "string",
+ "value": "This string has a ' quote character."
+ },
+ "firstnl": {
+ "type": "string",
+ "value": "This string has a ' quote character."
+ },
+ "multiline": {
+ "type": "string",
+ "value": "This string\nhas ' a quote character\nand more than\none newline\nin it."
+ }
+}
diff --git a/test-suite/tests/valid/raw-multiline-string.toml b/test-suite/tests/valid/raw-multiline-string.toml
new file mode 100644
index 0000000..8094c03
--- /dev/null
+++ b/test-suite/tests/valid/raw-multiline-string.toml
@@ -0,0 +1,9 @@
+oneline = '''This string has a ' quote character.'''
+firstnl = '''
+This string has a ' quote character.'''
+multiline = '''
+This string
+has ' a quote character
+and more than
+one newline
+in it.'''
diff --git a/test-suite/tests/valid/raw-string.json b/test-suite/tests/valid/raw-string.json
new file mode 100644
index 0000000..693ab9b
--- /dev/null
+++ b/test-suite/tests/valid/raw-string.json
@@ -0,0 +1,30 @@
+{
+ "backspace": {
+ "type": "string",
+ "value": "This string has a \\b backspace character."
+ },
+ "tab": {
+ "type": "string",
+ "value": "This string has a \\t tab character."
+ },
+ "newline": {
+ "type": "string",
+ "value": "This string has a \\n new line character."
+ },
+ "formfeed": {
+ "type": "string",
+ "value": "This string has a \\f form feed character."
+ },
+ "carriage": {
+ "type": "string",
+ "value": "This string has a \\r carriage return character."
+ },
+ "slash": {
+ "type": "string",
+ "value": "This string has a \\/ slash character."
+ },
+ "backslash": {
+ "type": "string",
+ "value": "This string has a \\\\ backslash character."
+ }
+}
diff --git a/test-suite/tests/valid/raw-string.toml b/test-suite/tests/valid/raw-string.toml
new file mode 100644
index 0000000..92acd25
--- /dev/null
+++ b/test-suite/tests/valid/raw-string.toml
@@ -0,0 +1,7 @@
+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.'
+slash = 'This string has a \/ slash character.'
+backslash = 'This string has a \\ backslash character.'
diff --git a/test-suite/tests/valid/string-empty.json b/test-suite/tests/valid/string-empty.json
new file mode 100644
index 0000000..6c26d69
--- /dev/null
+++ b/test-suite/tests/valid/string-empty.json
@@ -0,0 +1,6 @@
+{
+ "answer": {
+ "type": "string",
+ "value": ""
+ }
+}
diff --git a/test-suite/tests/valid/string-empty.toml b/test-suite/tests/valid/string-empty.toml
new file mode 100644
index 0000000..e37e681
--- /dev/null
+++ b/test-suite/tests/valid/string-empty.toml
@@ -0,0 +1 @@
+answer = ""
diff --git a/test-suite/tests/valid/string-escapes.json b/test-suite/tests/valid/string-escapes.json
new file mode 100644
index 0000000..62dac51
--- /dev/null
+++ b/test-suite/tests/valid/string-escapes.json
@@ -0,0 +1,50 @@
+{
+ "backspace": {
+ "type": "string",
+ "value": "This string has a \u0008 backspace character."
+ },
+ "tab": {
+ "type": "string",
+ "value": "This string has a \u0009 tab character."
+ },
+ "newline": {
+ "type": "string",
+ "value": "This string has a \u000A new line character."
+ },
+ "formfeed": {
+ "type": "string",
+ "value": "This string has a \u000C form feed character."
+ },
+ "carriage": {
+ "type": "string",
+ "value": "This string has a \u000D carriage return character."
+ },
+ "quote": {
+ "type": "string",
+ "value": "This string has a \u0022 quote character."
+ },
+ "slash": {
+ "type": "string",
+ "value": "This string has a \u002F slash character."
+ },
+ "backslash": {
+ "type": "string",
+ "value": "This string has a \u005C backslash character."
+ },
+ "notunicode1": {
+ "type": "string",
+ "value": "This string does not have a unicode \\u escape."
+ },
+ "notunicode2": {
+ "type": "string",
+ "value": "This string does not have a unicode \u005Cu escape."
+ },
+ "notunicode3": {
+ "type": "string",
+ "value": "This string does not have a unicode \\u0075 escape."
+ },
+ "notunicode4": {
+ "type": "string",
+ "value": "This string does not have a unicode \\\u0075 escape."
+ }
+}
diff --git a/test-suite/tests/valid/string-escapes.toml b/test-suite/tests/valid/string-escapes.toml
new file mode 100644
index 0000000..c5d4954
--- /dev/null
+++ b/test-suite/tests/valid/string-escapes.toml
@@ -0,0 +1,12 @@
+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."
+slash = "This string has a / slash 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."
diff --git a/test-suite/tests/valid/string-simple.json b/test-suite/tests/valid/string-simple.json
new file mode 100644
index 0000000..2e05f99
--- /dev/null
+++ b/test-suite/tests/valid/string-simple.json
@@ -0,0 +1,6 @@
+{
+ "answer": {
+ "type": "string",
+ "value": "You are not drinking enough whisky."
+ }
+}
diff --git a/test-suite/tests/valid/string-simple.toml b/test-suite/tests/valid/string-simple.toml
new file mode 100644
index 0000000..e17ade6
--- /dev/null
+++ b/test-suite/tests/valid/string-simple.toml
@@ -0,0 +1 @@
+answer = "You are not drinking enough whisky."
diff --git a/test-suite/tests/valid/string-with-pound.json b/test-suite/tests/valid/string-with-pound.json
new file mode 100644
index 0000000..33cdc9c
--- /dev/null
+++ b/test-suite/tests/valid/string-with-pound.json
@@ -0,0 +1,7 @@
+{
+ "pound": {"type": "string", "value": "We see no # comments here."},
+ "poundcomment": {
+ "type": "string",
+ "value": "But there are # some comments here."
+ }
+}
diff --git a/test-suite/tests/valid/string-with-pound.toml b/test-suite/tests/valid/string-with-pound.toml
new file mode 100644
index 0000000..5fd8746
--- /dev/null
+++ b/test-suite/tests/valid/string-with-pound.toml
@@ -0,0 +1,2 @@
+pound = "We see no # comments here."
+poundcomment = "But there are # some comments here." # Did I # mess you up?
diff --git a/test-suite/tests/valid/table-array-implicit.json b/test-suite/tests/valid/table-array-implicit.json
new file mode 100644
index 0000000..32e4640
--- /dev/null
+++ b/test-suite/tests/valid/table-array-implicit.json
@@ -0,0 +1,7 @@
+{
+ "albums": {
+ "songs": [
+ {"name": {"type": "string", "value": "Glory Days"}}
+ ]
+ }
+}
diff --git a/test-suite/tests/valid/table-array-implicit.toml b/test-suite/tests/valid/table-array-implicit.toml
new file mode 100644
index 0000000..3157ac9
--- /dev/null
+++ b/test-suite/tests/valid/table-array-implicit.toml
@@ -0,0 +1,2 @@
+[[albums.songs]]
+name = "Glory Days"
diff --git a/test-suite/tests/valid/table-array-many.json b/test-suite/tests/valid/table-array-many.json
new file mode 100644
index 0000000..84df2da
--- /dev/null
+++ b/test-suite/tests/valid/table-array-many.json
@@ -0,0 +1,16 @@
+{
+ "people": [
+ {
+ "first_name": {"type": "string", "value": "Bruce"},
+ "last_name": {"type": "string", "value": "Springsteen"}
+ },
+ {
+ "first_name": {"type": "string", "value": "Eric"},
+ "last_name": {"type": "string", "value": "Clapton"}
+ },
+ {
+ "first_name": {"type": "string", "value": "Bob"},
+ "last_name": {"type": "string", "value": "Seger"}
+ }
+ ]
+}
diff --git a/test-suite/tests/valid/table-array-many.toml b/test-suite/tests/valid/table-array-many.toml
new file mode 100644
index 0000000..46062be
--- /dev/null
+++ b/test-suite/tests/valid/table-array-many.toml
@@ -0,0 +1,11 @@
+[[people]]
+first_name = "Bruce"
+last_name = "Springsteen"
+
+[[people]]
+first_name = "Eric"
+last_name = "Clapton"
+
+[[people]]
+first_name = "Bob"
+last_name = "Seger"
diff --git a/test-suite/tests/valid/table-array-nest-no-keys.json b/test-suite/tests/valid/table-array-nest-no-keys.json
new file mode 100644
index 0000000..7537b1a
--- /dev/null
+++ b/test-suite/tests/valid/table-array-nest-no-keys.json
@@ -0,0 +1,14 @@
+{
+ "albums": [
+ {
+ "songs": [{}, {}]
+ }
+ ],
+ "artists": [
+ {
+ "home": {
+ "address": {}
+ }
+ }
+ ]
+}
diff --git a/test-suite/tests/valid/table-array-nest-no-keys.toml b/test-suite/tests/valid/table-array-nest-no-keys.toml
new file mode 100644
index 0000000..ad6eb10
--- /dev/null
+++ b/test-suite/tests/valid/table-array-nest-no-keys.toml
@@ -0,0 +1,6 @@
+[[ albums ]]
+ [[ albums.songs ]]
+ [[ albums.songs ]]
+
+[[ artists ]]
+ [ artists.home.address ]
diff --git a/test-suite/tests/valid/table-array-nest.json b/test-suite/tests/valid/table-array-nest.json
new file mode 100644
index 0000000..c117afa
--- /dev/null
+++ b/test-suite/tests/valid/table-array-nest.json
@@ -0,0 +1,18 @@
+{
+ "albums": [
+ {
+ "name": {"type": "string", "value": "Born to Run"},
+ "songs": [
+ {"name": {"type": "string", "value": "Jungleland"}},
+ {"name": {"type": "string", "value": "Meeting Across the River"}}
+ ]
+ },
+ {
+ "name": {"type": "string", "value": "Born in the USA"},
+ "songs": [
+ {"name": {"type": "string", "value": "Glory Days"}},
+ {"name": {"type": "string", "value": "Dancing in the Dark"}}
+ ]
+ }
+ ]
+}
diff --git a/test-suite/tests/valid/table-array-nest.toml b/test-suite/tests/valid/table-array-nest.toml
new file mode 100644
index 0000000..d659a3d
--- /dev/null
+++ b/test-suite/tests/valid/table-array-nest.toml
@@ -0,0 +1,17 @@
+[[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"
diff --git a/test-suite/tests/valid/table-array-one.json b/test-suite/tests/valid/table-array-one.json
new file mode 100644
index 0000000..d75faae
--- /dev/null
+++ b/test-suite/tests/valid/table-array-one.json
@@ -0,0 +1,8 @@
+{
+ "people": [
+ {
+ "first_name": {"type": "string", "value": "Bruce"},
+ "last_name": {"type": "string", "value": "Springsteen"}
+ }
+ ]
+}
diff --git a/test-suite/tests/valid/table-array-one.toml b/test-suite/tests/valid/table-array-one.toml
new file mode 100644
index 0000000..cd7e1b6
--- /dev/null
+++ b/test-suite/tests/valid/table-array-one.toml
@@ -0,0 +1,3 @@
+[[people]]
+first_name = "Bruce"
+last_name = "Springsteen"
diff --git a/test-suite/tests/valid/table-empty.json b/test-suite/tests/valid/table-empty.json
new file mode 100644
index 0000000..6f3873a
--- /dev/null
+++ b/test-suite/tests/valid/table-empty.json
@@ -0,0 +1,3 @@
+{
+ "a": {}
+}
diff --git a/test-suite/tests/valid/table-empty.toml b/test-suite/tests/valid/table-empty.toml
new file mode 100644
index 0000000..8bb6a0a
--- /dev/null
+++ b/test-suite/tests/valid/table-empty.toml
@@ -0,0 +1 @@
+[a]
diff --git a/test-suite/tests/valid/table-multi-empty.json b/test-suite/tests/valid/table-multi-empty.json
new file mode 100644
index 0000000..a6e17c9
--- /dev/null
+++ b/test-suite/tests/valid/table-multi-empty.json
@@ -0,0 +1,5 @@
+{
+ "a": { "b": {} },
+ "b": {},
+ "c": { "a": {} }
+}
diff --git a/test-suite/tests/valid/table-multi-empty.toml b/test-suite/tests/valid/table-multi-empty.toml
new file mode 100644
index 0000000..2266ed2
--- /dev/null
+++ b/test-suite/tests/valid/table-multi-empty.toml
@@ -0,0 +1,5 @@
+[a]
+[a.b]
+[b]
+[c]
+[c.a]
diff --git a/test-suite/tests/valid/table-sub-empty.json b/test-suite/tests/valid/table-sub-empty.json
new file mode 100644
index 0000000..9787770
--- /dev/null
+++ b/test-suite/tests/valid/table-sub-empty.json
@@ -0,0 +1,3 @@
+{
+ "a": { "b": {} }
+}
diff --git a/test-suite/tests/valid/table-sub-empty.toml b/test-suite/tests/valid/table-sub-empty.toml
new file mode 100644
index 0000000..70b7fe1
--- /dev/null
+++ b/test-suite/tests/valid/table-sub-empty.toml
@@ -0,0 +1,2 @@
+[a]
+[a.b]
diff --git a/test-suite/tests/valid/table-whitespace.json b/test-suite/tests/valid/table-whitespace.json
new file mode 100644
index 0000000..3a73ec8
--- /dev/null
+++ b/test-suite/tests/valid/table-whitespace.json
@@ -0,0 +1,3 @@
+{
+ "valid key": {}
+}
diff --git a/test-suite/tests/valid/table-whitespace.toml b/test-suite/tests/valid/table-whitespace.toml
new file mode 100644
index 0000000..daf881d
--- /dev/null
+++ b/test-suite/tests/valid/table-whitespace.toml
@@ -0,0 +1 @@
+["valid key"]
diff --git a/test-suite/tests/valid/table-with-pound.json b/test-suite/tests/valid/table-with-pound.json
new file mode 100644
index 0000000..5e594e4
--- /dev/null
+++ b/test-suite/tests/valid/table-with-pound.json
@@ -0,0 +1,5 @@
+{
+ "key#group": {
+ "answer": {"type": "integer", "value": "42"}
+ }
+}
diff --git a/test-suite/tests/valid/table-with-pound.toml b/test-suite/tests/valid/table-with-pound.toml
new file mode 100644
index 0000000..33f2c4f
--- /dev/null
+++ b/test-suite/tests/valid/table-with-pound.toml
@@ -0,0 +1,2 @@
+["key#group"]
+answer = 42
diff --git a/test-suite/tests/valid/unicode-escape.json b/test-suite/tests/valid/unicode-escape.json
new file mode 100644
index 0000000..32948c6
--- /dev/null
+++ b/test-suite/tests/valid/unicode-escape.json
@@ -0,0 +1,5 @@
+{
+ "answer1": {"type": "string", "value": "\u000B"},
+ "answer4": {"type": "string", "value": "\u03B4α"},
+ "answer8": {"type": "string", "value": "\u03B4β"}
+}
diff --git a/test-suite/tests/valid/unicode-escape.toml b/test-suite/tests/valid/unicode-escape.toml
new file mode 100644
index 0000000..c0d5a25
--- /dev/null
+++ b/test-suite/tests/valid/unicode-escape.toml
@@ -0,0 +1,3 @@
+answer1 = "\u000B"
+answer4 = "\u03B4α"
+answer8 = "\U000003B4β"
diff --git a/test-suite/tests/valid/unicode-literal.json b/test-suite/tests/valid/unicode-literal.json
new file mode 100644
index 0000000..00aa2f8
--- /dev/null
+++ b/test-suite/tests/valid/unicode-literal.json
@@ -0,0 +1,3 @@
+{
+ "answer": {"type": "string", "value": "δ"}
+}
diff --git a/test-suite/tests/valid/unicode-literal.toml b/test-suite/tests/valid/unicode-literal.toml
new file mode 100644
index 0000000..c65723c
--- /dev/null
+++ b/test-suite/tests/valid/unicode-literal.toml
@@ -0,0 +1 @@
+answer = "δ"