mixlib-config 2.2.11 → 3.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile DELETED
@@ -1,3 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec
data/README.md DELETED
@@ -1,304 +0,0 @@
1
- # Mixlib::Config
2
-
3
- [![Build Status](https://travis-ci.org/chef/mixlib-config.svg?branch=master)](https://travis-ci.org/chef/mixlib-config)[![Gem Version](https://badge.fury.io/rb/mixlib-config.svg)](https://badge.fury.io/rb/mixlib-config)
4
-
5
- Mixlib::Config provides a class-based configuration object, as used in Chef. To use in your project:
6
-
7
- ```ruby
8
- require 'mixlib/config'
9
-
10
- module MyConfig
11
- extend Mixlib::Config
12
- config_strict_mode true
13
- default :first_value, 'something'
14
- default :other_value, 'something_else'
15
- end
16
- ```
17
-
18
- You can use this to provide a configuration file for a user. For example, if you do this:
19
-
20
- ```ruby
21
- MyConfig.from_file('~/.myconfig.rb')
22
- ```
23
-
24
- A user could write a Ruby config file that looked like this:
25
-
26
- ```ruby
27
- first_value 'hi'
28
- second_value "#{first_value}! 10 times 10 is #{10*10}!"
29
- ```
30
-
31
- Inside your app, you can check configuration values with this syntax:
32
-
33
- ```ruby
34
- MyConfig.first_value # returns 'something'
35
- MyConfig[:first_value] # returns 'something'
36
- ```
37
-
38
- And you can modify configuration values with this syntax:
39
-
40
- ```ruby
41
- MyConfig.first_value('foobar') # sets first_value to 'foobar'
42
- MyConfig.first_value = 'foobar' # sets first_value to 'foobar'
43
- MyConfig[:first_value] = 'foobar' # sets first_value to 'foobar'
44
- ```
45
-
46
- If you prefer to allow your users to pass in configuration via YAML, JSON or TOML files, `mixlib-config` supports that too!
47
-
48
- ```ruby
49
- MyConfig.from_file('~/.myconfig.yml')
50
- MyConfig.from_file('~/.myconfig.json')
51
- MyConfig.from_file('~/.myconfig.toml')
52
- ```
53
-
54
- This way, a user could write a YAML config file that looked like this:
55
-
56
- ```yaml
57
- ---
58
- first_value: 'hi'
59
- second_value: 'goodbye'
60
- ```
61
-
62
- or a JSON file that looks like this:
63
-
64
- ```json
65
- {
66
- "first_value": "hi",
67
- "second_value": "goodbye"
68
- }
69
- ```
70
-
71
- or a TOML file that looks like this:
72
-
73
- ```toml
74
- first_value = "hi"
75
- second_value = "goodbye"
76
- ```
77
-
78
- Please note: There is an inherent limitation in the logic you can do with YAML and JSON file. At this time, `mixlib-config` does not support ERB or other logic in YAML or JSON config (read "static content only").
79
-
80
- ## Nested Configuration
81
-
82
- Often you want to be able to group configuration options to provide a common context. Mixlib::Config supports this thus:
83
-
84
- ```ruby
85
- require 'mixlib/config'
86
-
87
- module MyConfig
88
- extend Mixlib::Config
89
- config_context :logging do
90
- default :base_filename, 'mylog'
91
- default :max_log_files, 10
92
- end
93
- end
94
- ```
95
-
96
- The user can write their config file in one of three formats:
97
-
98
- ### Method Style
99
-
100
- ```ruby
101
- logging.base_filename 'superlog'
102
- logging.max_log_files 2
103
- ```
104
-
105
- ### Block Style
106
-
107
- Using this format the block is executed in the context, so all configurables on that context is directly accessible
108
-
109
- ```ruby
110
- logging do
111
- base_filename 'superlog'
112
- max_log_files 2
113
- end
114
- ```
115
-
116
- ### Block with Argument Style
117
-
118
- Using this format the context is given to the block as an argument
119
-
120
- ```ruby
121
- logging do |l|
122
- l.base_filename = 'superlog'
123
- l.max_log_files = 2
124
- end
125
- ```
126
-
127
- You can access these variables thus:
128
-
129
- ```ruby
130
- MyConfig.logging.base_filename
131
- MyConfig[:logging][:max_log_files]
132
- ```
133
-
134
- ### Lists of Contexts
135
- For use cases where you need to be able to specify a list of things with identical configuration
136
- you can define a `context_config_list` like so:
137
-
138
- ```ruby
139
- require 'mixlib/config'
140
-
141
- module MyConfig
142
- extend Mixlib::Config
143
-
144
- # The first argument is the plural word for your item, the second is the singular
145
- config_context_list :apples, :apple do
146
- default :species
147
- default :color, 'red'
148
- default :crispness, 10
149
- end
150
- end
151
- ```
152
-
153
- With this definition everytime the `apple` is called within the config file it
154
- will create a new item that can be configured with a block like so:
155
-
156
- ```ruby
157
- apple do
158
- species 'Royal Gala'
159
- end
160
- apple do
161
- species 'Granny Smith'
162
- color 'green'
163
- end
164
- ```
165
-
166
- You can then iterate over the defined values in code:
167
-
168
- ```ruby
169
- MyConfig.apples.each do |apple|
170
- puts "#{apple.species} are #{apple.color}"
171
- end
172
-
173
- # => Royal Gala are red
174
- # => Granny Smith are green
175
- ```
176
-
177
- _**Note**: When using the config context lists they must use the [block style](#block-style) or [block with argument style](#block-with-argument-style)_
178
-
179
- ### Hashes of Contexts
180
- For use cases where you need to be able to specify a list of things with identical configuration
181
- that are keyed to a specific value, you can define a `context_config_hash` like so:
182
-
183
- ```ruby
184
- require 'mixlib/config'
185
-
186
- module MyConfig
187
- extend Mixlib::Config
188
-
189
- # The first argument is the plural word for your item, the second is the singular
190
- config_context_hash :apples, :apple do
191
- default :species
192
- default :color, 'red'
193
- default :crispness, 10
194
- end
195
- end
196
- ```
197
-
198
- This can then be used in the config file like so:
199
-
200
- ```ruby
201
- apple 'Royal Gala' do
202
- species 'Royal Gala'
203
- end
204
- apple 'Granny Smith' do
205
- species 'Granny Smith'
206
- color 'green'
207
- end
208
-
209
- # You can also reopen a context to edit a value
210
- apple 'Royal Gala' do
211
- crispness 3
212
- end
213
- ```
214
-
215
- You can then iterate over the defined values in code:
216
-
217
- ```ruby
218
- MyConfig.apples.each do |key, apple|
219
- puts "#{key} => #{apple.species} are #{apple.color}"
220
- end
221
-
222
- # => Royal Gala => Royal Gala are red
223
- # => Granny Smith => Granny Smith are green
224
- ```
225
-
226
- _**Note**: When using the config context hashes they must use the [block style](#block-style) or [block with argument style](#block-with-argument-style)_
227
-
228
- ## Default Values
229
-
230
- Mixlib::Config has a powerful default value facility. In addition to being able to specify explicit default values, you can even specify Ruby code blocks that will run if the config value is not set. This can allow you to build options whose values are based on other options.
231
-
232
- ```ruby
233
- require 'mixlib/config'
234
-
235
- module MyConfig
236
- extend Mixlib::Config
237
- config_strict_mode true
238
- default :verbosity, 1
239
- default(:print_network_requests) { verbosity >= 2 }
240
- default(:print_ridiculously_unimportant_stuff) { verbosity >= 10 }
241
- end
242
- ```
243
-
244
- This allows the user to quickly specify a number of values with one default, while still allowing them to override anything:
245
-
246
- ```ruby
247
- verbosity 5
248
- print_network_requests false
249
- ```
250
-
251
- ## Strict Mode
252
-
253
- Misspellings are a common configuration problem, and Mixlib::Config has an answer: `config_strict_mode`. Setting `config_strict_mode` to `true` will cause any misspelled or incorrect configuration option references to throw `Mixlib::Config::UnknownConfigOptionError`.
254
-
255
- ```ruby
256
- require 'mixlib/config'
257
-
258
- module MyConfig
259
- extend Mixlib::Config
260
- config_strict_mode true
261
- default :filename, '~/output.txt'
262
- configurable :server_url # configurable declares an option with no default value
263
- config_context :logging do
264
- default :base_name, 'log'
265
- default :max_files, 20
266
- end
267
- end
268
- ```
269
-
270
- Now if a user types `fielname "~/output-mine.txt"` in their configuration file, it will toss an exception telling them that the option "fielname" is unknown. If you do not set config_strict_mode, the fielname option will be merrily set and the application just won't know about it.
271
-
272
- Different config_contexts can have different strict modes; but they inherit the strict mode of their parent if you don't explicitly set it. So setting it once at the top level is sufficient. In the above example, `logging.base_naem 'mylog'` will raise an error.
273
-
274
- In conclusion: _always set config_strict_mode to true_. You know you want to.
275
-
276
- ## Testing and Reset
277
-
278
- Testing your application with different sets of arguments can by simplified with `reset`. Call `MyConfig.reset` before each test and all configuration will be reset to its default value. There's no need to explicitly unset all your options between each run.
279
-
280
- NOTE: if you have arrays of arrays, or other deep nesting, we suggest you use code blocks to set up your default values (`default(:option) { [ [ 1, 2 ], [ 3, 4 ] ] }`). Deep children will not always be reset to their default values.
281
-
282
- Enjoy!
283
-
284
- ## Contributing
285
-
286
- For information on contributing to this project see <https://github.com/chef/chef/blob/master/CONTRIBUTING.md>
287
-
288
- ## License
289
-
290
- - Copyright:: Copyright (c) 2009-2016 Chef Software, Inc.
291
- - License:: Apache License, Version 2.0
292
-
293
- ```text
294
- Licensed under the Apache License, Version 2.0 (the "License");
295
- you may not use this file except in compliance with the License.
296
- You may obtain a copy of the License at
297
-
298
- http://www.apache.org/licenses/LICENSE-2.0
299
-
300
- Unless required by applicable law or agreed to in writing, software
301
- distributed under the License is distributed on an "AS IS" BASIS,
302
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
303
- See the License for the specific language governing permissions and
304
- limitations under the License.
data/Rakefile DELETED
@@ -1,32 +0,0 @@
1
- require "bundler"
2
- require "rubygems"
3
- require "rubygems/package_task"
4
- require "rdoc/task"
5
- require "rspec/core/rake_task"
6
- require "mixlib/config/version"
7
-
8
- Bundler::GemHelper.install_tasks
9
-
10
- task default: [:style, :spec]
11
-
12
- desc "Run specs"
13
- RSpec::Core::RakeTask.new(:spec) do |spec|
14
- spec.pattern = "spec/**/*_spec.rb"
15
- end
16
-
17
- begin
18
- require "chefstyle"
19
- require "rubocop/rake_task"
20
- RuboCop::RakeTask.new(:style) do |task|
21
- task.options += ["--display-cop-names", "--no-color"]
22
- end
23
- rescue LoadError
24
- puts "chefstyle/rubocop is not available. gem install chefstyle to do style checking."
25
- end
26
-
27
- RDoc::Task.new do |rdoc|
28
- rdoc.rdoc_dir = "rdoc"
29
- rdoc.title = "mixlib-config #{Mixlib::Config::VERSION}"
30
- rdoc.rdoc_files.include("README*")
31
- rdoc.rdoc_files.include("lib/**/*.rb")
32
- end
@@ -1,32 +0,0 @@
1
- # -*- encoding: utf-8 -*-
2
-
3
- $:.unshift(File.dirname(__FILE__) + "/lib")
4
- require "mixlib/config/version"
5
-
6
- Gem::Specification.new do |s|
7
- s.name = "mixlib-config"
8
- s.version = Mixlib::Config::VERSION
9
-
10
- s.authors = ["Chef Software, Inc."]
11
- s.email = "legal@chef.io"
12
- s.extra_rdoc_files = [
13
- "LICENSE",
14
- "README.md",
15
- ]
16
- s.files = ["LICENSE", "NOTICE", "README.md", "Gemfile", "Rakefile"] + Dir.glob("*.gemspec") +
17
- Dir.glob("{lib,spec}/**/*", File::FNM_DOTMATCH).reject { |f| File.directory?(f) }
18
- s.homepage = "https://www.chef.io"
19
- s.require_paths = ["lib"]
20
- s.rubygems_version = "1.8.23"
21
- s.required_ruby_version = ">= 2.2"
22
- s.summary = "A class based configuration library"
23
- s.description = s.summary
24
- s.license = "Apache-2.0"
25
-
26
- s.add_dependency "tomlrb"
27
-
28
- s.add_development_dependency "rake"
29
- s.add_development_dependency "rspec", "~> 3.0"
30
- s.add_development_dependency "chefstyle"
31
- s.add_development_dependency "rdoc"
32
- end
@@ -1,1273 +0,0 @@
1
- #
2
- # Author:: Adam Jacob (<adam@chef.io>)
3
- # Copyright:: Copyright (c) 2008-2018, Chef Software Inc.
4
- # License:: Apache License, Version 2.0
5
- #
6
- # Licensed under the Apache License, Version 2.0 (the "License");
7
- # you may not use this file except in compliance with the License.
8
- # You may obtain a copy of the License at
9
- #
10
- # http://www.apache.org/licenses/LICENSE-2.0
11
- #
12
- # Unless required by applicable law or agreed to in writing, software
13
- # distributed under the License is distributed on an "AS IS" BASIS,
14
- # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
- # See the License for the specific language governing permissions and
16
- # limitations under the License.
17
- #
18
-
19
- require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
20
-
21
- describe Mixlib::Config do
22
- before(:each) do
23
- ConfigIt.configure do |c|
24
- c[:alpha] = "omega"
25
- c[:foo] = nil
26
- end
27
- end
28
-
29
- it "loads a config file" do
30
- allow(File).to receive(:exists?).and_return(true)
31
- allow(File).to receive(:readable?).and_return(true)
32
- allow(IO).to receive(:read).with("config.rb").and_return("alpha = 'omega'\nfoo = 'bar'")
33
- expect(lambda do
34
- ConfigIt.from_file("config.rb")
35
- end).to_not raise_error
36
- end
37
-
38
- it "doesn't raise an ArgumentError with an explanation if you try and set a non-existent variable" do
39
- expect(lambda do
40
- ConfigIt[:foobar] = "blah"
41
- end).to_not raise_error
42
- end
43
-
44
- it "raises an Errno::ENOENT if it can't find the file" do
45
- expect(lambda do
46
- ConfigIt.from_file("/tmp/timmytimmytimmy")
47
- end).to raise_error(Errno::ENOENT)
48
- end
49
-
50
- it "allows the error to bubble up when it's anything other than IOError" do
51
- allow(IO).to receive(:read).with("config.rb").and_return("@#asdf")
52
- expect(lambda do
53
- ConfigIt.from_file("config.rb")
54
- end).to raise_error(SyntaxError)
55
- end
56
-
57
- it "allows you to reference a value by index" do
58
- expect(ConfigIt[:alpha]).to eql("omega")
59
- end
60
-
61
- it "allows you to reference a value by string index" do
62
- expect(ConfigIt["alpha"]).to eql("omega")
63
- end
64
-
65
- it "allows you to set a value by index" do
66
- ConfigIt[:alpha] = "one"
67
- expect(ConfigIt[:alpha]).to eql("one")
68
- end
69
-
70
- it "allows you to set a value by string index" do
71
- ConfigIt["alpha"] = "one"
72
- expect(ConfigIt[:alpha]).to eql("one")
73
- end
74
-
75
- it "allows setting a value with attribute form" do
76
- ConfigIt.arbitrary_value = 50
77
- expect(ConfigIt.arbitrary_value).to eql(50)
78
- expect(ConfigIt[:arbitrary_value]).to eql(50)
79
- end
80
-
81
- it "allows setting a value with method form" do
82
- ConfigIt.arbitrary_value 50
83
- expect(ConfigIt.arbitrary_value).to eql(50)
84
- expect(ConfigIt[:arbitrary_value]).to eql(50)
85
- end
86
-
87
- describe "when strict mode is on" do
88
- class StrictClass
89
- extend ::Mixlib::Config
90
- config_strict_mode true
91
- default :x, 1
92
- end
93
-
94
- it "allows you to get and set configured values" do
95
- StrictClass.x = StrictClass.x * 2
96
- StrictClass[:x] = StrictClass[:x] * 2
97
- end
98
-
99
- it "raises an error when you get an arbitrary config option with .y" do
100
- expect(lambda { StrictClass.y }).to raise_error(Mixlib::Config::UnknownConfigOptionError, "Reading unsupported config value y.")
101
- end
102
-
103
- it "raises an error when you get an arbitrary config option with [:y]" do
104
- expect(lambda { StrictClass[:y] }).to raise_error(Mixlib::Config::UnknownConfigOptionError, "Reading unsupported config value y.")
105
- end
106
-
107
- it "raises an error when you set an arbitrary config option with .y = 10" do
108
- expect(lambda { StrictClass.y = 10 }).to raise_error(Mixlib::Config::UnknownConfigOptionError, "Cannot set unsupported config value y.")
109
- end
110
-
111
- it "raises an error when you set an arbitrary config option with .y 10" do
112
- expect(lambda { StrictClass.y 10 }).to raise_error(Mixlib::Config::UnknownConfigOptionError, "Cannot set unsupported config value y.")
113
- end
114
-
115
- it "raises an error when you set an arbitrary config option with [:y] = 10" do
116
- expect(lambda { StrictClass[:y] = 10 }).to raise_error(Mixlib::Config::UnknownConfigOptionError, "Cannot set unsupported config value y.")
117
- end
118
-
119
- it "does not break config_context_list" do
120
- expect(lambda do
121
- StrictClass.class_eval do
122
- config_context_list(:lists, :list) do
123
- default :y, 20
124
- end
125
- end
126
- end).not_to raise_error
127
- end
128
-
129
- it "does not break config_context_hash" do
130
- expect(lambda do
131
- StrictClass.class_eval do
132
- config_context_hash(:hashes, :hash) do
133
- default :z, 20
134
- end
135
- end
136
- end).not_to raise_error
137
- end
138
- end
139
-
140
- describe "when a block has been used to set config values" do
141
- before do
142
- ConfigIt.configure { |c| c[:cookbook_path] = "monkey_rabbit"; c[:otherthing] = "boo" }
143
- end
144
-
145
- { cookbook_path: "monkey_rabbit", otherthing: "boo" }.each do |k, v|
146
- it "allows you to retrieve the config value for #{k} via []" do
147
- expect(ConfigIt[k]).to eql(v)
148
- end
149
- it "allows you to retrieve the config value for #{k} via method_missing" do
150
- expect(ConfigIt.send(k)).to eql(v)
151
- end
152
- end
153
- end
154
-
155
- it "doesn't raise an ArgumentError if you access a config option that does not exist" do
156
- expect(lambda { ConfigIt[:snob_hobbery] }).to_not raise_error
157
- end
158
-
159
- it "returns true or false with has_key?" do
160
- expect(ConfigIt.has_key?(:monkey)).to be false
161
- ConfigIt[:monkey] = "gotcha"
162
- expect(ConfigIt.has_key?(:monkey)).to be true
163
- end
164
-
165
- it "returns true or false with key?" do
166
- expect(ConfigIt.key?(:monkey2)).to be false
167
- ConfigIt[:monkey2] = "gotcha"
168
- expect(ConfigIt.key?(:monkey2)).to be true
169
- end
170
-
171
- describe "when a class method override writer exists" do
172
- before do
173
- @klass = Class.new
174
- @klass.extend(::Mixlib::Config)
175
- @klass.class_eval do
176
- config_attr_writer :test_method do |blah|
177
- blah.is_a?(Integer) ? blah * 1000 : blah
178
- end
179
- end
180
- end
181
-
182
- it "multiplies an integer by 1000" do
183
- @klass[:test_method] = 53
184
- expect(@klass[:test_method]).to eql(53000)
185
- end
186
-
187
- it "multiplies an integer by 1000 with the method_missing form" do
188
- @klass.test_method = 63
189
- expect(@klass.test_method).to eql(63000)
190
- end
191
-
192
- it "multiplies an integer by 1000 with the instance_eval DSL form" do
193
- @klass.instance_eval("test_method 73")
194
- expect(@klass.test_method).to eql(73000)
195
- end
196
-
197
- it "multiplies an integer by 1000 via from-file, too" do
198
- allow(IO).to receive(:read).with("config.rb").and_return("test_method 99")
199
- @klass.from_file("config.rb")
200
- expect(@klass.test_method).to eql(99000)
201
- end
202
-
203
- it "receives internal_set with the method name and config value" do
204
- expect(@klass).to receive(:internal_set).with(:test_method, 53).and_return(true)
205
- @klass[:test_method] = 53
206
- end
207
-
208
- end
209
-
210
- describe "When a configurable exists" do
211
- before :each do
212
- @klass = Class.new
213
- @klass.extend(::Mixlib::Config)
214
- @klass.class_eval do
215
- configurable :daemonizeme
216
- default :a, 1
217
- config_attr_writer(:b) { |v| v }
218
- config_context(:c)
219
- end
220
- end
221
-
222
- it "Getter methods are created for the configurable" do
223
- expect(@klass.respond_to?(:daemonizeme)).to be true
224
- expect(@klass.respond_to?(:a)).to be true
225
- expect(@klass.respond_to?(:b)).to be true
226
- expect(@klass.respond_to?(:c)).to be true
227
- expect(@klass.respond_to?(:z)).to be false
228
- end
229
-
230
- it "Setter methods are created for the configurable" do
231
- expect(@klass.respond_to?("daemonizeme=".to_sym)).to be true
232
- expect(@klass.respond_to?("a=".to_sym)).to be true
233
- expect(@klass.respond_to?("b=".to_sym)).to be true
234
- expect(@klass.respond_to?("c=".to_sym)).to be true
235
- expect(@klass.respond_to?("z=".to_sym)).to be false
236
- end
237
-
238
- describe "and extra methods have been dumped into Object" do
239
- class NopeError < StandardError
240
- end
241
- before :each do
242
- Object.send :define_method, :daemonizeme do
243
- raise NopeError, "NOPE"
244
- end
245
- Object.send :define_method, "daemonizeme=".to_sym do
246
- raise NopeError, "NOPE"
247
- end
248
- end
249
-
250
- after do
251
- Object.send :remove_method, :daemonizeme
252
- Object.send :remove_method, :'daemonizeme='
253
- end
254
-
255
- it "Normal classes call the extra method" do
256
- normal_class = Class.new
257
- normal_class.extend(::Mixlib::Config)
258
- expect(lambda { normal_class.daemonizeme }).to raise_error(NopeError)
259
- end
260
-
261
- it "Configurables with the same name as the extra method can be set" do
262
- @klass.daemonizeme = 10
263
- expect(@klass[:daemonizeme]).to eql(10)
264
- end
265
-
266
- it "Configurables with the same name as the extra method can be retrieved" do
267
- @klass[:daemonizeme] = 10
268
- expect(@klass.daemonizeme).to eql(10)
269
- end
270
- end
271
- end
272
-
273
- describe "When config has a default value" do
274
- before :each do
275
- @klass = Class.new
276
- @klass.extend(::Mixlib::Config)
277
- @klass.class_eval { default :attr, 4 }
278
- end
279
-
280
- it "defaults to that value" do
281
- expect(@klass.attr).to eql(4)
282
- end
283
-
284
- it "defaults to that value when retrieved as a hash" do
285
- expect(@klass[:attr]).to eql(4)
286
- end
287
-
288
- it "is settable to another value" do
289
- @klass.attr 5
290
- expect(@klass.attr).to eql(5)
291
- end
292
-
293
- it "still defaults to that value after delete" do
294
- @klass.attr 5
295
- @klass.delete(:attr)
296
- expect(@klass.attr).to eql(4)
297
- end
298
-
299
- it "still defaults to that value after reset" do
300
- @klass.attr 5
301
- @klass.reset
302
- expect(@klass.attr).to eql(4)
303
- end
304
-
305
- it "save should not save anything for it" do
306
- expect(@klass.save).to eql({})
307
- end
308
-
309
- it "save with include_defaults should save all defaults" do
310
- expect(@klass.save(true)).to eql({ attr: 4 })
311
- end
312
-
313
- it "saves the new value if it gets set" do
314
- @klass.attr 5
315
- expect((saved = @klass.save)).to eql({ attr: 5 })
316
- @klass.reset
317
- expect(@klass.attr).to eql(4)
318
- @klass.restore(saved)
319
- expect(@klass.attr).to eql(5)
320
- end
321
-
322
- it "saves the new value even if it is set to its default value" do
323
- @klass.attr 4
324
- expect((saved = @klass.save)).to eql({ attr: 4 })
325
- @klass.reset
326
- expect(@klass.save).to eql({})
327
- @klass.restore(saved)
328
- expect(@klass.save).to eql({ attr: 4 })
329
- end
330
- end
331
-
332
- describe "When config has a default value block" do
333
- before :each do
334
- @klass = Class.new
335
- @klass.extend(::Mixlib::Config)
336
- @klass.class_eval do
337
- default :x, 4
338
- default(:attr) { x * 2 }
339
- end
340
- end
341
-
342
- it "defaults to that value" do
343
- expect(@klass.attr).to eql(8)
344
- end
345
-
346
- it "is recalculated each time it is retrieved" do
347
- expect(@klass.attr).to eql(8)
348
- @klass.x = 2
349
- expect(@klass.attr).to eql(4)
350
- end
351
-
352
- it "defaults to that value when retrieved as a hash" do
353
- expect(@klass[:attr]).to eql(8)
354
- end
355
-
356
- it "is settable to another value" do
357
- @klass.attr 5
358
- expect(@klass.attr).to eql(5)
359
- end
360
-
361
- it "still defaults to that value after delete" do
362
- @klass.attr 5
363
- @klass.delete(:attr)
364
- expect(@klass.attr).to eql(8)
365
- end
366
-
367
- it "still defaults to that value after reset" do
368
- @klass.attr 5
369
- @klass.reset
370
- expect(@klass.attr).to eql(8)
371
- end
372
-
373
- it "save should not save anything for it" do
374
- expect(@klass.save).to eql({})
375
- end
376
-
377
- it "save with include_defaults should save all defaults" do
378
- expect(@klass.save(true)).to eql({ attr: 8, x: 4 })
379
- end
380
-
381
- it "saves the new value if it gets set" do
382
- @klass.attr 5
383
- expect((saved = @klass.save)).to eql({ attr: 5 })
384
- @klass.reset
385
- expect(@klass.attr).to eql(8)
386
- @klass.restore(saved)
387
- expect(@klass.attr).to eql(5)
388
- end
389
-
390
- it "saves the new value even if it is set to its default value" do
391
- @klass.attr 8
392
- expect((saved = @klass.save)).to eql({ attr: 8 })
393
- @klass.reset
394
- expect(@klass.save).to eql({})
395
- @klass.restore(saved)
396
- expect(@klass.save).to eql({ attr: 8 })
397
- end
398
- end
399
-
400
- describe "When config has an array default value" do
401
- before :each do
402
- @klass = Class.new
403
- @klass.extend(::Mixlib::Config)
404
- @klass.class_eval { default :attr, [] }
405
- end
406
-
407
- it "reset clears it to its default" do
408
- @klass.attr << "x"
409
- expect(@klass.attr).to eql([ "x" ])
410
- @klass.reset
411
- expect(@klass.attr).to eql([])
412
- end
413
-
414
- it "save should not save anything for it" do
415
- expect(@klass.save).to eql({})
416
- end
417
-
418
- it "save with include_defaults should save all defaults" do
419
- expect(@klass.save(true)).to eql({ attr: [] })
420
- end
421
-
422
- it "saves the new value if it gets set" do
423
- @klass.attr << "x"
424
- expect((saved = @klass.save)).to eql({ attr: [ "x" ] })
425
- @klass.reset
426
- expect(@klass.attr).to eql([])
427
- @klass.restore(saved)
428
- expect(@klass.attr).to eql([ "x" ])
429
- end
430
-
431
- it "saves the new value even if it is set to its default value" do
432
- @klass.attr = []
433
- expect((saved = @klass.save)).to eql({ attr: [] })
434
- @klass.reset
435
- expect(@klass.save).to eql({})
436
- @klass.restore(saved)
437
- expect(@klass.save).to eql({ attr: [] })
438
- end
439
- end
440
-
441
- describe "When config has a hash default value" do
442
- before :each do
443
- @klass = Class.new
444
- @klass.extend(::Mixlib::Config)
445
- @klass.class_eval { default :attr, {} }
446
- end
447
-
448
- it "reset clears it to its default" do
449
- @klass.attr[:x] = 10
450
- expect(@klass.attr[:x]).to eql(10)
451
- @klass.reset
452
- expect(@klass.attr[:x]).to be_nil
453
- end
454
-
455
- it "save should not save anything for it" do
456
- expect(@klass.save).to eql({})
457
- end
458
-
459
- it "save with include_defaults should save all defaults" do
460
- expect(@klass.save(true)).to eql({ attr: {} })
461
- end
462
-
463
- it "saves the new value if it gets set" do
464
- @klass.attr[:hi] = "lo"
465
- expect((saved = @klass.save)).to eql({ attr: { hi: "lo" } })
466
- @klass.reset
467
- expect(@klass.attr).to eql({})
468
- @klass.restore(saved)
469
- expect(@klass.save).to eql({ attr: { hi: "lo" } })
470
- end
471
-
472
- it "saves the new value even if it is set to its default value" do
473
- @klass.attr = {}
474
- expect((saved = @klass.save)).to eql({ attr: {} })
475
- @klass.reset
476
- expect(@klass.save).to eql({})
477
- @klass.restore(saved)
478
- expect(@klass.save).to eql({ attr: {} })
479
- end
480
- end
481
-
482
- describe "When config has a string default value" do
483
- before :each do
484
- @klass = Class.new
485
- @klass.extend(::Mixlib::Config)
486
- @klass.class_eval { default :attr, "hello" }
487
- end
488
-
489
- it "reset clears it to its default" do
490
- @klass.attr << " world"
491
- expect(@klass.attr).to eql("hello world")
492
- @klass.reset
493
- expect(@klass.attr).to eql("hello")
494
- end
495
-
496
- it "save should not save anything for it" do
497
- expect(@klass.save).to eql({})
498
- end
499
-
500
- it "save with include_defaults should save all defaults" do
501
- expect(@klass.save(true)).to eql({ attr: "hello" })
502
- end
503
-
504
- it "saves the new value if it gets set" do
505
- @klass.attr << " world"
506
- expect((saved = @klass.save)).to eql({ attr: "hello world" })
507
- @klass.reset
508
- expect(@klass.attr).to eql("hello")
509
- @klass.restore(saved)
510
- expect(@klass.attr).to eql("hello world")
511
- end
512
-
513
- it "saves the new value even if it is set to its default value" do
514
- @klass.attr "hello world"
515
- expect((saved = @klass.save)).to eql({ attr: "hello world" })
516
- @klass.reset
517
- expect(@klass.save).to eql({})
518
- @klass.restore(saved)
519
- expect(@klass.save).to eql({ attr: "hello world" })
520
- end
521
- end
522
-
523
- describe "When config has a a default value block" do
524
- before :each do
525
- @klass = Class.new
526
- @klass.extend(::Mixlib::Config)
527
- @klass.class_eval do
528
- default(:attr) { 4 }
529
- end
530
- end
531
-
532
- it "defaults to that value" do
533
- expect(@klass.attr).to eql(4)
534
- end
535
-
536
- it "defaults to that value when retrieved as a hash" do
537
- expect(@klass[:attr]).to eql(4)
538
- end
539
-
540
- it "is settable to another value" do
541
- @klass.attr 5
542
- expect(@klass.attr).to eql(5)
543
- expect(@klass[:attr]).to eql(5)
544
- end
545
-
546
- it "still defaults to that value after delete" do
547
- @klass.attr 5
548
- @klass.delete(:attr)
549
- expect(@klass.attr).to eql(4)
550
- end
551
-
552
- it "still defaults to that value after reset" do
553
- @klass.attr 5
554
- @klass.reset
555
- expect(@klass.attr).to eql(4)
556
- end
557
-
558
- it "save should not save anything for it" do
559
- expect(@klass.save).to eql({})
560
- end
561
-
562
- it "save with include_defaults should save all defaults" do
563
- expect(@klass.save(true)).to eql({ attr: 4 })
564
- end
565
-
566
- it "saves the new value if it gets set" do
567
- @klass.attr 5
568
- expect((saved = @klass.save)).to eql({ attr: 5 })
569
- @klass.reset
570
- expect(@klass.attr).to eql(4)
571
- @klass.restore(saved)
572
- expect(@klass.attr).to eql(5)
573
- end
574
-
575
- it "saves the new value even if it is set to its default value" do
576
- @klass.attr 4
577
- expect((saved = @klass.save)).to eql({ attr: 4 })
578
- @klass.reset
579
- expect(@klass.save).to eql({})
580
- @klass.restore(saved)
581
- expect(@klass.save).to eql({ attr: 4 })
582
- end
583
- end
584
-
585
- describe "When a configurable exists with writer and default value" do
586
- before :each do
587
- @klass = Class.new
588
- @klass.extend(::Mixlib::Config)
589
- @klass.class_eval do
590
- configurable(:attr) do |c|
591
- c.defaults_to(4)
592
- c.writes_value { |value| value * 2 }
593
- end
594
- end
595
- end
596
-
597
- it "defaults to that value" do
598
- expect(@klass.attr).to eql(4)
599
- end
600
-
601
- it "defaults to that value when retrieved as a hash" do
602
- expect(@klass[:attr]).to eql(4)
603
- end
604
-
605
- it "is settable to another value" do
606
- @klass.attr 5
607
- expect(@klass.attr).to eql(10)
608
- expect(@klass[:attr]).to eql(10)
609
- end
610
-
611
- it "is settable to another value with attr=" do
612
- @klass.attr = 5
613
- expect(@klass.attr).to eql(10)
614
- expect(@klass[:attr]).to eql(10)
615
- end
616
-
617
- it "is settable to another value with [:attr]=" do
618
- @klass[:attr] = 5
619
- expect(@klass.attr).to eql(10)
620
- expect(@klass[:attr]).to eql(10)
621
- end
622
-
623
- it "still defaults to that value after delete" do
624
- @klass.attr 5
625
- @klass.delete(:attr)
626
- expect(@klass.attr).to eql(4)
627
- end
628
-
629
- it "still defaults to that value after reset" do
630
- @klass.attr 5
631
- @klass.reset
632
- expect(@klass.attr).to eql(4)
633
- end
634
-
635
- it "save should not save anything for it" do
636
- expect(@klass.save).to eql({})
637
- end
638
-
639
- it "save with include_defaults should save all defaults" do
640
- expect(@klass.save(true)).to eql({ attr: 4 })
641
- end
642
-
643
- it "saves the new value if it gets set" do
644
- @klass.attr 5
645
- expect((saved = @klass.save)).to eql({ attr: 10 })
646
- @klass.reset
647
- expect(@klass.attr).to eql(4)
648
- @klass.restore(saved)
649
- expect(@klass.attr).to eql(10)
650
- end
651
-
652
- it "saves the new value even if it is set to its default value" do
653
- @klass.attr 4
654
- expect((saved = @klass.save)).to eql({ attr: 8 })
655
- @klass.reset
656
- expect(@klass.save).to eql({})
657
- @klass.restore(saved)
658
- expect(@klass.save).to eql({ attr: 8 })
659
- end
660
- end
661
-
662
- describe "When a configurable exists with writer and default value set in chained form" do
663
- before :each do
664
- @klass = Class.new
665
- @klass.extend(::Mixlib::Config)
666
- @klass.class_eval do
667
- configurable(:attr).defaults_to(4).writes_value { |value| value * 2 }
668
- end
669
- end
670
-
671
- it "defaults to that value" do
672
- expect(@klass.attr).to eql(4)
673
- end
674
-
675
- it "defaults to that value when retrieved as a hash" do
676
- expect(@klass[:attr]).to eql(4)
677
- end
678
-
679
- it "is settable to another value" do
680
- @klass.attr 5
681
- expect(@klass.attr).to eql(10)
682
- expect(@klass[:attr]).to eql(10)
683
- end
684
-
685
- it "is settable to another value with attr=" do
686
- @klass.attr = 5
687
- expect(@klass.attr).to eql(10)
688
- expect(@klass[:attr]).to eql(10)
689
- end
690
-
691
- it "is settable to another value with [:attr]=" do
692
- @klass[:attr] = 5
693
- expect(@klass.attr).to eql(10)
694
- expect(@klass[:attr]).to eql(10)
695
- end
696
-
697
- it "still defaults to that value after delete" do
698
- @klass.attr 5
699
- @klass.delete(:attr)
700
- expect(@klass.attr).to eql(4)
701
- end
702
-
703
- it "still defaults to that value after reset" do
704
- @klass.attr 5
705
- @klass.reset
706
- expect(@klass.attr).to eql(4)
707
- end
708
-
709
- it "save should not save anything for it" do
710
- expect(@klass.save).to eql({})
711
- end
712
-
713
- it "save with include_defaults should save all defaults" do
714
- expect(@klass.save(true)).to eql({ attr: 4 })
715
- end
716
-
717
- it "saves the new value if it gets set" do
718
- @klass.attr 5
719
- expect((saved = @klass.save)).to eql({ attr: 10 })
720
- @klass.reset
721
- expect(@klass.attr).to eql(4)
722
- @klass.restore(saved)
723
- expect(@klass.attr).to eql(10)
724
- end
725
-
726
- it "saves the new value even if it is set to its default value" do
727
- @klass.attr 2
728
- expect((saved = @klass.save)).to eql({ attr: 4 })
729
- @klass.reset
730
- expect(@klass.save).to eql({})
731
- @klass.restore(saved)
732
- expect(@klass.save).to eql({ attr: 4 })
733
- end
734
- end
735
-
736
- describe "When a configurable exists with a context" do
737
- before :each do
738
- @klass = Class.new
739
- @klass.extend(::Mixlib::Config)
740
- @klass.class_eval do
741
- configurable :x
742
- config_context(:blah) do
743
- default :x, 5
744
- end
745
- end
746
- end
747
-
748
- it "configurable defaults in that context work" do
749
- expect(@klass.blah.x).to eql(5)
750
- end
751
-
752
- it "after setting values in the context, the values remain set" do
753
- @klass.blah.x = 10
754
- expect(@klass.blah.x).to eql(10)
755
- end
756
-
757
- it "setting values with the same name in the parent context do not affect the child context" do
758
- @klass.x = 10
759
- expect(@klass.x).to eql(10)
760
- expect(@klass.blah.x).to eql(5)
761
- end
762
-
763
- it "setting the entire context to a hash with default value overridden sets the value" do
764
- @klass.blah = { x: 10 }
765
- expect(@klass.blah.x).to eql(10)
766
- end
767
-
768
- it "setting the entire context to a hash sets non-default values" do
769
- @klass.blah = { y: 10 }
770
- expect(@klass.blah.x).to eql(5)
771
- expect(@klass.blah.y).to eql(10)
772
- end
773
-
774
- it "setting the entire context to a hash deletes any non-default values and resets default values" do
775
- @klass.blah.x = 10
776
- @klass.blah.y = 10
777
- @klass.blah = { z: 10 }
778
- expect(@klass.blah.x).to eql(5)
779
- expect(@klass.blah.y).to be_nil
780
- expect(@klass.blah.z).to eql(10)
781
- end
782
-
783
- it "setting the context values in a block overrides the default values" do
784
- @klass.blah do
785
- x 10
786
- y 20
787
- end
788
- expect(@klass.blah.x).to eq 10
789
- expect(@klass.blah.y).to eq 20
790
- end
791
-
792
- it "setting the context values in a yielded block overrides the default values" do
793
- @klass.blah do |b|
794
- b.x = 10
795
- b.y = 20
796
- end
797
- expect(@klass.blah.x).to eq 10
798
- expect(@klass.blah.y).to eq 20
799
- end
800
-
801
- it "after reset of the parent class, children are reset" do
802
- @klass.blah.x = 10
803
- expect(@klass.blah.x).to eql(10)
804
- @klass.reset
805
- expect(@klass.blah.x).to eql(5)
806
- end
807
-
808
- it "save should not save anything for it by default" do
809
- expect(@klass.save).to eql({})
810
- end
811
-
812
- it "save with include_defaults should save all defaults" do
813
- expect(@klass.save(true)).to eql({ blah: { x: 5 } })
814
- end
815
-
816
- it "saves any new values that are set in the context" do
817
- @klass.blah.x = 10
818
- expect((saved = @klass.save)).to eql({ blah: { x: 10 } })
819
- @klass.reset
820
- expect(@klass.blah.x).to eql(5)
821
- @klass.restore(saved)
822
- expect(@klass.blah.x).to eql(10)
823
- expect(@klass.save).to eql({ blah: { x: 10 } })
824
- end
825
-
826
- # this tests existing (somewhat bizzare) behavior of mixlib-config where testing to
827
- # see if a key exists is equivalent to testing if the key has been set -- we can still
828
- # retrieve the default value if it was set. the code in chef/chef which merges
829
- # knife config values into cli values will be sensitive to this behavior.
830
- it "defaults values do not show up when querying with #has_key?" do
831
- expect(@klass.blah.has_key?(:x)).to be false
832
- expect(@klass.blah.x).to be 5
833
- end
834
-
835
- it "if we assign the values, they show up when querying with #has_key?" do
836
- @klass.blah.x = 5
837
- expect(@klass.blah.has_key?(:x)).to be true
838
- end
839
- end
840
-
841
- describe "When a configurable exists with a nested context" do
842
- before :each do
843
- @klass = Class.new
844
- @klass.extend(::Mixlib::Config)
845
- @klass.class_eval do
846
- config_context(:blah) do
847
- config_context(:yarr) do
848
- default :x, 5
849
- default :y, 6
850
- end
851
- end
852
- configurable :x
853
- end
854
- end
855
-
856
- it "configurable defaults in that context work" do
857
- expect(@klass.blah.yarr.x).to eql(5)
858
- expect(@klass.blah.yarr.y).to eql(6)
859
- end
860
-
861
- it "after setting values in the context, the values remain set" do
862
- @klass.blah.yarr.x = 10
863
- @klass.blah.yarr.y = 11
864
- expect(@klass.blah.yarr.x).to eql(10)
865
- expect(@klass.blah.yarr.y).to eql(11)
866
- end
867
-
868
- it "setting values with the same name in the parent context do not affect the child context" do
869
- @klass.x = 10
870
- expect(@klass.x).to eql(10)
871
- expect(@klass.blah.yarr.x).to eql(5)
872
- end
873
-
874
- it "after reset of the parent class, children are reset" do
875
- @klass.blah.yarr.x = 10
876
- @klass.blah.yarr.y = 11
877
- expect(@klass.blah.yarr.x).to eql(10)
878
- expect(@klass.blah.yarr.y).to eql(11)
879
- @klass.reset
880
- expect(@klass.blah.yarr.x).to eql(5)
881
- expect(@klass.blah.yarr.y).to eql(6)
882
- end
883
-
884
- it "save should not save anything for it by default" do
885
- expect(@klass.save).to eql({})
886
- end
887
-
888
- it "save with include_defaults should save all defaults" do
889
- expect(@klass.save(true)).to eql({ blah: { yarr: { x: 5, y: 6 } } })
890
- end
891
-
892
- it "saves any new values that are set in the context" do
893
- @klass.blah.yarr.x = 10
894
- @klass.blah.yarr.y = 11
895
- expect((saved = @klass.save)).to eql({ blah: { yarr: { x: 10, y: 11 } } })
896
- @klass.reset
897
- expect(@klass.blah.yarr.x).to eql(5)
898
- expect(@klass.blah.yarr.y).to eql(6)
899
- @klass.restore(saved)
900
- expect(@klass.blah.yarr.x).to eql(10)
901
- expect(@klass.blah.yarr.y).to eql(11)
902
- expect(@klass.save).to eql({ blah: { yarr: { x: 10, y: 11 } } })
903
- end
904
-
905
- it "restores defaults not included in saved data" do
906
- @klass.restore( blah: { yarr: { x: 10 } } )
907
- expect(@klass.blah.yarr.x).to eql(10)
908
- expect(@klass.blah.yarr.y).to eql(6)
909
- end
910
-
911
- it "removes added properties not included in saved state" do
912
- @klass.blah.yarr.z = 12
913
- @klass.restore( blah: { yarr: { x: 10 } } )
914
- expect(@klass.blah.yarr.x).to eql(10)
915
- expect(@klass.blah.yarr.z).to eql(nil)
916
- end
917
-
918
- it "can set a config context from another context" do
919
- @klass.blah.blyme = { x: 7 }
920
- blyme = @klass.blah.blyme
921
- @klass.blah.yarr.x = 12
922
- @klass.blah.yarr = blyme
923
- expect(@klass.blah.yarr.x).to eql(7)
924
- end
925
- end
926
-
927
- describe "When a config_context with no defaulted values exists" do
928
- before :each do
929
- @klass = Class.new
930
- @klass.extend(::Mixlib::Config)
931
- @klass.class_eval do
932
- config_context(:blah) do
933
- configurable(:x)
934
- end
935
- end
936
- end
937
-
938
- it "has_key? finds the subcontext" do
939
- expect(@klass.has_key?(:blah)).to be true
940
- end
941
-
942
- it "key? finds the subcontext" do
943
- expect(@klass.key?(:blah)).to be true
944
- end
945
-
946
- it "save does not save the hash for the config_context" do
947
- expect(@klass.save).to eql({})
948
- end
949
-
950
- it "save with defaults saves the hash for the config_context" do
951
- expect(@klass.save(true)).to eql({ blah: {} })
952
- end
953
- end
954
-
955
- describe "When a config_context with no configurables exists" do
956
- before :each do
957
- @klass = Class.new
958
- @klass.extend(::Mixlib::Config)
959
- @klass.class_eval do
960
- config_context(:blah)
961
- end
962
- end
963
-
964
- it "save does not save the hash for the config_context" do
965
- expect(@klass.save).to eql({})
966
- end
967
-
968
- it "save with defaults saves the hash for the config_context" do
969
- expect(@klass.save(true)).to eql({ blah: {} })
970
- end
971
- end
972
-
973
- describe "When a nested context has strict mode on" do
974
- class StrictClass2
975
- extend ::Mixlib::Config
976
- config_context :c do
977
- config_strict_mode true
978
- default :x, 1
979
- end
980
- end
981
-
982
- it "The parent class allows you to set arbitrary config options" do
983
- StrictClass2.y = 10
984
- end
985
-
986
- it "The nested class does not allow you to set arbitrary config options" do
987
- expect(lambda { StrictClass2.c.y = 10 }).to raise_error(Mixlib::Config::UnknownConfigOptionError, "Cannot set unsupported config value y.")
988
- end
989
- end
990
-
991
- describe "When strict mode is on but a nested context has strict mode unspecified" do
992
- class StrictClass3
993
- extend ::Mixlib::Config
994
- config_strict_mode true
995
- default :x, 1
996
- config_context :c
997
- end
998
-
999
- it "The parent class does not allow you to set arbitrary config options" do
1000
- expect(lambda { StrictClass3.y = 10 }).to raise_error(Mixlib::Config::UnknownConfigOptionError, "Cannot set unsupported config value y.")
1001
- end
1002
-
1003
- it "The nested class does not allow you to set arbitrary config options" do
1004
- expect(lambda { StrictClass3.y = 10 }).to raise_error(Mixlib::Config::UnknownConfigOptionError, "Cannot set unsupported config value y.")
1005
- end
1006
- end
1007
-
1008
- describe "When a config_context is opened twice" do
1009
- before :each do
1010
- @klass = Class.new
1011
- @klass.extend(::Mixlib::Config)
1012
- @klass.class_eval do
1013
- config_context(:blah) do
1014
- default :x, 10
1015
- end
1016
- config_context(:blah) do
1017
- default :y, 20
1018
- end
1019
- end
1020
- end
1021
-
1022
- it "Both config_context blocks are honored" do
1023
- @klass.blah.x == 10
1024
- @klass.blah.y == 20
1025
- end
1026
- end
1027
-
1028
- it "When a config_context is opened in place of a regular configurable, an error is raised" do
1029
- klass = Class.new
1030
- klass.extend(::Mixlib::Config)
1031
- expect(lambda do
1032
- klass.class_eval do
1033
- default :blah, 10
1034
- config_context(:blah) do
1035
- default :y, 20
1036
- end
1037
- end
1038
- end).to raise_error(Mixlib::Config::ReopenedConfigurableWithConfigContextError)
1039
- end
1040
-
1041
- it "When a config_context is opened in place of a regular configurable, an error is raised" do
1042
- klass = Class.new
1043
- klass.extend(::Mixlib::Config)
1044
- expect(lambda do
1045
- klass.class_eval do
1046
- config_context(:blah) do
1047
- default :y, 20
1048
- end
1049
- default :blah, 10
1050
- end
1051
- end).to raise_error(Mixlib::Config::ReopenedConfigContextWithConfigurableError)
1052
- end
1053
-
1054
- describe "config context lists" do
1055
- let(:klass) do
1056
- klass = Class.new
1057
- klass.extend ::Mixlib::Config
1058
- klass.instance_eval do
1059
- config_context_list(:tests, :test) do
1060
- default :y, 20
1061
- end
1062
- end
1063
- klass
1064
- end
1065
- it "defines list methods when declaring a config_context_list" do
1066
- expect(klass.methods).to include :test
1067
- expect(klass.methods).to include :tests
1068
- end
1069
-
1070
- it "creates a new item each time the singular list is called" do
1071
- klass.test do
1072
- y 40
1073
- end
1074
- klass.test do
1075
- y 50
1076
- end
1077
- expect(klass.tests.length).to be 2
1078
- expect(klass.tests.first.y).to be 40
1079
- expect(klass.tests.last.y).to be 50
1080
- end
1081
-
1082
- it "can save the config list" do
1083
- klass.test do
1084
- y 40
1085
- end
1086
- klass.test do
1087
- y 50
1088
- end
1089
- expect(klass.save).to eq({
1090
- tests: [
1091
- { y: 40 },
1092
- { y: 50 },
1093
- ],
1094
- })
1095
- end
1096
-
1097
- it "can restore the config list from a hash" do
1098
- hash = {
1099
- tests: [
1100
- { y: 40 },
1101
- { y: 50 },
1102
- ],
1103
- }
1104
- klass.restore(hash)
1105
- expect(klass.tests.length).to be 2
1106
- expect(klass.tests.first.y).to be 40
1107
- expect(klass.tests.last.y).to be 50
1108
- end
1109
- end
1110
-
1111
- describe "config context hashes" do
1112
- let(:klass) do
1113
- klass = Class.new
1114
- klass.extend ::Mixlib::Config
1115
- klass.instance_eval do
1116
- config_context_hash(:tests, :test) do
1117
- default :y, 20
1118
- end
1119
- end
1120
- klass
1121
- end
1122
-
1123
- it "defines list methods when declaring a config_context_hash" do
1124
- expect(klass.methods).to include :test
1125
- expect(klass.methods).to include :tests
1126
- end
1127
-
1128
- context "when called with a new key each time" do
1129
- it "creates a new item each time" do
1130
- klass.test :one do
1131
- y 40
1132
- end
1133
- klass.test :two do
1134
- y 50
1135
- end
1136
- expect(klass.tests.length).to be 2
1137
- expect(klass.tests[:one].y).to be 40
1138
- expect(klass.tests[:two].y).to be 50
1139
- end
1140
- end
1141
- context "when called with the same key" do
1142
- it "modifies the existing value" do
1143
- klass.test :only do
1144
- y 40
1145
- end
1146
- klass.test :only do
1147
- y 50
1148
- end
1149
- expect(klass.tests.length).to be 1
1150
- expect(klass.tests[:only].y).to be 50
1151
- end
1152
- end
1153
-
1154
- it "can save the config hash" do
1155
- klass.test :one do
1156
- y 40
1157
- end
1158
- klass.test :two do
1159
- y 50
1160
- end
1161
- expect(klass.save).to eq({
1162
- tests: {
1163
- one: { y: 40 },
1164
- two: { y: 50 },
1165
- },
1166
- })
1167
- end
1168
-
1169
- it "can restore the config hash from a hash" do
1170
- hash = {
1171
- tests: {
1172
- one: { y: 40 },
1173
- two: { y: 50 },
1174
- },
1175
- }
1176
- klass.restore(hash)
1177
- expect(klass.tests.length).to be 2
1178
- expect(klass.tests[:one].y).to be 40
1179
- expect(klass.tests[:two].y).to be 50
1180
- end
1181
- end
1182
-
1183
- describe ".from_yaml" do
1184
- let(:yaml) do
1185
- <<-EOH
1186
- ---
1187
- foo:
1188
- - bar
1189
- - baz
1190
- - matazz
1191
- alpha: beta
1192
- EOH
1193
- end
1194
-
1195
- it "turns YAML into method-style setting" do
1196
- allow(File).to receive(:exists?).and_return(true)
1197
- allow(File).to receive(:readable?).and_return(true)
1198
- allow(IO).to receive(:read).with("config.yml").and_return(yaml)
1199
-
1200
- expect(lambda do
1201
- ConfigIt.from_file("config.yml")
1202
- end).to_not raise_error
1203
-
1204
- expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
1205
- expect(ConfigIt.alpha).to eql("beta")
1206
- end
1207
- end
1208
-
1209
- describe ".from_json" do
1210
- let(:json) do
1211
- <<-EOH
1212
- {
1213
- "foo": [
1214
- "bar",
1215
- "baz",
1216
- "matazz"
1217
- ],
1218
- "alpha": "beta"
1219
- }
1220
- EOH
1221
- end
1222
-
1223
- it "turns JSON into method-style setting" do
1224
- allow(File).to receive(:exists?).and_return(true)
1225
- allow(File).to receive(:readable?).and_return(true)
1226
- allow(IO).to receive(:read).with("config.json").and_return(json)
1227
-
1228
- expect(lambda do
1229
- ConfigIt.from_file("config.json")
1230
- end).to_not raise_error
1231
-
1232
- expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
1233
- expect(ConfigIt.alpha).to eql("beta")
1234
- end
1235
- end
1236
-
1237
- describe ".from_toml" do
1238
- let(:toml) do
1239
- <<-EOH
1240
- foo = ["bar", "baz", "matazz"]
1241
- alpha = "beta"
1242
- EOH
1243
- end
1244
-
1245
- it "turns TOML into method-style setting" do
1246
- allow(File).to receive(:exists?).and_return(true)
1247
- allow(File).to receive(:readable?).and_return(true)
1248
- allow(IO).to receive(:read).with("config.toml").and_return(toml)
1249
-
1250
- expect(lambda do
1251
- ConfigIt.from_file("config.toml")
1252
- end).to_not raise_error
1253
-
1254
- expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
1255
- expect(ConfigIt.alpha).to eql("beta")
1256
- end
1257
- end
1258
-
1259
- describe ".from_hash" do
1260
- let(:hash) do
1261
- {
1262
- "alpha" => "beta",
1263
- "foo" => %w{ bar baz matazz},
1264
- }
1265
- end
1266
-
1267
- it "translates the Hash into method-style" do
1268
- ConfigIt.from_hash(hash)
1269
- expect(ConfigIt.foo).to eql(%w{ bar baz matazz })
1270
- expect(ConfigIt.alpha).to eql("beta")
1271
- end
1272
- end
1273
- end