mixlib-config 1.1.2 → 2.0.0.rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,55 @@
1
+ #
2
+ # Author:: John Keiser (<jkeiser@opscode.com>)
3
+ # Copyright:: Copyright (c) 2013 Opscode, 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
+ module Mixlib
20
+ module Config
21
+ class Configurable
22
+ def initialize(symbol)
23
+ @symbol = symbol
24
+ @default = nil
25
+ @default_value = nil
26
+ @writes_value = nil
27
+ end
28
+
29
+ def defaults_to(default_value = nil, &block)
30
+ @default = block
31
+ @default_value = default_value
32
+ self
33
+ end
34
+
35
+ def writes_value(&block)
36
+ @writes_value = block
37
+ self
38
+ end
39
+
40
+ def get(config)
41
+ if config.has_key?(@symbol)
42
+ config[@symbol]
43
+ elsif @default
44
+ @default.call
45
+ else
46
+ @default_value
47
+ end
48
+ end
49
+
50
+ def set(config, value)
51
+ config[@symbol] = @writes_value ? @writes_value.call(value) : value
52
+ end
53
+ end
54
+ end
55
+ end
@@ -1,14 +1,14 @@
1
1
  #
2
- # Author:: Adam Jacob (<adam@opscode.com>)
3
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
2
+ # Author:: John Keiser (<jkeiser@opscode.com>)
3
+ # Copyright:: Copyright (c) 2013 Opscode, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
8
8
  # You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing, software
13
13
  # distributed under the License is distributed on an "AS IS" BASIS,
14
14
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,16 +16,9 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- $: << File.join(File.dirname(__FILE__), '..', '..', 'lib')
20
-
21
- require 'spec/expectations'
22
- require 'mixlib/config'
23
- require 'tmpdir'
24
- require 'stringio'
25
-
26
- class MyWorld
27
- end
28
-
29
- World do
30
- MyWorld.new
19
+ module Mixlib
20
+ module Config
21
+ class InvalidValueError < Error
22
+ end
23
+ end
31
24
  end
@@ -0,0 +1,24 @@
1
+ #
2
+ # Author:: John Keiser (<jkeiser@opscode.com>)
3
+ # Copyright:: Copyright (c) 2013 Opscode, 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
+ module Mixlib
20
+ module Config
21
+ class UnknownConfigOptionError < StandardError
22
+ end
23
+ end
24
+ end
@@ -1,14 +1,14 @@
1
1
  #
2
- # Author:: Adam Jacob (<adam@opscode.com>)
3
- # Copyright:: Copyright (c) 2008 Opscode, Inc.
2
+ # Author:: Daniel DeLeo (<dan@opscode.com>)
3
+ # Copyright:: Copyright (c) 2013 Opscode, Inc.
4
4
  # License:: Apache License, Version 2.0
5
5
  #
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
8
8
  # You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing, software
13
13
  # distributed under the License is distributed on an "AS IS" BASIS,
14
14
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -16,13 +16,10 @@
16
16
  # limitations under the License.
17
17
  #
18
18
 
19
- $: << File.join(File.dirname(__FILE__), '..', '..', 'lib')
20
- require 'mixlib/config'
19
+ module Mixlib
20
+ module Config
21
21
 
22
- class ConfigIt
23
- extend Mixlib::Config
24
- end
22
+ VERSION = "2.0.0.rc.1"
25
23
 
26
- class ConfigItToo
27
- extend Mixlib::Config
28
- end
24
+ end
25
+ end
@@ -6,9 +6,9 @@
6
6
  # Licensed under the Apache License, Version 2.0 (the "License");
7
7
  # you may not use this file except in compliance with the License.
8
8
  # You may obtain a copy of the License at
9
- #
9
+ #
10
10
  # http://www.apache.org/licenses/LICENSE-2.0
11
- #
11
+ #
12
12
  # Unless required by applicable law or agreed to in writing, software
13
13
  # distributed under the License is distributed on an "AS IS" BASIS,
14
14
  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -30,39 +30,39 @@ describe Mixlib::Config do
30
30
  c[:foo] = nil
31
31
  end
32
32
  end
33
-
33
+
34
34
  it "should load a config file" do
35
- File.stub!(:exists?).and_return(true)
36
- File.stub!(:readable?).and_return(true)
37
- IO.stub!(:read).with('config.rb').and_return("alpha = 'omega'\nfoo = 'bar'")
38
- lambda {
35
+ File.stub(:exists?).and_return(true)
36
+ File.stub(:readable?).and_return(true)
37
+ IO.stub(:read).with('config.rb').and_return("alpha = 'omega'\nfoo = 'bar'")
38
+ lambda {
39
39
  ConfigIt.from_file('config.rb')
40
40
  }.should_not raise_error
41
41
  end
42
-
42
+
43
43
  it "should not raise an ArgumentError with an explanation if you try and set a non-existent variable" do
44
- lambda {
44
+ lambda {
45
45
  ConfigIt[:foobar] = "blah"
46
- }.should_not raise_error(ArgumentError)
46
+ }.should_not raise_error
47
47
  end
48
-
48
+
49
49
  it "should raise an Errno::ENOENT if it can't find the file" do
50
- lambda {
50
+ lambda {
51
51
  ConfigIt.from_file("/tmp/timmytimmytimmy")
52
52
  }.should raise_error(Errno::ENOENT)
53
53
  end
54
54
 
55
55
  it "should allow the error to bubble up when it's anything other than IOError" do
56
- IO.stub!(:read).with('config.rb').and_return("@#asdf")
56
+ IO.stub(:read).with('config.rb').and_return("@#asdf")
57
57
  lambda {
58
58
  ConfigIt.from_file('config.rb')
59
59
  }.should raise_error(SyntaxError)
60
60
  end
61
-
61
+
62
62
  it "should allow you to reference a value by index" do
63
63
  ConfigIt[:alpha].should == 'omega'
64
64
  end
65
-
65
+
66
66
  it "should allow you to set a value by index" do
67
67
  ConfigIt[:alpha] = "one"
68
68
  ConfigIt[:alpha].should == "one"
@@ -73,12 +73,51 @@ describe Mixlib::Config do
73
73
  ConfigIt.arbitrary_value.should == 50
74
74
  ConfigIt[:arbitrary_value].should == 50
75
75
  end
76
-
76
+
77
+ it "should allow setting a value with method form" do
78
+ ConfigIt.arbitrary_value 50
79
+ ConfigIt.arbitrary_value.should == 50
80
+ ConfigIt[:arbitrary_value].should == 50
81
+ end
82
+
83
+ describe "when strict mode is on" do
84
+ class StrictClass
85
+ extend ::Mixlib::Config
86
+ config_strict_mode true
87
+ default :x, 1
88
+ end
89
+
90
+ it "allows you to get and set configured values" do
91
+ StrictClass.x = StrictClass.x * 2
92
+ StrictClass[:x] = StrictClass[:x] * 2
93
+ end
94
+
95
+ it "raises an error when you get an arbitrary config option with .y" do
96
+ lambda { StrictClass.y }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
97
+ end
98
+
99
+ it "raises an error when you get an arbitrary config option with [:y]" do
100
+ lambda { StrictClass[:y] }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
101
+ end
102
+
103
+ it "raises an error when you set an arbitrary config option with .y = 10" do
104
+ lambda { StrictClass.y = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
105
+ end
106
+
107
+ it "raises an error when you get an arbitrary config option with .y 10" do
108
+ lambda { StrictClass.y 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
109
+ end
110
+
111
+ it "raises an error when you get an arbitrary config option with [:y] = 10" do
112
+ lambda { StrictClass[:y] = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
113
+ end
114
+ end
115
+
77
116
  describe "when a block has been used to set config values" do
78
117
  before do
79
118
  ConfigIt.configure { |c| c[:cookbook_path] = "monkey_rabbit"; c[:otherthing] = "boo" }
80
119
  end
81
-
120
+
82
121
  {:cookbook_path => "monkey_rabbit", :otherthing => "boo"}.each do |k,v|
83
122
  it "should allow you to retrieve the config value for #{k} via []" do
84
123
  ConfigIt[k].should == v
@@ -88,18 +127,18 @@ describe Mixlib::Config do
88
127
  end
89
128
  end
90
129
  end
91
-
130
+
92
131
  it "should not raise an ArgumentError if you access a config option that does not exist" do
93
- lambda { ConfigIt[:snob_hobbery] }.should_not raise_error(ArgumentError)
132
+ lambda { ConfigIt[:snob_hobbery] }.should_not raise_error
94
133
  end
95
-
134
+
96
135
  it "should return true or false with has_key?" do
97
136
  ConfigIt.has_key?(:monkey).should eql(false)
98
137
  ConfigIt[:monkey] = "gotcha"
99
138
  ConfigIt.has_key?(:monkey).should eql(true)
100
139
  end
101
-
102
- describe "when a class method override accessor exists" do
140
+
141
+ describe "when a class method override writer exists" do
103
142
  before do
104
143
  @klass = Class.new
105
144
  @klass.extend(::Mixlib::Config)
@@ -107,7 +146,6 @@ describe Mixlib::Config do
107
146
  config_attr_writer :test_method do |blah|
108
147
  blah.is_a?(Integer) ? blah * 1000 : blah
109
148
  end
110
- pp self.methods
111
149
  EVAL
112
150
  end
113
151
 
@@ -127,15 +165,288 @@ describe Mixlib::Config do
127
165
  end
128
166
 
129
167
  it "should multiply an integer by 1000 via from-file, too" do
130
- IO.stub!(:read).with('config.rb').and_return("test_method 99")
168
+ IO.stub(:read).with('config.rb').and_return("test_method 99")
131
169
  @klass.from_file('config.rb')
132
170
  @klass.test_method.should == 99000
133
171
  end
134
-
172
+
135
173
  it "should receive internal_set with the method name and config value" do
136
174
  @klass.should_receive(:internal_set).with(:test_method, 53).and_return(true)
137
175
  @klass[:test_method] = 53
138
176
  end
139
-
177
+
178
+ end
179
+
180
+ describe "When a default value exists" do
181
+ before :each do
182
+ @klass = Class.new
183
+ @klass.extend(::Mixlib::Config)
184
+ @klass.class_eval { default :attr, 4 }
185
+ end
186
+
187
+ it "should default to that value" do
188
+ @klass.attr.should == 4
189
+ end
190
+
191
+ it "should default to that value when retrieved as a hash" do
192
+ @klass[:attr].should == 4
193
+ end
194
+
195
+ it "should be settable to another value" do
196
+ @klass.attr 5
197
+ @klass.attr.should == 5
198
+ end
199
+
200
+ it "should still default to that value after delete" do
201
+ @klass.attr 5
202
+ @klass.delete(:attr)
203
+ @klass.attr.should == 4
204
+ end
205
+
206
+ it "should still default to that value after reset" do
207
+ @klass.attr 5
208
+ @klass.reset
209
+ @klass.attr.should == 4
210
+ end
211
+ end
212
+
213
+ describe "When a default value block exists" do
214
+ before :each do
215
+ @klass = Class.new
216
+ @klass.extend(::Mixlib::Config)
217
+ @klass.class_eval do
218
+ default(:attr) { 4 }
219
+ end
220
+ end
221
+
222
+ it "should default to that value" do
223
+ @klass.attr.should == 4
224
+ end
225
+
226
+ it "should default to that value when retrieved as a hash" do
227
+ @klass[:attr].should == 4
228
+ end
229
+
230
+ it "should be settable to another value" do
231
+ @klass.attr 5
232
+ @klass.attr.should == 5
233
+ @klass[:attr].should == 5
234
+ end
235
+
236
+ it "should still default to that value after delete" do
237
+ @klass.attr 5
238
+ @klass.delete(:attr)
239
+ @klass.attr.should == 4
240
+ end
241
+
242
+ it "should still default to that value after reset" do
243
+ @klass.attr 5
244
+ @klass.reset
245
+ @klass.attr.should == 4
246
+ end
247
+ end
248
+
249
+ describe "When a configurable exists with writer and default value" do
250
+ before :each do
251
+ @klass = Class.new
252
+ @klass.extend(::Mixlib::Config)
253
+ @klass.class_eval do
254
+ configurable(:attr) do |c|
255
+ c.defaults_to(4)
256
+ c.writes_value { |value| value*2 }
257
+ end
258
+ end
259
+ end
260
+
261
+ it "should default to that value" do
262
+ @klass.attr.should == 4
263
+ end
264
+
265
+ it "should default to that value when retrieved as a hash" do
266
+ @klass[:attr].should == 4
267
+ end
268
+
269
+ it "should be settable to another value" do
270
+ @klass.attr 5
271
+ @klass.attr.should == 10
272
+ @klass[:attr].should == 10
273
+ end
274
+
275
+ it "should be settable to another value with attr=" do
276
+ @klass.attr = 5
277
+ @klass.attr.should == 10
278
+ @klass[:attr].should == 10
279
+ end
280
+
281
+ it "should be settable to another value with [:attr]=" do
282
+ @klass[:attr] = 5
283
+ @klass.attr.should == 10
284
+ @klass[:attr].should == 10
285
+ end
286
+
287
+ it "should still default to that value after delete" do
288
+ @klass.attr 5
289
+ @klass.delete(:attr)
290
+ @klass.attr.should == 4
291
+ end
292
+
293
+ it "should still default to that value after reset" do
294
+ @klass.attr 5
295
+ @klass.reset
296
+ @klass.attr.should == 4
297
+ end
298
+ end
299
+
300
+ describe "When a configurable exists with writer and default value set in chained form" do
301
+ before :each do
302
+ @klass = Class.new
303
+ @klass.extend(::Mixlib::Config)
304
+ @klass.class_eval do
305
+ configurable(:attr).defaults_to(4).writes_value { |value| value*2 }
306
+ end
307
+ end
308
+
309
+ it "should default to that value" do
310
+ @klass.attr.should == 4
311
+ end
312
+
313
+ it "should default to that value when retrieved as a hash" do
314
+ @klass[:attr].should == 4
315
+ end
316
+
317
+ it "should be settable to another value" do
318
+ @klass.attr 5
319
+ @klass.attr.should == 10
320
+ @klass[:attr].should == 10
321
+ end
322
+
323
+ it "should be settable to another value with attr=" do
324
+ @klass.attr = 5
325
+ @klass.attr.should == 10
326
+ @klass[:attr].should == 10
327
+ end
328
+
329
+ it "should be settable to another value with [:attr]=" do
330
+ @klass[:attr] = 5
331
+ @klass.attr.should == 10
332
+ @klass[:attr].should == 10
333
+ end
334
+
335
+ it "should still default to that value after delete" do
336
+ @klass.attr 5
337
+ @klass.delete(:attr)
338
+ @klass.attr.should == 4
339
+ end
340
+
341
+ it "should still default to that value after reset" do
342
+ @klass.attr 5
343
+ @klass.reset
344
+ @klass.attr.should == 4
345
+ end
346
+ end
347
+
348
+ describe "When a configurable exists with a context" do
349
+ before :each do
350
+ @klass = Class.new
351
+ @klass.extend(::Mixlib::Config)
352
+ @klass.class_eval do
353
+ config_context(:blah) do
354
+ default :x, 5
355
+ end
356
+ end
357
+ end
358
+
359
+ it "configurable defaults in that context work" do
360
+ @klass.blah.x.should == 5
361
+ end
362
+
363
+ it "after setting values in the context, the values remain set" do
364
+ @klass.blah.x = 10
365
+ @klass.blah.x.should == 10
366
+ end
367
+
368
+ it "setting values with the same name in the parent context do not affect the child context" do
369
+ @klass.x = 10
370
+ @klass.x.should == 10
371
+ @klass.blah.x.should == 5
372
+ end
373
+
374
+ it "after reset of the parent class, children are reset" do
375
+ @klass.blah.x = 10
376
+ @klass.blah.x.should == 10
377
+ @klass.reset
378
+ @klass.blah.x.should == 5
379
+ end
380
+ end
381
+
382
+ describe "When a configurable exists with a nested context" do
383
+ before :each do
384
+ @klass = Class.new
385
+ @klass.extend(::Mixlib::Config)
386
+ @klass.class_eval do
387
+ config_context(:blah) do
388
+ config_context(:yarr) do
389
+ default :x, 5
390
+ end
391
+ end
392
+ end
393
+ end
394
+
395
+ it "configurable defaults in that context work" do
396
+ @klass.blah.yarr.x.should == 5
397
+ end
398
+
399
+ it "after setting values in the context, the values remain set" do
400
+ @klass.blah.yarr.x = 10
401
+ @klass.blah.yarr.x.should == 10
402
+ end
403
+
404
+ it "setting values with the same name in the parent context do not affect the child context" do
405
+ @klass.x = 10
406
+ @klass.x.should == 10
407
+ @klass.blah.yarr.x.should == 5
408
+ end
409
+
410
+ it "after reset of the parent class, children are reset" do
411
+ @klass.blah.yarr.x = 10
412
+ @klass.blah.yarr.x.should == 10
413
+ @klass.reset
414
+ @klass.blah.yarr.x.should == 5
415
+ end
416
+ end
417
+
418
+ describe "When a nested context has strict mode on" do
419
+ class StrictClass2
420
+ extend ::Mixlib::Config
421
+ config_context :c do
422
+ config_strict_mode true
423
+ default :x, 1
424
+ end
425
+ end
426
+
427
+ it "The parent class allows you to set arbitrary config options" do
428
+ StrictClass2.y = 10
429
+ end
430
+
431
+ it "The nested class does not allow you to set arbitrary config options" do
432
+ lambda { StrictClass2.c.y = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
433
+ end
434
+ end
435
+
436
+ describe "When strict mode is on but a nested context has strict mode unspecified" do
437
+ class StrictClass3
438
+ extend ::Mixlib::Config
439
+ config_strict_mode true
440
+ default :x, 1
441
+ config_context :c
442
+ end
443
+
444
+ it "The parent class does not allow you to set arbitrary config options" do
445
+ lambda { StrictClass3.y = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
446
+ end
447
+
448
+ it "The nested class allows you to set arbitrary config options" do
449
+ StrictClass3.c.y = 10
450
+ end
140
451
  end
141
452
  end