diff options
author | John Keiser <jkeiser@opscode.com> | 2013-09-09 21:58:53 -0700 |
---|---|---|
committer | John Keiser <jkeiser@opscode.com> | 2013-09-09 21:58:53 -0700 |
commit | dbe3521f75e6fe37a7e58bc79fbe89ec7ac2c071 (patch) | |
tree | b7a45d48694bf7b1e5b6296e070a802ec35b1d14 | |
parent | 6a329b4abea7c624a88d05d3122679a5273d65a9 (diff) | |
download | mixlib-config-dbe3521f75e6fe37a7e58bc79fbe89ec7ac2c071.tar.gz |
Add context() DSL for config classes
-rw-r--r-- | lib/mixlib/config.rb | 28 | ||||
-rw-r--r-- | spec/mixlib/config_spec.rb | 70 |
2 files changed, 98 insertions, 0 deletions
diff --git a/lib/mixlib/config.rb b/lib/mixlib/config.rb index 6819b38..28a22b9 100644 --- a/lib/mixlib/config.rb +++ b/lib/mixlib/config.rb @@ -26,8 +26,10 @@ module Mixlib def self.extended(base) class << base; attr_accessor :configuration; end class << base; attr_accessor :configurables; end + class << base; attr_accessor :contexts; end base.configuration = Hash.new base.configurables = Hash.new + base.contexts = Array.new end # Loads a given ruby file, and runs instance_eval against it in the context of the current @@ -98,6 +100,7 @@ module Mixlib # Resets all config options to their defaults. def reset self.configuration = Hash.new + self.contexts.each { |context| context.reset } end # Merge an incoming hash with our config options @@ -182,6 +185,31 @@ module Mixlib configurables[symbol] end + # Allows you to create a new config context where you can define new + # options with default values. + # + # For example: + # + # context :server_info do + # configurable(:url).defaults_to("http://localhost") + # end + # + # === Parameters + # symbol<Symbol>: the name of the context + # block<Block>: a block that will be run in the context of this new config + # class. + def context(symbol, &block) + context = Class.new + context.extend(::Mixlib::Config) + contexts << context + if block + context.instance_eval(&block) + end + configurable(symbol).defaults_to(context).writes_value do |value| + raise "config context #{symbol} cannot be modified" + end + end + # Allows for simple lookups and setting of config options via method calls # on Mixlib::Config. If there any arguments to the method, they are used to set # the value of the config option. Otherwise, it's a simple get operation. diff --git a/spec/mixlib/config_spec.rb b/spec/mixlib/config_spec.rb index 420e36f..4e141c8 100644 --- a/spec/mixlib/config_spec.rb +++ b/spec/mixlib/config_spec.rb @@ -311,4 +311,74 @@ describe Mixlib::Config do @klass.attr.should == 4 end end + + describe "When a configurable exists with a context" do + before :each do + @klass = Class.new + @klass.extend(::Mixlib::Config) + @klass.class_eval do + context(:blah) do + default :x, 5 + end + end + end + + it "configurable defaults in that context work" do + @klass.blah.x.should == 5 + end + + it "after setting values in the context, the values remain set" do + @klass.blah.x = 10 + @klass.blah.x.should == 10 + end + + it "setting values with the same name in the parent context do not affect the child context" do + @klass.x = 10 + @klass.x.should == 10 + @klass.blah.x.should == 5 + end + + it "after reset of the parent class, children are reset" do + @klass.blah.x = 10 + @klass.blah.x.should == 10 + @klass.reset + @klass.blah.x.should == 5 + end + end + + describe "When a configurable exists with a nested context" do + before :each do + @klass = Class.new + @klass.extend(::Mixlib::Config) + @klass.class_eval do + context(:blah) do + context(:yarr) do + default :x, 5 + end + end + end + end + + it "configurable defaults in that context work" do + @klass.blah.yarr.x.should == 5 + end + + it "after setting values in the context, the values remain set" do + @klass.blah.yarr.x = 10 + @klass.blah.yarr.x.should == 10 + end + + it "setting values with the same name in the parent context do not affect the child context" do + @klass.x = 10 + @klass.x.should == 10 + @klass.blah.yarr.x.should == 5 + end + + it "after reset of the parent class, children are reset" do + @klass.blah.yarr.x = 10 + @klass.blah.yarr.x.should == 10 + @klass.reset + @klass.blah.yarr.x.should == 5 + end + end end |