Commit Graph

23 Commits

Author SHA1 Message Date
Kapil Sachdev cdcef128cf fix(rubocop): Add trailing comma in args, Hash and Arrays [ci skip]
- Satisfies Style/TrailingCommaInArguments, 
Style/TrailingCommaInArrayLiteral and Style/TrailingCommaInHashLiteral
2020-11-03 10:05:25 -07:00
Pedro Paiva 7d098c92f2 Revert "Use autoloading instead of requiring all files up front"
This reverts commit ce78101362.
2020-08-26 10:52:54 -06:00
Pedro Paiva ce78101362 Use autoloading instead of requiring all files up front 2020-08-24 21:47:12 -06:00
Elliot Winkler a4289e9651
Add the qualifier allow_blank to validate_length_of (#1318)
Co-authored-by: Elliot Winkler <elliot.winkler@gmail.com>
2020-07-11 11:33:54 -06:00
Elliot Winkler 507dc57004 Fix negative versions of validation matchers
When using a validation matcher in the negative, i.e.:

    should_not validate_*(...)

as opposed to:

    should validate_*(...)

...it's common to receive the following error:

    undefined method `attribute_setter' for nil:NilClass

This happens particularly when using a matcher that makes use of
AllowValueMatcher or DisallowValueMatcher internally (which all of the
validation matchers do).

Whenever you make an assertion by using a matcher in the negative as
opposed to the positive, RSpec still calls the `matches?` method for
that matcher; however, the assertion will pass if that returns *false*
as opposed to true. In other words, it just inverts the result.

However, whenever we are using AllowValueMatcher or
DisallowValueMatcher, it doesn't really work to invert the result. like
this. This is because AllowValueMatcher and DisallowValueMatcher,
despite their name, aren't truly opposites of each other.

AllowValueMatcher performs these steps:

1. Set the attribute on the record to some value
2. Run validations on the record
3. Ask whether validations pass or fail
4. If validations fail, store the value that caused the failure along
   with the validation errors and return false
5. Otherwise, return true

However, DisallowValueMatcher performs these steps:

1. Set the attribute on the record to some value
2. Run validations on the record
3. Ask whether validations pass or fail
4. If validations *pass*, store the value that caused the failure along
   with some metadata and return false
5. Otherwise, return true

This difference in logic is achieved by having AllowValueMatcher
implement `does_not_match?` and then having DisallowValueMatcher use
this for its positive case and use `matches?` for its negative case.
It's easy to see because of this that `does_not_match?` is not the same
as `!matches?` and vice versa.

So a matcher that makes use of these submatchers internally needs to use
their opposite versions whenever that matcher is used in the negative
case. In other words, all of the matchers need a `does_not_match?` which
is like `matches?`, except that all of the logic is inverted, and in all
the cases in which AllowValueMatcher is used, DisallowValueMatcher needs
to be used.

Doing this ensures that when `failure_message` is called on
AllowValueMatcher or DisallowValueMatcher, step 4 in the list of steps
above stores a proper value that can then be referenced in the failure
message for the validation matcher itself.
2018-09-15 13:43:30 -03:00
Elliot Winkler 1189934806 Add ignoring_interference_by_writer to all matchers
`allow_value` matcher is, of course, concerned with setting values on a
particular attribute on a particular record, and then checking that the
record is valid after doing so. That comes with a caveat: if the
attribute is overridden in such a way so that the same value going into
the attribute isn't the same value coming out of it, then `allow_value`
will balk -- it'll say, "I can't do that because that changes how I
work."

That's all well and good, but what the attribute intentionally changes
incoming values? ActiveRecord's typecasting behavior, for instance,
would trigger such an exception. What if the developer needs a way to
get around this? This is where `ignoring_interference_by_writer` comes
into play. You can tack it on to the end of the matcher, and you're free
to go on your way.

So, prior to this commit you could already apply it to `allow_value`,
but now in this commit it also works on any other matcher.

But, one little thing: sometimes using this qualifier isn't going to
work. Perhaps you or something else actually *is* overriding the
attribute to change incoming values in a specific way, and perhaps the
value that comes out makes the record fail validation, and there's
nothing you can do about it. So in this case, even if you're using
`ignoring_interference_by_writer`, we want to inform you about what the
attribute is doing -- what the input and output was. And so we do.
2016-01-05 00:58:16 -07:00
Elliot Winkler 8361f39579 Refactor ValidationMatcher
This is part of a collection of commits that aim to improve failure
messages across the board, in order to make matchers easier to debug
when something goes wrong.

In this case, we're improving ValidationMatcher, which applies to most
matchers except for numericality.

* Reword the overall failure message so that it includes the failure
  message for the last submatcher that failed.
* Extract code to build the description to BuildDescription. This code
  now checks to see whether certain qualifiers have been specified and
  includes information about them in the description, if present.
* Add a base implementation of `with_message` to ValidationMatcher.
* Add simple booleans to check whether `with_message` or `strict` have
  been specified.
2015-12-13 20:22:21 -07:00
Mauro George 32c0e62596 Drop support for RSpec 2 2015-09-22 13:12:46 -06:00
Elliot Winkler 12cc7aaace Remove all Ruby-emitted warnings
Run RSpec tests with warnings enabled so we stay on top of this better
in the future.
2014-07-18 18:00:08 -06:00
Elliot Winkler c22d7c89e0 Extract examples in README to inline documentation 2014-06-20 16:41:27 -06:00
Christopher Chow 1878e89a13 Update deprecated matcher protocol for RSpec 3.
The methods failure_message_for_should and failure_message_for_should_not
have been updated to failure_message and failure_message_negated respectively.
Alias to the old methods to remain backwards compatibility with RSpec 2.
2013-12-24 22:34:26 +11:00
Elliot Winkler a026afb800 Fix validates_confirmation_of matcher so that it works under Rails 4
Rails 4 changed how validates_confirmation_of works so that the error
message is applied to the confirmation attribute, not the original
attribute.
2013-08-16 16:17:26 -06:00
Samuel Cochran e40f778515 Fix context support for disallowed value and validation matchers 2013-07-02 12:18:56 +10:00
patrick brisbin a1afc5771a Don't swap failure messages in ValidationMatcher
It's not entirely clear why these were being swapped to begin with, but
it was causing messages to appear backwards in the presence validation
matcher.

Other matchers using these methods were tested by hand and still output
correct messages -- they too may have been backwards before this fix.
2013-05-24 11:13:52 -04:00
Samuel Cochran d680e7d47b Add support for validation contexts. 2013-04-26 13:40:06 -04:00
Melissa Xie 058f39f187 Use DisallowValueMatcher for `disallows_value_of` method 2013-03-28 14:02:03 -04:00
Brian Shaver 4f8684c6db Rename failure_message and negative_failure_message
* fixes #108 : RSpec 2.10 compatibility
* remove unnecessary attr_readr
2013-03-08 14:49:12 -05:00
Joe Ferris 96d32c289c Remove duplication in ValidationMatcher 2012-09-12 09:47:20 -04:00
Joe Ferris d9289fa5c7 Add #strict option to validation matchers
* Allow verifying validates! and :strict => true
2012-09-11 20:53:21 -04:00
Gabe Berke-Williams 2910dfa999 Check all values when validating against an array.
Clean up tests a bit.
2012-04-20 11:37:18 -04:00
Victor Pereira e40e2cb1ac looks like its working 2012-04-20 11:36:27 -04:00
Gabe Berke-Williams ff0d364475 Fix alignment. 2012-03-23 10:50:45 -04:00
Markus Schwed 2a54fdb28d Seperate ActiveRecord and ActiveModel related matchers 2011-05-06 15:56:36 +02:00
Renamed from lib/shoulda/matchers/active_record/validation_matcher.rb (Browse further)