HEAD
Backward-incompatible changes
We've dropped support for Rails 3.x, Ruby 1.9.2, and Ruby 1.9.3, and RSpec 2. All of these things have been end-of-lifed. This doesn't mean that the gem will stop working immediately, but we won't accept any pull requests to fix any compatibility issues, so you're encouraged to upgrade. (a4045a1, b7fe87a)
The gem no longer detects the test framework you're using or mixes itself into that framework automatically. History has shown that performing any kind of detection is prone to bugs and more complicated than it should be.
Here are the updated instructions:
- You no longer need to say
require: falsein your Gemfile; you can include the gem as normal. - You'll need to add the following somewhere in your
rails_helper(for RSpec) ortest_helper(for Minitest / Test::Unit):
Shoulda::Matchers.configure do |config| config.integrate do |with| # Choose a test framework: with.test_framework :rspec with.test_framework :minitest with.test_framework :minitest_4 with.test_framework :test_unit # Choose one or more libraries: with.library :active_record with.library :active_model with.library :action_controller # Or, choose the following (which implies all of the above): with.library :rails end end(1900071)
- You no longer need to say
There are two changes to
allow_value:The negative form of the matcher has been changed so that instead of asserting that any of the given values is an invalid value (allowing good values to pass through), assert that all values are invalid values (allowing good values not to pass through). This means that this test which formerly passed will now fail:
expect(record).not_to allow_value('good value', *bad_values)
(19ce8a6) * The matcher may raise an error if the attribute in question contains custom logic to ignore certain values, resulting in a discrepancy between the value you provide and the value that the attribute is actually set to. Specifically, if the attribute cannot be changed from a non-nil value to a nil value, or vice versa, then you'll get a CouldNotSetAttributeError. The current behavior (which is to permit this) is misleading, as the test that you're writing under the hood by using
allow_valuecould be different from the test that actually ends up getting run. (eaaa2d8)validate_uniqueness_ofis now properly case-insensitive by default, to match the default behavior of the validation itself. This is a backward-incompatible change because this test which incorrectly passed before will now fail:class Product < ActiveRecord::Base validates_uniqueness_of :name, case_sensitive: false end describe Product do it { is_expected.to validate_uniqueness_of(:name) } end(57a1922)
ensure_inclusion_of,ensure_exclusion_of, andensure_length_ofhave been removed in favor of theirvalidate_*counterparts. (55c8d09)set_the_flashandset_sessionhave been changed to more closely align with each other:Change behavior of
validate_uniqueness_ofwhen the matcher is not qualified with any scopes, but your validation is. Previously the following test would pass when it now fails:class Post < ActiveRecord::Base validate :slug, uniqueness: { scope: :user_id } end describe Post do it { should validate_uniqueness_of(:slug) } end(6ac7b81)
Bug fixes
So far the tests for the gem have been running against only SQLite. Now they run against PostgreSQL, too. As a result we were able to fix some Postgres-related bugs, specifically around
validate_uniqueness_of:- When scoped to a UUID column that ends in an "f", the matcher is able to generate a proper "next" value without erroring. (#402, #587, #662)
- Support scopes that are PostgreSQL array columns. Please note that this is only supported for Rails 4.2 and greater, as versions before this cannot handle array columns correctly, particularly in conjunction with the uniqueness validator. (#554)
- Fix so that when scoped to a text column and the scope is set to nil before running it through the matcher, the matcher does not fail. (#521, #607)
Fix
define_enum_forso that it actually tests that the attribute is present in the list of defined enums, as you could fool it by merely defining a class method that was the pluralized version of the attribute name. In the same vein, passing a pluralized version of the attribute name todefine_enum_forwould erroneously pass, and now it fails. (#641)Fix
permitso that it does not break the functionality of ActionController::Parameters#require. (#648, #675)Fix
validate_uniqueness_of+scoped_toso that it does not raise an error if a record exists where the scoped attribute is nil. (#677)Fix
routematcher so if your route includes a defaultformat, you can specify this as a symbol or string. (#693)Fix
validate_uniqueness_ofso that it allows you to test against scoped attributes that are boolean columns. (#457, #694)Fix failure message for
validate_numericality_ofas it sometimes didn't provide the reason for failure. (#699)
Features
Add
onqualifier topermit. This allows you to make an assertion that a restriction was placed on a slice of theparamshash and not the entireparamshash. Although we don't require you to use this qualifier, we do recommend it, as it's a more precise check. (#675)Add
strictqualifier tovalidate_numericality_of. (#620)Add
onqualifier tovalidate_numericality_of. (9748869; h/t #356, #358)Add
join_tablequalifier tohave_and_belong_to_many. (#556)allow_valuesis now an alias forallow_value. This makes more sense when checking against multiple values:it { should allow_values('this', 'and', 'that') }(#692)
2.8.0
Deprecations
ensure_length_ofhas been renamed tovalidate_length_of.ensure_length_ofis deprecated and will be removed in 3.0.0.set_the_flashhas been renamed toset_flash.set_the_flashis deprecated and will be removed in 3.0.0.set_session(:foo)is deprecated in favor ofset_session[:foo].set_session(:foo)will be invalid syntax in 3.0.0.Using
should set_session[:key].to(nil)to assert that that a value has not been set is deprecated. Please useshould_not set_session[:key]instead. In 3.0.0,should set_session[:key].to(nil)will only pass if the value is truly nil.
Bug fixes
Fix
delegate_methodso that it works again with shoulda-context. (#591)Fix
validate_uniqueness_ofwhen used withscoped_toso that when one of the scope attributes is a polymorphic*_typeattribute and the model has another validation on the same attribute, the matcher does not fail with an error. (#592)Fix
has_manyused withthroughso that when the association does not exist, and the matcher fails, it does not raise an error when producing the failure message. (#588)Fix
have_and_belong_to_manyused withjoin_tableso that it does not fail whenforeign_keyand/orassociation_foreign_keywas specified on the association as a symbol instead of a string. (#584)Fix
allow_valuewhen an i18n translation key is passed towith_messageand the:againstoption is used to specify an alternate attribute. A bug here also happened to affectvalidate_confirmation_ofwhen an i18n translation key is passed towith_message. (#593)Fix
class_namequalifier for association matchers so that if the model being referenced is namespaced, the matcher will correctly resolve the class before checking it against the association'sclass_name. (#537)Fix
validate_inclusion_ofused withwith_messageso that it fails if given a message that does not match the message on the validation. (#598)Fix
routematcher so that when controller and action are specified in hash notation (e.g.posts#show), route parameters such asiddo not need to be specified as a string but may be specified as a number as well. (#602)Fix
allow_value,validate_numericality_ofandvalidate_inclusion_ofso that they handle RangeErrors emitted from ActiveRecord 4.2. These exceptions arise whenever we attempt to set an attribute using a value that lies outside the range of the column (assuming the column is an integer). RangeError is now treated specially, failing the test instead of bubbling up as an error. (#634, #637, #642)
Features
Add ability to test
:primary_keyoption on associations. (#597)Add
allow_blankqualifier tovalidate_uniqueness_ofto complement theallow_blankoption. (#543)Change
set_sessionso that #[] and #to qualifiers are optional, similar toset_flash. That is, you can now sayshould set_sessionto assert that any flash value has been set, orshould set_session.to('value')to assert that any value in the session is 'value'.Change
set_sessionso that its #to qualifier supports regexps, similar toset_flash.Add
with_prefixqualifier todelegate_methodto correspond to theprefixoption for Rails'sdelegatemacro. (#622)Add support for Rails 4.2, especially fixing
serializematcher to remove warning aboutserialized_attributesbeing deprecated. (#627)Update
dependentqualifier on association matchers to support:destroy,:delete,:nullify,:restrict,:restrict_with_exception, and:restrict_with_error. You can also passtrueorfalseto assert that the association has (or has not) been declared with any dependent option. (#631)
Improvements
- Tweak
allow_valuefailure message so that it reads a bit nicer when listing existing errors.
2.7.0
Deprecations
ensure_inclusion_ofhas been renamed tovalidate_inclusion_of.ensure_inclusion_ofis deprecated and will be removed in 3.0.0.ensure_exclusion_ofhas been renamed tovalidate_exclusion_of.ensure_exclusion_ofis deprecated and will be removed in 3.0.0.
Bug fixes
Fix
delegate_methodso that it does not raise an error if the method that returns the delegate object is private.Warn when
ensure_inclusion_ofis chained with.in_array([false, true])as well as with.in_array([true, false]).Fix
set_sessionso that thetoqualifier if given nil checks that the session variable in question was set to nil (previously this actually did nothing).Fix
filter_paramso that it works whenconfig.filter_parameterscontains regexes.Fix
delegate_methodso that it can be required independent of Active Support.Fix
validate_uniqueness_of. When used against an unpersisted record whose model contained a non-nullable column other than the one being validated, the matcher would break. Even if the test set that column to a value beforehand, the record had to be persisted in order for the matcher to work. Now this is no longer the case and the record can remain unpersisted.Fix
validate_absence_of: it required that a string be passed as the attribute name rather than a symbol (which is the usual and documented usage).
Features
- Add new matcher
define_enum_forto test usage of theenummacro introduced in Rails 4.1.
Improvements
have_and_belongs_to_manynow checks to make sure that the join table contains the correct columns for the left- and right-hand side of the association.Reword failure message for
delegate_methodso that it's a little more helpful.
2.6.2
Bug fixes
If you have a Rails >= 4.1 project and you are running tests using Spring, matchers that depend on assertions within Rails' testing layer (e.g.
render_templateandroute) will no longer fail.Fix
permitso that it can be used more than once in the same test.Revert change to
validate_uniqueness_ofmade in 2.6.0 so that it no longer provides default values for non-primary, non-nullable columns. This approach was causing test failures because it makes the assumption that none of these columns allow only specific values, which is not true. If you get an error fromvalidate_uniqueness_of, your best bet continues to be creating a record manually and callingvalidate_uniqueness_ofon that instead.The majority of warnings that the gem produced have been removed. The gem still produces warnings under Ruby 1.9.3; we will address this in a future release.
2.6.1
Bug fixes
Revert changes to
validate_numericality_ofmade in the last release, which made it so that comparison qualifiers specified on the validation are tested using a very small decimal number offset rather than a whole number by default, except if the matcher was qualified withonly_integer. This means that prior to 2.6.0, if your validation specifiedonly_integerand you did not, then after 2.6.0 that test would fail. This is now fixed.Fix regression in previous release where ActiveRecord matchers would not be included when ActiveRecord wasn't defined (i.e. if you were using ActiveModel only).
Revert the behavior of
allow_valuechanged in 2.6.0 (it will no longer raise CouldNotClearAttribute). This was originally done as a part of a fix forvalidate_presence_ofwhen used in conjunction withhas_secure_password. That fix has been updated so that it does not affectallow_value.Fix callback matchers and correct test coverage.
Fix
permitso that it does not interfere with different usages ofparamsin your controller action. Specifically, this will not raise an error:params.fetch(:foo, {}).permit(:bar, :baz)(thepermitwill have no problems recognizing that :bar and :baz are permitted params).Fix
permiton Rails 4.1 to use PATCH by default for #update instead of PUT. Previously you had to specify this manually.Fix
permitso that it track multiple calls to #permit in your controller action. Previously only the last usage of #permit would be considered in determining whether the matcher matched.Fix
permitso that if the route for your action requires params (such as id) then you can now specify those params:permit(:first_name, :last_name).for(:update, params: { id: 42 }).Fix
delegate_methodso that it does not stub the target method forever, returning it to its original implementation after the match ends.Fix
validate_uniqueness_ofto work with Rails 4.1 enum columns.
Features
- Teach
with_messagequalifier onallow_valueto accept a hash of i18n interpolation values:allow_value('foo').for(:attr).with_message(:greater_than, values: { count: 20 }).
2.6.0
The boolean argument to
have_db_index'suniqueoption is now optional, for consistency with other matchers.Association matchers now test that the model being referred to (either implicitly or explicitly, using
:class_name) actually exists.Add ability to test
:autosaveoption on associations.Fix
validate_uniqueness_of(...).allow_nilso that it can be used against an non-password attribute which is in a model thathas_secure_password. Doing so previously would result in a "Password digest missing on new record" error.Fix description for
validate_numericality_ofso that if the matcher fails, the error message reported does not say the matcher accepts integer values if you didn't specify that.Fix
ensure_inclusion_ofso that you can use it against a boolean column (and pass boolean values toin_array). There are two caveats:- You should not test that your attribute allows both true and false
(
.in_array([true, false]); there's no way to test that it doesn't accept anything other than that. - You cannot test that your attribute allows nil (
.in_array([nil])) if the column does not allow null values.
- You should not test that your attribute allows both true and false
(
Change
validate_uniqueness_of(...)so that it provides default values for non-nullable attributes.Running
rakenow installs Appraisals before running the test suite. (Additionally, we now manage Appraisals using theappraisalexecutable in Appraisal 1.0.0.)Add
allow_niloption tovalidate_numericality_ofso that you can validate that numeric values are validated only if a value is supplied.Fix
validate_numericality_ofso that test fails when the value withgreater_than,greater_than_or_equal_to,less_than,less_than_or_equal_ toorequal_tois not appropriate.Change
validate_presence_ofunder Rails 4 so that if you are using it with a user whose modelhas_secure_passwordand whose password is set to a value, you will be instructed to use a user whose password is blank instead. The reason for this change is due to the fact that Rails 4's version ofhas_secure_passworddefines #password= such thatnilwill be ignored, which interferes with howvalidate_presence_ofworks.Add ability to test
belongs_toassociations defined with:inverse_of.Add back matchers that were removed in 2.0.0:
permit, for testing strong parameters, anddelegate_method, for testing delegation.Add new matchers for testing controller filters:
before_filter,after_filter, andaround_filter(aliased tobefore_action,after_actionandaround_actionfor Rails 4).Fix
rescue_frommatcher so that it does not raise an error when testing a method handler which has been marked as protected or private.Fix compatibility issues with Rails 4.1:
set_the_flashandhave_and_belongs_to_manyno longer raise errors- Minitest no longer prints warnings whenever shoulda-matchers is required
v 2.5.0
Fix Rails/Test::Unit integration to ensure that the test case classes we are re-opening actually exist.
Fix
ensure_length_ofso that it uses the right message to validate whenis_equal_tois specified in conjunction with a custom message.The
routematcher now accepts specifying a controller/action pair as a string instead of only a hash (e.g.route(...).to('posts#index')instead ofroute(...).to(controller: 'posts', action: 'index')).The
ensure_inclusion_ofmatcher now works with a decimal column.Under Rails 3, if you had an association matcher chained with the the
ordersubmatcher -- e.g.should have_many(:foos).order(:bar)-- and your association had an:includeon it, using the matcher would raise an error. This has been fixed.Fix
validate_uniqueness_ofso it doesn't fail if the attribute under test has a limit of fewer than 16 characters.You can now test that your
has_many :throughorhas_one :throughassociations are defined with a:sourceoption.Add new matcher
validates_absence_of.Update matchers so that they use
failure_messageandfailure_message_when_negatedto define error messages. These are new methods in the upcoming RSpec 3 release which replacefailure_message_for_shouldandfailure_message_for_should_not. We've kept backward compatibility so all of your existing tests should still work -- this is just to make sure when RSpec 3 is released you don't get a bunch of warnings.
v 2.4.0
Fix a bug with the
validate_numericality_ofmatcher that would not allow thewith_messageoption on certain submatchers.Fix a regression with context-dependent validations in ActiveResource
shoulda-matchers is now fully compatible with Rails 4.
When not using RSpec, shoulda-matchers is now auto-included into ActiveSupport::TestCase instead of Test::Unit::TestCase (in Rails 4 the former no longer inherits from the latter).
v 2.3.0
Fix a bug in
ensure_inclusion_ofthat would cause issues with usingin_arraywith an integer value.Add support for PostgreSQL UUID columns to
validates_uniqueness_of(#334).Fix
validates_numericality_ofso thatis_equal_tosubmatcher works correctly (#326).Fix context support for validation matchers and disallowed values (#313).
Add a
counter_cachesubmatcher forbelongs_toassociations (#311).Add a
rescue_frommatcher for Rails controllers which checks that the correct ActiveSupport call has been made and that the handlers exist without actually throwing an exception (#287).Changed the scope of AssociationMatcher methods from protected to private.
Extracted
#order,#through, and#dependentfrom AssociationMatcher as their own submatchers.
v 2.2.0
Fix
have_and_belong_to_manymatcher issue for Rails 4.Fix
validate_uniqueness_of.scoped_toissue when the scoped field is already taken (#207).Add comparison submatchers to
validate_numericality_ofto correspond to the comparison options you can give tovalidates_numericality_of(#244).
v 2.1.0
Add missing
failure_message_for_should_notimplementations tovalidate_numericality_ofand its submatchersSupport validation contexts for testing validations
on: :createand when using custom contexts likemodel.valid?(:my_context).Fix a bug in validations with autosaved models.
Fix maximum value detection for the
ensure_inclusion_ofandensure_exclusion_ofmatchers.Add
:oddand:evenoptions to thevalidate_numericality_ofmatcher.Add
:touchoption to AssociationMatcher.Ruby 2.0.0 is now officially supported.
Fix the issue where using
%{attribute}or%{model}in I18n translations raised exceptions.Support datetime columns in
validate_uniqueness_of.scoped_to.Add
allow_niloption to thevalidate_uniqueness_ofmatcher.
v 2.0.0
Remove the following matchers:
assign_torespond_with_content_typequery_the_databasevalidate_format_ofhave_sent_emailpermit(strong parameters matcher)delegate_method
For more information about 2.0 changes, see: http://robots.thoughtbot.com/post/47031676783/shoulda-matchers-2-0.
v 1.5.6
- Revert previous change in AllowValueMatcher that added a check for a properly-set attribute.
v 1.5.5
AllowValueMatcher checks that the right value is used for attempts at setting the attribute with it.
- Please note that previously-passing tests might now fail. It is likely that it's not a bug, but please make sure that the code you're testing is written properly before submitting an issue.
Use DisallowValueMatcher for
disallows_value_ofmethod.Assert
class_namevalue on real class name for AssociationMatcher.Correct the variable used for
validate_confirmation_ofmatcher description.
v 1.5.4
- Properly-released version of 1.5.3.
v 1.5.3 - yanked due to mis-release
- Alleviate the need to add
rspecgem to your app.
v 1.5.1
Bump version dependency of Bourne to allow for Mocha upgrade.
Should fix incompatibility with MiniTest.
v 1.5.0
Deprecate the following matchers:
assign_torespond_with_content_typequery_the_databasevalidate_format_ofhave_sent_emailpermit(strong parameters matcher)delegate_method
Use RSpec's native
configure.includesyntax for including matchers into RSpec (#204).Do not force MiniTest loading when test-unit is available (this was fixed before 1.3.0 then reverted in 1.3.0).
v1.4.2
- Add a new
delegate_methodmatcher.
v1.4.1
Fix an issue when used with Test::Unit on the allow value matcher.
Fix an issue with using
ensure_inclusion_of(:attr)given an array of true or false values.
v1.4.0
Add
strictoption to validation matchers.Verify that arguments to
set_the_flashmatcher are valid.Fix issue in ValidateUniquenessMatcher that could cause an error on postgres.
You can now pass an array to
ensure_exclusion_ofusingin_array.Allow testing of
:foreign_keyoption forhas_onerelationships using the association matcher.Fix bug where
ensure_length_ofwould pass if the given string was too long.allow_blankwill now allow values such as: ' ', '\n', and '\r'.Test outside values for
ensure_inclusion_ofwhen given an array.Fix the output of the
set_the_flashmatcher.
v1.3.0
validate_format_ofwill acceptallow_blank(bool)andallow_nil(bool).Prefer Test::Unit to MiniTest when loading integrations so that RubyMine is happy (#88).
validates_uniqueness_ofwill now create a record if one does not exist. Previously, users were required to create a record in the database before using this matcher.Fix an edge case when where the matchers weren't loaded into Test::Unit when mixing RSpec and Test::Unit tests and also loading both the 'rspec-rails' gem and 'shoulda-matchers' gem from the same Gemfile group, namely [:test, :development].
controller.should_not render_partialnow correctly matchesrender partial: "partial".
v1.2.0
ensure_inclusion_ofnow has anin_arrayparameter:ensure_inclusion_of(:attr).in_array(['foo', 'bar']). It cannot be used with the.in_rangeoption. (vpereira)ensure_in_inclusion_ofwithin_arraywill acceptallow_blank(bool)andallow_nil(false)Test against Rails 3.2.
Fix
ensure_length_ofto use all possible I18n error messages.have_db_index.unique(nil)used to function exactly the same ashave_db_indexwith no unique option. It now functions the same ashave_db_index.unique(false).In 1.1.0,
have_sent_emailchecked all emails to ensure they matched. It now checks that only one email matches, which restores 1.0.0 behavior.
v1.1.0
Add
only_integeroption tovalidate_numericality_of:should validate_numericality_of(:attribute).only_integerAdd a
query_the_databasematcher:it { should query_the_database(4.times).when_calling(:complicated_method) }it { should query_the_database(4.times).or_less.when_calling(:complicated_method) }it { should_not query_the_database.when_calling(:complicated_method) }Database columns are now correctly checked for primality. E.G., this works now:
it { should have_db_column(:id).with_options(:primary => true) }The flash matcher can check specific flash keys using [], like so:
it { should set_the_flash[:alert].to("Password doesn't match") }The
have_sent_emailmatcher can checkreply_to:it { should have_sent_email.reply_to([user, other]) }Add
validates_confirmation_ofmatcher:it { should validate_confirmation_of(:password) }Add
serializematcher:it { should serialize(:details).as(Hash).as_instance_of(Hash) }shoulda-matchers checks for all possible I18n keys, instead of just e.g.
activerecord.errors.messages.blankAdd
accept_nested_attributesmatcherOur very first dependency: ActiveSupport >= 3.0.0