mixlib-config 2.0.0 → 2.1.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7ca325df755b8481f9df5769f4bfae832f1df100
4
- data.tar.gz: ced3a08fd6400a9a35bc1dff83951e1fff262fc4
3
+ metadata.gz: 4aae86fdcef0c668433aa9862d10608ce3d5bcca
4
+ data.tar.gz: 96cbdd874fd78ffe00883b1e3149e981cc70db37
5
5
  SHA512:
6
- metadata.gz: 1fc1e26b90f05e80d3695dff13e8689e47895b4dd8afe67547c8e66b7b464c5b9aa0c473c1ee5aa1fdda9b7224db21a7937a7bb309af9a4f3cf26bad2a8080ec
7
- data.tar.gz: 27e0903f9186c48ad9e68a5febd5f6eb32a69251a406a814632f2fb553fe310356c07b185f4bf59929b8de3dd06445f1d92690bdfb304b473b735d5dc6b657b9
6
+ metadata.gz: ca9da0a8e7e0f6a0c577e22ae62b1c8abd29eef3c6f64d9ebfe04f7dee57e8a6722e548c936a46ca4f5467f9c93c20daaacfb65762e249c6d046ffd3dae45031
7
+ data.tar.gz: 657670f954f61bb02a919bfd4570613bc999e0d23c03ac4cea8f92e38f4fae8d53f739f35daf391c4dc73720c2db9fa02917bac8667ff63dedccf19cc6395f10
data/lib/mixlib/config.rb CHANGED
@@ -21,6 +21,8 @@
21
21
  require 'mixlib/config/version'
22
22
  require 'mixlib/config/configurable'
23
23
  require 'mixlib/config/unknown_config_option_error'
24
+ require 'mixlib/config/reopened_config_context_with_configurable_error'
25
+ require 'mixlib/config/reopened_configurable_with_config_context_error'
24
26
 
25
27
  module Mixlib
26
28
  module Config
@@ -31,7 +33,7 @@ module Mixlib
31
33
  class << base; attr_accessor :config_parent; end
32
34
  base.configuration = Hash.new
33
35
  base.configurables = Hash.new
34
- base.config_contexts = Array.new
36
+ base.config_contexts = Hash.new
35
37
  end
36
38
 
37
39
  # Loads a given ruby file, and runs instance_eval against it in the context of the current
@@ -105,21 +107,106 @@ module Mixlib
105
107
  # Resets all config options to their defaults.
106
108
  def reset
107
109
  self.configuration = Hash.new
108
- self.config_contexts.each { |config_context| config_context.reset }
110
+ self.config_contexts.values.each { |config_context| config_context.reset }
111
+ end
112
+
113
+ # Makes a copy of any non-default values.
114
+ #
115
+ # This returns a shallow copy of the hash; while the hash itself is
116
+ # duplicated a la dup, modifying data inside arrays and hashes may modify
117
+ # the original Config object.
118
+ #
119
+ # === Returns
120
+ #
121
+ # Hash of values the user has set.
122
+ #
123
+ # === Examples
124
+ #
125
+ # For example, this config class:
126
+ #
127
+ # class MyConfig < Mixlib::Config
128
+ # default :will_be_set, 1
129
+ # default :will_be_set_to_default, 1
130
+ # default :will_not_be_set, 1
131
+ # configurable(:computed_value) { |x| x*2 }
132
+ # config_context :group do
133
+ # default :will_not_be_set, 1
134
+ # end
135
+ # config_context :group_never_set
136
+ # end
137
+ #
138
+ # MyConfig.x = 2
139
+ # MyConfig.will_be_set = 2
140
+ # MyConfig.will_be_set_to_default = 1
141
+ # MyConfig.computed_value = 2
142
+ # MyConfig.group.x = 3
143
+ #
144
+ # produces this:
145
+ #
146
+ # MyConfig.save == {
147
+ # :x => 2,
148
+ # :will_be_set => 2,
149
+ # :will_be_set_to_default => 1,
150
+ # :computed_value => 4,
151
+ # :group => {
152
+ # :x => 3
153
+ # }
154
+ # }
155
+ #
156
+ def save(include_defaults = false)
157
+ result = self.configuration.dup
158
+ if include_defaults
159
+ (self.configurables.keys - result.keys).each do |missing_default|
160
+ # Ask any configurables to save themselves into the result array
161
+ if self.configurables[missing_default].has_default
162
+ result[missing_default] = self.configurables[missing_default].default
163
+ end
164
+ end
165
+ end
166
+ self.config_contexts.each_pair do |key, context|
167
+ context_result = context.save(include_defaults)
168
+ result[key] = context_result if context_result.size != 0 || include_defaults
169
+ end
170
+ result
171
+ end
172
+
173
+ # Restore non-default values from the given hash.
174
+ #
175
+ # This method is the equivalent of +reset+ followed by +merge!(hash)+.
176
+ #
177
+ # === Parameters
178
+ # hash<Hash>: a hash in the same format as output by save.
179
+ #
180
+ # === Returns
181
+ # self
182
+ def restore(hash)
183
+ reset
184
+ merge!(hash)
109
185
  end
110
186
 
111
187
  # Merge an incoming hash with our config options
112
188
  #
113
189
  # === Parameters
114
- # hash<Hash>:: The incoming hash
190
+ # hash<Hash>: a hash in the same format as output by save.
115
191
  #
116
192
  # === Returns
117
- # result of Hash#merge!
193
+ # self
118
194
  def merge!(hash)
119
- self.configuration.merge!(hash)
195
+ hash.each do |key, value|
196
+ if self.config_contexts.has_key?(key)
197
+ # Grab the config context and let internal_get cache it if so desired
198
+ self.config_contexts[key].restore(value)
199
+ else
200
+ self.configuration[key] = value
201
+ end
202
+ end
203
+ self
120
204
  end
121
205
 
122
- # Return the set of config hash keys
206
+ # Return the set of config hash keys.
207
+ # This *only* returns hash keys which have been set by the user. In future
208
+ # versions this will likely be removed in favor of something more explicit.
209
+ # For now though, we want this to match has_key?
123
210
  #
124
211
  # === Returns
125
212
  # result of Hash#keys
@@ -128,11 +215,13 @@ module Mixlib
128
215
  end
129
216
 
130
217
  # Creates a shallow copy of the internal hash
218
+ # NOTE: remove this in 3.0 in favor of save. This is completely useless
219
+ # with default values and configuration_context.
131
220
  #
132
221
  # === Returns
133
222
  # result of Hash#dup
134
223
  def hash_dup
135
- self.configuration.dup
224
+ save
136
225
  end
137
226
 
138
227
  # metaprogramming to ensure that the slot for method_symbol
@@ -184,6 +273,9 @@ module Mixlib
184
273
  # The value of the config option.
185
274
  def configurable(symbol, &block)
186
275
  unless configurables[symbol]
276
+ if config_contexts.has_key?(symbol)
277
+ raise ReopenedConfigContextWithConfigurableError, "Cannot redefine config_context #{symbol} as a configurable value"
278
+ end
187
279
  configurables[symbol] = Configurable.new(symbol)
188
280
  define_attr_accessor_methods(symbol)
189
281
  end
@@ -196,6 +288,8 @@ module Mixlib
196
288
  # Allows you to create a new config context where you can define new
197
289
  # options with default values.
198
290
  #
291
+ # This method allows you to open up the configurable more than once.
292
+ #
199
293
  # For example:
200
294
  #
201
295
  # config_context :server_info do
@@ -207,16 +301,25 @@ module Mixlib
207
301
  # block<Block>: a block that will be run in the context of this new config
208
302
  # class.
209
303
  def config_context(symbol, &block)
210
- context = Class.new
211
- context.extend(::Mixlib::Config)
212
- context.config_parent = self
213
- config_contexts << context
304
+ if configurables.has_key?(symbol)
305
+ raise ReopenedConfigurableWithConfigContextError, "Cannot redefine config value #{symbol} with a config context"
306
+ end
307
+
308
+ if config_contexts.has_key?(symbol)
309
+ context = config_contexts[symbol]
310
+ else
311
+ context = Class.new
312
+ context.extend(::Mixlib::Config)
313
+ context.config_parent = self
314
+ config_contexts[symbol] = context
315
+ define_attr_accessor_methods(symbol)
316
+ end
317
+
214
318
  if block
215
319
  context.instance_eval(&block)
216
320
  end
217
- configurable(symbol).defaults_to(context).writes_value do |value|
218
- raise "config context #{symbol} cannot be modified"
219
- end
321
+
322
+ context
220
323
  end
221
324
 
222
325
  NOT_PASSED = Object.new
@@ -295,6 +398,7 @@ module Mixlib
295
398
  private
296
399
 
297
400
  # Internal dispatch setter for config values.
401
+ #
298
402
  # === Parameters
299
403
  # symbol<Symbol>:: Name of the method (variable setter)
300
404
  # value<Object>:: Value to be set in config hash
@@ -302,6 +406,8 @@ module Mixlib
302
406
  def internal_set(symbol,value)
303
407
  if configurables.has_key?(symbol)
304
408
  configurables[symbol].set(self.configuration, value)
409
+ elsif config_contexts.has_key?(symbol)
410
+ config_contexts[symbol].restore(value)
305
411
  else
306
412
  if config_strict_mode == :warn
307
413
  Chef::Log.warn("Setting unsupported config value #{method_name}..")
@@ -315,6 +421,8 @@ module Mixlib
315
421
  def internal_get(symbol)
316
422
  if configurables.has_key?(symbol)
317
423
  configurables[symbol].get(self.configuration)
424
+ elsif config_contexts.has_key?(symbol)
425
+ config_contexts[symbol]
318
426
  else
319
427
  if config_strict_mode == :warn
320
428
  Chef::Log.warn("Reading unsupported config value #{symbol}.")
@@ -21,13 +21,17 @@ module Mixlib
21
21
  class Configurable
22
22
  def initialize(symbol)
23
23
  @symbol = symbol
24
- @default = nil
24
+ @default_block = nil
25
+ @has_default = false
25
26
  @default_value = nil
26
27
  @writes_value = nil
27
28
  end
28
29
 
30
+ attr_reader :has_default
31
+
29
32
  def defaults_to(default_value = nil, &block)
30
- @default = block
33
+ @has_default = true
34
+ @default_block = block
31
35
  @default_value = default_value
32
36
  self
33
37
  end
@@ -40,11 +44,12 @@ module Mixlib
40
44
  def get(config)
41
45
  if config.has_key?(@symbol)
42
46
  config[@symbol]
43
- elsif @default
44
- @default.call
47
+ elsif @default_block
48
+ @default_block.call
45
49
  else
46
50
  begin
47
51
  # Some things cannot be dup'd, and you won't know this till after the fact
52
+ # because all values implement dup
48
53
  config[@symbol] = @default_value.dup
49
54
  rescue TypeError
50
55
  @default_value
@@ -55,6 +60,14 @@ module Mixlib
55
60
  def set(config, value)
56
61
  config[@symbol] = @writes_value ? @writes_value.call(value) : value
57
62
  end
63
+
64
+ def default
65
+ if @default_block
66
+ @default_block.call
67
+ else
68
+ @default_value
69
+ end
70
+ end
58
71
  end
59
72
  end
60
73
  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 ReopenedConfigContextWithConfigurableError < StandardError
22
+ end
23
+ end
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 ReopenedConfigurableWithConfigContextError < StandardError
22
+ end
23
+ end
24
+ end
@@ -19,7 +19,7 @@
19
19
  module Mixlib
20
20
  module Config
21
21
 
22
- VERSION = "2.0.0"
22
+ VERSION = "2.1.0.rc.1"
23
23
 
24
24
  end
25
25
  end
@@ -275,6 +275,32 @@ describe Mixlib::Config do
275
275
  @klass.reset
276
276
  @klass.attr.should == 4
277
277
  end
278
+
279
+ it "save should not save anything for it" do
280
+ @klass.save.should == {}
281
+ end
282
+
283
+ it "save with include_defaults should save all defaults" do
284
+ @klass.save(true).should == { :attr => 4 }
285
+ end
286
+
287
+ it "save should save the new value if it gets set" do
288
+ @klass.attr 5
289
+ (saved = @klass.save).should == { :attr => 5 }
290
+ @klass.reset
291
+ @klass.attr.should == 4
292
+ @klass.restore(saved)
293
+ @klass.attr.should == 5
294
+ end
295
+
296
+ it "save should save the new value even if it is set to its default value" do
297
+ @klass.attr 4
298
+ (saved = @klass.save).should == { :attr => 4 }
299
+ @klass.reset
300
+ @klass.save.should == {}
301
+ @klass.restore(saved)
302
+ @klass.save.should == { :attr => 4 }
303
+ end
278
304
  end
279
305
 
280
306
  describe "When config has a default value block" do
@@ -283,7 +309,7 @@ describe Mixlib::Config do
283
309
  @klass.extend(::Mixlib::Config)
284
310
  @klass.class_eval do
285
311
  default :x, 4
286
- default(:attr) { x*2}
312
+ default(:attr) { x*2 }
287
313
  end
288
314
  end
289
315
 
@@ -317,6 +343,32 @@ describe Mixlib::Config do
317
343
  @klass.reset
318
344
  @klass.attr.should == 8
319
345
  end
346
+
347
+ it "save should not save anything for it" do
348
+ @klass.save.should == {}
349
+ end
350
+
351
+ it "save with include_defaults should save all defaults" do
352
+ @klass.save(true).should == { :attr => 8, :x => 4 }
353
+ end
354
+
355
+ it "save should save the new value if it gets set" do
356
+ @klass.attr 5
357
+ (saved = @klass.save).should == { :attr => 5 }
358
+ @klass.reset
359
+ @klass.attr.should == 8
360
+ @klass.restore(saved)
361
+ @klass.attr.should == 5
362
+ end
363
+
364
+ it "save should save the new value even if it is set to its default value" do
365
+ @klass.attr 8
366
+ (saved = @klass.save).should == { :attr => 8 }
367
+ @klass.reset
368
+ @klass.save.should == {}
369
+ @klass.restore(saved)
370
+ @klass.save.should == { :attr => 8 }
371
+ end
320
372
  end
321
373
 
322
374
  describe "When config has an array default value" do
@@ -332,6 +384,32 @@ describe Mixlib::Config do
332
384
  @klass.reset
333
385
  @klass.attr.should == []
334
386
  end
387
+
388
+ it "save should not save anything for it" do
389
+ @klass.save.should == {}
390
+ end
391
+
392
+ it "save with include_defaults should save all defaults" do
393
+ @klass.save(true).should == { :attr => [] }
394
+ end
395
+
396
+ it "save should save the new value if it gets set" do
397
+ @klass.attr << 'x'
398
+ (saved = @klass.save).should == { :attr => [ 'x' ] }
399
+ @klass.reset
400
+ @klass.attr.should == []
401
+ @klass.restore(saved)
402
+ @klass.attr.should == [ 'x' ]
403
+ end
404
+
405
+ it "save should save the new value even if it is set to its default value" do
406
+ @klass.attr = []
407
+ (saved = @klass.save).should == { :attr => [] }
408
+ @klass.reset
409
+ @klass.save.should == {}
410
+ @klass.restore(saved)
411
+ @klass.save.should == { :attr => [] }
412
+ end
335
413
  end
336
414
 
337
415
  describe "When config has a hash default value" do
@@ -347,6 +425,32 @@ describe Mixlib::Config do
347
425
  @klass.reset
348
426
  @klass.attr[:x].should == nil
349
427
  end
428
+
429
+ it "save should not save anything for it" do
430
+ @klass.save.should == {}
431
+ end
432
+
433
+ it "save with include_defaults should save all defaults" do
434
+ @klass.save(true).should == { :attr => {} }
435
+ end
436
+
437
+ it "save should save the new value if it gets set" do
438
+ @klass.attr[:hi] = 'lo'
439
+ (saved = @klass.save).should == { :attr => { :hi => 'lo' } }
440
+ @klass.reset
441
+ @klass.attr.should == {}
442
+ @klass.restore(saved)
443
+ @klass.save.should == { :attr => { :hi => 'lo' } }
444
+ end
445
+
446
+ it "save should save the new value even if it is set to its default value" do
447
+ @klass.attr = {}
448
+ (saved = @klass.save).should == { :attr => {} }
449
+ @klass.reset
450
+ @klass.save.should == {}
451
+ @klass.restore(saved)
452
+ @klass.save.should == { :attr => {} }
453
+ end
350
454
  end
351
455
 
352
456
  describe "When config has a string default value" do
@@ -362,6 +466,32 @@ describe Mixlib::Config do
362
466
  @klass.reset
363
467
  @klass.attr.should == 'hello'
364
468
  end
469
+
470
+ it "save should not save anything for it" do
471
+ @klass.save.should == {}
472
+ end
473
+
474
+ it "save with include_defaults should save all defaults" do
475
+ @klass.save(true).should == { :attr => 'hello' }
476
+ end
477
+
478
+ it "save should save the new value if it gets set" do
479
+ @klass.attr << ' world'
480
+ (saved = @klass.save).should == { :attr => 'hello world' }
481
+ @klass.reset
482
+ @klass.attr.should == 'hello'
483
+ @klass.restore(saved)
484
+ @klass.attr.should == 'hello world'
485
+ end
486
+
487
+ it "save should save the new value even if it is set to its default value" do
488
+ @klass.attr 'hello world'
489
+ (saved = @klass.save).should == { :attr => 'hello world' }
490
+ @klass.reset
491
+ @klass.save.should == {}
492
+ @klass.restore(saved)
493
+ @klass.save.should == { :attr => 'hello world' }
494
+ end
365
495
  end
366
496
 
367
497
  describe "When config has a a default value block" do
@@ -398,6 +528,32 @@ describe Mixlib::Config do
398
528
  @klass.reset
399
529
  @klass.attr.should == 4
400
530
  end
531
+
532
+ it "save should not save anything for it" do
533
+ @klass.save.should == {}
534
+ end
535
+
536
+ it "save with include_defaults should save all defaults" do
537
+ @klass.save(true).should == { :attr => 4 }
538
+ end
539
+
540
+ it "save should save the new value if it gets set" do
541
+ @klass.attr 5
542
+ (saved = @klass.save).should == { :attr => 5 }
543
+ @klass.reset
544
+ @klass.attr.should == 4
545
+ @klass.restore(saved)
546
+ @klass.attr.should == 5
547
+ end
548
+
549
+ it "save should save the new value even if it is set to its default value" do
550
+ @klass.attr 4
551
+ (saved = @klass.save).should == { :attr => 4 }
552
+ @klass.reset
553
+ @klass.save.should == {}
554
+ @klass.restore(saved)
555
+ @klass.save.should == { :attr => 4 }
556
+ end
401
557
  end
402
558
 
403
559
  describe "When a configurable exists with writer and default value" do
@@ -449,6 +605,32 @@ describe Mixlib::Config do
449
605
  @klass.reset
450
606
  @klass.attr.should == 4
451
607
  end
608
+
609
+ it "save should not save anything for it" do
610
+ @klass.save.should == {}
611
+ end
612
+
613
+ it "save with include_defaults should save all defaults" do
614
+ @klass.save(true).should == { :attr => 4 }
615
+ end
616
+
617
+ it "save should save the new value if it gets set" do
618
+ @klass.attr 5
619
+ (saved = @klass.save).should == { :attr => 10 }
620
+ @klass.reset
621
+ @klass.attr.should == 4
622
+ @klass.restore(saved)
623
+ @klass.attr.should == 10
624
+ end
625
+
626
+ it "save should save the new value even if it is set to its default value" do
627
+ @klass.attr 4
628
+ (saved = @klass.save).should == { :attr => 8 }
629
+ @klass.reset
630
+ @klass.save.should == {}
631
+ @klass.restore(saved)
632
+ @klass.save.should == { :attr => 8 }
633
+ end
452
634
  end
453
635
 
454
636
  describe "When a configurable exists with writer and default value set in chained form" do
@@ -497,6 +679,32 @@ describe Mixlib::Config do
497
679
  @klass.reset
498
680
  @klass.attr.should == 4
499
681
  end
682
+
683
+ it "save should not save anything for it" do
684
+ @klass.save.should == {}
685
+ end
686
+
687
+ it "save with include_defaults should save all defaults" do
688
+ @klass.save(true).should == { :attr => 4 }
689
+ end
690
+
691
+ it "save should save the new value if it gets set" do
692
+ @klass.attr 5
693
+ (saved = @klass.save).should == { :attr => 10 }
694
+ @klass.reset
695
+ @klass.attr.should == 4
696
+ @klass.restore(saved)
697
+ @klass.attr.should == 10
698
+ end
699
+
700
+ it "save should save the new value even if it is set to its default value" do
701
+ @klass.attr 2
702
+ (saved = @klass.save).should == { :attr => 4 }
703
+ @klass.reset
704
+ @klass.save.should == {}
705
+ @klass.restore(saved)
706
+ @klass.save.should == { :attr => 4 }
707
+ end
500
708
  end
501
709
 
502
710
  describe "When a configurable exists with a context" do
@@ -526,12 +734,50 @@ describe Mixlib::Config do
526
734
  @klass.blah.x.should == 5
527
735
  end
528
736
 
737
+ it "setting the entire context to a hash with default value overridden sets the value" do
738
+ @klass.blah = { :x => 10 }
739
+ @klass.blah.x.should == 10
740
+ end
741
+
742
+ it "setting the entire context to a hash sets non-default values" do
743
+ @klass.blah = { :y => 10 }
744
+ @klass.blah.x.should == 5
745
+ @klass.blah.y.should == 10
746
+ end
747
+
748
+ it "setting the entire context to a hash deletes any non-default values and resets default values" do
749
+ @klass.blah.x = 10
750
+ @klass.blah.y = 10
751
+ @klass.blah = { :z => 10 }
752
+ @klass.blah.x.should == 5
753
+ @klass.blah.y.should == nil
754
+ @klass.blah.z.should == 10
755
+ end
756
+
529
757
  it "after reset of the parent class, children are reset" do
530
758
  @klass.blah.x = 10
531
759
  @klass.blah.x.should == 10
532
760
  @klass.reset
533
761
  @klass.blah.x.should == 5
534
762
  end
763
+
764
+ it "save should not save anything for it by default" do
765
+ @klass.save.should == {}
766
+ end
767
+
768
+ it "save with include_defaults should save all defaults" do
769
+ @klass.save(true).should == { :blah => { :x => 5 } }
770
+ end
771
+
772
+ it "save should save any new values that are set in the context" do
773
+ @klass.blah.x = 10
774
+ (saved = @klass.save).should == { :blah => { :x => 10 } }
775
+ @klass.reset
776
+ @klass.blah.x.should == 5
777
+ @klass.restore(saved)
778
+ @klass.blah.x.should == 10
779
+ @klass.save.should == { :blah => { :x => 10 } }
780
+ end
535
781
  end
536
782
 
537
783
  describe "When a configurable exists with a nested context" do
@@ -569,6 +815,62 @@ describe Mixlib::Config do
569
815
  @klass.reset
570
816
  @klass.blah.yarr.x.should == 5
571
817
  end
818
+
819
+ it "save should not save anything for it by default" do
820
+ @klass.save.should == {}
821
+ end
822
+
823
+ it "save with include_defaults should save all defaults" do
824
+ @klass.save(true).should == { :blah => { :yarr => { :x => 5 } } }
825
+ end
826
+
827
+ it "save should save any new values that are set in the context" do
828
+ @klass.blah.yarr.x = 10
829
+ (saved = @klass.save).should == { :blah => { :yarr => { :x => 10 } } }
830
+ @klass.reset
831
+ @klass.blah.yarr.x.should == 5
832
+ @klass.restore(saved)
833
+ @klass.blah.yarr.x.should == 10
834
+ @klass.save.should == { :blah => { :yarr => { :x => 10 } } }
835
+ end
836
+ end
837
+
838
+ describe "When a config_context with no defaulted values exists" do
839
+ before :each do
840
+ @klass = Class.new
841
+ @klass.extend(::Mixlib::Config)
842
+ @klass.class_eval do
843
+ config_context(:blah) do
844
+ configurable(:x)
845
+ end
846
+ end
847
+ end
848
+
849
+ it "save does not save the hash for the config_context" do
850
+ @klass.save.should == {}
851
+ end
852
+
853
+ it "save with defaults saves the hash for the config_context" do
854
+ @klass.save(true).should == { :blah => {} }
855
+ end
856
+ end
857
+
858
+ describe "When a config_context with no configurables exists" do
859
+ before :each do
860
+ @klass = Class.new
861
+ @klass.extend(::Mixlib::Config)
862
+ @klass.class_eval do
863
+ config_context(:blah)
864
+ end
865
+ end
866
+
867
+ it "save does not save the hash for the config_context" do
868
+ @klass.save.should == {}
869
+ end
870
+
871
+ it "save with defaults saves the hash for the config_context" do
872
+ @klass.save(true).should == { :blah => {} }
873
+ end
572
874
  end
573
875
 
574
876
  describe "When a nested context has strict mode on" do
@@ -605,4 +907,51 @@ describe Mixlib::Config do
605
907
  lambda { StrictClass3.y = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
606
908
  end
607
909
  end
910
+
911
+ describe "When a config_context is opened twice" do
912
+ before :each do
913
+ @klass = Class.new
914
+ @klass.extend(::Mixlib::Config)
915
+ @klass.class_eval do
916
+ config_context(:blah) do
917
+ default :x, 10
918
+ end
919
+ config_context(:blah) do
920
+ default :y, 20
921
+ end
922
+ end
923
+ end
924
+
925
+ it "Both config_context blocks are honored" do
926
+ @klass.blah.x == 10
927
+ @klass.blah.y == 20
928
+ end
929
+ end
930
+
931
+ it "When a config_context is opened in place of a regular configurable, an error is raised" do
932
+ klass = Class.new
933
+ klass.extend(::Mixlib::Config)
934
+ lambda do
935
+ klass.class_eval do
936
+ default :blah, 10
937
+ config_context(:blah) do
938
+ default :y, 20
939
+ end
940
+ end
941
+ end.should raise_error(Mixlib::Config::ReopenedConfigurableWithConfigContextError)
942
+ end
943
+
944
+ it "When a config_context is opened in place of a regular configurable, an error is raised" do
945
+ klass = Class.new
946
+ klass.extend(::Mixlib::Config)
947
+ lambda do
948
+ klass.class_eval do
949
+ config_context(:blah) do
950
+ default :y, 20
951
+ end
952
+ default :blah, 10
953
+ end
954
+ end.should raise_error(Mixlib::Config::ReopenedConfigContextWithConfigurableError)
955
+ end
956
+
608
957
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mixlib-config
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.1.0.rc.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Opscode, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-09-25 00:00:00.000000000 Z
11
+ date: 2013-12-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -65,6 +65,8 @@ files:
65
65
  - README.md
66
66
  - Rakefile
67
67
  - lib/mixlib/config/configurable.rb
68
+ - lib/mixlib/config/reopened_config_context_with_configurable_error.rb
69
+ - lib/mixlib/config/reopened_configurable_with_config_context_error.rb
68
70
  - lib/mixlib/config/unknown_config_option_error.rb
69
71
  - lib/mixlib/config/version.rb
70
72
  - lib/mixlib/config.rb
@@ -84,9 +86,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
84
86
  version: '0'
85
87
  required_rubygems_version: !ruby/object:Gem::Requirement
86
88
  requirements:
87
- - - '>='
89
+ - - '>'
88
90
  - !ruby/object:Gem::Version
89
- version: '0'
91
+ version: 1.3.1
90
92
  requirements: []
91
93
  rubyforge_project:
92
94
  rubygems_version: 2.0.3