confset 1.0.0

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.
Files changed (66) hide show
  1. checksums.yaml +7 -0
  2. data/Rakefile +44 -0
  3. data/docs/CHANGELOG.md +15 -0
  4. data/docs/LICENSE.md +29 -0
  5. data/lib/confset/configuration.rb +37 -0
  6. data/lib/confset/integrations/heroku.rb +61 -0
  7. data/lib/confset/integrations/rails/railtie.rb +40 -0
  8. data/lib/confset/integrations/sinatra.rb +27 -0
  9. data/lib/confset/options.rb +187 -0
  10. data/lib/confset/rack/reloader.rb +17 -0
  11. data/lib/confset/sources/env_source.rb +74 -0
  12. data/lib/confset/sources/hash_source.rb +18 -0
  13. data/lib/confset/sources/yaml_source.rb +34 -0
  14. data/lib/confset/tasks/heroku.rake +9 -0
  15. data/lib/confset/validation/error.rb +13 -0
  16. data/lib/confset/validation/schema.rb +22 -0
  17. data/lib/confset/validation/validate.rb +26 -0
  18. data/lib/confset/version.rb +5 -0
  19. data/lib/confset.rb +89 -0
  20. data/lib/generators/confset/install_generator.rb +34 -0
  21. data/lib/generators/confset/templates/confset.rb +58 -0
  22. data/lib/generators/confset/templates/settings/development.yml +0 -0
  23. data/lib/generators/confset/templates/settings/production.yml +0 -0
  24. data/lib/generators/confset/templates/settings/test.yml +0 -0
  25. data/lib/generators/confset/templates/settings.local.yml +0 -0
  26. data/lib/generators/confset/templates/settings.yml +0 -0
  27. data/spec/config_env_spec.rb +238 -0
  28. data/spec/config_spec.rb +468 -0
  29. data/spec/configuration_spec.rb +16 -0
  30. data/spec/fixtures/bool_override/config1.yml +2 -0
  31. data/spec/fixtures/bool_override/config2.yml +2 -0
  32. data/spec/fixtures/custom_types/hash.yml +7 -0
  33. data/spec/fixtures/deep_merge/config1.yml +31 -0
  34. data/spec/fixtures/deep_merge/config2.yml +28 -0
  35. data/spec/fixtures/deep_merge2/config1.yml +3 -0
  36. data/spec/fixtures/deep_merge2/config2.yml +2 -0
  37. data/spec/fixtures/deep_merge3/config1.yml +1 -0
  38. data/spec/fixtures/deep_merge3/config2.yml +1 -0
  39. data/spec/fixtures/development.yml +4 -0
  40. data/spec/fixtures/empty1.yml +0 -0
  41. data/spec/fixtures/empty2.yml +0 -0
  42. data/spec/fixtures/knockout_prefix/config1.yml +40 -0
  43. data/spec/fixtures/knockout_prefix/config2.yml +28 -0
  44. data/spec/fixtures/knockout_prefix/config3.yml +14 -0
  45. data/spec/fixtures/malformed.yml +6 -0
  46. data/spec/fixtures/multilevel.yml +10 -0
  47. data/spec/fixtures/overwrite_arrays/config1.yml +17 -0
  48. data/spec/fixtures/overwrite_arrays/config2.yml +12 -0
  49. data/spec/fixtures/overwrite_arrays/config3.yml +10 -0
  50. data/spec/fixtures/reserved_keywords.yml +7 -0
  51. data/spec/fixtures/settings.yml +22 -0
  52. data/spec/fixtures/settings2.yml +1 -0
  53. data/spec/fixtures/unsafe_load.yml +12 -0
  54. data/spec/fixtures/validation/confset.yml +3 -0
  55. data/spec/fixtures/with_erb.yml +4 -0
  56. data/spec/fixtures/with_malformed_erb.yml +1 -0
  57. data/spec/options_spec.rb +255 -0
  58. data/spec/sources/env_source_spec.rb +81 -0
  59. data/spec/sources/hash_source_spec.rb +49 -0
  60. data/spec/sources/yaml_source_spec.rb +145 -0
  61. data/spec/spec_helper.rb +28 -0
  62. data/spec/support/fixture_helper.rb +14 -0
  63. data/spec/support/rails_helper.rb +24 -0
  64. data/spec/support/shared_contexts/rake.rb +8 -0
  65. data/spec/validation_spec.rb +84 -0
  66. metadata +295 -0
@@ -0,0 +1,17 @@
1
+ array1:
2
+ - item1
3
+ - item2
4
+ - item3
5
+ - item4
6
+
7
+ array2:
8
+ inner:
9
+ - item1
10
+ - item2
11
+ - item3
12
+ - item4
13
+
14
+ array3:
15
+ - item1
16
+ - item2
17
+ - item3
@@ -0,0 +1,12 @@
1
+ array1:
2
+ - item2
3
+ - item4
4
+ - item5
5
+
6
+ array2:
7
+ inner:
8
+ - item2
9
+ - item4
10
+ - item5
11
+
12
+ array3: []
@@ -0,0 +1,10 @@
1
+ array1:
2
+ - item4
3
+ - item5
4
+ - item6
5
+
6
+ array2:
7
+ inner:
8
+ - item4
9
+ - item5
10
+ - item6
@@ -0,0 +1,7 @@
1
+ select: apple
2
+ collect: banana
3
+ count: lemon
4
+ zip: cherry
5
+ max: kumquat
6
+ min: fig
7
+ exit!: taro
@@ -0,0 +1,22 @@
1
+ ##
2
+ # Settings for Rails database.yml
3
+ #
4
+ databases:
5
+ development:
6
+ database: db/development.sqlite3
7
+ test:
8
+ database: db/test.sqlite3
9
+ production:
10
+ database: db/production.sqlite3
11
+ ##
12
+ # ...
13
+ #
14
+ size: 1
15
+ number_in_quotes: "2.56"
16
+ server: google.com
17
+ 1: "one"
18
+ photo_sizes:
19
+ avatar: [60, 60]
20
+ root:
21
+ yahoo.com: 2
22
+ 'google.com': 3
@@ -0,0 +1 @@
1
+ another: "something"
@@ -0,0 +1,12 @@
1
+ development: &defaults
2
+ adapter: postgresql
3
+ encoding: unicode
4
+ pool: &pool 5
5
+ test:
6
+ <<: *defaults # Psych::BadAlias: Unknown alias
7
+ database: myapp_test
8
+ pool: *pool # Psych::BadAlias: Unknown alias
9
+ others:
10
+ regex: !ruby/regexp '/https?:\/\/.*exmaple\.com/' # Tried to load unspecified class: Regexp (Psych::DisallowedClass)
11
+ date: 2021-08-03 # Tried to load unspecified class: Date (Psych::DisallowedClass)
12
+ time: 2001-12-14T21:59:43.10-05:00 # Tried to load unspecified class: Time (Psych::DisallowedClass)
@@ -0,0 +1,3 @@
1
+ youtube:
2
+ api_key: ADSEF453
3
+ multiple_requirements: A
@@ -0,0 +1,4 @@
1
+ computed: <%= 1 + 2 + 3 %>
2
+ section:
3
+ computed1: <%= "1" %>
4
+ computed2: <%= "2" %>
@@ -0,0 +1 @@
1
+ malformed_erb: <%= = %>
@@ -0,0 +1,255 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ describe Confset::Options do
6
+ before :each do
7
+ Confset.reset
8
+ end
9
+
10
+ context "when Settings file is using keywords reserved for OpenStruct" do
11
+ let(:config) do
12
+ Confset.load_files("spec/fixtures/reserved_keywords.yml")
13
+ end
14
+
15
+ it "should allow to access them via object member notation" do
16
+ expect(config.select).to eq("apple")
17
+ expect(config.collect).to eq("banana")
18
+ expect(config.count).to eq("lemon")
19
+ expect(config.zip).to eq("cherry")
20
+ expect(config.max).to eq("kumquat")
21
+ expect(config.min).to eq("fig")
22
+ expect(config.exit!).to eq("taro")
23
+ end
24
+
25
+ it "should allow to access them using [] operator" do
26
+ expect(config["select"]).to eq("apple")
27
+ expect(config["collect"]).to eq("banana")
28
+ expect(config["count"]).to eq("lemon")
29
+ expect(config["zip"]).to eq("cherry")
30
+ expect(config["max"]).to eq("kumquat")
31
+ expect(config["min"]).to eq("fig")
32
+ expect(config["exit!"]).to eq("taro")
33
+
34
+ expect(config[:select]).to eq("apple")
35
+ expect(config[:collect]).to eq("banana")
36
+ expect(config[:count]).to eq("lemon")
37
+ expect(config[:zip]).to eq("cherry")
38
+ expect(config[:max]).to eq("kumquat")
39
+ expect(config[:min]).to eq("fig")
40
+ expect(config[:exit!]).to eq("taro")
41
+ end
42
+ end
43
+
44
+ context "adding sources" do
45
+ let(:config) do
46
+ Confset.load_files("spec/fixtures/settings.yml")
47
+ end
48
+
49
+ before do
50
+ config.add_source!("spec/fixtures/deep_merge2/config1.yml")
51
+ config.reload!
52
+ end
53
+
54
+ it "should still have the initial config" do
55
+ expect(config["size"]).to eq(1)
56
+ end
57
+
58
+ it "should add keys from the added file" do
59
+ expect(config["tvrage"]["service_url"]).to eq("http://services.tvrage.com")
60
+ end
61
+
62
+ context "overwrite with YAML file" do
63
+ before do
64
+ config.add_source!("spec/fixtures/deep_merge2/config2.yml")
65
+ config.reload!
66
+ end
67
+
68
+ it "should overwrite the previous values" do
69
+ expect(config["tvrage"]["service_url"]).to eq("http://url2")
70
+ end
71
+ end
72
+
73
+ context "overwrite with Hash" do
74
+ before do
75
+ config.add_source!({ tvrage: { service_url: "http://url3" } })
76
+ config.reload!
77
+ end
78
+
79
+ it "should overwrite the previous values" do
80
+ expect(config["tvrage"]["service_url"]).to eq("http://url3")
81
+ end
82
+ end
83
+ end
84
+
85
+ context "prepending sources" do
86
+ let(:config) do
87
+ Confset.load_files("spec/fixtures/settings.yml")
88
+ end
89
+
90
+ before do
91
+ config.prepend_source!("spec/fixtures/deep_merge2/config1.yml")
92
+ config.reload!
93
+ end
94
+
95
+ it "should still have the initial config" do
96
+ expect(config["size"]).to eq(1)
97
+ end
98
+
99
+ it "should add keys from the added file" do
100
+ expect(config["tvrage"]["service_url"]).to eq("http://services.tvrage.com")
101
+ end
102
+
103
+ context "be overwritten" do
104
+ before do
105
+ config.prepend_source!("spec/fixtures/deep_merge2/config2.yml")
106
+ config.reload!
107
+ end
108
+
109
+ it "should overwrite the previous values" do
110
+ expect(config["tvrage"]["service_url"]).to eq("http://services.tvrage.com")
111
+ end
112
+ end
113
+
114
+ context "source is a hash" do
115
+ let(:hash_source) {
116
+ { tvrage: { service_url: "http://url3" }, meaning_of_life: 42 }
117
+ }
118
+ before do
119
+ config.prepend_source!(hash_source)
120
+ config.reload!
121
+ end
122
+
123
+ it "should be overwriten by the following values" do
124
+ expect(config["tvrage"]["service_url"]).to eq("http://services.tvrage.com")
125
+ end
126
+
127
+ it "should set meaning of life" do
128
+ expect(config["meaning_of_life"]).to eq(42)
129
+ end
130
+ end
131
+ end
132
+
133
+ context "when fail_on_missing option" do
134
+ context "is set to true" do
135
+ before { Confset.setup { |cfg| cfg.fail_on_missing = true } }
136
+
137
+ it "should raise an error when accessing a missing key" do
138
+ config = Confset.load_files("spec/fixtures/empty1.yml")
139
+
140
+ expect { config.not_existing_method }.to raise_error(KeyError)
141
+ expect { config[:not_existing_method] }.to raise_error(KeyError)
142
+ end
143
+
144
+ it "should raise an error when accessing a removed key" do
145
+ config = Confset.load_files("spec/fixtures/empty1.yml")
146
+
147
+ config.tmp_existing = 1337
148
+ expect(config.tmp_existing).to eq(1337)
149
+
150
+ config.delete_field(:tmp_existing)
151
+ expect { config.tmp_existing }.to raise_error(KeyError)
152
+ expect { config[:tmp_existing] }.to raise_error(KeyError)
153
+ end
154
+ end
155
+
156
+ context "is set to false" do
157
+ before { Confset.setup { |cfg| cfg.fail_on_missing = false } }
158
+
159
+ it "should return nil when accessing a missing key" do
160
+ config = Confset.load_files("spec/fixtures/empty1.yml")
161
+
162
+ expect(config.not_existing_method).to eq(nil)
163
+ expect(config[:not_existing_method]).to eq(nil)
164
+ end
165
+ end
166
+ end
167
+
168
+ context "#key? and #has_key? methods" do
169
+ let(:config) {
170
+ config = Confset.load_files("spec/fixtures/empty1.yml")
171
+ config.existing = nil
172
+ config.send("complex_value=", nil)
173
+ config.send("even_more_complex_value==", nil)
174
+ config.nested = Confset.load_files("spec/fixtures/empty2.yml")
175
+ config.nested.existing = nil
176
+ config
177
+ }
178
+
179
+ it "should test if a value exists for a given key" do
180
+ expect(config.key?(:not_existing)).to eq(false)
181
+ expect(config.key?(:complex_value)).to eq(true)
182
+ expect(config.key?("even_more_complex_value=".to_sym)).to eq(true)
183
+ expect(config.key?(:nested)).to eq(true)
184
+ expect(config.nested.key?(:not_existing)).to eq(false)
185
+ expect(config.nested.key?(:existing)).to eq(true)
186
+ end
187
+
188
+ it "should be sensible to key's class" do
189
+ expect(config.key?(:existing)).to eq(true)
190
+ expect(config.key?("existing")).to eq(false)
191
+ end
192
+ end
193
+
194
+ context "when merge_hash_arrays options" do
195
+ context "is set to true" do
196
+ before { Confset.setup { |cfg|
197
+ cfg.overwrite_arrays = false
198
+ cfg.merge_hash_arrays = true
199
+ } }
200
+
201
+ it "should merge the arrays" do
202
+ config = Confset.load_files("spec/fixtures/deep_merge3/config1.yml", "spec/fixtures/deep_merge3/config2.yml")
203
+
204
+ expect(config.array.length).to eq(1)
205
+ expect(config.array[0].a).to eq("one")
206
+ expect(config.array[0].b).to eq("two")
207
+ end
208
+ end
209
+
210
+ context "is set to false" do
211
+ before { Confset.setup { |cfg|
212
+ cfg.overwrite_arrays = false
213
+ cfg.merge_hash_arrays = false
214
+ } }
215
+
216
+ it "should merge the arrays" do
217
+ config = Confset.load_files("spec/fixtures/deep_merge3/config1.yml", "spec/fixtures/deep_merge3/config2.yml")
218
+
219
+ expect(config.array.length).to eq(2)
220
+ expect(config.array[0].b).to eq(nil)
221
+ expect(config.array[1].b).to eq("two")
222
+ end
223
+ end
224
+ end
225
+
226
+ context "when calling #as_json" do
227
+ it "should return a Hash of the keys and values" do
228
+ unless defined?(::Rails)
229
+ skip <<~REASON
230
+ Confset::Options#as_json raises a runtime error unless Active Support
231
+ Core Extensions are loaded. We don't expect users to call this method
232
+ at all if they're not using AS, so we disable this test except when
233
+ running the suite against Rails.
234
+ REASON
235
+ end
236
+
237
+ options = Confset::Options.new(foo: :bar)
238
+ expect(options.as_json).to eq({ "foo" => "bar" })
239
+ end
240
+ end
241
+
242
+ context "parsing values" do
243
+ let(:config) do
244
+ Confset.load_files("spec/fixtures/settings.yml")
245
+ end
246
+
247
+ it "should return number when its specified without quotes" do
248
+ expect(config["size"]).to eq(1)
249
+ end
250
+
251
+ it "should return string when number specified with quotes" do
252
+ expect(config["number_in_quotes"]).to eq("2.56")
253
+ end
254
+ end
255
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Confset::Sources
6
+ describe EnvSource do
7
+ context "configuration options" do
8
+ before :each do
9
+ Confset.reset
10
+ Confset.env_prefix = nil
11
+ Confset.env_separator = "."
12
+ Confset.env_converter = :downcase
13
+ Confset.env_parse_values = true
14
+ end
15
+
16
+ context "default configuration" do
17
+ it "should use global prefix configuration by default" do
18
+ Confset.env_prefix = "MY_CONFIG"
19
+
20
+ source = EnvSource.new({ "MY_CONFIG.ACTION_MAILER" => "enabled" })
21
+ results = source.load
22
+ expect(results["action_mailer"]).to eq("enabled")
23
+ end
24
+
25
+ it "should use global separator configuration by default" do
26
+ Confset.env_separator = "__"
27
+
28
+ source = EnvSource.new({ "Settings__ACTION_MAILER__ENABLED" => "yes" })
29
+ results = source.load
30
+ expect(results["action_mailer"]["enabled"]).to eq("yes")
31
+ end
32
+
33
+ it "should use global converter configuration by default" do
34
+ Confset.env_converter = nil
35
+
36
+ source = EnvSource.new({ "Settings.ActionMailer.Enabled" => "yes" })
37
+ results = source.load
38
+ expect(results["ActionMailer"]["Enabled"]).to eq("yes")
39
+ end
40
+
41
+ it "should use global parse_values configuration by default" do
42
+ Confset.env_parse_values = false
43
+
44
+ source = EnvSource.new({ "Settings.ACTION_MAILER.ENABLED" => "true" })
45
+ results = source.load
46
+ expect(results["action_mailer"]["enabled"]).to eq("true")
47
+ end
48
+ end
49
+
50
+ context "configuration overrides" do
51
+ it "should allow overriding prefix configuration" do
52
+ source = EnvSource.new({ "MY_CONFIG.ACTION_MAILER" => "enabled" },
53
+ prefix: "MY_CONFIG")
54
+ results = source.load
55
+ expect(results["action_mailer"]).to eq("enabled")
56
+ end
57
+
58
+ it "should allow overriding separator configuration" do
59
+ source = EnvSource.new({ "Settings__ACTION_MAILER__ENABLED" => "yes" },
60
+ separator: "__")
61
+ results = source.load
62
+ expect(results["action_mailer"]["enabled"]).to eq("yes")
63
+ end
64
+
65
+ it "should allow overriding converter configuration" do
66
+ source = EnvSource.new({ "Settings.ActionMailer.Enabled" => "yes" },
67
+ converter: nil)
68
+ results = source.load
69
+ expect(results["ActionMailer"]["Enabled"]).to eq("yes")
70
+ end
71
+
72
+ it "should allow overriding parse_values configuration" do
73
+ source = EnvSource.new({ "Settings.ACTION_MAILER.ENABLED" => "true" },
74
+ parse_values: false)
75
+ results = source.load
76
+ expect(results["action_mailer"]["enabled"]).to eq("true")
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Confset::Sources
6
+ describe HashSource do
7
+ it "should take a hash as initializer" do
8
+ source = HashSource.new(foo: 5)
9
+ expect(source.hash).to eq(foo: 5)
10
+ end
11
+
12
+ context "basic hash" do
13
+ let(:source) do
14
+ HashSource.new(
15
+ {
16
+ "size" => 2,
17
+ "section" => {
18
+ "size" => 3,
19
+ "servers" => [ { "name" => "yahoo.com" }, { "name" => "amazon.com" } ]
20
+ }
21
+ }
22
+ )
23
+ end
24
+
25
+ it "should properly read the settings" do
26
+ results = source.load
27
+ expect(results["size"]).to eq(2)
28
+ end
29
+
30
+ it "should properly read nested settings" do
31
+ results = source.load
32
+ expect(results["section"]["size"]).to eq(3)
33
+ expect(results["section"]["servers"]).to be_instance_of(Array)
34
+ expect(results["section"]["servers"].size).to eq(2)
35
+ end
36
+ end
37
+
38
+ context "parameter is not a hash" do
39
+ let(:source) do
40
+ HashSource.new "hello world"
41
+ end
42
+
43
+ it "should return an empty hash" do
44
+ results = source.load
45
+ expect(results).to eq({})
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,145 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ module Confset::Sources
6
+ describe YAMLSource do
7
+ it "should take a path as initializer" do
8
+ source = YAMLSource.new "somepath"
9
+ expect(source.path).to eq("somepath")
10
+ end
11
+
12
+ context "basic yml file" do
13
+ let(:source) do
14
+ YAMLSource.new "spec/fixtures/development.yml"
15
+ end
16
+
17
+ it "should properly read the settings" do
18
+ results = source.load
19
+ expect(results["size"]).to eq(2)
20
+ end
21
+
22
+ it "should properly read nested settings" do
23
+ results = source.load
24
+ expect(results["section"]["size"]).to eq(3)
25
+ expect(results["section"]["servers"]).to be_instance_of(Array)
26
+ expect(results["section"]["servers"].size).to eq(2)
27
+ end
28
+ end
29
+
30
+ context "yml file with erb tags" do
31
+ let(:source) do
32
+ YAMLSource.new("spec/fixtures/with_erb.yml")
33
+ end
34
+
35
+ it "should properly evaluate the erb" do
36
+ results = source.load
37
+ expect(results["computed"]).to eq(6)
38
+ end
39
+
40
+ it "should properly evaluate the nested erb settings" do
41
+ results = source.load
42
+ expect(results["section"]["computed1"]).to eq(1)
43
+ expect(results["section"]["computed2"]).to eq(2)
44
+ end
45
+
46
+ context "with malformed erb tags" do
47
+ let(:source) do
48
+ YAMLSource.new("spec/fixtures/with_malformed_erb.yml")
49
+ end
50
+
51
+ it "should properly evaluate the erb" do
52
+ expect {
53
+ source.load
54
+ }.to raise_error(SyntaxError)
55
+ end
56
+ end
57
+ end
58
+
59
+ context "yaml file with erb tags but erb disabled" do
60
+ let(:source) do
61
+ YAMLSource.new("spec/fixtures/with_erb.yml", evaluate_erb: false)
62
+ end
63
+
64
+ it "should load the file and leave the erb without being evaluated" do
65
+ results = source.load
66
+ expect(results["computed"]).to eq("<%= 1 + 2 + 3 %>")
67
+ expect(results["section"]["computed1"]).to eq("<%= \"1\" %>")
68
+ end
69
+
70
+ context "with global config" do
71
+ let(:source) do
72
+ YAMLSource.new("spec/fixtures/with_erb.yml")
73
+ end
74
+
75
+ around do |example|
76
+ original_evaluate_erb_in_yaml = Confset.evaluate_erb_in_yaml
77
+ Confset.evaluate_erb_in_yaml = false
78
+ example.run
79
+ Confset.evaluate_erb_in_yaml = original_evaluate_erb_in_yaml
80
+ end
81
+
82
+ it "should load the file and leave the erb without being evaluated" do
83
+ results = source.load
84
+ expect(results["computed"]).to eq("<%= 1 + 2 + 3 %>")
85
+ expect(results["section"]["computed1"]).to eq("<%= \"1\" %>")
86
+ end
87
+ end
88
+
89
+ context "with malformed erb tags" do
90
+ let(:source) do
91
+ YAMLSource.new("spec/fixtures/with_malformed_erb.yml", evaluate_erb: false)
92
+ end
93
+
94
+ it "should properly evaluate the erb" do
95
+ expect {
96
+ results = source.load
97
+ expect(results["malformed_erb"]).to eq("<%= = %>")
98
+ }.to_not raise_error
99
+ end
100
+ end
101
+ end
102
+
103
+ context "missing yml file" do
104
+ let(:source) do
105
+ YAMLSource.new "somewhere_that_doesnt_exist.yml"
106
+ end
107
+
108
+ it "should return an empty hash" do
109
+ results = source.load
110
+ expect(results).to eq({})
111
+ end
112
+ end
113
+
114
+ context "blank yml file" do
115
+ let(:source) do
116
+ YAMLSource.new "spec/fixtures/empty1.yml"
117
+ end
118
+
119
+ it "should return an empty hash" do
120
+ results = source.load
121
+ expect(results).to eq({})
122
+ end
123
+ end
124
+
125
+ context "malformed yml file" do
126
+ let(:source) do
127
+ YAMLSource.new "spec/fixtures/malformed.yml"
128
+ end
129
+
130
+ it "should raise an useful exception" do
131
+ expect { source.load }.to raise_error(/malformed\.yml/)
132
+ end
133
+ end
134
+
135
+ context "unsafe yml file" do
136
+ let(:source) do
137
+ YAMLSource.new "spec/fixtures/unsafe_load.yml"
138
+ end
139
+
140
+ it "should load without any exception" do
141
+ expect { source.load }.not_to raise_error
142
+ end
143
+ end
144
+ end
145
+ end
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ ENV["RAILS_ENV"] ||= "test"
4
+
5
+ require "confset"
6
+
7
+ Dir["./spec/support/**/*.rb"].each { |f| require f }
8
+
9
+ RSpec.configure do |config|
10
+ # Turn the deprecation warnings into errors, giving you the full backtrace
11
+ config.raise_errors_for_deprecations!
12
+
13
+ config.before(:suite) do
14
+ Confset.module_eval do
15
+ # Extend Confset module with ability to reset configuration to the default values
16
+ def self.reset
17
+ self.const_name = "Settings"
18
+ self.use_env = false
19
+ self.knockout_prefix = nil
20
+ self.overwrite_arrays = true
21
+ self.schema = nil
22
+ self.validation_contract = nil
23
+ self.fail_on_missing = false
24
+ instance_variable_set(:@_ran_once, false)
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ ##
4
+ # Confset Fixture Helpers
5
+ #
6
+
7
+ module FixtureHelper
8
+ FIXTURE_PATH = File.expand_path("../../fixtures", __FILE__)
9
+
10
+ # Provide fixture path as same way as rspec-rails
11
+ def fixture_path
12
+ FIXTURE_PATH
13
+ end
14
+ end