hocon 1.2.5 → 1.2.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -1
- data/lib/hocon/version.rb +1 -1
- metadata +1 -47
- data/spec/fixtures/hocon/by_extension/cat.conf +0 -4
- data/spec/fixtures/hocon/by_extension/cat.test +0 -4
- data/spec/fixtures/hocon/by_extension/cat.test-json +0 -3
- data/spec/fixtures/hocon/with_substitution/subst.conf +0 -2
- data/spec/fixtures/parse_render/example1/input.conf +0 -21
- data/spec/fixtures/parse_render/example1/output.conf +0 -26
- data/spec/fixtures/parse_render/example1/output_nocomments.conf +0 -17
- data/spec/fixtures/parse_render/example2/input.conf +0 -10
- data/spec/fixtures/parse_render/example2/output.conf +0 -17
- data/spec/fixtures/parse_render/example2/output_nocomments.conf +0 -17
- data/spec/fixtures/parse_render/example3/input.conf +0 -2
- data/spec/fixtures/parse_render/example3/output.conf +0 -2
- data/spec/fixtures/parse_render/example4/input.json +0 -6
- data/spec/fixtures/parse_render/example4/output.conf +0 -6
- data/spec/fixtures/test_utils/resources/bom.conf +0 -2
- data/spec/fixtures/test_utils/resources/cycle.conf +0 -1
- data/spec/fixtures/test_utils/resources/file-include.conf +0 -5
- data/spec/fixtures/test_utils/resources/include-from-list.conf +0 -4
- data/spec/fixtures/test_utils/resources/subdir/bar.conf +0 -1
- data/spec/fixtures/test_utils/resources/subdir/baz.conf +0 -1
- data/spec/fixtures/test_utils/resources/subdir/foo.conf +0 -5
- data/spec/fixtures/test_utils/resources/test01.conf +0 -80
- data/spec/fixtures/test_utils/resources/test01.json +0 -4
- data/spec/fixtures/test_utils/resources/test03.conf +0 -36
- data/spec/fixtures/test_utils/resources/utf16.conf +0 -0
- data/spec/fixtures/test_utils/resources/utf8.conf +0 -2
- data/spec/fixtures/test_utils/resources//341/232/240/341/233/207/341/232/273.conf +0 -2
- data/spec/spec_helper.rb +0 -43
- data/spec/test_utils.rb +0 -758
- data/spec/unit/cli/cli_spec.rb +0 -157
- data/spec/unit/hocon/README.md +0 -7
- data/spec/unit/hocon/hocon_spec.rb +0 -114
- data/spec/unit/typesafe/config/README.md +0 -4
- data/spec/unit/typesafe/config/concatenation_spec.rb +0 -417
- data/spec/unit/typesafe/config/conf_parser_spec.rb +0 -831
- data/spec/unit/typesafe/config/config_document_parser_spec.rb +0 -494
- data/spec/unit/typesafe/config/config_document_spec.rb +0 -576
- data/spec/unit/typesafe/config/config_factory_spec.rb +0 -120
- data/spec/unit/typesafe/config/config_node_spec.rb +0 -552
- data/spec/unit/typesafe/config/config_value_factory_spec.rb +0 -85
- data/spec/unit/typesafe/config/config_value_spec.rb +0 -959
- data/spec/unit/typesafe/config/path_spec.rb +0 -261
- data/spec/unit/typesafe/config/public_api_spec.rb +0 -520
- data/spec/unit/typesafe/config/simple_config_spec.rb +0 -112
- data/spec/unit/typesafe/config/token_spec.rb +0 -188
- data/spec/unit/typesafe/config/tokenizer_spec.rb +0 -801
data/spec/unit/cli/cli_spec.rb
DELETED
@@ -1,157 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'test_utils'
|
5
|
-
|
6
|
-
|
7
|
-
describe Hocon::CLI do
|
8
|
-
####################
|
9
|
-
# Argument Parsing
|
10
|
-
####################
|
11
|
-
context 'argument parsing' do
|
12
|
-
it 'should find all the flags and arguments' do
|
13
|
-
args = %w(-i foo -o bar set some.path some_value --json)
|
14
|
-
expected_options = {
|
15
|
-
in_file: 'foo',
|
16
|
-
out_file: 'bar',
|
17
|
-
subcommand: 'set',
|
18
|
-
path: 'some.path',
|
19
|
-
new_value: 'some_value',
|
20
|
-
json: true
|
21
|
-
}
|
22
|
-
expect(Hocon::CLI.parse_args(args)).to eq(expected_options)
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should set -i and -o to -f if given' do
|
26
|
-
args = %w(-f foo set some.path some_value)
|
27
|
-
expected_options = {
|
28
|
-
file: 'foo',
|
29
|
-
in_file: 'foo',
|
30
|
-
out_file: 'foo',
|
31
|
-
subcommand: 'set',
|
32
|
-
path: 'some.path',
|
33
|
-
new_value: 'some_value'
|
34
|
-
}
|
35
|
-
expect(Hocon::CLI.parse_args(args)).to eq(expected_options)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
context 'subcommands' do
|
40
|
-
hocon_text =
|
41
|
-
'foo.bar {
|
42
|
-
baz = 42
|
43
|
-
array = [1, 2, 3]
|
44
|
-
hash: {key: value}
|
45
|
-
}'
|
46
|
-
|
47
|
-
context 'do_get()' do
|
48
|
-
it 'should get simple values' do
|
49
|
-
options = {path: 'foo.bar.baz'}
|
50
|
-
expect(Hocon::CLI.do_get(options, hocon_text)).to eq('42')
|
51
|
-
end
|
52
|
-
|
53
|
-
it 'should work with arrays' do
|
54
|
-
options = {path: 'foo.bar.array'}
|
55
|
-
expected = "[\n 1,\n 2,\n 3\n]"
|
56
|
-
expect(Hocon::CLI.do_get(options, hocon_text)).to eq(expected)
|
57
|
-
end
|
58
|
-
|
59
|
-
it 'should work with hashes' do
|
60
|
-
options = {path: 'foo.bar.hash'}
|
61
|
-
expected = "key: value\n"
|
62
|
-
expect(Hocon::CLI.do_get(options, hocon_text)).to eq(expected)
|
63
|
-
end
|
64
|
-
|
65
|
-
it 'should output json if specified' do
|
66
|
-
options = {path: 'foo.bar.hash', json: true}
|
67
|
-
|
68
|
-
# Note that this is valid json, while the test above is not
|
69
|
-
expected = "{\n \"key\": \"value\"\n}\n"
|
70
|
-
expect(Hocon::CLI.do_get(options, hocon_text)).to eq(expected)
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should throw a MissingPathError if the path does not exist' do
|
74
|
-
options = {path: 'not.a.path'}
|
75
|
-
expect {Hocon::CLI.do_get(options, hocon_text)}
|
76
|
-
.to raise_error(Hocon::CLI::MissingPathError)
|
77
|
-
end
|
78
|
-
|
79
|
-
it 'should throw a MissingPathError if the path leads into an array' do
|
80
|
-
options = {path: 'foo.array.1'}
|
81
|
-
expect {Hocon::CLI.do_get(options, hocon_text)}
|
82
|
-
.to raise_error(Hocon::CLI::MissingPathError)
|
83
|
-
end
|
84
|
-
|
85
|
-
it 'should throw a MissingPathError if the path leads into a string' do
|
86
|
-
options = {path: 'foo.hash.key.value'}
|
87
|
-
expect {Hocon::CLI.do_get(options, hocon_text)}
|
88
|
-
.to raise_error(Hocon::CLI::MissingPathError)
|
89
|
-
end
|
90
|
-
end
|
91
|
-
|
92
|
-
context 'do_set()' do
|
93
|
-
it 'should overwrite values' do
|
94
|
-
options = {path: 'foo.bar.baz', new_value: 'pi'}
|
95
|
-
expected = hocon_text.sub(/42/, 'pi')
|
96
|
-
expect(Hocon::CLI.do_set(options, hocon_text)).to eq(expected)
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'should create new nested values' do
|
100
|
-
options = {path: 'new.nested.path', new_value: 'hello'}
|
101
|
-
expected = "new: {\n nested: {\n path: hello\n }\n}"
|
102
|
-
# No config is supplied, so it will need to add new nested hashes
|
103
|
-
expect(Hocon::CLI.do_set(options, '')).to eq(expected)
|
104
|
-
end
|
105
|
-
|
106
|
-
it 'should allow arrays to be set' do
|
107
|
-
options = {path: 'my_array', new_value: '[1, 2, 3]'}
|
108
|
-
expected = 'my_array: [1, 2, 3]'
|
109
|
-
expect(Hocon::CLI.do_set(options, '')).to eq(expected)
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'should allow arrays in strings to be set as strings' do
|
113
|
-
options = {path: 'my_array', new_value: '"[1, 2, 3]"'}
|
114
|
-
expected = 'my_array: "[1, 2, 3]"'
|
115
|
-
expect(Hocon::CLI.do_set(options, '')).to eq(expected)
|
116
|
-
end
|
117
|
-
|
118
|
-
it 'should allow hashes to be set' do
|
119
|
-
do_set_options = {path: 'my_hash', new_value: '{key: value}'}
|
120
|
-
do_set_expected = 'my_hash: {key: value}'
|
121
|
-
do_set_result = Hocon::CLI.do_set(do_set_options, '')
|
122
|
-
expect(do_set_result).to eq(do_set_expected)
|
123
|
-
|
124
|
-
# Make sure it can be parsed again and be seen as a real hash
|
125
|
-
do_get_options = {path: 'my_hash.key'}
|
126
|
-
do_get_expected = 'value'
|
127
|
-
expect(Hocon::CLI.do_get(do_get_options, do_set_result)).to eq(do_get_expected)
|
128
|
-
end
|
129
|
-
|
130
|
-
it 'should allow hashes to be set as strings' do
|
131
|
-
do_set_options = {path: 'my_hash', new_value: '"{key: value}"'}
|
132
|
-
do_set_expected = 'my_hash: "{key: value}"'
|
133
|
-
do_set_result = Hocon::CLI.do_set(do_set_options, '')
|
134
|
-
expect(do_set_result).to eq(do_set_expected)
|
135
|
-
|
136
|
-
# Make sure it can't be parsed again and be seen as a real hash
|
137
|
-
do_get_options = {path: 'my_hash.key'}
|
138
|
-
expect{Hocon::CLI.do_get(do_get_options, do_set_result)}
|
139
|
-
.to raise_error(Hocon::CLI::MissingPathError)
|
140
|
-
end
|
141
|
-
end
|
142
|
-
|
143
|
-
context 'do_unset()' do
|
144
|
-
it 'should remove values' do
|
145
|
-
options = {path: 'foo.bar.baz'}
|
146
|
-
expected = hocon_text.sub(/baz = 42/, '')
|
147
|
-
expect(Hocon::CLI.do_unset(options, hocon_text)).to eq(expected)
|
148
|
-
end
|
149
|
-
|
150
|
-
it 'should throw a MissingPathError if the path does not exist' do
|
151
|
-
options = {path: 'fake.path'}
|
152
|
-
expect{Hocon::CLI.do_unset(options, hocon_text)}
|
153
|
-
.to raise_error(Hocon::CLI::MissingPathError)
|
154
|
-
end
|
155
|
-
end
|
156
|
-
end
|
157
|
-
end
|
data/spec/unit/hocon/README.md
DELETED
@@ -1,7 +0,0 @@
|
|
1
|
-
## RUBY-SPECIFIC TESTS
|
2
|
-
|
3
|
-
This directory should only contain tests that are specific to the Ruby library/API.
|
4
|
-
Tests ported from the upstream Java library should live in spec/typesafe/config.
|
5
|
-
|
6
|
-
Where possible it would be good to avoid sharing fixtures between the two types
|
7
|
-
of tests as well.
|
@@ -1,114 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'spec_helper'
|
4
|
-
require 'hocon'
|
5
|
-
require 'hocon/config_render_options'
|
6
|
-
require 'hocon/config_error'
|
7
|
-
require 'hocon/config_syntax'
|
8
|
-
|
9
|
-
ConfigParseError = Hocon::ConfigError::ConfigParseError
|
10
|
-
ConfigWrongTypeError = Hocon::ConfigError::ConfigWrongTypeError
|
11
|
-
|
12
|
-
describe Hocon do
|
13
|
-
let(:render_options) { Hocon::ConfigRenderOptions.defaults }
|
14
|
-
|
15
|
-
before do
|
16
|
-
render_options.origin_comments = false
|
17
|
-
render_options.json = false
|
18
|
-
end
|
19
|
-
|
20
|
-
RSpec.shared_examples "hocon_parsing" do
|
21
|
-
|
22
|
-
it "should make the config data available as a map" do
|
23
|
-
expect(conf).to eq(expected)
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
28
|
-
[EXAMPLE1, EXAMPLE2].each do |example|
|
29
|
-
let(:input_file) { "#{FIXTURE_DIR}/parse_render/#{example[:name]}/input.conf" }
|
30
|
-
let(:output_file) { "#{FIXTURE_DIR}/parse_render/#{example[:name]}/output.conf" }
|
31
|
-
let(:output) { File.read("#{output_file}") }
|
32
|
-
let(:output_nocomments_file) { "#{FIXTURE_DIR}/parse_render/#{example[:name]}/output_nocomments.conf" }
|
33
|
-
let(:output_nocomments) { File.read("#{output_nocomments_file}") }
|
34
|
-
let(:expected) { example[:hash] }
|
35
|
-
# TODO 'reparsed' appears to be unused
|
36
|
-
let(:reparsed) { Hocon::ConfigFactory.parse_file("#{FIXTURE_DIR}/parse_render/#{example[:name]}/output.conf") }
|
37
|
-
|
38
|
-
context "loading a HOCON file" do
|
39
|
-
let(:conf) { Hocon.load(input_file) }
|
40
|
-
include_examples "hocon_parsing"
|
41
|
-
end
|
42
|
-
|
43
|
-
context "parsing a HOCON string" do
|
44
|
-
let(:string) { File.open(input_file).read }
|
45
|
-
let(:conf) { Hocon.parse(string) }
|
46
|
-
include_examples "hocon_parsing"
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
it "should fail to parse an array" do
|
51
|
-
puts
|
52
|
-
expect{(Hocon.parse('[1,2,3]'))}.
|
53
|
-
to raise_error(ConfigWrongTypeError)
|
54
|
-
end
|
55
|
-
|
56
|
-
it "should fail to parse an array" do
|
57
|
-
expect{(Hocon.parse('["one", "two" "three"]'))}.
|
58
|
-
to raise_error(ConfigWrongTypeError)
|
59
|
-
end
|
60
|
-
|
61
|
-
context "loading a HOCON file with a substitution" do
|
62
|
-
conf = Hocon.load("#{FIXTURE_DIR}/parse_render/#{EXAMPLE3[:name]}/input.conf")
|
63
|
-
expected = EXAMPLE3[:hash]
|
64
|
-
it "should successfully resolve the substitution" do
|
65
|
-
expect(conf).to eq(expected)
|
66
|
-
end
|
67
|
-
end
|
68
|
-
|
69
|
-
context "loading a file with an unknown extension" do
|
70
|
-
context "without specifying the config format" do
|
71
|
-
it "should raise an error" do
|
72
|
-
expect {
|
73
|
-
Hocon.load("#{FIXTURE_DIR}/hocon/by_extension/cat.test")
|
74
|
-
}.to raise_error(ConfigParseError, /Unrecognized file extension '.test'/)
|
75
|
-
end
|
76
|
-
end
|
77
|
-
|
78
|
-
context "while specifying the config format" do
|
79
|
-
it "should parse properly if the config format is correct" do
|
80
|
-
expect(Hocon.load("#{FIXTURE_DIR}/hocon/by_extension/cat.test",
|
81
|
-
{:syntax => Hocon::ConfigSyntax::HOCON})).
|
82
|
-
to eq({"meow" => "cats"})
|
83
|
-
expect(Hocon.load("#{FIXTURE_DIR}/hocon/by_extension/cat.test-json",
|
84
|
-
{:syntax => Hocon::ConfigSyntax::HOCON})).
|
85
|
-
to eq({"meow" => "cats"})
|
86
|
-
end
|
87
|
-
it "should parse properly if the config format is compatible" do
|
88
|
-
expect(Hocon.load("#{FIXTURE_DIR}/hocon/by_extension/cat.test-json",
|
89
|
-
{:syntax => Hocon::ConfigSyntax::JSON})).
|
90
|
-
to eq({"meow" => "cats"})
|
91
|
-
end
|
92
|
-
it "should raise an error if the config format is incompatible" do
|
93
|
-
expect {
|
94
|
-
Hocon.load("#{FIXTURE_DIR}/hocon/by_extension/cat.test",
|
95
|
-
{:syntax => Hocon::ConfigSyntax::JSON})
|
96
|
-
}.to raise_error(ConfigParseError, /Document must have an object or array at root/)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
context "loading config that includes substitutions" do
|
102
|
-
it "should be able to `load` from a file" do
|
103
|
-
expect(Hocon.load("#{FIXTURE_DIR}/hocon/with_substitution/subst.conf")).
|
104
|
-
to eq({"a" => true, "b" => true})
|
105
|
-
end
|
106
|
-
it "should be able to `parse` from a string" do
|
107
|
-
expect(Hocon.parse(File.read("#{FIXTURE_DIR}/hocon/with_substitution/subst.conf"))).
|
108
|
-
to eq({"a" => true, "b" => true})
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
|
-
|
113
|
-
end
|
114
|
-
|
@@ -1,417 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'test_utils'
|
4
|
-
|
5
|
-
describe "concatenation" do
|
6
|
-
|
7
|
-
it "string concat, no substitutions" do
|
8
|
-
conf = TestUtils.parse_config(' a : true "xyz" 123 foo ').resolve
|
9
|
-
expect(conf.get_string("a")).to eq("true xyz 123 foo")
|
10
|
-
end
|
11
|
-
|
12
|
-
it "trivial string concat" do
|
13
|
-
conf = TestUtils.parse_config(" a : ${x}foo, x = 1 ").resolve
|
14
|
-
expect(conf.get_string("a")).to eq("1foo")
|
15
|
-
end
|
16
|
-
|
17
|
-
it "two substitutions and string concat" do
|
18
|
-
conf = TestUtils.parse_config(" a : ${x}foo${x}, x = 1 ").resolve
|
19
|
-
expect(conf.get_string("a")).to eq("1foo1")
|
20
|
-
end
|
21
|
-
|
22
|
-
it "string concat cannot span lines" do
|
23
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigParseError) {
|
24
|
-
TestUtils.parse_config(" a : ${x}
|
25
|
-
foo, x = 1 ")
|
26
|
-
}
|
27
|
-
expect(e.message).to include("not be followed")
|
28
|
-
expect(e.message).to include("','")
|
29
|
-
end
|
30
|
-
|
31
|
-
it "no objects in string concat" do
|
32
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
33
|
-
TestUtils.parse_config(" a : abc { x : y } ")
|
34
|
-
}
|
35
|
-
expect(e.message).to include("Cannot concatenate")
|
36
|
-
expect(e.message).to include("abc")
|
37
|
-
expect(e.message).to include('{"x":"y"}')
|
38
|
-
end
|
39
|
-
|
40
|
-
it "no object concat with nil" do
|
41
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
42
|
-
TestUtils.parse_config(" a : null { x : y } ")
|
43
|
-
}
|
44
|
-
expect(e.message).to include("Cannot concatenate")
|
45
|
-
expect(e.message).to include("null")
|
46
|
-
expect(e.message).to include('{"x":"y"}')
|
47
|
-
end
|
48
|
-
|
49
|
-
it "no arrays in string concat" do
|
50
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
51
|
-
TestUtils.parse_config(" a : abc [1, 2] ")
|
52
|
-
}
|
53
|
-
expect(e.message).to include("Cannot concatenate")
|
54
|
-
expect(e.message).to include("abc")
|
55
|
-
expect(e.message).to include("[1,2]")
|
56
|
-
end
|
57
|
-
|
58
|
-
it "no objects substituted in string concat" do
|
59
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
60
|
-
TestUtils.parse_config(" a : abc ${x}, x : { y : z } ").resolve
|
61
|
-
}
|
62
|
-
expect(e.message).to include("Cannot concatenate")
|
63
|
-
expect(e.message).to include("abc")
|
64
|
-
end
|
65
|
-
|
66
|
-
it "no arrays substituted in string concat" do
|
67
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
68
|
-
TestUtils.parse_config(" a : abc ${x}, x : [1,2] ").resolve
|
69
|
-
}
|
70
|
-
expect(e.message).to include("Cannot concatenate")
|
71
|
-
expect(e.message).to include("abc")
|
72
|
-
end
|
73
|
-
|
74
|
-
it "no substitutions in list concat" do
|
75
|
-
conf = TestUtils.parse_config(" a : [1,2] [3,4] ")
|
76
|
-
expect([1, 2, 3, 4]).to eq(conf.get_list("a").unwrapped)
|
77
|
-
end
|
78
|
-
|
79
|
-
it "list concat with substitutions" do
|
80
|
-
conf = TestUtils.parse_config(" a : ${x} [3,4] ${y}, x : [1,2], y : [5,6] ").resolve
|
81
|
-
expect([1, 2, 3, 4, 5, 6]).to eq(conf.get_list("a").unwrapped)
|
82
|
-
end
|
83
|
-
|
84
|
-
it "list concat self referential" do
|
85
|
-
conf = TestUtils.parse_config(" a : [1, 2], a : ${a} [3,4], a : ${a} [5,6] ").resolve
|
86
|
-
expect([1, 2, 3, 4, 5, 6]).to eq(conf.get_list("a").unwrapped)
|
87
|
-
end
|
88
|
-
|
89
|
-
it "no substitutions in list concat cannot span lines" do
|
90
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigParseError) {
|
91
|
-
TestUtils.parse_config(" a : [1,2]
|
92
|
-
[3,4] ")
|
93
|
-
}
|
94
|
-
expect(e.message).to include("expecting")
|
95
|
-
expect(e.message).to include("'['")
|
96
|
-
end
|
97
|
-
|
98
|
-
it "list concat can span lines inside brackest" do
|
99
|
-
conf = TestUtils.parse_config(" a : [1,2
|
100
|
-
] [3,4] ")
|
101
|
-
expect([1, 2, 3, 4]).to eq(conf.get_list("a").unwrapped)
|
102
|
-
end
|
103
|
-
|
104
|
-
it "no substitutions object concat" do
|
105
|
-
conf = TestUtils.parse_config(" a : { b : c } { x : y } ")
|
106
|
-
expect({"b" => "c", "x" => "y"}).to eq(conf.get_object("a").unwrapped)
|
107
|
-
end
|
108
|
-
|
109
|
-
it "object concat merge order" do
|
110
|
-
conf = TestUtils.parse_config(" a : { b : 1 } { b : 2 } { b : 3 } { b : 4 } ")
|
111
|
-
expect(4).to eq(conf.get_int("a.b"))
|
112
|
-
end
|
113
|
-
|
114
|
-
it "object concat with substitutions" do
|
115
|
-
conf = TestUtils.parse_config(" a : ${x} { b : 1 } ${y}, x : { a : 0 }, y : { c : 2 } ").resolve
|
116
|
-
expect({"a" => 0, "b" => 1, "c" => 2}).to eq(conf.get_object("a").unwrapped)
|
117
|
-
end
|
118
|
-
|
119
|
-
it "object concat self referential" do
|
120
|
-
conf = TestUtils.parse_config(" a : { a : 0 }, a : ${a} { b : 1 }, a : ${a} { c : 2 } ").resolve
|
121
|
-
expect({"a" => 0, "b" => 1, "c" => 2}).to eq(conf.get_object("a").unwrapped)
|
122
|
-
end
|
123
|
-
|
124
|
-
it "object concat self referential override" do
|
125
|
-
conf = TestUtils.parse_config(" a : { b : 3 }, a : { b : 2 } ${a} ").resolve
|
126
|
-
expect({"b" => 3}).to eq(conf.get_object("a").unwrapped)
|
127
|
-
end
|
128
|
-
|
129
|
-
it "no substitutions object concat cannot span lines" do
|
130
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigParseError) {
|
131
|
-
TestUtils.parse_config(" a : { b : c }
|
132
|
-
{ x : y }")
|
133
|
-
}
|
134
|
-
expect(e.message).to include("expecting")
|
135
|
-
expect(e.message).to include("'{'")
|
136
|
-
end
|
137
|
-
|
138
|
-
it "object concat can span lines inside braces" do
|
139
|
-
conf = TestUtils.parse_config(" a : { b : c
|
140
|
-
} { x : y } ")
|
141
|
-
expect({"b" => "c", "x" => "y"}).to eq(conf.get_object("a").unwrapped)
|
142
|
-
end
|
143
|
-
|
144
|
-
it "string concat inside array value" do
|
145
|
-
conf = TestUtils.parse_config(" a : [ foo bar 10 ] ")
|
146
|
-
expect(["foo bar 10"]).to eq(conf.get_string_list("a"))
|
147
|
-
end
|
148
|
-
|
149
|
-
it "string non concat inside array value" do
|
150
|
-
conf = TestUtils.parse_config(" a : [ foo
|
151
|
-
bar
|
152
|
-
10 ] ")
|
153
|
-
expect(["foo", "bar", "10"]).to eq(conf.get_string_list("a"))
|
154
|
-
end
|
155
|
-
|
156
|
-
it "object concat inside array value" do
|
157
|
-
conf = TestUtils.parse_config(" a : [ { b : c } { x : y } ] ")
|
158
|
-
expect([{"b" => "c", "x" => "y"}]).to eq(conf.get_object_list("a").map { |x| x.unwrapped })
|
159
|
-
end
|
160
|
-
|
161
|
-
it "object non concat inside array value" do
|
162
|
-
conf = TestUtils.parse_config(" a : [ { b : c }
|
163
|
-
{ x : y } ] ")
|
164
|
-
expect([{"b" => "c"}, {"x" => "y"}]).to eq(conf.get_object_list("a").map { |x| x.unwrapped })
|
165
|
-
end
|
166
|
-
|
167
|
-
it "list concat inside array value" do
|
168
|
-
conf = TestUtils.parse_config(" a : [ [1, 2] [3, 4] ] ")
|
169
|
-
expect([[1,2,3,4]]).to eq(conf.get_list("a").unwrapped)
|
170
|
-
end
|
171
|
-
|
172
|
-
it "list non concat inside array value" do
|
173
|
-
conf = TestUtils.parse_config(" a : [ [1, 2]
|
174
|
-
[3, 4] ] ")
|
175
|
-
expect([[1, 2], [3, 4]]).to eq(conf.get_list("a").unwrapped)
|
176
|
-
end
|
177
|
-
|
178
|
-
it "string concats are keys" do
|
179
|
-
conf = TestUtils.parse_config(' 123 foo : "value" ')
|
180
|
-
expect("value").to eq(conf.get_string("123 foo"))
|
181
|
-
end
|
182
|
-
|
183
|
-
it "objects are not keys" do
|
184
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigParseError) {
|
185
|
-
TestUtils.parse_config('{ { a : 1 } : "value" }')
|
186
|
-
}
|
187
|
-
expect(e.message).to include("expecting a close")
|
188
|
-
expect(e.message).to include("'{'")
|
189
|
-
end
|
190
|
-
|
191
|
-
it "arrays are not keys" do
|
192
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigParseError) {
|
193
|
-
TestUtils.parse_config('{ [ "a" ] : "value" }')
|
194
|
-
}
|
195
|
-
expect(e.message).to include("expecting a close")
|
196
|
-
expect(e.message).to include("'['")
|
197
|
-
end
|
198
|
-
|
199
|
-
it "empty array plus equals" do
|
200
|
-
conf = TestUtils.parse_config(' a = [], a += 2 ').resolve
|
201
|
-
expect([2]).to eq(conf.get_int_list("a"))
|
202
|
-
end
|
203
|
-
|
204
|
-
it "missing array plus equals" do
|
205
|
-
conf = TestUtils.parse_config(' a += 2 ').resolve
|
206
|
-
expect([2]).to eq(conf.get_int_list("a"))
|
207
|
-
end
|
208
|
-
|
209
|
-
it "short array plus equals" do
|
210
|
-
conf = TestUtils.parse_config(' a = [1], a += 2 ').resolve
|
211
|
-
expect([1, 2]).to eq(conf.get_int_list("a"))
|
212
|
-
end
|
213
|
-
|
214
|
-
it "number plus equals" do
|
215
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
216
|
-
TestUtils.parse_config(' a = 10, a += 2 ').resolve
|
217
|
-
}
|
218
|
-
expect(e.message).to include("Cannot concatenate")
|
219
|
-
expect(e.message).to include("10")
|
220
|
-
expect(e.message).to include("[2]")
|
221
|
-
end
|
222
|
-
|
223
|
-
it "string plus equals" do
|
224
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
225
|
-
TestUtils.parse_config(' a = abc, a += 2 ').resolve
|
226
|
-
}
|
227
|
-
expect(e.message).to include("Cannot concatenate")
|
228
|
-
expect(e.message).to include("abc")
|
229
|
-
expect(e.message).to include("[2]")
|
230
|
-
end
|
231
|
-
|
232
|
-
it "objects plus equals" do
|
233
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
234
|
-
TestUtils.parse_config(' a = { x : y }, a += 2 ').resolve
|
235
|
-
}
|
236
|
-
expect(e.message).to include("Cannot concatenate")
|
237
|
-
expect(e.message).to include("\"x\":\"y\"")
|
238
|
-
expect(e.message).to include("[2]")
|
239
|
-
end
|
240
|
-
|
241
|
-
it "plus equals nested path" do
|
242
|
-
conf = TestUtils.parse_config(' a.b.c = [1], a.b.c += 2 ').resolve
|
243
|
-
expect([1, 2]).to eq(conf.get_int_list("a.b.c"))
|
244
|
-
end
|
245
|
-
|
246
|
-
it "plus equals nested objects" do
|
247
|
-
conf = TestUtils.parse_config(' a : { b : { c : [1] } }, a : { b : { c += 2 } }').resolve
|
248
|
-
expect([1, 2]).to eq(conf.get_int_list("a.b.c"))
|
249
|
-
end
|
250
|
-
|
251
|
-
it "plus equals single nested object" do
|
252
|
-
conf = TestUtils.parse_config(' a : { b : { c : [1], c += 2 } }').resolve
|
253
|
-
expect([1, 2]).to eq(conf.get_int_list("a.b.c"))
|
254
|
-
end
|
255
|
-
|
256
|
-
it "substitution plus equals substitution" do
|
257
|
-
conf = TestUtils.parse_config(' a = ${x}, a += ${y}, x = [1], y = 2 ').resolve
|
258
|
-
expect([1, 2]).to eq(conf.get_int_list("a"))
|
259
|
-
end
|
260
|
-
|
261
|
-
it "plus equals multiple times" do
|
262
|
-
conf = TestUtils.parse_config(' a += 1, a += 2, a += 3 ').resolve
|
263
|
-
expect([1, 2, 3]).to eq(conf.get_int_list("a"))
|
264
|
-
end
|
265
|
-
|
266
|
-
it "plus equals multiple times nested" do
|
267
|
-
conf = TestUtils.parse_config(' x { a += 1, a += 2, a += 3 } ').resolve
|
268
|
-
expect([1, 2, 3]).to eq(conf.get_int_list("x.a"))
|
269
|
-
end
|
270
|
-
|
271
|
-
it "plus equals an object multiple times" do
|
272
|
-
conf = TestUtils.parse_config(' a += { b: 1 }, a += { b: 2 }, a += { b: 3 } ').resolve
|
273
|
-
expect([1, 2, 3]).to eq(conf.get_object_list("a").map { |x| x.to_config.get_int("b")})
|
274
|
-
end
|
275
|
-
|
276
|
-
it "plus equals an object multiple times nested" do
|
277
|
-
conf = TestUtils.parse_config(' x { a += { b: 1 }, a += { b: 2 }, a += { b: 3 } } ').resolve
|
278
|
-
expect([1, 2, 3]).to eq(conf.get_object_list("x.a").map { |x| x.to_config.get_int("b") })
|
279
|
-
end
|
280
|
-
|
281
|
-
# We would ideally make this case NOT throw an exception but we need to do some work
|
282
|
-
# to get there, see https: // github.com/typesafehub/config/issues/160
|
283
|
-
it "plus equals multiple times nested in array" do
|
284
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigParseError) {
|
285
|
-
conf = TestUtils.parse_config('x = [ { a += 1, a += 2, a += 3 } ] ').resolve
|
286
|
-
expect([1, 2, 3]).to eq(conf.get_object_list("x").to_config.get_int_list("a"))
|
287
|
-
}
|
288
|
-
expect(e.message).to include("limitation")
|
289
|
-
end
|
290
|
-
|
291
|
-
# We would ideally make this case NOT throw an exception but we need to do some work
|
292
|
-
# to get there, see https: // github.com/typesafehub/config/issues/160
|
293
|
-
it "plus equals multiple times nested in plus equals" do
|
294
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigParseError) {
|
295
|
-
conf = TestUtils.parse_config('x += { a += 1, a += 2, a += 3 } ').resolve
|
296
|
-
expect([1, 2, 3]).to eq(conf.get_object_list("x").to_config.get_int_list("a"))
|
297
|
-
}
|
298
|
-
expect(e.message).to include("limitation")
|
299
|
-
end
|
300
|
-
|
301
|
-
# from https://github.com/typesafehub/config/issues/177
|
302
|
-
it "array concatenation in double nested delayed merge" do
|
303
|
-
unresolved = TestUtils.parse_config("d { x = [] }, c : ${d}, c { x += 1, x += 2 }")
|
304
|
-
conf = unresolved.resolve
|
305
|
-
expect([1,2]).to eq(conf.get_int_list("c.x"))
|
306
|
-
end
|
307
|
-
|
308
|
-
# from https://github.com/typesafehub/config/issues/177
|
309
|
-
it "array concatenation as part of delayed merge" do
|
310
|
-
unresolved = TestUtils.parse_config(" c { x: [], x : ${c.x}[1], x : ${c.x}[2] }")
|
311
|
-
conf = unresolved.resolve
|
312
|
-
expect([1,2]).to eq(conf.get_int_list("c.x"))
|
313
|
-
end
|
314
|
-
|
315
|
-
# from https://github.com/typesafehub/config/issues/177
|
316
|
-
it "array concatenation in double nested delayed merge 2" do
|
317
|
-
unresolved = TestUtils.parse_config("d { x = [] }, c : ${d}, c { x : ${c.x}[1], x : ${c.x}[2] }")
|
318
|
-
conf = unresolved.resolve
|
319
|
-
expect([1,2]).to eq(conf.get_int_list("c.x"))
|
320
|
-
end
|
321
|
-
|
322
|
-
# from https://github.com/typesafehub/config/issues/177
|
323
|
-
it "array concatenation in triple nested delayed merge" do
|
324
|
-
unresolved = TestUtils.parse_config("{ r: { d.x=[] }, q: ${r}, q : { d { x = [] }, c : ${q.d}, c { x : ${q.c.x}[1], x : ${q.c.x}[2] } } }")
|
325
|
-
conf = unresolved.resolve
|
326
|
-
expect([1,2]).to eq(conf.get_int_list("q.c.x"))
|
327
|
-
end
|
328
|
-
|
329
|
-
it "concat undefined substitution with string" do
|
330
|
-
conf = TestUtils.parse_config("a = foo${?bar}").resolve
|
331
|
-
expect("foo").to eq(conf.get_string("a"))
|
332
|
-
end
|
333
|
-
|
334
|
-
it "concat defined optional substitution with string" do
|
335
|
-
conf = TestUtils.parse_config("bar=bar, a = foo${?bar}").resolve
|
336
|
-
expect("foobar").to eq(conf.get_string("a"))
|
337
|
-
end
|
338
|
-
|
339
|
-
it "concat defined substitution with array" do
|
340
|
-
conf = TestUtils.parse_config("a = [1] ${?bar}").resolve
|
341
|
-
expect([1]).to eq(conf.get_int_list("a"))
|
342
|
-
end
|
343
|
-
|
344
|
-
it "concat defined optional substitution with array" do
|
345
|
-
conf = TestUtils.parse_config("bar=[2], a = [1] ${?bar}").resolve
|
346
|
-
expect([1, 2]).to eq(conf.get_int_list("a"))
|
347
|
-
end
|
348
|
-
|
349
|
-
it "concat undefined substitution with object" do
|
350
|
-
conf = TestUtils.parse_config('a = { x : "foo" } ${?bar}').resolve
|
351
|
-
expect('foo').to eq(conf.get_string("a.x"))
|
352
|
-
end
|
353
|
-
|
354
|
-
it "concat defined optional substitution with object" do
|
355
|
-
conf = TestUtils.parse_config('bar={ y : 42 }, a = { x : "foo" } ${?bar}').resolve
|
356
|
-
expect('foo').to eq(conf.get_string("a.x"))
|
357
|
-
expect(42).to eq(conf.get_int("a.y"))
|
358
|
-
end
|
359
|
-
|
360
|
-
it "concat two undefined substitutions" do
|
361
|
-
conf = TestUtils.parse_config("a = ${?foo}${?bar}").resolve
|
362
|
-
expect(conf.has_path?("a")).to be_falsey
|
363
|
-
end
|
364
|
-
|
365
|
-
it "concat several undefined substitutions" do
|
366
|
-
conf = TestUtils.parse_config("a = ${?foo}${?bar}${?baz}${?woooo}").resolve
|
367
|
-
expect(conf.has_path?("a")).to be_falsey
|
368
|
-
end
|
369
|
-
|
370
|
-
it "concat two undefined substitutions with a space" do
|
371
|
-
conf = TestUtils.parse_config("a = ${?foo} ${?bar}").resolve
|
372
|
-
expect(conf.get_string("a")).to eq(" ")
|
373
|
-
end
|
374
|
-
|
375
|
-
it "concat two defined substitutions with a space" do
|
376
|
-
conf = TestUtils.parse_config("foo=abc, bar=def, a = ${foo} ${bar}").resolve
|
377
|
-
expect(conf.get_string("a")).to eq("abc def")
|
378
|
-
end
|
379
|
-
|
380
|
-
it "concat two undefined substitutions with empty string" do
|
381
|
-
conf = TestUtils.parse_config('a = ""${?foo}${?bar}').resolve
|
382
|
-
expect(conf.get_string("a")).to eq("")
|
383
|
-
end
|
384
|
-
|
385
|
-
it "concat substitutions that are objects with no space" do
|
386
|
-
conf = TestUtils.parse_config('foo = { a : 1}, bar = { b : 2 }, x = ${foo}${bar}').resolve
|
387
|
-
expect(1).to eq(conf.get_int("x.a"))
|
388
|
-
expect(2).to eq(conf.get_int("x.b"))
|
389
|
-
end
|
390
|
-
|
391
|
-
# whitespace is insignificant if substitutions don't turn out to be a string
|
392
|
-
it "concat substitutions that are objects with space" do
|
393
|
-
conf = TestUtils.parse_config('foo = { a : 1}, bar = { b : 2 }, x = ${foo} ${bar}').resolve
|
394
|
-
expect(1).to eq(conf.get_int("x.a"))
|
395
|
-
expect(2).to eq(conf.get_int("x.b"))
|
396
|
-
end
|
397
|
-
|
398
|
-
# whitespace is insignificant if substitutions don't turn out to be a string
|
399
|
-
it "concat substitutions that are lists with space" do
|
400
|
-
conf = TestUtils.parse_config('foo = [1], bar = [2], x = ${foo} ${bar}').resolve
|
401
|
-
expect([1,2]).to eq(conf.get_int_list("x"))
|
402
|
-
end
|
403
|
-
|
404
|
-
# but quoted whitespace should be an error
|
405
|
-
it "concat substitutions that are objects with quoted space" do
|
406
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
407
|
-
conf = TestUtils.parse_config('foo = { a : 1}, bar = { b : 2 }, x = ${foo}" "${bar}').resolve
|
408
|
-
}
|
409
|
-
end
|
410
|
-
|
411
|
-
# but quoted whitespace should be an error
|
412
|
-
it "concat substitutions that are lists with quoted space" do
|
413
|
-
e = TestUtils.intercept(Hocon::ConfigError::ConfigWrongTypeError) {
|
414
|
-
conf = TestUtils.parse_config('foo = [1], bar = [2], x = ${foo}" "${bar}').resolve
|
415
|
-
}
|
416
|
-
end
|
417
|
-
end
|