Add support for validation contexts #246

Closed
wants to merge 1 commit into
from

Projects

None yet

6 participants

@sj26

There's no easy way to test validation contexts with the current shoulda matchers. The context must be provided in the call to the instance's valid? method. This patch adds a simple way to optionally pass a context.

Example:

class User
  include ActiveModel::Model
  validates_presence_of :email, on: :emailable
end

describe User do
  it { should_not validate_presence_of(:email) }
  it { should validate_presence_of(:email).on(:emailable) }
end

Previously this would have to involve stubbing the implementation detail validation_context, simply setting it is not enough as it is overridden by every run of valid?:

describe User do
  it { should_not validate_presence_of(:email) }
  context do
    before { subject.stub(validation_context: :emailable) }
    it { should validate_presence_of(:email) }
  end
end

This can also be used for the idiomatic activerecord contexts:

class User < ActiveRecord::Base
  validates_presence_of :password, on: :create
end

describe User do
  it { should validate_presence_of(:password).on(:create) }
  it { should_not validate_presence_of(:password).on(:update) }
end
@mxie mxie commented on an outdated diff Mar 25, 2013
spec/shoulda/active_model/allow_value_matcher_spec.rb
@@ -25,6 +25,30 @@
end
end
+ context "an attribute with a context-dependent validation" do
+ let(:model) do
+ define_model :example, :attr => :string do
+ validates_format_of :attr, :with => /abc/, :on => :customisable
+ end.new
+ end
+
+ context "without the validation context" do
+ it "allows a bad value" do
+ model.should allow_value("xyz").for(:attr)
@mxie
mxie Mar 25, 2013

Instead of using your let above and model.should here (and lines 43, 47), take advantage of the validating_format method that's already available (from spec/shoulda/matchers/active_model/allow_value_matcher_spec.rb). It'll look something like this:

 validating_format(:with => /abc/, :on => :customisable).should allow_value("xyz").for(:attr)
@mxie
thoughtbot, inc. member

I like this idea, and it looks like this would fulfill #131 as well, so that's awesome! However, please rebase and check out my comment on the spec.

@mxie
thoughtbot, inc. member

Also, I just noticed that your allow_value_matcher_spec.rb file is in a different directory structure than it's supposed to be in...definitely rebase and resolve that please. Thanks!

@sj26

Sorry for the delays, but I've rebased and fixed up those specs—master has moved fast! Should be good to go now.

@camelmasa

👍

@drapergeek
thoughtbot, inc. member

Thanks @sj26! Merged.

@drapergeek drapergeek closed this Apr 26, 2013
@anujbiyani

Any reason why this functionality wasn't added to validate_numericality_of?

@mcmire

I believe this should work with all matchers, is this not working with validate_numericality_of?

@anujbiyani
Failures:

  1) Upload 
     Failure/Error: it { should validate_numericality_of(:picture_count).on(:create).is_greater_than(0) }
     NoMethodError:
       undefined method `on' for #<Shoulda::Matchers::ActiveModel::ValidateNumericalityOfMatcher:0x007fa324d82c40>
     # ./spec/models/upload_spec.rb:11:in `block (2 levels) in <top (required)>'

This is on version 2.3.0.

I'll try and open a PR (or at least a separate issue).

@mcmire

Okay, thanks.

@sj26

@anujbiyani did #313 fix your issue? There was an oversight which means some matchers weren't accepting #on.

@sj26

Ah, no, I see— ValidateNumericalityOfMatcher doesn't inherit from ValidationMatcher since 6ba8c9f. Have you submitted a pull yet, or shall I?

(I don't see anything in your activity so I'll have a stab.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment