Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for validation contexts #246

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
# HEAD

* Support validation contexts for testing validations `on: :create` and when
using custom contexts like `model.valid?(:my_context)`.

# v 1.5.6
* Revert previous change in `AllowValueMatcher` that added a check for a
properly-set attribute.
Expand Down
9 changes: 7 additions & 2 deletions lib/shoulda/matchers/active_model/allow_value_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ def for(attribute)
self
end

def on(context)
@context = context
self
end

def with_message(message)
self.options[:expected_message] = message
self
Expand Down Expand Up @@ -78,7 +83,7 @@ def description
private

attr_accessor :values_to_match, :message_finder_factory,
:instance, :attribute, :value, :matched_error
:instance, :attribute, :context, :value, :matched_error

def errors_match?
has_messages? && errors_for_attribute_match?
Expand Down Expand Up @@ -161,7 +166,7 @@ def model_name
end

def message_finder
message_finder_factory.new(instance, attribute)
message_finder_factory.new(instance, attribute, context)
end
end
end
Expand Down
5 changes: 3 additions & 2 deletions lib/shoulda/matchers/active_model/exception_message_finder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ module Matchers
module ActiveModel
# Finds message information from exceptions thrown by #valid?
class ExceptionMessageFinder
def initialize(instance, attribute)
def initialize(instance, attribute, context=nil)
@instance = instance
@attribute = attribute
@context = context
end

def allow_description(allowed_values)
Expand Down Expand Up @@ -39,7 +40,7 @@ def expected_message_from(attribute_message)
private

def validate_and_rescue
@instance.valid?
@instance.valid?(@context)
[]
rescue ::ActiveModel::StrictValidationFailed => exception
[exception.message]
Expand Down
5 changes: 5 additions & 0 deletions lib/shoulda/matchers/active_model/validation_matcher.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,11 @@ def initialize(attribute)
@strict = false
end

def on(context)
@context = context
self
end

def strict
@strict = true
self
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@ module ActiveModel
class ValidationMessageFinder
include Helpers

def initialize(instance, attribute)
def initialize(instance, attribute, context=nil)
@instance = instance
@attribute = attribute
@context = context
end

def allow_description(allowed_values)
Expand Down Expand Up @@ -58,7 +59,7 @@ def validated_instance
end

def validate_instance
@instance.valid?
@instance.valid?(@context)
@instance
end
end
Expand Down
18 changes: 18 additions & 0 deletions spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,24 @@
end
end

context "an attribute with a context-dependent validation" do
context "without the validation context" do
it "allows a bad value" do
validating_format(:with => /abc/, :on => :customisable).should allow_value("xyz").for(:attr)
end
end

context "with the validation context" do
it "allows a good value" do
validating_format(:with => /abc/, :on => :customisable).should allow_value("abcde").for(:attr).on(:customisable)
end

it "rejects a bad value" do
validating_format(:with => /abc/, :on => :customisable).should_not allow_value("xyz").for(:attr).on(:customisable)
end
end
end

context 'an attribute with several validations' do
let(:model) do
define_model :example, :attr => :string do
Expand Down