toml-rb-hs 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- data.tar.gz.sig +0 -0
- data/README.md +101 -0
- data/Rakefile +6 -0
- data/lib/toml-rb.rb +106 -0
- data/lib/toml-rb/array.rb +14 -0
- data/lib/toml-rb/dumper.rb +103 -0
- data/lib/toml-rb/errors.rb +17 -0
- data/lib/toml-rb/grammars/array.citrus +39 -0
- data/lib/toml-rb/grammars/document.citrus +40 -0
- data/lib/toml-rb/grammars/helper.citrus +17 -0
- data/lib/toml-rb/grammars/primitive.citrus +119 -0
- data/lib/toml-rb/inline_table.rb +72 -0
- data/lib/toml-rb/keygroup.rb +41 -0
- data/lib/toml-rb/keyvalue.rb +49 -0
- data/lib/toml-rb/parser.rb +36 -0
- data/lib/toml-rb/string.rb +68 -0
- data/lib/toml-rb/table_array.rb +50 -0
- data/test/dumper_test.rb +100 -0
- data/test/errors_test.rb +94 -0
- data/test/example-v0.4.0.toml +244 -0
- data/test/example.toml +49 -0
- data/test/grammar_test.rb +246 -0
- data/test/hard_example.toml +46 -0
- data/test/helper.rb +8 -0
- data/test/toml_examples.rb +203 -0
- data/test/toml_test.rb +131 -0
- data/toml-rb-hs.gemspec +24 -0
- metadata +142 -0
- metadata.gz.sig +1 -0
data/test/errors_test.rb
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
unless defined? require_relative
|
2
|
+
def require_relative(path)
|
3
|
+
require path
|
4
|
+
end
|
5
|
+
end
|
6
|
+
|
7
|
+
require_relative 'helper'
|
8
|
+
|
9
|
+
class ErrorsTest < Minitest::Test
|
10
|
+
def test_text_after_keygroup
|
11
|
+
str = "[error] if you didn't catch this, your parser is broken"
|
12
|
+
assert_raises(TomlRB::ParseError) { TomlRB.parse(str) }
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_text_after_string
|
16
|
+
str = 'string = "Anything other than tabs, spaces and newline after a '
|
17
|
+
str += 'keygroup or key value pair has ended should produce an error '
|
18
|
+
str += 'unless it is a comment" like this'
|
19
|
+
|
20
|
+
assert_raises(TomlRB::ParseError) { TomlRB.parse(str) }
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_multiline_array_bad_string
|
24
|
+
str = <<-EOS
|
25
|
+
array = [
|
26
|
+
"This might most likely happen in multiline arrays",
|
27
|
+
Like here,
|
28
|
+
"or here,
|
29
|
+
and here"
|
30
|
+
] End of array comment, forgot the #
|
31
|
+
EOS
|
32
|
+
|
33
|
+
assert_raises(TomlRB::ParseError) { TomlRB.parse(str) }
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_multiline_array_string_not_ended
|
37
|
+
str = <<-EOS
|
38
|
+
array = [
|
39
|
+
"This might most likely happen in multiline arrays",
|
40
|
+
"or here,
|
41
|
+
and here"
|
42
|
+
] End of array comment, forgot the #
|
43
|
+
EOS
|
44
|
+
|
45
|
+
assert_raises(TomlRB::ParseError) { TomlRB.parse(str) }
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_text_after_multiline_array
|
49
|
+
str = <<-EOS
|
50
|
+
array = [
|
51
|
+
"This might most likely happen in multiline arrays",
|
52
|
+
"or here",
|
53
|
+
"and here"
|
54
|
+
] End of array comment, forgot the #
|
55
|
+
EOS
|
56
|
+
|
57
|
+
assert_raises(TomlRB::ParseError) { TomlRB.parse(str) }
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_text_after_number
|
61
|
+
str = 'number = 3.14 pi <--again forgot the #'
|
62
|
+
assert_raises(TomlRB::ParseError) { TomlRB.parse(str) }
|
63
|
+
end
|
64
|
+
|
65
|
+
def test_value_overwrite
|
66
|
+
str = "a = 1\na = 2"
|
67
|
+
e = assert_raises(TomlRB::ValueOverwriteError) { TomlRB.parse(str) }
|
68
|
+
assert_equal "Key \"a\" is defined more than once", e.message
|
69
|
+
assert_equal "a", e.key
|
70
|
+
|
71
|
+
str = "a = false\na = true"
|
72
|
+
assert_raises(TomlRB::ValueOverwriteError) { TomlRB.parse(str) }
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_table_overwrite
|
76
|
+
str = "[a]\nb=1\n[a]\nc=2"
|
77
|
+
e = assert_raises(TomlRB::ValueOverwriteError) { TomlRB.parse(str) }
|
78
|
+
assert_equal "Key \"a\" is defined more than once", e.message
|
79
|
+
|
80
|
+
str = "[a]\nb=1\n[a]\nb=1"
|
81
|
+
e = assert_raises(TomlRB::ValueOverwriteError) { TomlRB.parse(str) }
|
82
|
+
assert_equal "Key \"a\" is defined more than once", e.message
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_value_overwrite_with_table
|
86
|
+
str = "[a]\nb=1\n[a.b]\nc=2"
|
87
|
+
e = assert_raises(TomlRB::ValueOverwriteError) { TomlRB.parse(str) }
|
88
|
+
assert_equal "Key \"b\" is defined more than once", e.message
|
89
|
+
|
90
|
+
str = "[a]\nb=1\n[a.b.c]\nd=3"
|
91
|
+
e = assert_raises(TomlRB::ValueOverwriteError) { TomlRB.parse(str) }
|
92
|
+
assert_equal "Key \"b\" is defined more than once", e.message
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,244 @@
|
|
1
|
+
################################################################################
|
2
|
+
## Comment
|
3
|
+
|
4
|
+
# Speak your mind with the hash symbol. They go from the symbol to the end of
|
5
|
+
# the line.
|
6
|
+
|
7
|
+
|
8
|
+
################################################################################
|
9
|
+
## Table
|
10
|
+
|
11
|
+
# Tables (also known as hash tables or dictionaries) are collections of
|
12
|
+
# key/value pairs. They appear in square brackets on a line by themselves.
|
13
|
+
|
14
|
+
[table]
|
15
|
+
|
16
|
+
key = "value" # Yeah, you can do this.
|
17
|
+
|
18
|
+
# Nested tables are denoted by table names with dots in them. Name your tables
|
19
|
+
# whatever crap you please, just don't use #, ., [ or ].
|
20
|
+
|
21
|
+
[table.subtable]
|
22
|
+
|
23
|
+
key = "another value"
|
24
|
+
|
25
|
+
# You don't need to specify all the super-tables if you don't want to. TomlRB
|
26
|
+
# knows how to do it for you.
|
27
|
+
|
28
|
+
# [x] you
|
29
|
+
# [x.y] don't
|
30
|
+
# [x.y.z] need these
|
31
|
+
[x.y.z.w] # for this to work
|
32
|
+
|
33
|
+
|
34
|
+
################################################################################
|
35
|
+
## Inline Table
|
36
|
+
|
37
|
+
# Inline tables provide a more compact syntax for expressing tables. They are
|
38
|
+
# especially useful for grouped data that can otherwise quickly become verbose.
|
39
|
+
# Inline tables are enclosed in curly braces `{` and `}`. No newlines are
|
40
|
+
# allowed between the curly braces unless they are valid within a value.
|
41
|
+
|
42
|
+
[table.inline]
|
43
|
+
|
44
|
+
name = { first = "Tom", last = "Preston-Werner" }
|
45
|
+
point = { x = 1, y = 2 }
|
46
|
+
|
47
|
+
|
48
|
+
################################################################################
|
49
|
+
## String
|
50
|
+
|
51
|
+
# There are four ways to express strings: basic, multi-line basic, literal, and
|
52
|
+
# multi-line literal. All strings must contain only valid UTF-8 characters.
|
53
|
+
|
54
|
+
[string.basic]
|
55
|
+
|
56
|
+
basic = "I'm a string. \"You can quote me\". Name\tJos\u00E9\nLocation\tSF."
|
57
|
+
|
58
|
+
[string.multiline]
|
59
|
+
|
60
|
+
# The following strings are byte-for-byte equivalent:
|
61
|
+
key1 = "One\nTwo"
|
62
|
+
key2 = """One\nTwo"""
|
63
|
+
key3 = """
|
64
|
+
One
|
65
|
+
Two"""
|
66
|
+
|
67
|
+
[string.multiline.continued]
|
68
|
+
|
69
|
+
# The following strings are byte-for-byte equivalent:
|
70
|
+
key1 = "The quick brown fox jumps over the lazy dog."
|
71
|
+
|
72
|
+
key2 = """
|
73
|
+
The quick brown \
|
74
|
+
|
75
|
+
|
76
|
+
fox jumps over \
|
77
|
+
the lazy dog."""
|
78
|
+
|
79
|
+
key3 = """\
|
80
|
+
The quick brown \
|
81
|
+
fox jumps over \
|
82
|
+
the lazy dog.\
|
83
|
+
"""
|
84
|
+
|
85
|
+
[string.literal]
|
86
|
+
|
87
|
+
# What you see is what you get.
|
88
|
+
winpath = 'C:\Users\nodejs\templates'
|
89
|
+
winpath2 = '\\ServerX\admin$\system32\'
|
90
|
+
quoted = 'Tom "Dubs" Preston-Werner'
|
91
|
+
regex = '<\i\c*\s*>'
|
92
|
+
|
93
|
+
|
94
|
+
[string.literal.multiline]
|
95
|
+
|
96
|
+
regex2 = '''I [dw]on't need \d{2} apples'''
|
97
|
+
lines = '''
|
98
|
+
The first newline is
|
99
|
+
trimmed in raw strings.
|
100
|
+
All other whitespace
|
101
|
+
is preserved.
|
102
|
+
'''
|
103
|
+
|
104
|
+
|
105
|
+
################################################################################
|
106
|
+
## Integer
|
107
|
+
|
108
|
+
# Integers are whole numbers. Positive numbers may be prefixed with a plus sign.
|
109
|
+
# Negative numbers are prefixed with a minus sign.
|
110
|
+
|
111
|
+
[integer]
|
112
|
+
|
113
|
+
key1 = +99
|
114
|
+
key2 = 42
|
115
|
+
key3 = 0
|
116
|
+
key4 = -17
|
117
|
+
|
118
|
+
[integer.underscores]
|
119
|
+
|
120
|
+
# For large numbers, you may use underscores to enhance readability. Each
|
121
|
+
# underscore must be surrounded by at least one digit.
|
122
|
+
key1 = 1_000
|
123
|
+
key2 = 5_349_221
|
124
|
+
key3 = 1_2_3_4_5 # valid but inadvisable
|
125
|
+
|
126
|
+
|
127
|
+
################################################################################
|
128
|
+
## Float
|
129
|
+
|
130
|
+
# A float consists of an integer part (which may be prefixed with a plus or
|
131
|
+
# minus sign) followed by a fractional part and/or an exponent part.
|
132
|
+
|
133
|
+
[float.fractional]
|
134
|
+
|
135
|
+
key1 = +1.0
|
136
|
+
key2 = 3.1415
|
137
|
+
key3 = -0.01
|
138
|
+
|
139
|
+
[float.exponent]
|
140
|
+
|
141
|
+
key1 = 5e+22
|
142
|
+
key2 = 1e6
|
143
|
+
key3 = -2E-2
|
144
|
+
|
145
|
+
[float.both]
|
146
|
+
|
147
|
+
key = 6.626e-34
|
148
|
+
|
149
|
+
[float.underscores]
|
150
|
+
|
151
|
+
key1 = 9_224_617.445_991_228_313
|
152
|
+
key2 = 1e1_000
|
153
|
+
|
154
|
+
|
155
|
+
################################################################################
|
156
|
+
## Boolean
|
157
|
+
|
158
|
+
# Booleans are just the tokens you're used to. Always lowercase.
|
159
|
+
|
160
|
+
[boolean]
|
161
|
+
|
162
|
+
True = true
|
163
|
+
False = false
|
164
|
+
|
165
|
+
|
166
|
+
################################################################################
|
167
|
+
## Datetime
|
168
|
+
|
169
|
+
# Datetimes are RFC 3339 dates.
|
170
|
+
|
171
|
+
[datetime]
|
172
|
+
|
173
|
+
key1 = 1979-05-27T07:32:00Z
|
174
|
+
key2 = 1979-05-27T00:32:00-07:00
|
175
|
+
key3 = 1979-05-27T00:32:00.999999-07:00
|
176
|
+
|
177
|
+
|
178
|
+
################################################################################
|
179
|
+
## Array
|
180
|
+
|
181
|
+
# Arrays are square brackets with other primitives inside. Whitespace is
|
182
|
+
# ignored. Elements are separated by commas. Data types may not be mixed.
|
183
|
+
|
184
|
+
[array]
|
185
|
+
|
186
|
+
key1 = [ 1, 2, 3 ]
|
187
|
+
key2 = [ "red", "yellow", "green" ]
|
188
|
+
key3 = [ [ 1, 2 ], [3, 4, 5] ]
|
189
|
+
key4 = [ [ 1, 2 ], ["a", "b", "c"] ] # this is ok
|
190
|
+
|
191
|
+
# Arrays can also be multiline. So in addition to ignoring whitespace, arrays
|
192
|
+
# also ignore newlines between the brackets. Terminating commas are ok before
|
193
|
+
# the closing bracket.
|
194
|
+
|
195
|
+
key5 = [
|
196
|
+
1, 2, 3
|
197
|
+
]
|
198
|
+
key6 = [
|
199
|
+
1,
|
200
|
+
2, # this is ok
|
201
|
+
]
|
202
|
+
|
203
|
+
|
204
|
+
################################################################################
|
205
|
+
## Array of Tables
|
206
|
+
|
207
|
+
# These can be expressed by using a table name in double brackets. Each table
|
208
|
+
# with the same double bracketed name will be an element in the array. The
|
209
|
+
# tables are inserted in the order encountered.
|
210
|
+
|
211
|
+
[[products]]
|
212
|
+
|
213
|
+
name = "Hammer"
|
214
|
+
sku = 738594937
|
215
|
+
|
216
|
+
[[products]]
|
217
|
+
|
218
|
+
[[products]]
|
219
|
+
|
220
|
+
name = "Nail"
|
221
|
+
sku = 284758393
|
222
|
+
color = "gray"
|
223
|
+
|
224
|
+
|
225
|
+
# You can create nested arrays of tables as well.
|
226
|
+
|
227
|
+
[[fruit]]
|
228
|
+
name = "apple"
|
229
|
+
|
230
|
+
[fruit.physical]
|
231
|
+
color = "red"
|
232
|
+
shape = "round"
|
233
|
+
|
234
|
+
[[fruit.variety]]
|
235
|
+
name = "red delicious"
|
236
|
+
|
237
|
+
[[fruit.variety]]
|
238
|
+
name = "granny smith"
|
239
|
+
|
240
|
+
[[fruit]]
|
241
|
+
name = "banana"
|
242
|
+
|
243
|
+
[[fruit.variety]]
|
244
|
+
name = "plantain"
|
data/test/example.toml
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# This is a TomlRB document. Boom.
|
2
|
+
|
3
|
+
title = "TomlRB Example"
|
4
|
+
|
5
|
+
[owner]
|
6
|
+
name = "Tom Preston-Werner"
|
7
|
+
organization = "GitHub"
|
8
|
+
bio = "GitHub Cofounder & CEO\nLikes tater tots and beer."
|
9
|
+
dob = 1979-05-27T07:32:00Z # First class dates? Why not?
|
10
|
+
|
11
|
+
[database]
|
12
|
+
server = "192.168.1.1"
|
13
|
+
ports = [ 8001, 8001, 8002 ]
|
14
|
+
connection_max = 5000
|
15
|
+
enabled = true
|
16
|
+
|
17
|
+
[servers]
|
18
|
+
|
19
|
+
# You can indent as you please. Tabs or spaces. TomlRB don't care.
|
20
|
+
[servers.alpha]
|
21
|
+
ip = "10.0.0.1"
|
22
|
+
dc = "eqdc10"
|
23
|
+
|
24
|
+
[servers.beta]
|
25
|
+
ip = "10.0.0.2"
|
26
|
+
dc = "eqdc10"
|
27
|
+
|
28
|
+
[clients]
|
29
|
+
data = [ ["gamma", "delta"], [1, 2] ]
|
30
|
+
|
31
|
+
# Line breaks are OK when inside arrays
|
32
|
+
hosts = [
|
33
|
+
"alpha",
|
34
|
+
"omega"
|
35
|
+
]
|
36
|
+
|
37
|
+
[amqp]
|
38
|
+
exchange = {durable = true, auto_delete = false}
|
39
|
+
|
40
|
+
[[products]]
|
41
|
+
name = "Hammer"
|
42
|
+
sku = 738594937
|
43
|
+
|
44
|
+
[[products]]
|
45
|
+
|
46
|
+
[[products]]
|
47
|
+
name = "Nail"
|
48
|
+
sku = 284758393
|
49
|
+
color = "gray"
|
@@ -0,0 +1,246 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
unless defined? require_relative
|
4
|
+
def require_relative(path)
|
5
|
+
require path
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
require_relative 'helper'
|
10
|
+
|
11
|
+
class GrammarTest < Minitest::Test
|
12
|
+
def test_comment
|
13
|
+
match = TomlRB::Document.parse(' # A comment', root: :comment)
|
14
|
+
assert_equal(nil, match.value)
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_key
|
18
|
+
match = TomlRB::Document.parse('bad_key-', root: :key)
|
19
|
+
assert_equal('bad_key-', match.value)
|
20
|
+
|
21
|
+
match = TomlRB::Document.parse('"123.ʎǝʞ.#?"', root: :key)
|
22
|
+
assert_equal('123.ʎǝʞ.#?', match.value)
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_keygroup
|
26
|
+
indentation_alternatives_for('[akey]') do |str|
|
27
|
+
match = TomlRB::Document.parse(str, root: :keygroup)
|
28
|
+
assert_equal(TomlRB::Keygroup, match.value.class)
|
29
|
+
assert_equal(['akey'], match.value.instance_variable_get('@nested_keys'))
|
30
|
+
end
|
31
|
+
|
32
|
+
match = TomlRB::Document.parse('[owner.emancu]', root: :keygroup)
|
33
|
+
assert_equal(%w(owner emancu),
|
34
|
+
match.value.instance_variable_get('@nested_keys'))
|
35
|
+
|
36
|
+
match = TomlRB::Document.parse('["owner.emancu"]', root: :keygroup)
|
37
|
+
assert_equal(%w(owner.emancu),
|
38
|
+
match.value.instance_variable_get('@nested_keys'))
|
39
|
+
|
40
|
+
match = TomlRB::Document.parse('["first key"."second key"]', root: :keygroup)
|
41
|
+
assert_equal(['first key', 'second key'],
|
42
|
+
match.value.instance_variable_get('@nested_keys'))
|
43
|
+
|
44
|
+
match = TomlRB::Document.parse('[ owner . emancu ]', root: :keygroup)
|
45
|
+
assert_equal(%w(owner emancu),
|
46
|
+
match.value.instance_variable_get('@nested_keys'))
|
47
|
+
|
48
|
+
assert_raises Citrus::ParseError do
|
49
|
+
TomlRB::Document.parse('[ owner emancu ]', root: :keygroup)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_keyvalue
|
54
|
+
indentation_alternatives_for('key = "value"') do |str|
|
55
|
+
match = TomlRB::Document.parse(str, root: :keyvalue)
|
56
|
+
assert_equal(TomlRB::Keyvalue, match.value.class)
|
57
|
+
|
58
|
+
keyvalue = match.value
|
59
|
+
assert_equal('key', keyvalue.instance_variable_get('@key'))
|
60
|
+
assert_equal('value', keyvalue.instance_variable_get('@value'))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_string
|
65
|
+
match = TomlRB::Document.parse('"TomlRB-Example, should work."', root: :string)
|
66
|
+
assert_equal('TomlRB-Example, should work.', match.value)
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_multiline_string
|
70
|
+
match = TomlRB::Document.parse('"""\tOne\nTwo"""', root: :multiline_string)
|
71
|
+
assert_equal "\tOne\nTwo", match.value
|
72
|
+
|
73
|
+
to_parse = '"""\
|
74
|
+
One \
|
75
|
+
Two\
|
76
|
+
"""'
|
77
|
+
|
78
|
+
match = TomlRB::Document.parse(to_parse, root: :multiline_string)
|
79
|
+
assert_equal "One Two", match.value
|
80
|
+
end
|
81
|
+
|
82
|
+
def test_empty_multiline_string
|
83
|
+
to_parse = '""""""'
|
84
|
+
|
85
|
+
match = TomlRB::Document.parse(to_parse, root: :multiline_string)
|
86
|
+
assert_equal '', match.value
|
87
|
+
end
|
88
|
+
|
89
|
+
def test_special_characters
|
90
|
+
match = TomlRB::Document.parse('"\0 \" \t \n \r"', root: :string)
|
91
|
+
assert_equal("\0 \" \t \n \r", match.value)
|
92
|
+
|
93
|
+
match = TomlRB::Document.parse('"C:\\\\Documents\\\\nada.exe"', root: :string)
|
94
|
+
assert_equal('C:\\Documents\\nada.exe', match.value)
|
95
|
+
end
|
96
|
+
|
97
|
+
def test_bool
|
98
|
+
match = TomlRB::Document.parse('true', root: :bool)
|
99
|
+
assert_equal(true, match.value)
|
100
|
+
|
101
|
+
match = TomlRB::Document.parse('false', root: :bool)
|
102
|
+
assert_equal(false, match.value)
|
103
|
+
end
|
104
|
+
|
105
|
+
def test_integer
|
106
|
+
match = TomlRB::Document.parse('26', root: :number)
|
107
|
+
assert_equal(26, match.value)
|
108
|
+
|
109
|
+
match = TomlRB::Document.parse('1_200_000_999', root: :number)
|
110
|
+
assert_equal(1_200_000_999, match.value)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_float
|
114
|
+
match = TomlRB::Document.parse('1.69', root: :number)
|
115
|
+
assert_equal(1.69, match.value)
|
116
|
+
|
117
|
+
match = TomlRB::Document.parse('1_000.69', root: :number)
|
118
|
+
assert_equal(1000.69, match.value)
|
119
|
+
|
120
|
+
match = TomlRB::Document.parse('1e6', root: :number)
|
121
|
+
assert_equal(1e6, match.value)
|
122
|
+
|
123
|
+
match = TomlRB::Document.parse('1.02e-46', root: :number)
|
124
|
+
assert_equal(1.02e-46, match.value)
|
125
|
+
|
126
|
+
match = TomlRB::Document.parse('+1e4_000_000', root: :number)
|
127
|
+
assert_equal(1e4_000_000, match.value)
|
128
|
+
end
|
129
|
+
|
130
|
+
def test_signed_numbers
|
131
|
+
match = TomlRB::Document.parse('+26', root: :number)
|
132
|
+
assert_equal(26, match.value)
|
133
|
+
|
134
|
+
match = TomlRB::Document.parse('-26', root: :number)
|
135
|
+
assert_equal(-26, match.value)
|
136
|
+
|
137
|
+
match = TomlRB::Document.parse('1.69', root: :number)
|
138
|
+
assert_equal(1.69, match.value)
|
139
|
+
|
140
|
+
match = TomlRB::Document.parse('-1.69', root: :number)
|
141
|
+
assert_equal(-1.69, match.value)
|
142
|
+
end
|
143
|
+
|
144
|
+
def test_expressions_with_comments
|
145
|
+
match = TomlRB::Document.parse('[shouldwork] # with comment', root: :keygroup)
|
146
|
+
assert_equal(['shouldwork'],
|
147
|
+
match.value.instance_variable_get('@nested_keys'))
|
148
|
+
|
149
|
+
match = TomlRB::Document.parse('works = true # with comment', root: :keyvalue).value
|
150
|
+
assert_equal('works', match.instance_variable_get('@key'))
|
151
|
+
assert_equal(true, match.instance_variable_get('@value'))
|
152
|
+
end
|
153
|
+
|
154
|
+
def test_array
|
155
|
+
match = TomlRB::Document.parse('[]', root: :array)
|
156
|
+
assert_equal([], match.value)
|
157
|
+
|
158
|
+
match = TomlRB::Document.parse('[ 2, 4]', root: :array)
|
159
|
+
assert_equal([2, 4], match.value)
|
160
|
+
|
161
|
+
match = TomlRB::Document.parse('[ 2.4, 4.72]', root: :array)
|
162
|
+
assert_equal([2.4, 4.72], match.value)
|
163
|
+
|
164
|
+
match = TomlRB::Document.parse('[ "hey", "TomlRB"]', root: :array)
|
165
|
+
assert_equal(%w(hey TomlRB), match.value)
|
166
|
+
|
167
|
+
match = TomlRB::Document.parse('[ ["hey", "TomlRB"], [2,4] ]', root: :array)
|
168
|
+
assert_equal([%w(hey TomlRB), [2, 4]], match.value)
|
169
|
+
|
170
|
+
match = TomlRB::Document.parse('[ { one = 1 }, { two = 2, three = 3} ]',
|
171
|
+
root: :inline_table_array)
|
172
|
+
assert_equal([{ 'one' => 1 }, { 'two' => 2, 'three' => 3 }], match.value)
|
173
|
+
end
|
174
|
+
|
175
|
+
def test_empty_array
|
176
|
+
# test that [] is parsed as array and not as inline table array
|
177
|
+
match = TomlRB::Document.parse("a = []", root: :keyvalue).value
|
178
|
+
assert_equal [], match.value
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_multiline_array
|
182
|
+
multiline_array = "[ \"hey\",\n \"ho\",\n\t \"lets\", \"go\",\n ]"
|
183
|
+
match = TomlRB::Document.parse(multiline_array, root: :array)
|
184
|
+
assert_equal(%w(hey ho lets go), match.value)
|
185
|
+
|
186
|
+
multiline_array = "[\n#1,\n2,\n# 3\n]"
|
187
|
+
match = TomlRB::Document.parse(multiline_array, root: :array)
|
188
|
+
assert_equal([2], match.value)
|
189
|
+
|
190
|
+
multiline_array = "[\n# comment\n#, more comments\n4]"
|
191
|
+
match = TomlRB::Document.parse(multiline_array, root: :array)
|
192
|
+
assert_equal([4], match.value)
|
193
|
+
|
194
|
+
multiline_array = "[\n 1,\n # 2,\n 3 ,\n]"
|
195
|
+
match = TomlRB::Document.parse(multiline_array, root: :array)
|
196
|
+
assert_equal([1, 3], match.value)
|
197
|
+
|
198
|
+
multiline_array = "[\n 1 , # useless comment\n # 2,\n 3 #other comment\n]"
|
199
|
+
match = TomlRB::Document.parse(multiline_array, root: :array)
|
200
|
+
assert_equal([1, 3], match.value)
|
201
|
+
end
|
202
|
+
|
203
|
+
# Dates are really hard to test from JSON, due the imposibility to represent
|
204
|
+
# datetimes without quotes.
|
205
|
+
def test_datetime
|
206
|
+
match = TomlRB::Document.parse('1986-08-28T15:15:00Z', root: :datetime)
|
207
|
+
assert_equal(Time.utc(1986, 8, 28, 15, 15), match.value)
|
208
|
+
|
209
|
+
match = TomlRB::Document.parse('1986-08-28T15:15:00-03:00', root: :datetime)
|
210
|
+
assert_equal(Time.utc(1986, 8, 28, 18, 15), match.value)
|
211
|
+
|
212
|
+
match = TomlRB::Document.parse('1986-08-28T15:15:00.123-03:00', root: :datetime)
|
213
|
+
assert_equal(Time.utc(1986, 8, 28, 18, 15, 0.123), match.value)
|
214
|
+
|
215
|
+
match = TomlRB::Document.parse('1986-08-28', root: :datetime)
|
216
|
+
assert_equal(Time.utc(1986, 8, 28, 0, 0, 0), match.value)
|
217
|
+
|
218
|
+
match = TomlRB::Document.parse('1986-08-28T15:15:00', root: :datetime)
|
219
|
+
assert_equal(Time.utc(1986, 8, 28, 15, 15), match.value)
|
220
|
+
|
221
|
+
match = TomlRB::Document.parse('1986-08-28T15:15:00.999999', root: :datetime)
|
222
|
+
assert_equal(Time.utc(1986, 8, 28, 15, 15, 0.999999), match.value)
|
223
|
+
end
|
224
|
+
|
225
|
+
def test_inline_table
|
226
|
+
match = TomlRB::Document.parse('{ }', root: :inline_table)
|
227
|
+
assert_equal({}, match.value.value)
|
228
|
+
|
229
|
+
match = TomlRB::Document.parse('{ simple = true, params = 2 }', root: :inline_table)
|
230
|
+
assert_equal({ 'simple' => true, 'params' => 2 }, match.value.value)
|
231
|
+
|
232
|
+
match = TomlRB::Document.parse('{ nest = { really = { hard = true } } }',
|
233
|
+
root: :inline_table)
|
234
|
+
assert_equal({ 'nest' => { 'really' => { 'hard' => true } } }, match.value.value)
|
235
|
+
assert_equal({ nest: { really: { hard: true } } }, match.value.value(true))
|
236
|
+
end
|
237
|
+
|
238
|
+
private
|
239
|
+
|
240
|
+
# Creates all the alternatives of valid indentations to test
|
241
|
+
def indentation_alternatives_for(str)
|
242
|
+
[str, " #{str}", "\t#{str}", "\t\t#{str}"].each do |alternative|
|
243
|
+
yield(alternative)
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|