summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBryan McLellan <btm@opscode.com>2013-05-24 11:21:31 -0700
committerBryan McLellan <btm@opscode.com>2013-05-24 11:21:31 -0700
commitb04d31e6d3f21031bcc2e2b3326232d20d8ed0c2 (patch)
treeccdb02970fcf1dd7d85ce0a81d09e41480c85934
parent4eae072fd47c883b988f0192eff41a0641fb9e40 (diff)
parentba8abc1b2d33dd20963d8e626acc4f2b19781c1b (diff)
downloadchef-b04d31e6d3f21031bcc2e2b3326232d20d8ed0c2.tar.gz
Merge branch 'CHEF-3731' into 10-stable
-rw-r--r--chef/lib/chef/mixin/params_validate.rb25
-rw-r--r--chef/spec/unit/mixin/params_validate_spec.rb35
2 files changed, 54 insertions, 6 deletions
diff --git a/chef/lib/chef/mixin/params_validate.rb b/chef/lib/chef/mixin/params_validate.rb
index 649224f978..2f00ca0de8 100644
--- a/chef/lib/chef/mixin/params_validate.rb
+++ b/chef/lib/chef/mixin/params_validate.rb
@@ -16,7 +16,8 @@
# limitations under the License.
class Chef
-
+ class DelayedEvaluator < Proc
+ end
module Mixin
module ParamsValidate
@@ -75,18 +76,30 @@ class Chef
end
opts
end
-
+
+ def lazy(&block)
+ DelayedEvaluator.new(&block)
+ end
+
def set_or_return(symbol, arg, validation)
iv_symbol = "@#{symbol.to_s}".to_sym
map = {
symbol => validation
}
-
if arg == nil && self.instance_variable_defined?(iv_symbol) == true
- self.instance_variable_get(iv_symbol)
+ ivar = self.instance_variable_get(iv_symbol)
+ if(ivar.is_a?(DelayedEvaluator))
+ validate({ symbol => ivar.call }, { symbol => validation })[symbol]
+ else
+ ivar
+ end
else
- opts = validate({ symbol => arg }, { symbol => validation })
- self.instance_variable_set(iv_symbol, opts[symbol])
+ if(arg.is_a?(DelayedEvaluator))
+ val = arg
+ else
+ val = validate({ symbol => arg }, { symbol => validation })[symbol]
+ end
+ self.instance_variable_set(iv_symbol, val)
end
end
diff --git a/chef/spec/unit/mixin/params_validate_spec.rb b/chef/spec/unit/mixin/params_validate_spec.rb
index dd0366c37c..9802a8729c 100644
--- a/chef/spec/unit/mixin/params_validate_spec.rb
+++ b/chef/spec/unit/mixin/params_validate_spec.rb
@@ -366,5 +366,40 @@ describe Chef::Mixin::ParamsValidate do
@vo.set_or_return(:name, value, { }).object_id.should == value.object_id
@vo.set_or_return(:foo, nil, { :name_attribute => true }).object_id.should == value.object_id
end
+
+ it "should allow DelayedEvaluator instance to be set for value regardless of restriction" do
+ value = Chef::DelayedEvaluator.new{ 'test' }
+ @vo.set_or_return(:test, value, {:kind_of => Numeric})
+ end
+
+ it "should raise an error when delayed evaluated attribute is not valid" do
+ value = Chef::DelayedEvaluator.new{ 'test' }
+ @vo.set_or_return(:test, value, {:kind_of => Numeric})
+ lambda do
+ @vo.set_or_return(:test, nil, {:kind_of => Numeric})
+ end.should raise_error(Chef::Exceptions::ValidationFailed)
+ end
+
+ it "should create DelayedEvaluator instance when #lazy is used" do
+ @vo.set_or_return(:delayed, @vo.lazy{ 'test' }, {})
+ @vo.instance_variable_get(:@delayed).should be_a(Chef::DelayedEvaluator)
+ end
+
+ it "should execute block on each call when DelayedEvaluator" do
+ value = 'fubar'
+ @vo.set_or_return(:test, @vo.lazy{ value }, {})
+ @vo.set_or_return(:test, nil, {}).should == 'fubar'
+ value = 'foobar'
+ @vo.set_or_return(:test, nil, {}).should == 'foobar'
+ value = 'fauxbar'
+ @vo.set_or_return(:test, nil, {}).should == 'fauxbar'
+ end
+
+ it "should not evaluate non DelayedEvaluator instances" do
+ value = lambda{ 'test' }
+ @vo.set_or_return(:test, value, {})
+ @vo.set_or_return(:test, nil, {}).object_id.should == value.object_id
+ @vo.set_or_return(:test, nil, {}).should be_a(Proc)
+ end
end