mixlib-config 1.1.2 → 2.0.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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