summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThom May <thom@chef.io>2018-02-12 15:10:53 +0000
committerThom May <thom@chef.io>2018-03-08 11:32:07 +0000
commitc6744e65c51c79481a59f5af183e369ccdca4760 (patch)
tree95362567de050ed67bf3ff7ec3c3406332cf3df4
parentc420eb377d2f25804ac3e69607d6c98990e941ae (diff)
downloadchef-c6744e65c51c79481a59f5af183e369ccdca4760.tar.gz
Implement RFC 101: Custom Validation Messages
Adds validation_message as a property option Signed-off-by: Thom May <thom@chef.io>
-rw-r--r--lib/chef/mixin/params_validate.rb28
-rw-r--r--spec/unit/mixin/params_validate_spec.rb13
-rw-r--r--spec/unit/property/validation_spec.rb9
3 files changed, 40 insertions, 10 deletions
diff --git a/lib/chef/mixin/params_validate.rb b/lib/chef/mixin/params_validate.rb
index d90e38b916..c955dd3b12 100644
--- a/lib/chef/mixin/params_validate.rb
+++ b/lib/chef/mixin/params_validate.rb
@@ -1,6 +1,6 @@
#
# Author:: Adam Jacob (<adam@chef.io>)
-# Copyright:: Copyright 2008-2017, Chef Software Inc.
+# Copyright:: Copyright 2008-2018, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -35,6 +35,8 @@ class Chef
# map options are:
#
# @param opts [Hash<Symbol,Object>] Validation opts.
+ # @option opts [String] :validation_message A custom message to return
+ # should validation fail.
# @option opts [Object,Array] :is An object, or list of
# objects, that must match the value using Ruby's `===` operator
# (`opts[:is].any? { |v| v === value }`). (See #_pv_is.)
@@ -91,16 +93,20 @@ class Chef
raise ArgumentError, "Options must be a hash" unless opts.kind_of?(Hash)
raise ArgumentError, "Validation Map must be a hash" unless map.kind_of?(Hash)
+ @validation_message ||= {}
+
map.each do |key, validation|
unless key.kind_of?(Symbol) || key.kind_of?(String)
raise ArgumentError, "Validation map keys must be symbols or strings!"
end
+
case validation
when true
_pv_required(opts, key)
when false
true
when Hash
+ @validation_message[key] = validation.delete(:validation_message) if validation.has_key?(:validation_message)
validation.each do |check, carg|
check_method = "_pv_#{check}"
if respond_to?(check_method, true)
@@ -129,6 +135,10 @@ class Chef
validation.has_key?(:is) && _pv_is({ key => nil }, key, validation[:is], raise_error: false)
end
+ def _validation_message(key, default)
+ @validation_message.has_key?(key) ? @validation_message[key] : default
+ end
+
# 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)
@@ -145,7 +155,7 @@ class Chef
if is_required
return true if opts.has_key?(key.to_s) && (explicitly_allows_nil || !opts[key.to_s].nil?)
return true if opts.has_key?(key.to_sym) && (explicitly_allows_nil || !opts[key.to_sym].nil?)
- raise Exceptions::ValidationFailed, "Required argument #{key.inspect} is missing!"
+ raise Exceptions::ValidationFailed, _validation_message(key, "Required argument #{key.inspect} is missing!")
end
true
end
@@ -168,7 +178,7 @@ class Chef
to_be.each do |tb|
return true if value == tb
end
- raise Exceptions::ValidationFailed, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}."
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} must be equal to one of: #{to_be.join(", ")}! You passed #{value.inspect}.")
end
end
@@ -187,7 +197,7 @@ class Chef
to_be.each do |tb|
return true if value.kind_of?(tb)
end
- raise Exceptions::ValidationFailed, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}."
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} must be a kind of #{to_be}! You passed #{value.inspect}.")
end
end
@@ -202,7 +212,7 @@ class Chef
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!"
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} must have a #{method_name} method!")
end
end
end
@@ -234,7 +244,7 @@ class Chef
if value.respond_to?(predicate_method)
if value.send(predicate_method)
- raise Exceptions::ValidationFailed, "Option #{key} cannot be #{predicate_method_base_name}"
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key} cannot be #{predicate_method_base_name}")
end
end
end
@@ -294,7 +304,7 @@ class Chef
Array(regex).flatten.each do |r|
return true if r.match(value.to_s)
end
- raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}"
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key}'s value #{value} does not match regular expression #{regex.inspect}")
end
end
@@ -316,7 +326,7 @@ class Chef
if !value.nil?
callbacks.each do |message, zeproc|
unless zeproc.call(value)
- raise Exceptions::ValidationFailed, "Option #{key}'s value #{value} #{message}!"
+ raise Exceptions::ValidationFailed, _validation_message(key, "Option #{key}'s value #{value} #{message}!")
end
end
end
@@ -428,7 +438,7 @@ class Chef
unless errors.empty?
message << " Errors:\n#{errors.map { |m| "- #{m}" }.join("\n")}"
end
- raise Exceptions::ValidationFailed, message
+ raise Exceptions::ValidationFailed, _validation_message(key, message)
end
end
diff --git a/spec/unit/mixin/params_validate_spec.rb b/spec/unit/mixin/params_validate_spec.rb
index 0cafb925c8..7bc8a27398 100644
--- a/spec/unit/mixin/params_validate_spec.rb
+++ b/spec/unit/mixin/params_validate_spec.rb
@@ -1,6 +1,6 @@
#
# Author:: Adam Jacob (<adam@chef.io>)
-# Copyright:: Copyright 2008-2016, Chef Software Inc.
+# Copyright:: Copyright 2008-2018, Chef Software Inc.
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -342,6 +342,17 @@ describe Chef::Mixin::ParamsValidate do
end.to raise_error(Chef::Exceptions::ValidationFailed)
end
+ it "allows a custom validation message" do
+ expect do
+ @vo.validate({ :not_blank => "should pass" },
+ { :not_blank => { :cannot_be => [ :nil, :empty ], validation_message: "my validation message" } })
+ end.not_to raise_error
+ expect do
+ @vo.validate({ :not_blank => "" },
+ { :not_blank => { :cannot_be => [ :nil, :empty ], validation_message: "my validation message" } })
+ end.to raise_error(Chef::Exceptions::ValidationFailed, "my validation message")
+ end
+
it "should set and return a value, then return the same value" do
value = "meow"
expect(@vo.set_or_return(:test, value, {}).object_id).to eq(value.object_id)
diff --git a/spec/unit/property/validation_spec.rb b/spec/unit/property/validation_spec.rb
index 13afcdfbc2..882ea3353b 100644
--- a/spec/unit/property/validation_spec.rb
+++ b/spec/unit/property/validation_spec.rb
@@ -699,4 +699,13 @@ describe "Chef::Resource.property validation" do
end
end
end
+
+ context "custom validation messages" do
+ with_property ":x, String, validation_message: 'Must be a string, fool'" do
+ it "raise with the correct error message" do
+ expect { resource.x 1 }.to raise_error Chef::Exceptions::ValidationFailed,
+ "Must be a string, fool"
+ end
+ end
+ end
end