* Add Appraisal for Rails 6.1
* Upgrade Rails
* fix: standardize error message of association matcher
* Bump listen version to v3.5.1
* Fix the wrong number of arguments (given 2, expected 1)
* Remove deprecated method
* Update Rails to 6.1.3.2
* Remove test for ActiveModel::Errors#generate_message
* Missing ':through' option for has_many association.
* Fix the actual_foreign_key method that is returning a string instead of an array of foreign keys
* Fix Bundler::GemNotFound: Could not find gem 'puma (~> 5.0)'
* Fix Bundler::GemNotFound: Could not find gem 'rack-mini-profiler (~> 2.0)'
* Bump rspec-rails to 4.1.2
* Fix 'rails generate' not working with Rails 6.1
While attempting to add support for `ignoring_interference_by_writer` to
the confirmation matcher, I was noticing that there are two attributes
we are concerned with: the attribute under test, and the confirmation
attribute -- for instance, `password` and `password_confirmation`. The
way that the matcher works, `password_confirmation` is set first on the
record before `password` is set, and then the whole record is validated.
This is fine, but I also noticed that `allow_value` has a specific way
of setting attributes -- not only does it check whether the attribute
being set exists and fail properly if it is does not, but it also
raises a CouldNotSetAttribute error if the attribute changes incoming
values. This logic needs to be performed on both `password_confirmation`
as well as `password`.
With that in mind, `allow_value` now supports a `values_to_preset=`
writer method which allows one to assign additional attributes unrelated
to the one being tested prior to validation. This will be used by the
confirmation matcher in a future commit.
This means that `allow_value` now operates in two steps:
1. Set attributes unrelated to the test, raising an error if any of the
attributes do not exist on the model.
2. Set the attribute under test to one or more values, raising an error
if the attribute does not exist, then running validations on the
record, failing with an appropriate error message if the validations
fail.
Note that the second step is similar to the first, although there are
more things involved. To that end, `allow_value` has been completely
refactored so that the logic for setting and validating attributes
happens in other places. Specifically, the core logic to set an
attribute (and capture the results) is located in a new AttributeSetter
class.
Also, the CouldNotSetAttributeError class has been moved to a namespace
and renamed to AttributeChangedValueError.
Finally, this commit fixes DisallowValueMatcher so that it is the true
opposite of AllowValueMatcher: DVM#matches? calls AVM#does_not_match?
and DVM#does_not_match? calls AVM#matches?.
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.
* Have the failure message describe more clearly what the `allow_value`
matcher was trying to do when it failed.
* Make the description of the matcher more readable.
* For each value that `allow_value` sets, use a different Validator
instance. The matcher still changes state as it runs, but a future
commit will refactor this further.
* Merge StrictValidator back into Validator, and remove it. The way that
StrictValidator worked (as a module that was mixed into an instance of
Validator at runtime) was confusing, and there's really no need to
split out the logic anymore.
* Fix or fill in tests involving failure messages and descriptions.
Active Record 4.2.1 and upper no more raises a `RangeError` on the
assign, only at database level [1].
This will remove all code related to handling of Active Record `RangeError`.
Also, this upgrades the internal dependency on Rails 4.2 to 4.2.3.
[1]: fed7d7cd7c
In Rails 4.2, ActiveRecord was changed such that if you attempt to set
an attribute to a value and that value is outside the range of the
column, then it will raise a RangeError. For instance, an integer column
with a limit of 2 (i.e. a smallint) only accepts values between -32768
and +32767.
This means that if you try to do any of these three things, a RangeError
could be raised:
* Use validate_numericality_of along with any of the comparison
submatchers and a value that sits on either side of the boundary.
* Use allow_value with a value that sits outside the range.
* Use validates_inclusion_of against an integer column. (Here we attempt
to set that column to a non-integer value to verify that the attribute
does not allow said value. That value is really a string version of a
large number, so if the column does not take large numbers then the
matcher could blow up.)
Ancillary changes in this commit:
* Remove ValidationMessageFinder and ExceptionMessageFinder in favor of
Validator, StrictValidator, and ValidatorWithCapturedRangeError.
* The allow_value matcher now uses an instance of Validator under the
hood. StrictValidator and/or ValidatorWithCapturedRangeError may be
mixed into the Validator object as needed.