Commit Graph

15 Commits

Author SHA1 Message Date
Mauro George 73cf275d10 Stop handling AR RangeError when assign a attribute
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
2015-09-23 15:46:32 -06:00
Elliot Winkler e708789714 Fix failure message for numericality matcher
Secondary author: Mauro George <maurogot@gmail.com>

Sometimes the failure message did not always provide the reason for
failure. For instance, given this validation:

    validates :ano, numericality: { only_integer: true, greater_than_or_equal_to: 1900 }

this test:

    it { should validate_numericality_of(:ano).is_greater_than_or_equal_to(1900) }

would fail with the following:

    Did not expect errors  when ano is set to 1900.000000000001, got error:

as you can see, the failure message doesn't contain the validation
error.

In the process of making this fix, we changed how the matcher fails so
that it will so when the first submatcher fails, not the last. This
changes what the failure message looks like, but not the basic
functionality of the matcher itself.
2015-06-01 01:38:35 -06:00
Elliot Winkler e11891e818 Rewrite the tests for #permit
* Use `permit` directly instead of manually building the matcher
* Some tests were being tested by calling #matches? directly when they
  shouldn't have been, and some tests were duplicated
* Rename helper methods that define controllers to express intent better
* Don't make a global class (SimulatedError), keep the class local to
  the example group
* Use lambdas for that use `raise_error`
2015-02-28 23:41:01 -07:00
Anthony Navarre + Elliot Winkler eaaa2d83e5 allow_value: Raise error if attr sets value differently
`allow_value` will now raise a CouldNotSetAttribute error if the
attribute in question cannot be changed from a non-nil value to a nil
value, or vice versa. In other words, these are the exact cases in which
the error will occur:

* If you're testing whether the attribute allows `nil`, but the
  attribute detects and ignores nil. (For instance, you have a model
  that `has_secure_password`. This will add a #password= method to your
  model that is defined in a such a way that you cannot clear the
  password by setting it to nil -- nothing happens.)
* If you're testing whether the attribute allows a non-nil value, but
  the attribute fails to set that value. (For instance, you have an
  ActiveRecord model. If ActiveRecord cannot typecast the value in the
  context of the column, then it will do nothing, and the attribute will be
  effectively set to nil.)

What's the reasoning behind this change? Simply put, if you are assuming
that the attribute is changing but in fact it is not, then the test
you're writing isn't the test that actually gets run. We feel that this
is dishonest and produces an invalid test.
2015-02-17 23:09:56 -07:00
Elliot Winkler 6aeccd3c8e Uniqueness: Support PG array columns for scopes
Please note that array columns do not work properly between Rails 4.0
and 4.2.

* If you set an array-of-date or array-of-time attribute to an
  array, it will fail to hold that value. This is an issue with
  timestamp-aware attributes and is fixed in Rails 4.2.

* Even if this worked, the uniqueness validator cannot cope with array
  columns, producing an invalid query. This will be fixed in 4.1.10.
2015-02-13 16:33:26 -07:00
Elliot Winkler 74fa081ef5 Stop testing against columns unsupported by SQLite 2015-02-12 16:05:46 -07:00
Elliot Winkler 72f60fae94 Add support for Postgres
When running tests, you can now switch between running them against a
SQLite or PostgreSQL database. This is accomplished by modifying the
unit and acceptance tests so that when they generate and load the test
Rails application, database.yml is replaced with content that will
configure the database appropriately.
2015-02-12 16:01:00 -07:00
Elliot Winkler a43b8e44dd Rewrite tests for validate_uniqueness_of
* The main problem I had with the old tests is that information that
  the reader didn't need to care about was not properly abstracted away.
  For instance, a helper method used by almost all tests will always
  create a model called Example, and will always use an attribute called
  "attr" (on which the validation is present). However, in some tests
  the class or attribute is referred to directly. The reader shouldn't
  have to care about either of these things, since they are constant --
  the tests should be readable enough so that this information is not
  necessary to understand the case being tested against.

* Speaking of this helper method, some of the tests used it and some
  didn't. Some defined their own helper methods to represent a
  particular case (`case_sensitive: true`, `allow_nil`, etc.). This is
  now fixed so that all but two tests use the same helper method to
  define a model. This model is completely customizable -- one can
  specify the type of the attribute being validated, the names and types
  of scoped attributes, etc.

* The tests around scoped attributes and different types are all
  basically the same, so they are now compressed into a shared context.

* Related to this, we no longer have to worry about setting a proper
  value for a scope attribute. One had to know which type that attribute
  had and come up with a reasonable default for that type. Now there is
  a helper method that worries about this automatically.

* Finally, we remove tests around case_insensitive against an integer
  attribute (these don't make any sense, and don't work).
2015-02-11 16:09:40 -07:00
Elliot Winkler 9ba21381d7 Handle RangeErrors emitted now in ActiveRecord 4.2
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.
2015-01-22 21:05:09 -07:00
Elliot Winkler 547d8b762f Fix AR matcher tests for Rails 4.2 2014-12-25 00:45:06 -05:00
Elliot Winkler fab4f02da3 Fix AC matcher tests for Rails 4.2
Modify helper methods provided by ControllerBuilder so that we use as
much of rspec-rails's controller example group capabilities as possible.
All of this can still be improved but this is a good start for now.
2014-12-25 00:45:04 -05:00
Elliot Winkler df6c0ef56e Clear schema cache after each test
When running unit tests in a random order, some tests may fail as the
columns hash within a model may not be in sync with the database. This
is because the columns hash is cached outside of the model, so removing
the model from the object space and then recreating that model won't
clear the columns hash.
2014-11-06 14:16:17 -07:00
Elliot Winkler 4c9dfa7616 Fix another warning 2014-11-05 16:39:04 -07:00
Elliot Winkler f922613386 Reorganize unit tests, part II
* Change 'spec' Rake task to 'spec:unit'
* Require unit_spec_helper.rb in unit tests, not spec_helper.rb
* Re-namespace files in spec/support/unit under UnitTests
* Files in spec/support/unit/helpers no longer automatically add
  themselves to RSpec - this happens in unit_spec_helper.rb
* Extract RecordWithDifferentErrorAttributeBuilder and
  RecordValidatingConfirmationBuilder to separate files
2014-11-05 09:53:20 -07:00
Elliot Winkler bbdf8a807e Reorganize unit tests, part I
* Move spec/shoulda to spec/unit_tests/shoulda
* Move spec/support/*.rb to spec/support/unit_tests/{helpers,matchers}
* Move spec_helper.rb to unit_spec_helper.rb
2014-11-04 14:43:59 -07:00