summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Keiser <john@johnkeiser.com>2015-06-03 14:32:43 -0700
committerJohn Keiser <john@johnkeiser.com>2015-06-23 15:23:01 -0700
commit4e34d816167af65b36c7a57ad33dca3b1f39c1e4 (patch)
tree0572f1f83c28db05fb5225837b13ab97c36fe3e2
parentc4257f9d016871c6b4243079542d803d5e7fa383 (diff)
downloadchef-4e34d816167af65b36c7a57ad33dca3b1f39c1e4.tar.gz
Add "is" to property
-rw-r--r--lib/chef/mixin/params_validate.rb212
-rw-r--r--lib/chef/resource.rb3
-rw-r--r--spec/unit/property/validation_spec.rb110
-rw-r--r--spec/unit/property_spec.rb6
4 files changed, 175 insertions, 156 deletions
diff --git a/lib/chef/mixin/params_validate.rb b/lib/chef/mixin/params_validate.rb
index ccc313db32..6fe5036570 100644
--- a/lib/chef/mixin/params_validate.rb
+++ b/lib/chef/mixin/params_validate.rb
@@ -109,137 +109,155 @@ class Chef
private
- # Return the value of a parameter, or nil if it doesn't exist.
- def _pv_opts_lookup(opts, key)
- if opts.has_key?(key.to_s)
- opts[key.to_s]
- elsif opts.has_key?(key.to_sym)
- opts[key.to_sym]
+ # Return the value of a parameter, or nil if it doesn't exist.
+ def _pv_opts_lookup(opts, key)
+ if opts.has_key?(key.to_s)
+ opts[key.to_s]
+ elsif opts.has_key?(key.to_sym)
+ opts[key.to_sym]
+ else
+ nil
+ end
+ end
+
+ # Raise an exception if the parameter is not found.
+ def _pv_required(opts, key, is_required=true)
+ if is_required
+ if (opts.has_key?(key.to_s) && !opts[key.to_s].nil?) ||
+ (opts.has_key?(key.to_sym) && !opts[key.to_sym].nil?)
+ true
else
- nil
+ raise Exceptions::ValidationFailed, "Required argument #{key} is missing!"
end
end
+ end
- # Raise an exception if the parameter is not found.
- def _pv_required(opts, key, is_required=true)
- if is_required
- if (opts.has_key?(key.to_s) && !opts[key.to_s].nil?) ||
- (opts.has_key?(key.to_sym) && !opts[key.to_sym].nil?)
- true
- else
- raise Exceptions::ValidationFailed, "Required argument #{key} is missing!"
- end
+ def _pv_equal_to(opts, key, to_be)
+ value = _pv_opts_lookup(opts, key)
+ unless value.nil?
+ passes = false
+ to_be = Array(to_be)
+ to_be.each do |tb|
+ passes = true if value == tb
+ end
+ unless passes
+ raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
end
end
+ end
- def _pv_equal_to(opts, key, to_be)
- value = _pv_opts_lookup(opts, key)
- unless value.nil?
- passes = false
- to_be = Array(to_be)
- to_be.each do |tb|
- passes = true if value == tb
- end
- unless passes
- raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
- end
+ # Raise an exception if the parameter is not a kind_of?(to_be)
+ def _pv_kind_of(opts, key, to_be)
+ value = _pv_opts_lookup(opts, key)
+ unless value.nil?
+ passes = false
+ to_be = Array(to_be)
+ to_be.each do |tb|
+ passes = true if value.kind_of?(tb)
+ end
+ unless passes
+ raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
end
end
+ end
- # Raise an exception if the parameter is not a kind_of?(to_be)
- def _pv_kind_of(opts, key, to_be)
- value = _pv_opts_lookup(opts, key)
- unless value.nil?
- passes = false
- to_be = Array(to_be)
- to_be.each do |tb|
- passes = true if value.kind_of?(tb)
- end
- unless passes
- raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
+ # Raise an exception if the parameter does not respond to a given set of methods.
+ def _pv_respond_to(opts, key, method_name_list)
+ value = _pv_opts_lookup(opts, key)
+ unless value.nil?
+ Array(method_name_list).each do |method_name|
+ unless value.respond_to?(method_name)
+ raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!"
end
end
end
+ end
- # Raise an exception if the parameter does not respond to a given set of methods.
- def _pv_respond_to(opts, key, method_name_list)
- value = _pv_opts_lookup(opts, key)
- unless value.nil?
- Array(method_name_list).each do |method_name|
- unless value.respond_to?(method_name)
- raise Exceptions::ValidationFailed, "Option #{key} must have a #{method_name} method!"
- end
+ # Assert that parameter returns false when passed a predicate method.
+ # For example, :cannot_be => :blank will raise a Exceptions::ValidationFailed
+ # error value.blank? returns a 'truthy' (not nil or false) value.
+ #
+ # Note, this will *PASS* if the object doesn't respond to the method.
+ # So, to make sure a value is not nil and not blank, you need to do
+ # both :cannot_be => [ :blank, :nil ]
+ def _pv_cannot_be(opts, key, predicate_method_base_name)
+ value = _pv_opts_lookup(opts, key)
+ Array(predicate_method_base_name).each do |method_name|
+ predicate_method = :"#{method_name}?"
+
+ if value.respond_to?(predicate_method)
+ if value.send(predicate_method)
+ raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
end
end
end
+ end
+
+ # Assign a default value to a parameter.
+ def _pv_default(opts, key, default_value)
+ value = _pv_opts_lookup(opts, key)
+ if value == nil
+ opts[key] = default_value
+ end
+ end
- # Assert that parameter returns false when passed a predicate method.
- # For example, :cannot_be => :blank will raise a Exceptions::ValidationFailed
- # error value.blank? returns a 'truthy' (not nil or false) value.
- #
- # Note, this will *PASS* if the object doesn't respond to the method.
- # So, to make sure a value is not nil and not blank, you need to do
- # both :cannot_be => [ :blank, :nil ]
- def _pv_cannot_be(opts, key, predicate_method_base_name)
- value = _pv_opts_lookup(opts, key)
- Array(predicate_method_base_name).each do |method_name|
- predicate_method = :"#{method_name}?"
-
- if value.respond_to?(predicate_method)
- if value.send(predicate_method)
- raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
+ # Check a parameter against a regular expression.
+ def _pv_regex(opts, key, regex)
+ value = _pv_opts_lookup(opts, key)
+ if value != nil
+ passes = false
+ Array(regex).each do |r|
+ if value != nil
+ if r.match(value.to_s)
+ passes = true
end
end
end
- end
-
- # Assign a default value to a parameter.
- def _pv_default(opts, key, default_value)
- value = _pv_opts_lookup(opts, key)
- if value == nil
- opts[key] = default_value
+ unless passes
+ raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
end
end
+ end
- # Check a parameter against a regular expression.
- def _pv_regex(opts, key, regex)
- value = _pv_opts_lookup(opts, key)
- if value != nil
- passes = false
- Array(regex).each do |r|
- if value != nil
- if r.match(value.to_s)
- passes = true
- end
- end
- end
- unless passes
- raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
+ # Check a parameter against a hash of proc's.
+ def _pv_callbacks(opts, key, callbacks)
+ raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash)
+ value = _pv_opts_lookup(opts, key)
+ if value != nil
+ callbacks.each do |message, zeproc|
+ if zeproc.call(value) != true
+ raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!"
end
end
end
+ end
- # Check a parameter against a hash of proc's.
- def _pv_callbacks(opts, key, callbacks)
- raise ArgumentError, "Callback list must be a hash!" unless callbacks.kind_of?(Hash)
- value = _pv_opts_lookup(opts, key)
- if value != nil
- callbacks.each do |message, zeproc|
- if zeproc.call(value) != true
- raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!"
- end
- end
+ # Allow a parameter to default to @name
+ def _pv_name_attribute(opts, key, is_name_attribute=true)
+ if is_name_attribute
+ if opts[key] == nil
+ opts[key] = self.instance_variable_get("@name")
end
end
+ end
- # Allow a parameter to default to @name
- def _pv_name_attribute(opts, key, is_name_attribute=true)
- if is_name_attribute
- if opts[key] == nil
- opts[key] = self.instance_variable_get("@name")
+ # Compare the way "case" would (i.e. `===`)
+ def _pv_is(opts, key, to_be)
+ value = _pv_opts_lookup(opts, key)
+ unless value.nil?
+ passes = false
+ to_be = Array(to_be)
+ to_be.each do |tb|
+ if tb.is_a?(Proc)
+ return if instance_exec(value, &tb)
+ else
+ return if tb === value
end
end
+
+ raise Exceptions::ValidationFailed, "Option #{key} must be one of: #{to_be.join(", ")}! You passed #{value.inspect}."
end
+ end
end
end
end
diff --git a/lib/chef/resource.rb b/lib/chef/resource.rb
index 40a6e911a6..712b7b36cb 100644
--- a/lib/chef/resource.rb
+++ b/lib/chef/resource.rb
@@ -720,6 +720,9 @@ class Chef
#
# @param name [Symbol] The name of the property.
# @param options [Hash<Symbol,Object>] Validation options.
+ # @option options [Object,Array] :is An object, or list of
+ # objects, that must match the value using Ruby's `===` operator
+ # (`options[:is].any? { |v| v === value }`).
# @option options [Object,Array] :equal_to An object, or list
# of objects, that must be equal to the value using Ruby's `==`
# operator (`options[:is].any? { |v| v == value }`)
diff --git a/spec/unit/property/validation_spec.rb b/spec/unit/property/validation_spec.rb
index a88ebfd0cf..4aa8a5474e 100644
--- a/spec/unit/property/validation_spec.rb
+++ b/spec/unit/property/validation_spec.rb
@@ -136,61 +136,61 @@ describe "Chef::Resource.property validation" do
# end
# is
- # context "is" do
- # # Class
- # validation_test 'is: String',
- # [ 'a', '' ],
- # [ nil, :a, 1 ]
- #
- # # Value
- # validation_test 'is: :a',
- # [ :a ],
- # [ :b, nil ]
- #
- # validation_test 'is: [ :a, :b ]',
- # [ :a, :b ],
- # [ [ :a, :b ], nil ]
- #
- # validation_test 'is: [ [ :a, :b ] ]',
- # [ [ :a, :b ] ],
- # [ :a, :b, nil ]
- #
- # # Regex
- # validation_test 'is: /abc/',
- # [ 'abc', 'wowabcwow' ],
- # [ '', 'abac', nil ]
- #
- # # PropertyType
- # validation_test 'is: PropertyType.new(is: :a)',
- # [ :a ],
- # [ :b, nil ]
- #
- # # RSpec Matcher
- # class Globalses
- # extend RSpec::Matchers
- # end
- #
- # validation_test "is: Globalses.eq(10)",
- # [ 10 ],
- # [ 1, nil ]
- #
- # # Proc
- # validation_test 'is: proc { |x| x }',
- # [ true, 1 ],
- # [ false, nil ]
- #
- # validation_test 'is: proc { |x| x > blah }',
- # [ 10 ],
- # [ -1 ]
- #
- # validation_test 'is: nil',
- # [ nil ],
- # [ 'a' ]
- #
- # validation_test 'is: [ String, nil ]',
- # [ 'a', nil ],
- # [ :b ]
- # end
+ context "is" do
+ # Class
+ validation_test 'is: String',
+ [ 'a', '' ],
+ [ nil, :a, 1 ]
+
+ # Value
+ validation_test 'is: :a',
+ [ :a ],
+ [ :b, nil ]
+
+ validation_test 'is: [ :a, :b ]',
+ [ :a, :b ],
+ [ [ :a, :b ], nil ]
+
+ validation_test 'is: [ [ :a, :b ] ]',
+ [ [ :a, :b ] ],
+ [ :a, :b, nil ]
+
+ # Regex
+ validation_test 'is: /abc/',
+ [ 'abc', 'wowabcwow' ],
+ [ '', 'abac', nil ]
+
+ # PropertyType
+ # validation_test 'is: PropertyType.new(is: :a)',
+ # [ :a ],
+ # [ :b, nil ]
+
+ # RSpec Matcher
+ class Globalses
+ extend RSpec::Matchers
+ end
+
+ validation_test "is: Globalses.eq(10)",
+ [ 10 ],
+ [ 1, nil ]
+
+ # Proc
+ validation_test 'is: proc { |x| x }',
+ [ true, 1 ],
+ [ false, nil ]
+
+ validation_test 'is: proc { |x| x > blah }',
+ [ 10 ],
+ [ -1 ]
+
+ validation_test 'is: nil',
+ [ nil ],
+ [ 'a' ]
+
+ validation_test 'is: [ String, nil ]',
+ [ 'a', nil ],
+ [ :b ]
+ end
# Combination
context "combination" do
diff --git a/spec/unit/property_spec.rb b/spec/unit/property_spec.rb
index b9c0d27da8..d948ad20e0 100644
--- a/spec/unit/property_spec.rb
+++ b/spec/unit/property_spec.rb
@@ -652,8 +652,7 @@ describe "Chef::Resource.property" do
end
end
- # with_property ':x, is: proc { |v| Namer.next_index; true }' do
- with_property ':x, callbacks: { "a" => proc { |v| Namer.next_index; true } }' do
+ with_property ':x, is: proc { |v| Namer.next_index; true }' do
it "lazy values are validated on each access" do
resource.x lazy { Namer.next_index }
expect(resource.x).to eq 1
@@ -730,8 +729,7 @@ describe "Chef::Resource.property" do
# end
context "Chef::Resource::PropertyType validation" do
- # with_property ':x, is: proc { |v| Namer.next_index; v.is_a?(Integer) }' do
- with_property ':x, callbacks: { "a" => proc { |v| Namer.next_index; v.is_a?(Integer) } }' do
+ with_property ':x, is: proc { |v| Namer.next_index; v.is_a?(Integer) }' do
it "validation runs on set" do
expect(resource.x 10).to eq 10
expect(Namer.current_index).to eq 1