hocon 0.9.5 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -2
- data/README.md +22 -10
- data/lib/hocon.rb +9 -3
- data/lib/hocon/config_factory.rb +4 -0
- data/lib/hocon/config_value_factory.rb +13 -2
- data/lib/hocon/impl/config_reference.rb +5 -2
- data/lib/hocon/impl/simple_config_origin.rb +1 -1
- data/spec/fixtures/parse_render/example1/input.conf +21 -0
- data/spec/fixtures/parse_render/example1/output.conf +26 -0
- data/spec/fixtures/parse_render/example1/output_nocomments.conf +17 -0
- data/spec/fixtures/parse_render/example2/input.conf +10 -0
- data/spec/fixtures/parse_render/example2/output.conf +17 -0
- data/spec/fixtures/parse_render/example2/output_nocomments.conf +17 -0
- data/spec/fixtures/parse_render/example3/input.conf +2 -0
- data/spec/fixtures/parse_render/example3/output.conf +2 -0
- data/spec/fixtures/parse_render/example4/input.json +6 -0
- data/spec/fixtures/parse_render/example4/output.conf +6 -0
- data/spec/fixtures/test_utils/resources/bom.conf +2 -0
- data/spec/fixtures/test_utils/resources/cycle.conf +1 -0
- data/spec/fixtures/test_utils/resources/file-include.conf +5 -0
- data/spec/fixtures/test_utils/resources/include-from-list.conf +4 -0
- data/spec/fixtures/test_utils/resources/subdir/bar.conf +1 -0
- data/spec/fixtures/test_utils/resources/subdir/baz.conf +1 -0
- data/spec/fixtures/test_utils/resources/subdir/foo.conf +5 -0
- data/spec/fixtures/test_utils/resources/test01.conf +80 -0
- data/spec/fixtures/test_utils/resources/test01.json +4 -0
- data/spec/fixtures/test_utils/resources/test03.conf +36 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/test_utils.rb +757 -0
- data/spec/unit/typesafe/config/concatenation_spec.rb +417 -0
- data/spec/unit/typesafe/config/conf_parser_spec.rb +822 -0
- data/spec/unit/typesafe/config/config_document_parser_spec.rb +494 -0
- data/spec/unit/typesafe/config/config_document_spec.rb +576 -0
- data/spec/unit/typesafe/config/config_factory_spec.rb +120 -0
- data/spec/unit/typesafe/config/config_node_spec.rb +552 -0
- data/spec/unit/typesafe/config/config_value_factory_spec.rb +85 -0
- data/spec/unit/typesafe/config/config_value_spec.rb +935 -0
- data/spec/unit/typesafe/config/hocon_spec.rb +54 -0
- data/spec/unit/typesafe/config/path_spec.rb +261 -0
- data/spec/unit/typesafe/config/public_api_spec.rb +520 -0
- data/spec/unit/typesafe/config/simple_config_spec.rb +112 -0
- data/spec/unit/typesafe/config/token_spec.rb +188 -0
- data/spec/unit/typesafe/config/tokenizer_spec.rb +801 -0
- metadata +39 -3
@@ -0,0 +1,494 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require 'hocon'
|
5
|
+
require 'hocon/impl/config_document_parser'
|
6
|
+
require 'test_utils'
|
7
|
+
|
8
|
+
describe "ConfigDocumentParser" do
|
9
|
+
ConfigDocumentParser = Hocon::Impl::ConfigDocumentParser
|
10
|
+
ConfigParseOptions = Hocon::ConfigParseOptions
|
11
|
+
ConfigSyntax = Hocon::ConfigSyntax
|
12
|
+
shared_examples_for "parse test" do
|
13
|
+
it "should correctly render the parsed node" do
|
14
|
+
node = ConfigDocumentParser.parse(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
15
|
+
expect(node.render).to eq(orig_text)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
shared_examples_for "parse JSON failures test" do
|
20
|
+
it "should thrown an exception when parsing invalid JSON" do
|
21
|
+
e = TestUtils.intercept(Hocon::ConfigError) {
|
22
|
+
ConfigDocumentParser.parse(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults.set_syntax(ConfigSyntax::JSON))
|
23
|
+
}
|
24
|
+
expect(e.message).to include(contains_message)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
shared_examples_for "parse simple value test" do
|
29
|
+
it "should correctly parse and render the original text as CONF" do
|
30
|
+
expected_rendered_text = final_text.nil? ? orig_text : final_text
|
31
|
+
node = ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
32
|
+
expect(node.render).to eq(expected_rendered_text)
|
33
|
+
expect(node).to be_a(Hocon::Impl::ConfigNodeSimpleValue)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should correctly parse and render the original text as JSON" do
|
37
|
+
expected_rendered_text = final_text.nil? ? orig_text : final_text
|
38
|
+
nodeJSON = ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults.set_syntax(ConfigSyntax::JSON))
|
39
|
+
expect(nodeJSON.render).to eq(expected_rendered_text)
|
40
|
+
expect(nodeJSON).to be_a(Hocon::Impl::ConfigNodeSimpleValue)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
shared_examples_for "parse complex value test" do
|
45
|
+
it "should correctly parse and render the original text as CONF" do
|
46
|
+
node = ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
47
|
+
expect(node.render).to eq(orig_text)
|
48
|
+
expect(node).to be_a(Hocon::Impl::ConfigNodeComplexValue)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should correctly parse and render the original text as JSON" do
|
52
|
+
nodeJSON = ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults.set_syntax(ConfigSyntax::JSON))
|
53
|
+
expect(nodeJSON.render).to eq(orig_text)
|
54
|
+
expect(nodeJSON).to be_a(Hocon::Impl::ConfigNodeComplexValue)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
shared_examples_for "parse single value invalid JSON test" do
|
59
|
+
it "should correctly parse and render the original text as CONF" do
|
60
|
+
node = ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
61
|
+
expect(node.render).to eq(orig_text)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should throw an exception when parsing the original text as JSON" do
|
65
|
+
e = TestUtils.intercept(Hocon::ConfigError) {
|
66
|
+
ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults.set_syntax(ConfigSyntax::JSON))
|
67
|
+
}
|
68
|
+
expect(e.message).to include(contains_message)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
shared_examples_for "parse leading trailing failure" do
|
73
|
+
it "should throw an exception when parsing an invalid single value" do
|
74
|
+
e = TestUtils.intercept(Hocon::ConfigError) {
|
75
|
+
ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
76
|
+
}
|
77
|
+
expect(e.message).to include("The value from setValue cannot have leading or trailing newlines, whitespace, or comments")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
context "parse_success" do
|
82
|
+
context "simple map with no braces" do
|
83
|
+
let (:orig_text) { "foo:bar" }
|
84
|
+
include_examples "parse test"
|
85
|
+
end
|
86
|
+
|
87
|
+
context "simple map with no braces and whitespace" do
|
88
|
+
let (:orig_text) { " foo : bar " }
|
89
|
+
include_examples "parse test"
|
90
|
+
end
|
91
|
+
|
92
|
+
context "include with no braces" do
|
93
|
+
let (:orig_text) { 'include "foo.conf" ' }
|
94
|
+
include_examples "parse test"
|
95
|
+
end
|
96
|
+
|
97
|
+
context "simple map with no braces and newlines" do
|
98
|
+
let (:orig_text) { " \nfoo:bar\n " }
|
99
|
+
include_examples "parse test"
|
100
|
+
end
|
101
|
+
|
102
|
+
context "map with no braces and all simple types" do
|
103
|
+
let (:orig_text) { '
|
104
|
+
aUnquoted : bar
|
105
|
+
aString = "qux"
|
106
|
+
aNum:123
|
107
|
+
aDouble=123.456
|
108
|
+
aTrue=true
|
109
|
+
aFalse=false
|
110
|
+
aNull=null
|
111
|
+
aSub = ${a.b}
|
112
|
+
include "foo.conf"
|
113
|
+
' }
|
114
|
+
include_examples "parse test"
|
115
|
+
end
|
116
|
+
|
117
|
+
context "empty map" do
|
118
|
+
let (:orig_text) { "{}" }
|
119
|
+
include_examples "parse test"
|
120
|
+
end
|
121
|
+
|
122
|
+
context "simple map with braces" do
|
123
|
+
let (:orig_text) { "{foo:bar}" }
|
124
|
+
include_examples "parse test"
|
125
|
+
end
|
126
|
+
|
127
|
+
context "simple map with braces and whitespace" do
|
128
|
+
let (:orig_text) { "{ foo : bar }" }
|
129
|
+
include_examples "parse test"
|
130
|
+
end
|
131
|
+
|
132
|
+
context "simple map with braces and trailing whitespace" do
|
133
|
+
let (:orig_text) { "{foo:bar} " }
|
134
|
+
include_examples "parse test"
|
135
|
+
end
|
136
|
+
|
137
|
+
context "simple map with braces and include" do
|
138
|
+
let (:orig_text) { '{include "foo.conf"}' }
|
139
|
+
include_examples "parse test"
|
140
|
+
end
|
141
|
+
|
142
|
+
context "simple map with braces and leading/trailing newlines" do
|
143
|
+
let (:orig_text) { "\n{foo:bar}\n" }
|
144
|
+
include_examples "parse test"
|
145
|
+
end
|
146
|
+
|
147
|
+
context "map with braces and all simple types" do
|
148
|
+
let (:orig_text) { '{
|
149
|
+
aUnquoted : bar
|
150
|
+
aString = "qux"
|
151
|
+
aNum:123
|
152
|
+
aDouble=123.456
|
153
|
+
aTrue=true
|
154
|
+
aFalse=false
|
155
|
+
aNull=null
|
156
|
+
aSub = ${a.b}
|
157
|
+
include "foo.conf"
|
158
|
+
}' }
|
159
|
+
include_examples "parse test"
|
160
|
+
end
|
161
|
+
|
162
|
+
context "maps can be nested within other maps" do
|
163
|
+
let(:orig_text) {
|
164
|
+
'
|
165
|
+
foo.bar.baz : {
|
166
|
+
qux : "abcdefg"
|
167
|
+
"abc".def."ghi" : 123
|
168
|
+
abc = { foo:bar }
|
169
|
+
}
|
170
|
+
qux = 123.456
|
171
|
+
'}
|
172
|
+
include_examples "parse test"
|
173
|
+
end
|
174
|
+
|
175
|
+
context "comments can be parsed in maps" do
|
176
|
+
let(:orig_text) {
|
177
|
+
'{
|
178
|
+
foo: bar
|
179
|
+
// This is a comment
|
180
|
+
baz:qux // This is another comment
|
181
|
+
}'}
|
182
|
+
include_examples "parse test"
|
183
|
+
end
|
184
|
+
|
185
|
+
context "empty array" do
|
186
|
+
let (:orig_text) { "[]" }
|
187
|
+
include_examples "parse test"
|
188
|
+
end
|
189
|
+
|
190
|
+
context "single-element array" do
|
191
|
+
let (:orig_text) { "[foo]" }
|
192
|
+
include_examples "parse test"
|
193
|
+
end
|
194
|
+
|
195
|
+
context "trailing comment" do
|
196
|
+
let (:orig_text) { "[foo,]" }
|
197
|
+
include_examples "parse test"
|
198
|
+
end
|
199
|
+
|
200
|
+
context "trailing comment and whitespace" do
|
201
|
+
let (:orig_text) { "[foo,] " }
|
202
|
+
include_examples "parse test"
|
203
|
+
end
|
204
|
+
|
205
|
+
context "leading and trailing whitespace" do
|
206
|
+
let (:orig_text) { " \n[]\n " }
|
207
|
+
include_examples "parse test"
|
208
|
+
end
|
209
|
+
|
210
|
+
context "array with all simple types" do
|
211
|
+
let (:orig_text) { '[foo, bar,"qux", 123,123.456, true,false, null, ${a.b}]' }
|
212
|
+
include_examples "parse test"
|
213
|
+
end
|
214
|
+
|
215
|
+
context "array with all simple types and weird whitespace" do
|
216
|
+
let (:orig_text) { '[foo, bar,"qux" , 123 , 123.456, true,false, null, ${a.b} ]' }
|
217
|
+
include_examples "parse test"
|
218
|
+
end
|
219
|
+
|
220
|
+
context "basic concatenation inside an array" do
|
221
|
+
let (:orig_text) { "[foo bar baz qux]" }
|
222
|
+
include_examples "parse test"
|
223
|
+
end
|
224
|
+
|
225
|
+
context "basic concatenation inside a map" do
|
226
|
+
let (:orig_text) { "{foo: foo bar baz qux}" }
|
227
|
+
include_examples "parse test"
|
228
|
+
end
|
229
|
+
|
230
|
+
context "complex concatenation in an array with multiple elements" do
|
231
|
+
let (:orig_text) { "[abc 123 123.456 null true false [1, 2, 3] {a:b}, 2]" }
|
232
|
+
include_examples "parse test"
|
233
|
+
end
|
234
|
+
|
235
|
+
context "complex node with all types" do
|
236
|
+
let (:orig_text) {
|
237
|
+
'{
|
238
|
+
foo: bar baz qux ernie
|
239
|
+
// The above was a concatenation
|
240
|
+
|
241
|
+
baz = [ abc 123, {a:12
|
242
|
+
b: {
|
243
|
+
c: 13
|
244
|
+
d: {
|
245
|
+
a: 22
|
246
|
+
b: "abcdefg" # this is a comment
|
247
|
+
c: [1, 2, 3]
|
248
|
+
}
|
249
|
+
}
|
250
|
+
}, # this was an object in an array
|
251
|
+
//The above value is a map containing a map containing a map, all in an array
|
252
|
+
22,
|
253
|
+
// The below value is an array contained in another array
|
254
|
+
[1,2,3]]
|
255
|
+
// This is a map with some nested maps and arrays within it, as well as some concatenations
|
256
|
+
qux {
|
257
|
+
baz: abc 123
|
258
|
+
bar: {
|
259
|
+
baz: abcdefg
|
260
|
+
bar: {
|
261
|
+
a: null
|
262
|
+
b: true
|
263
|
+
c: [true false 123, null, [1, 2, 3]]
|
264
|
+
}
|
265
|
+
}
|
266
|
+
}
|
267
|
+
// Did I cover everything?
|
268
|
+
}'
|
269
|
+
}
|
270
|
+
include_examples "parse test"
|
271
|
+
end
|
272
|
+
|
273
|
+
context "can correctly parse a JSON string" do
|
274
|
+
it "should correctly parse and render a JSON string" do
|
275
|
+
orig_text =
|
276
|
+
'{
|
277
|
+
"foo": "bar",
|
278
|
+
"baz": 123,
|
279
|
+
"qux": true,
|
280
|
+
"array": [
|
281
|
+
{"a": true,
|
282
|
+
"c": false},
|
283
|
+
12
|
284
|
+
]
|
285
|
+
}
|
286
|
+
'
|
287
|
+
node = ConfigDocumentParser.parse(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults.set_syntax(ConfigSyntax::JSON))
|
288
|
+
expect(node.render).to eq(orig_text)
|
289
|
+
end
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
context "parse JSON failures" do
|
294
|
+
context "JSON does not support concatenations" do
|
295
|
+
let (:orig_text) { '{ "foo": 123 456 789 } ' }
|
296
|
+
let (:contains_message) { "Expecting close brace } or a comma" }
|
297
|
+
include_examples "parse JSON failures test"
|
298
|
+
end
|
299
|
+
|
300
|
+
context "JSON must begin with { or [" do
|
301
|
+
let (:orig_text) { '"a": 123, "b": 456' }
|
302
|
+
let (:contains_message) { "Document must have an object or array at root" }
|
303
|
+
include_examples "parse JSON failures test"
|
304
|
+
end
|
305
|
+
|
306
|
+
context "JSON does not support unquoted text" do
|
307
|
+
let (:orig_text) { '{"foo": unquotedtext}' }
|
308
|
+
let (:contains_message) { "Token not allowed in valid JSON" }
|
309
|
+
include_examples "parse JSON failures test"
|
310
|
+
end
|
311
|
+
|
312
|
+
context "JSON does not support substitutions" do
|
313
|
+
let (:orig_text) { '{"foo": ${"a.b"}}' }
|
314
|
+
let (:contains_message) { "Substitutions (${} syntax) not allowed in JSON" }
|
315
|
+
include_examples "parse JSON failures test"
|
316
|
+
end
|
317
|
+
|
318
|
+
context "JSON does not support multi-element paths" do
|
319
|
+
let (:orig_text) { '{"foo"."bar": 123}' }
|
320
|
+
let (:contains_message) { "Token not allowed in valid JSON" }
|
321
|
+
include_examples "parse JSON failures test"
|
322
|
+
end
|
323
|
+
|
324
|
+
context "JSON does not support =" do
|
325
|
+
let (:orig_text) { '{"foo"=123}' }
|
326
|
+
let (:contains_message) { "Key '\"foo\"' may not be followed by token: '='" }
|
327
|
+
include_examples "parse JSON failures test"
|
328
|
+
end
|
329
|
+
|
330
|
+
context "JSON does not support +=" do
|
331
|
+
let (:orig_text) { '{"foo" += "bar"}' }
|
332
|
+
let (:contains_message) { "Key '\"foo\"' may not be followed by token: '+='" }
|
333
|
+
include_examples "parse JSON failures test"
|
334
|
+
end
|
335
|
+
|
336
|
+
context "JSON does not support duplicate keys" do
|
337
|
+
let (:orig_text) { '{"foo" : 123, "foo": 456}' }
|
338
|
+
let (:contains_message) { "JSON does not allow duplicate fields" }
|
339
|
+
include_examples "parse JSON failures test"
|
340
|
+
end
|
341
|
+
|
342
|
+
context "JSON does not support trailing commas" do
|
343
|
+
let (:orig_text) { '{"foo" : 123,}' }
|
344
|
+
let (:contains_message) { "expecting a field name after a comma, got a close brace } instead" }
|
345
|
+
include_examples "parse JSON failures test"
|
346
|
+
end
|
347
|
+
|
348
|
+
context "JSON does not support empty documents" do
|
349
|
+
let (:orig_text) { '' }
|
350
|
+
let (:contains_message) { "Empty document" }
|
351
|
+
include_examples "parse JSON failures test"
|
352
|
+
end
|
353
|
+
end
|
354
|
+
|
355
|
+
context "parse single values" do
|
356
|
+
let (:final_text) { nil }
|
357
|
+
|
358
|
+
context "parse a single integer" do
|
359
|
+
let (:orig_text) { "123" }
|
360
|
+
include_examples "parse simple value test"
|
361
|
+
end
|
362
|
+
|
363
|
+
context "parse a single double" do
|
364
|
+
let (:orig_text) { "123.456" }
|
365
|
+
include_examples "parse simple value test"
|
366
|
+
end
|
367
|
+
|
368
|
+
context "parse a single string" do
|
369
|
+
let (:orig_text) { '"a string"' }
|
370
|
+
include_examples "parse simple value test"
|
371
|
+
end
|
372
|
+
|
373
|
+
context "parse true" do
|
374
|
+
let (:orig_text) { "true" }
|
375
|
+
include_examples "parse simple value test"
|
376
|
+
end
|
377
|
+
|
378
|
+
context "parse false" do
|
379
|
+
let (:orig_text) { "false" }
|
380
|
+
include_examples "parse simple value test"
|
381
|
+
end
|
382
|
+
|
383
|
+
context "parse null" do
|
384
|
+
let (:orig_text) { "null" }
|
385
|
+
include_examples "parse simple value test"
|
386
|
+
end
|
387
|
+
|
388
|
+
context "parse a map" do
|
389
|
+
let (:orig_text) { '{"a": "b"}' }
|
390
|
+
include_examples "parse complex value test"
|
391
|
+
end
|
392
|
+
|
393
|
+
context "parse an array" do
|
394
|
+
let (:orig_text) { '{"a": "b"}' }
|
395
|
+
include_examples "parse complex value test"
|
396
|
+
end
|
397
|
+
|
398
|
+
it "should parse concatenations when using CONF syntax" do
|
399
|
+
orig_text = "123 456 \"abc\""
|
400
|
+
node = ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
401
|
+
expect(node.render).to eq(orig_text)
|
402
|
+
end
|
403
|
+
|
404
|
+
it "should parse keys with no separators and object values with CONF parsing" do
|
405
|
+
orig_text = '{"foo" { "bar" : 12 } }'
|
406
|
+
node = ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
407
|
+
expect(node.render).to eq(orig_text)
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
context "parse single values failures" do
|
412
|
+
context "throws on leading whitespace" do
|
413
|
+
let (:orig_text) { " 123" }
|
414
|
+
include_examples "parse leading trailing failure"
|
415
|
+
end
|
416
|
+
|
417
|
+
context "throws on trailing whitespace" do
|
418
|
+
let (:orig_text) { "123 " }
|
419
|
+
include_examples "parse leading trailing failure"
|
420
|
+
end
|
421
|
+
|
422
|
+
context "throws on leading and trailing whitespace" do
|
423
|
+
let (:orig_text) { " 123 " }
|
424
|
+
include_examples "parse leading trailing failure"
|
425
|
+
end
|
426
|
+
|
427
|
+
context "throws on leading newline" do
|
428
|
+
let (:orig_text) { "\n123" }
|
429
|
+
include_examples "parse leading trailing failure"
|
430
|
+
end
|
431
|
+
|
432
|
+
context "throws on trailing newline" do
|
433
|
+
let (:orig_text) { "123\n" }
|
434
|
+
include_examples "parse leading trailing failure"
|
435
|
+
end
|
436
|
+
|
437
|
+
context "throws on leading and trailing newline" do
|
438
|
+
let (:orig_text) { "\n123\n" }
|
439
|
+
include_examples "parse leading trailing failure"
|
440
|
+
end
|
441
|
+
|
442
|
+
context "throws on leading and trailing comments" do
|
443
|
+
let (:orig_text) { "#thisisacomment\n123#comment" }
|
444
|
+
include_examples "parse leading trailing failure"
|
445
|
+
end
|
446
|
+
|
447
|
+
context "throws on whitespace after a concatenation" do
|
448
|
+
let (:orig_text) { "123 456 789 " }
|
449
|
+
include_examples "parse leading trailing failure"
|
450
|
+
end
|
451
|
+
|
452
|
+
context "throws on unquoted text in JSON" do
|
453
|
+
let (:orig_text) { "unquotedtext" }
|
454
|
+
let (:contains_message) { "Token not allowed in valid JSON" }
|
455
|
+
include_examples("parse single value invalid JSON test")
|
456
|
+
end
|
457
|
+
|
458
|
+
context "throws on substitutions in JSON" do
|
459
|
+
let (:orig_text) { "${a.b}" }
|
460
|
+
let (:contains_message) { "Substitutions (${} syntax) not allowed in JSON" }
|
461
|
+
include_examples("parse single value invalid JSON test")
|
462
|
+
end
|
463
|
+
|
464
|
+
it "should throw an error when parsing concatenations in JSON" do
|
465
|
+
orig_text = "123 456 \"abc\""
|
466
|
+
e = TestUtils.intercept(Hocon::ConfigError) {
|
467
|
+
ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults.set_syntax(ConfigSyntax::JSON))
|
468
|
+
}
|
469
|
+
expect(e.message).to include("Parsing JSON and the value set in setValue was either a concatenation or had trailing whitespace, newlines, or comments")
|
470
|
+
end
|
471
|
+
|
472
|
+
it "should throw an error when parsing keys with no separators in JSON" do
|
473
|
+
orig_text = '{"foo" { "bar" : 12 } }'
|
474
|
+
e = TestUtils.intercept(Hocon::ConfigError) {
|
475
|
+
ConfigDocumentParser.parse_value(TestUtils.tokenize_from_s(orig_text), TestUtils.fake_origin, ConfigParseOptions.defaults.set_syntax(ConfigSyntax::JSON))
|
476
|
+
}
|
477
|
+
expect(e.message).to include("Key '\"foo\"' may not be followed by token: '{'")
|
478
|
+
end
|
479
|
+
end
|
480
|
+
|
481
|
+
context "parse empty document" do
|
482
|
+
it "should parse an empty document with CONF syntax" do
|
483
|
+
node = ConfigDocumentParser.parse(TestUtils.tokenize_from_s(""), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
484
|
+
expect(node.value).to be_a(Hocon::Impl::ConfigNodeObject)
|
485
|
+
expect(node.value.children.empty?).to be_truthy
|
486
|
+
end
|
487
|
+
|
488
|
+
it "should parse a document with only comments and whitespace with CONF syntax" do
|
489
|
+
node = ConfigDocumentParser.parse(TestUtils.tokenize_from_s("#comment\n#comment\n\n"), TestUtils.fake_origin, ConfigParseOptions.defaults)
|
490
|
+
expect(node.value).to be_a(Hocon::Impl::ConfigNodeObject)
|
491
|
+
end
|
492
|
+
|
493
|
+
end
|
494
|
+
end
|