spec/mixlib/config_spec.rb in mixlib-config-1.1.2 vs spec/mixlib/config_spec.rb in mixlib-config-2.0.0.rc.1
- old
+ new
@@ -4,13 +4,13 @@
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
-#
+#
# http://www.apache.org/licenses/LICENSE-2.0
-#
+#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
@@ -28,88 +28,126 @@
ConfigIt.configure do |c|
c[:alpha] = 'omega'
c[:foo] = nil
end
end
-
+
it "should load a config file" do
- File.stub!(:exists?).and_return(true)
- File.stub!(:readable?).and_return(true)
- IO.stub!(:read).with('config.rb').and_return("alpha = 'omega'\nfoo = 'bar'")
- lambda {
+ File.stub(:exists?).and_return(true)
+ File.stub(:readable?).and_return(true)
+ IO.stub(:read).with('config.rb').and_return("alpha = 'omega'\nfoo = 'bar'")
+ lambda {
ConfigIt.from_file('config.rb')
}.should_not raise_error
end
-
+
it "should not raise an ArgumentError with an explanation if you try and set a non-existent variable" do
- lambda {
+ lambda {
ConfigIt[:foobar] = "blah"
- }.should_not raise_error(ArgumentError)
+ }.should_not raise_error
end
-
+
it "should raise an Errno::ENOENT if it can't find the file" do
- lambda {
+ lambda {
ConfigIt.from_file("/tmp/timmytimmytimmy")
}.should raise_error(Errno::ENOENT)
end
it "should allow the error to bubble up when it's anything other than IOError" do
- IO.stub!(:read).with('config.rb').and_return("@#asdf")
+ IO.stub(:read).with('config.rb').and_return("@#asdf")
lambda {
ConfigIt.from_file('config.rb')
}.should raise_error(SyntaxError)
end
-
+
it "should allow you to reference a value by index" do
ConfigIt[:alpha].should == 'omega'
end
-
+
it "should allow you to set a value by index" do
ConfigIt[:alpha] = "one"
ConfigIt[:alpha].should == "one"
end
it "should allow setting a value with attribute form" do
ConfigIt.arbitrary_value = 50
ConfigIt.arbitrary_value.should == 50
ConfigIt[:arbitrary_value].should == 50
end
-
+
+ it "should allow setting a value with method form" do
+ ConfigIt.arbitrary_value 50
+ ConfigIt.arbitrary_value.should == 50
+ ConfigIt[:arbitrary_value].should == 50
+ end
+
+ describe "when strict mode is on" do
+ class StrictClass
+ extend ::Mixlib::Config
+ config_strict_mode true
+ default :x, 1
+ end
+
+ it "allows you to get and set configured values" do
+ StrictClass.x = StrictClass.x * 2
+ StrictClass[:x] = StrictClass[:x] * 2
+ end
+
+ it "raises an error when you get an arbitrary config option with .y" do
+ lambda { StrictClass.y }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
+ end
+
+ it "raises an error when you get an arbitrary config option with [:y]" do
+ lambda { StrictClass[:y] }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
+ end
+
+ it "raises an error when you set an arbitrary config option with .y = 10" do
+ lambda { StrictClass.y = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
+ end
+
+ it "raises an error when you get an arbitrary config option with .y 10" do
+ lambda { StrictClass.y 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
+ end
+
+ it "raises an error when you get an arbitrary config option with [:y] = 10" do
+ lambda { StrictClass[:y] = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
+ end
+ end
+
describe "when a block has been used to set config values" do
before do
ConfigIt.configure { |c| c[:cookbook_path] = "monkey_rabbit"; c[:otherthing] = "boo" }
end
-
+
{:cookbook_path => "monkey_rabbit", :otherthing => "boo"}.each do |k,v|
it "should allow you to retrieve the config value for #{k} via []" do
ConfigIt[k].should == v
end
it "should allow you to retrieve the config value for #{k} via method_missing" do
ConfigIt.send(k).should == v
end
end
end
-
+
it "should not raise an ArgumentError if you access a config option that does not exist" do
- lambda { ConfigIt[:snob_hobbery] }.should_not raise_error(ArgumentError)
+ lambda { ConfigIt[:snob_hobbery] }.should_not raise_error
end
-
+
it "should return true or false with has_key?" do
ConfigIt.has_key?(:monkey).should eql(false)
ConfigIt[:monkey] = "gotcha"
ConfigIt.has_key?(:monkey).should eql(true)
end
-
- describe "when a class method override accessor exists" do
+
+ describe "when a class method override writer exists" do
before do
@klass = Class.new
@klass.extend(::Mixlib::Config)
@klass.class_eval(<<-EVAL)
config_attr_writer :test_method do |blah|
blah.is_a?(Integer) ? blah * 1000 : blah
end
- pp self.methods
EVAL
end
it "should multiply an integer by 1000" do
@klass[:test_method] = 53
@@ -125,17 +163,290 @@
@klass.instance_eval("test_method 73")
@klass.test_method.should == 73000
end
it "should multiply an integer by 1000 via from-file, too" do
- IO.stub!(:read).with('config.rb').and_return("test_method 99")
+ IO.stub(:read).with('config.rb').and_return("test_method 99")
@klass.from_file('config.rb')
@klass.test_method.should == 99000
end
-
+
it "should receive internal_set with the method name and config value" do
@klass.should_receive(:internal_set).with(:test_method, 53).and_return(true)
@klass[:test_method] = 53
end
-
+
+ end
+
+ describe "When a default value exists" do
+ before :each do
+ @klass = Class.new
+ @klass.extend(::Mixlib::Config)
+ @klass.class_eval { default :attr, 4 }
+ end
+
+ it "should default to that value" do
+ @klass.attr.should == 4
+ end
+
+ it "should default to that value when retrieved as a hash" do
+ @klass[:attr].should == 4
+ end
+
+ it "should be settable to another value" do
+ @klass.attr 5
+ @klass.attr.should == 5
+ end
+
+ it "should still default to that value after delete" do
+ @klass.attr 5
+ @klass.delete(:attr)
+ @klass.attr.should == 4
+ end
+
+ it "should still default to that value after reset" do
+ @klass.attr 5
+ @klass.reset
+ @klass.attr.should == 4
+ end
+ end
+
+ describe "When a default value block exists" do
+ before :each do
+ @klass = Class.new
+ @klass.extend(::Mixlib::Config)
+ @klass.class_eval do
+ default(:attr) { 4 }
+ end
+ end
+
+ it "should default to that value" do
+ @klass.attr.should == 4
+ end
+
+ it "should default to that value when retrieved as a hash" do
+ @klass[:attr].should == 4
+ end
+
+ it "should be settable to another value" do
+ @klass.attr 5
+ @klass.attr.should == 5
+ @klass[:attr].should == 5
+ end
+
+ it "should still default to that value after delete" do
+ @klass.attr 5
+ @klass.delete(:attr)
+ @klass.attr.should == 4
+ end
+
+ it "should still default to that value after reset" do
+ @klass.attr 5
+ @klass.reset
+ @klass.attr.should == 4
+ end
+ end
+
+ describe "When a configurable exists with writer and default value" do
+ before :each do
+ @klass = Class.new
+ @klass.extend(::Mixlib::Config)
+ @klass.class_eval do
+ configurable(:attr) do |c|
+ c.defaults_to(4)
+ c.writes_value { |value| value*2 }
+ end
+ end
+ end
+
+ it "should default to that value" do
+ @klass.attr.should == 4
+ end
+
+ it "should default to that value when retrieved as a hash" do
+ @klass[:attr].should == 4
+ end
+
+ it "should be settable to another value" do
+ @klass.attr 5
+ @klass.attr.should == 10
+ @klass[:attr].should == 10
+ end
+
+ it "should be settable to another value with attr=" do
+ @klass.attr = 5
+ @klass.attr.should == 10
+ @klass[:attr].should == 10
+ end
+
+ it "should be settable to another value with [:attr]=" do
+ @klass[:attr] = 5
+ @klass.attr.should == 10
+ @klass[:attr].should == 10
+ end
+
+ it "should still default to that value after delete" do
+ @klass.attr 5
+ @klass.delete(:attr)
+ @klass.attr.should == 4
+ end
+
+ it "should still default to that value after reset" do
+ @klass.attr 5
+ @klass.reset
+ @klass.attr.should == 4
+ end
+ end
+
+ describe "When a configurable exists with writer and default value set in chained form" do
+ before :each do
+ @klass = Class.new
+ @klass.extend(::Mixlib::Config)
+ @klass.class_eval do
+ configurable(:attr).defaults_to(4).writes_value { |value| value*2 }
+ end
+ end
+
+ it "should default to that value" do
+ @klass.attr.should == 4
+ end
+
+ it "should default to that value when retrieved as a hash" do
+ @klass[:attr].should == 4
+ end
+
+ it "should be settable to another value" do
+ @klass.attr 5
+ @klass.attr.should == 10
+ @klass[:attr].should == 10
+ end
+
+ it "should be settable to another value with attr=" do
+ @klass.attr = 5
+ @klass.attr.should == 10
+ @klass[:attr].should == 10
+ end
+
+ it "should be settable to another value with [:attr]=" do
+ @klass[:attr] = 5
+ @klass.attr.should == 10
+ @klass[:attr].should == 10
+ end
+
+ it "should still default to that value after delete" do
+ @klass.attr 5
+ @klass.delete(:attr)
+ @klass.attr.should == 4
+ end
+
+ it "should still default to that value after reset" do
+ @klass.attr 5
+ @klass.reset
+ @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
+ config_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
+ config_context(:blah) do
+ config_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
+
+ describe "When a nested context has strict mode on" do
+ class StrictClass2
+ extend ::Mixlib::Config
+ config_context :c do
+ config_strict_mode true
+ default :x, 1
+ end
+ end
+
+ it "The parent class allows you to set arbitrary config options" do
+ StrictClass2.y = 10
+ end
+
+ it "The nested class does not allow you to set arbitrary config options" do
+ lambda { StrictClass2.c.y = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
+ end
+ end
+
+ describe "When strict mode is on but a nested context has strict mode unspecified" do
+ class StrictClass3
+ extend ::Mixlib::Config
+ config_strict_mode true
+ default :x, 1
+ config_context :c
+ end
+
+ it "The parent class does not allow you to set arbitrary config options" do
+ lambda { StrictClass3.y = 10 }.should raise_error(Mixlib::Config::UnknownConfigOptionError)
+ end
+
+ it "The nested class allows you to set arbitrary config options" do
+ StrictClass3.c.y = 10
+ end
end
end