shoulda-matchers 6.4.0 → 6.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +116 -89
- data/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +8 -8
- data/lib/shoulda/matchers/action_controller/route_params.rb +1 -1
- data/lib/shoulda/matchers/active_model/allow_value_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +1 -1
- data/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +47 -0
- data/lib/shoulda/matchers/doublespeak/double_collection.rb +1 -1
- data/lib/shoulda/matchers/independent/delegate_method_matcher.rb +86 -5
- data/lib/shoulda/matchers/rails_shim.rb +3 -3
- data/lib/shoulda/matchers/version.rb +1 -1
- metadata +2 -2
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 28aa81eb37b239f9f7715725027b774736992c82c2f6905b0d244a35f9db080d
         | 
| 4 | 
            +
              data.tar.gz: 2433121dc12d086b12c19f5313abcaf8c885cd03de594dd3bcaae0f9150c4173
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: c3dab42effbda8285e424feab81c543bb2e84d9764b513db8007a6b6bb0a2dd923fc76db8f253013dc701588dda5ca314fa3d7e2de9e15af84a8a84f9245670b
         | 
| 7 | 
            +
              data.tar.gz: 6902d75fa7b45c3adc8c97917e9fc1c610be1e99a95bb860ba5112793cdb7653189e4f303f8c879842576a679e3975a520d8ff98dc160ad2168b3fa0b105ecf5
         | 
    
        data/README.md
    CHANGED
    
    | @@ -13,7 +13,7 @@ | |
| 13 13 | 
             
            [logo]: https://matchers.shoulda.io/images/shoulda-matchers-logo.png
         | 
| 14 14 | 
             
            [website]: https://matchers.shoulda.io/
         | 
| 15 15 |  | 
| 16 | 
            -
            Shoulda Matchers provides RSpec | 
| 16 | 
            +
            Shoulda Matchers provides RSpec and Minitest-compatible one-liners to test
         | 
| 17 17 | 
             
            common Rails functionality that, if written by hand, would be much longer, more
         | 
| 18 18 | 
             
            complex, and error-prone.
         | 
| 19 19 |  | 
| @@ -27,25 +27,33 @@ complex, and error-prone. | |
| 27 27 |  | 
| 28 28 | 
             
            ## Table of contents
         | 
| 29 29 |  | 
| 30 | 
            -
             | 
| 31 | 
            -
                | 
| 32 | 
            -
             | 
| 33 | 
            -
             | 
| 34 | 
            -
               | 
| 35 | 
            -
             | 
| 36 | 
            -
             | 
| 37 | 
            -
             | 
| 38 | 
            -
             | 
| 39 | 
            -
             | 
| 40 | 
            -
             | 
| 41 | 
            -
             | 
| 42 | 
            -
             | 
| 43 | 
            -
             | 
| 44 | 
            -
             | 
| 45 | 
            -
             | 
| 46 | 
            -
             | 
| 47 | 
            -
             | 
| 48 | 
            -
             | 
| 30 | 
            +
            - [Getting started](#getting-started)
         | 
| 31 | 
            +
               - [RSpec](#rspec)
         | 
| 32 | 
            +
                - [Rails apps](#rails-apps)
         | 
| 33 | 
            +
                - [Non-Rails apps](#non-rails-apps)
         | 
| 34 | 
            +
              - [Minitest](#minitest)
         | 
| 35 | 
            +
                - [Rails apps](#rails-apps-1)
         | 
| 36 | 
            +
                - [Non-Rails apps](#non-rails-apps-1)
         | 
| 37 | 
            +
            - [Usage](#usage)
         | 
| 38 | 
            +
              - [On the subject of `subject`](#on-the-subject-of-subject)
         | 
| 39 | 
            +
              - [Availability of RSpec matchers in example groups](#availability-of-rspec-matchers-in-example-groups)
         | 
| 40 | 
            +
                - [Rails projects](#rails-projects)
         | 
| 41 | 
            +
                - [Non-Rails projects](#non-rails-projects)
         | 
| 42 | 
            +
              - [`should` vs `is_expected.to`](#should-vs-is_expectedto)
         | 
| 43 | 
            +
              - [A Note on Testing Style](#a-note-on-testing-style)
         | 
| 44 | 
            +
            - [Matchers](#matchers)
         | 
| 45 | 
            +
              - [ActiveModel matchers](#activemodel-matchers)
         | 
| 46 | 
            +
              - [ActiveRecord matchers](#activerecord-matchers)
         | 
| 47 | 
            +
              - [ActionController matchers](#actioncontroller-matchers)
         | 
| 48 | 
            +
              - [Routing matchers](#routing-matchers)
         | 
| 49 | 
            +
              - [Independent matchers](#independent-matchers)
         | 
| 50 | 
            +
            - [Extensions](#extensions)
         | 
| 51 | 
            +
            - [Contributing](#contributing)
         | 
| 52 | 
            +
            - [Compatibility](#compatibility)
         | 
| 53 | 
            +
            - [Versioning](#versioning)
         | 
| 54 | 
            +
            - [Team](#team)
         | 
| 55 | 
            +
            - [Copyright/License](#copyrightlicense)
         | 
| 56 | 
            +
            - [About thoughtbot](#about-thoughtbot)
         | 
| 49 57 |  | 
| 50 58 | 
             
            ## Getting started
         | 
| 51 59 |  | 
| @@ -63,8 +71,8 @@ Then run `bundle install`. | |
| 63 71 |  | 
| 64 72 | 
             
            Now you need to configure the gem by telling it:
         | 
| 65 73 |  | 
| 66 | 
            -
             | 
| 67 | 
            -
             | 
| 74 | 
            +
            - which matchers you want to use in your tests
         | 
| 75 | 
            +
            - that you're using RSpec so that it can make those matchers available in
         | 
| 68 76 | 
             
              your example groups
         | 
| 69 77 |  | 
| 70 78 | 
             
            #### Rails apps
         | 
| @@ -125,8 +133,8 @@ Then run `bundle install`. | |
| 125 133 |  | 
| 126 134 | 
             
            Now you need to configure the gem by telling it:
         | 
| 127 135 |  | 
| 128 | 
            -
             | 
| 129 | 
            -
             | 
| 136 | 
            +
            - which matchers you want to use in your tests
         | 
| 137 | 
            +
            - that you're using Minitest so that it can make those matchers available in
         | 
| 130 138 | 
             
              your test case classes
         | 
| 131 139 |  | 
| 132 140 | 
             
            #### Rails apps
         | 
| @@ -167,18 +175,18 @@ end | |
| 167 175 | 
             
            Most of the matchers provided by this gem are useful in a Rails context, and as
         | 
| 168 176 | 
             
            such, can be used for different parts of a Rails app:
         | 
| 169 177 |  | 
| 170 | 
            -
             | 
| 171 | 
            -
             | 
| 178 | 
            +
            - [database models backed by ActiveRecord](#activerecord-matchers)
         | 
| 179 | 
            +
            - [non-database models, form objects, etc. backed by
         | 
| 172 180 | 
             
              ActiveModel](#activemodel-matchers)
         | 
| 173 | 
            -
             | 
| 174 | 
            -
             | 
| 175 | 
            -
             | 
| 181 | 
            +
            - [controllers](#actioncontroller-matchers)
         | 
| 182 | 
            +
            - [routes](#routing-matchers) (RSpec only)
         | 
| 183 | 
            +
            - [Rails-specific features like `delegate`](#independent-matchers)
         | 
| 176 184 |  | 
| 177 185 | 
             
            As the name of the gem indicates, most matchers are designed to be used in
         | 
| 178 186 | 
             
            "one-liner" form using the `should` macro, a special directive available in both
         | 
| 179 187 | 
             
            RSpec and [Shoulda]. For instance, a model test case may look something like:
         | 
| 180 188 |  | 
| 181 | 
            -
            ``` | 
| 189 | 
            +
            ```ruby
         | 
| 182 190 | 
             
            # RSpec
         | 
| 183 191 | 
             
            RSpec.describe MenuItem, type: :model do
         | 
| 184 192 | 
             
              describe 'associations' do
         | 
| @@ -216,7 +224,7 @@ in certain cases it can be advantageous to override it. For instance, when | |
| 216 224 | 
             
            testing validations in a model, it is customary to provide a valid model instead
         | 
| 217 225 | 
             
            of a fresh one:
         | 
| 218 226 |  | 
| 219 | 
            -
            ``` | 
| 227 | 
            +
            ```ruby
         | 
| 220 228 | 
             
            # RSpec
         | 
| 221 229 | 
             
            RSpec.describe Post, type: :model do
         | 
| 222 230 | 
             
              describe 'validations' do
         | 
| @@ -242,7 +250,7 @@ correct object. **When in doubt, provide an instance of the class under test.** | |
| 242 250 | 
             
            This is particularly necessary for controller tests, where it is easy to
         | 
| 243 251 | 
             
            accidentally write something like:
         | 
| 244 252 |  | 
| 245 | 
            -
            ``` | 
| 253 | 
            +
            ```ruby
         | 
| 246 254 | 
             
            RSpec.describe PostsController, type: :controller do
         | 
| 247 255 | 
             
              describe 'GET #index' do
         | 
| 248 256 | 
             
                subject { get :index }
         | 
| @@ -257,7 +265,7 @@ end | |
| 257 265 |  | 
| 258 266 | 
             
            In this case, you would want to use `before` rather than `subject`:
         | 
| 259 267 |  | 
| 260 | 
            -
            ``` | 
| 268 | 
            +
            ```ruby
         | 
| 261 269 | 
             
            RSpec.describe PostsController, type: :controller do
         | 
| 262 270 | 
             
              describe 'GET #index' do
         | 
| 263 271 | 
             
                before { get :index }
         | 
| @@ -275,26 +283,26 @@ end | |
| 275 283 | 
             
            #### Rails projects
         | 
| 276 284 |  | 
| 277 285 | 
             
            If you're using RSpec, then you're probably familiar with the concept of example
         | 
| 278 | 
            -
            groups. Example groups can be assigned tags  | 
| 286 | 
            +
            groups. Example groups can be assigned tags to assign different behaviors
         | 
| 279 287 | 
             
            to different kinds of example groups. This comes into play especially when using
         | 
| 280 288 | 
             
            `rspec-rails`, where, for instance, controller example groups, tagged with
         | 
| 281 289 | 
             
            `type: :controller`, are written differently than request example groups, tagged
         | 
| 282 290 | 
             
            with `type: :request`. This difference in writing style arises because
         | 
| 283 | 
            -
            `rspec-rails` mixes different  | 
| 291 | 
            +
            `rspec-rails` mixes different behaviors and methods into controller example
         | 
| 284 292 | 
             
            groups vs. request example groups.
         | 
| 285 293 |  | 
| 286 294 | 
             
            Relying on this behavior, Shoulda Matchers automatically makes certain matchers
         | 
| 287 295 | 
             
            available in certain kinds of example groups:
         | 
| 288 296 |  | 
| 289 | 
            -
             | 
| 297 | 
            +
            - ActiveRecord and ActiveModel matchers are available only in model example
         | 
| 290 298 | 
             
              groups, i.e., those tagged with `type: :model` or in files located under
         | 
| 291 299 | 
             
              `spec/models`.
         | 
| 292 | 
            -
             | 
| 300 | 
            +
            - ActionController matchers are available only in controller example groups,
         | 
| 293 301 | 
             
              i.e., those tagged with `type: :controller` or in files located under
         | 
| 294 302 | 
             
              `spec/controllers`.
         | 
| 295 | 
            -
             | 
| 303 | 
            +
            - The `route` matcher is available in routing example groups, i.e., those
         | 
| 296 304 | 
             
              tagged with `type: :routing` or in files located under `spec/routing`.
         | 
| 297 | 
            -
             | 
| 305 | 
            +
            - Independent matchers are available in all example groups.
         | 
| 298 306 |  | 
| 299 307 | 
             
            As long as you're using Rails, you don't need to worry about these details —
         | 
| 300 308 | 
             
            everything should "just work".
         | 
| @@ -306,7 +314,7 @@ and you want to use model matchers in a certain example group?** Then you'll | |
| 306 314 | 
             
            need to manually include the module that holds those matchers into that example
         | 
| 307 315 | 
             
            group. For instance, you might have to say:
         | 
| 308 316 |  | 
| 309 | 
            -
            ``` | 
| 317 | 
            +
            ```ruby
         | 
| 310 318 | 
             
            RSpec.describe MySpecialModel do
         | 
| 311 319 | 
             
              include Shoulda::Matchers::ActiveModel
         | 
| 312 320 | 
             
              include Shoulda::Matchers::ActiveRecord
         | 
| @@ -336,7 +344,7 @@ end | |
| 336 344 | 
             
            ### `should` vs `is_expected.to`
         | 
| 337 345 |  | 
| 338 346 | 
             
            In this README and throughout the documentation, you'll notice that we use the
         | 
| 339 | 
            -
            `should` form of RSpec's one-liner syntax over `is_expected.to`.  | 
| 347 | 
            +
            `should` form of RSpec's one-liner syntax over `is_expected.to`. Besides being
         | 
| 340 348 | 
             
            the namesake of the gem itself, this is our preferred syntax as it's short and
         | 
| 341 349 | 
             
            sweet. But if you prefer to use `is_expected.to`, you can do that too:
         | 
| 342 350 |  | 
| @@ -346,6 +354,25 @@ RSpec.describe Person, type: :model do | |
| 346 354 | 
             
            end
         | 
| 347 355 | 
             
            ```
         | 
| 348 356 |  | 
| 357 | 
            +
            ### A Note on Testing Style
         | 
| 358 | 
            +
             | 
| 359 | 
            +
            If you inspect the source code, you'll notice quickly that `shoulda-matchers`
         | 
| 360 | 
            +
            is largely implemented using reflections and other introspection methods that
         | 
| 361 | 
            +
            Rails provides. At first sight, this might seem to go against the common
         | 
| 362 | 
            +
            practice of testing behavior rather than implementation. However, as the
         | 
| 363 | 
            +
            available matchers indicate, we recommend that you treat `shoulda-matchers` as
         | 
| 364 | 
            +
            a tool to help you ensure correct configuration and adherence to best practices
         | 
| 365 | 
            +
            and idiomatic Rails in your models and controllers - especially for aspects
         | 
| 366 | 
            +
            that in your experience are often insufficiently tested, such as ActiveRecord
         | 
| 367 | 
            +
            validations or controller callbacks (a.k.a. the "framework-y" parts).
         | 
| 368 | 
            +
             | 
| 369 | 
            +
            For testing your application's unique business logic, however, we recommend focusing on
         | 
| 370 | 
            +
            behavior and outcomes over implementation details. This approach will better support
         | 
| 371 | 
            +
            refactoring and ensure that your tests remain resilient to changes in how your code
         | 
| 372 | 
            +
            is structured. While no generalized testing tool can fully capture the nuances of your
         | 
| 373 | 
            +
            specific domain, you can draw inspiration from shoulda-matchers to write custom
         | 
| 374 | 
            +
            matchers that align more closely with your application's needs.
         | 
| 375 | 
            +
             | 
| 349 376 | 
             
            ## Matchers
         | 
| 350 377 |  | 
| 351 378 | 
             
            Here is the full list of matchers that ship with this gem. If you need details
         | 
| @@ -353,106 +380,106 @@ about any of them, make sure to [consult the documentation][rubydocs]! | |
| 353 380 |  | 
| 354 381 | 
             
            ### ActiveModel matchers
         | 
| 355 382 |  | 
| 356 | 
            -
             | 
| 383 | 
            +
            - **[allow_value](lib/shoulda/matchers/active_model/allow_value_matcher.rb)**
         | 
| 357 384 | 
             
              tests that an attribute is valid or invalid if set to one or more values.
         | 
| 358 | 
            -
               | 
| 359 | 
            -
             | 
| 385 | 
            +
              _(Aliased as #allow_values.)_
         | 
| 386 | 
            +
            - **[have_secure_password](lib/shoulda/matchers/active_model/have_secure_password_matcher.rb)**
         | 
| 360 387 | 
             
              tests usage of `has_secure_password`.
         | 
| 361 | 
            -
             | 
| 388 | 
            +
            - **[validate_absence_of](lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb)**
         | 
| 362 389 | 
             
              tests usage of `validates_absence_of`.
         | 
| 363 | 
            -
             | 
| 390 | 
            +
            - **[validate_acceptance_of](lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb)**
         | 
| 364 391 | 
             
              tests usage of `validates_acceptance_of`.
         | 
| 365 | 
            -
             | 
| 392 | 
            +
            - **[validate_confirmation_of](lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb)**
         | 
| 366 393 | 
             
              tests usage of `validates_confirmation_of`.
         | 
| 367 | 
            -
             | 
| 394 | 
            +
            - **[validate_exclusion_of](lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb)**
         | 
| 368 395 | 
             
              tests usage of `validates_exclusion_of`.
         | 
| 369 | 
            -
             | 
| 396 | 
            +
            - **[validate_inclusion_of](lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb)**
         | 
| 370 397 | 
             
              tests usage of `validates_inclusion_of`.
         | 
| 371 | 
            -
             | 
| 398 | 
            +
            - **[validate_length_of](lib/shoulda/matchers/active_model/validate_length_of_matcher.rb)**
         | 
| 372 399 | 
             
              tests usage of `validates_length_of`.
         | 
| 373 | 
            -
             | 
| 400 | 
            +
            - **[validate_numericality_of](lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb)**
         | 
| 374 401 | 
             
              tests usage of `validates_numericality_of`.
         | 
| 375 | 
            -
             | 
| 402 | 
            +
            - **[validate_presence_of](lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb)**
         | 
| 376 403 | 
             
              tests usage of `validates_presence_of`.
         | 
| 377 | 
            -
             | 
| 404 | 
            +
            - **[validate_comparison_of](lib/shoulda/matchers/active_model/validate_comparison_of_matcher.rb)**
         | 
| 378 405 | 
             
              tests usage of `validates_comparison_of`.
         | 
| 379 406 |  | 
| 380 407 | 
             
            ### ActiveRecord matchers
         | 
| 381 408 |  | 
| 382 | 
            -
             | 
| 409 | 
            +
            - **[accept_nested_attributes_for](lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb)**
         | 
| 383 410 | 
             
              tests usage of the `accepts_nested_attributes_for` macro.
         | 
| 384 | 
            -
             | 
| 411 | 
            +
            - **[belong_to](lib/shoulda/matchers/active_record/association_matcher.rb)**
         | 
| 385 412 | 
             
              tests your `belongs_to` associations.
         | 
| 386 | 
            -
             | 
| 413 | 
            +
            - **[define_enum_for](lib/shoulda/matchers/active_record/define_enum_for_matcher.rb)**
         | 
| 387 414 | 
             
              tests usage of the `enum` macro.
         | 
| 388 | 
            -
             | 
| 415 | 
            +
            - **[have_and_belong_to_many](lib/shoulda/matchers/active_record/association_matcher.rb)**
         | 
| 389 416 | 
             
              tests your `has_and_belongs_to_many` associations.
         | 
| 390 | 
            -
             | 
| 417 | 
            +
            - **[have_delegated_type](lib/shoulda/matchers/active_record/association_matcher.rb#L687)**
         | 
| 391 418 | 
             
              tests usage of the `delegated_type` macro.
         | 
| 392 | 
            -
             | 
| 419 | 
            +
            - **[have_db_column](lib/shoulda/matchers/active_record/have_db_column_matcher.rb)**
         | 
| 393 420 | 
             
              tests that the table that backs your model has a specific column.
         | 
| 394 | 
            -
             | 
| 421 | 
            +
            - **[have_db_index](lib/shoulda/matchers/active_record/have_db_index_matcher.rb)**
         | 
| 395 422 | 
             
              tests that the table that backs your model has an index on a specific column.
         | 
| 396 | 
            -
             | 
| 423 | 
            +
            - **[have_implicit_order_column](lib/shoulda/matchers/active_record/have_implicit_order_column.rb)**
         | 
| 397 424 | 
             
              tests usage of `implicit_order_column`.
         | 
| 398 | 
            -
             | 
| 425 | 
            +
            - **[have_many](lib/shoulda/matchers/active_record/association_matcher.rb#L328)**
         | 
| 399 426 | 
             
              tests your `has_many` associations.
         | 
| 400 | 
            -
             | 
| 427 | 
            +
            - **[have_many_attached](lib/shoulda/matchers/active_record/have_attached_matcher.rb)**
         | 
| 401 428 | 
             
              tests your `has_many_attached` associations.
         | 
| 402 | 
            -
             | 
| 429 | 
            +
            - **[have_one](lib/shoulda/matchers/active_record/association_matcher.rb#L598)**
         | 
| 403 430 | 
             
              tests your `has_one` associations.
         | 
| 404 | 
            -
             | 
| 431 | 
            +
            - **[have_one_attached](lib/shoulda/matchers/active_record/have_attached_matcher.rb)**
         | 
| 405 432 | 
             
              tests your `has_one_attached` associations.
         | 
| 406 | 
            -
             | 
| 433 | 
            +
            - **[have_readonly_attribute](lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb)**
         | 
| 407 434 | 
             
              tests usage of the `attr_readonly` macro.
         | 
| 408 | 
            -
             | 
| 435 | 
            +
            - **[have_rich_text](lib/shoulda/matchers/active_record/have_rich_text_matcher.rb)**
         | 
| 409 436 | 
             
              tests your `has_rich_text` associations.
         | 
| 410 | 
            -
             | 
| 437 | 
            +
            - **[serialize](lib/shoulda/matchers/active_record/serialize_matcher.rb)** tests
         | 
| 411 438 | 
             
              usage of the `serialize` macro.
         | 
| 412 | 
            -
             | 
| 439 | 
            +
            - **[validate_uniqueness_of](lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb)**
         | 
| 413 440 | 
             
              tests usage of `validates_uniqueness_of`.
         | 
| 414 | 
            -
             | 
| 441 | 
            +
            - **[normalize](lib/shoulda/matchers/active_record/normalize_matcher.rb)** tests
         | 
| 415 442 | 
             
              usage of the `normalize` macro
         | 
| 416 | 
            -
             | 
| 443 | 
            +
            - **[encrypt](lib/shoulda/matchers/active_record/encrypt_matcher.rb)**
         | 
| 417 444 | 
             
              tests usage of the `encrypts` macro.
         | 
| 418 445 |  | 
| 419 446 | 
             
            ### ActionController matchers
         | 
| 420 447 |  | 
| 421 | 
            -
             | 
| 448 | 
            +
            - **[filter_param](lib/shoulda/matchers/action_controller/filter_param_matcher.rb)**
         | 
| 422 449 | 
             
              tests parameter filtering configuration.
         | 
| 423 | 
            -
             | 
| 424 | 
            -
              that an action  | 
| 425 | 
            -
             | 
| 450 | 
            +
            - **[permit](lib/shoulda/matchers/action_controller/permit_matcher.rb)** tests
         | 
| 451 | 
            +
              that an action restricts the `params` hash.
         | 
| 452 | 
            +
            - **[redirect_to](lib/shoulda/matchers/action_controller/redirect_to_matcher.rb)**
         | 
| 426 453 | 
             
              tests that an action redirects to a certain location.
         | 
| 427 | 
            -
             | 
| 454 | 
            +
            - **[render_template](lib/shoulda/matchers/action_controller/render_template_matcher.rb)**
         | 
| 428 455 | 
             
              tests that an action renders a template.
         | 
| 429 | 
            -
             | 
| 456 | 
            +
            - **[render_with_layout](lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb)**
         | 
| 430 457 | 
             
              tests that an action is rendered with a certain layout.
         | 
| 431 | 
            -
             | 
| 458 | 
            +
            - **[rescue_from](lib/shoulda/matchers/action_controller/rescue_from_matcher.rb)**
         | 
| 432 459 | 
             
              tests usage of the `rescue_from` macro.
         | 
| 433 | 
            -
             | 
| 460 | 
            +
            - **[respond_with](lib/shoulda/matchers/action_controller/respond_with_matcher.rb)**
         | 
| 434 461 | 
             
              tests that an action responds with a certain status code.
         | 
| 435 | 
            -
             | 
| 462 | 
            +
            - **[route](lib/shoulda/matchers/action_controller/route_matcher.rb)** tests
         | 
| 436 463 | 
             
              your routes.
         | 
| 437 | 
            -
             | 
| 464 | 
            +
            - **[set_session](lib/shoulda/matchers/action_controller/set_session_matcher.rb)**
         | 
| 438 465 | 
             
              makes assertions on the `session` hash.
         | 
| 439 | 
            -
             | 
| 466 | 
            +
            - **[set_flash](lib/shoulda/matchers/action_controller/set_flash_matcher.rb)**
         | 
| 440 467 | 
             
              makes assertions on the `flash` hash.
         | 
| 441 | 
            -
             | 
| 468 | 
            +
            - **[use_after_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L29)**
         | 
| 442 469 | 
             
              tests that an `after_action` callback is defined in your controller.
         | 
| 443 | 
            -
             | 
| 470 | 
            +
            - **[use_around_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L75)**
         | 
| 444 471 | 
             
              tests that an `around_action` callback is defined in your controller.
         | 
| 445 | 
            -
             | 
| 472 | 
            +
            - **[use_before_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L4)**
         | 
| 446 473 | 
             
              tests that a `before_action` callback is defined in your controller.
         | 
| 447 474 |  | 
| 448 475 | 
             
            ### Routing matchers
         | 
| 449 476 |  | 
| 450 | 
            -
             | 
| 477 | 
            +
            - **[route](lib/shoulda/matchers/action_controller/route_matcher.rb)** tests
         | 
| 451 478 | 
             
              your routes.
         | 
| 452 479 |  | 
| 453 480 | 
             
            ### Independent matchers
         | 
| 454 481 |  | 
| 455 | 
            -
             | 
| 482 | 
            +
            - **[delegate_method](lib/shoulda/matchers/independent/delegate_method_matcher.rb)**
         | 
| 456 483 | 
             
              tests that an object forwards messages to other, internal objects by way of
         | 
| 457 484 | 
             
              delegation.
         | 
| 458 485 |  | 
| @@ -461,7 +488,7 @@ about any of them, make sure to [consult the documentation][rubydocs]! | |
| 461 488 | 
             
            Over time our community has created extensions to Shoulda Matchers. If you've
         | 
| 462 489 | 
             
            created something that you want to share, please [let us know][new-issue]!
         | 
| 463 490 |  | 
| 464 | 
            -
             | 
| 491 | 
            +
            - **[shoulda-matchers-cucumber]** – Adds support for using Shoulda Matchers in
         | 
| 465 492 | 
             
              Cucumber tests.
         | 
| 466 493 |  | 
| 467 494 | 
             
            [new-issue]: https://github.com/thoughtbot/shoulda-matchers/issues/new
         | 
| @@ -512,7 +539,7 @@ Sales][matsales28]. Previous maintainers include [Elliot Winkler][mcmire], | |
| 512 539 | 
             
            ## Copyright/License
         | 
| 513 540 |  | 
| 514 541 | 
             
            Shoulda Matchers is copyright © Tammer Saleh and [thoughtbot,
         | 
| 515 | 
            -
            inc][thoughtbot-website]. It is free and  | 
| 542 | 
            +
            inc][thoughtbot-website]. It is free and open-source software and may be
         | 
| 516 543 | 
             
            redistributed under the terms specified in the [LICENSE](LICENSE) file.
         | 
| 517 544 |  | 
| 518 545 | 
             
            [thoughtbot-website]: https://thoughtbot.com
         | 
| @@ -94,14 +94,14 @@ module Shoulda | |
| 94 94 | 
             
                    end
         | 
| 95 95 |  | 
| 96 96 | 
             
                    def description
         | 
| 97 | 
            -
                       | 
| 98 | 
            -
             | 
| 99 | 
            -
             | 
| 100 | 
            -
             | 
| 101 | 
            -
             | 
| 102 | 
            -
             | 
| 103 | 
            -
             | 
| 104 | 
            -
                       | 
| 97 | 
            +
                      String.new('render with ').tap do |string|
         | 
| 98 | 
            +
                        string <<
         | 
| 99 | 
            +
                          if @expected_layout.nil?
         | 
| 100 | 
            +
                            'a layout'
         | 
| 101 | 
            +
                          else
         | 
| 102 | 
            +
                            "the #{@expected_layout.inspect} layout"
         | 
| 103 | 
            +
                          end
         | 
| 104 | 
            +
                      end
         | 
| 105 105 | 
             
                    end
         | 
| 106 106 |  | 
| 107 107 | 
             
                    private
         | 
| @@ -27,7 +27,7 @@ module Shoulda | |
| 27 27 |  | 
| 28 28 | 
             
                    def extract_params_from_string
         | 
| 29 29 | 
             
                      controller, action = args[0].split('#')
         | 
| 30 | 
            -
                      params = (args[1] || {}).merge(controller: controller, action: action)
         | 
| 30 | 
            +
                      params = (args[1] || {}).merge!(controller: controller, action: action)
         | 
| 31 31 | 
             
                      normalize_values(params)
         | 
| 32 32 | 
             
                    end
         | 
| 33 33 |  | 
| @@ -59,7 +59,7 @@ module Shoulda | |
| 59 59 | 
             
                          when String, Symbol
         | 
| 60 60 | 
             
                            { active: true, column: counter_cache.to_s }
         | 
| 61 61 | 
             
                          when Hash
         | 
| 62 | 
            -
                            { active: true, column: nil }.merge(counter_cache)
         | 
| 62 | 
            +
                            { active: true, column: nil }.merge!(counter_cache)
         | 
| 63 63 | 
             
                          else
         | 
| 64 64 | 
             
                            raise ArgumentError, 'Invalid counter_cache option'
         | 
| 65 65 | 
             
                          end
         | 
| @@ -258,6 +258,36 @@ module Shoulda | |
| 258 258 | 
             
                  #
         | 
| 259 259 | 
             
                  # @return [ValidateUniquenessOfMatcher]
         | 
| 260 260 | 
             
                  #
         | 
| 261 | 
            +
                  # ##### alternatives
         | 
| 262 | 
            +
                  #
         | 
| 263 | 
            +
                  # Use `alternatives` to specify alternative valid values to use
         | 
| 264 | 
            +
                  #   for testing uniqueness.
         | 
| 265 | 
            +
                  #
         | 
| 266 | 
            +
                  #     class Post < ActiveRecord::Base
         | 
| 267 | 
            +
                  #       validates :title, uniqueness: true
         | 
| 268 | 
            +
                  #     end
         | 
| 269 | 
            +
                  #
         | 
| 270 | 
            +
                  #     # RSpec
         | 
| 271 | 
            +
                  #     RSpec.describe Post, type: :model do
         | 
| 272 | 
            +
                  #       it do
         | 
| 273 | 
            +
                  #         should validate_uniqueness_of(:title).alternatives('Alternative Title')
         | 
| 274 | 
            +
                  #       end
         | 
| 275 | 
            +
                  #     end
         | 
| 276 | 
            +
                  #
         | 
| 277 | 
            +
                  #     # Minitest (Shoulda)
         | 
| 278 | 
            +
                  #     class PostTest < ActiveSupport::TestCase
         | 
| 279 | 
            +
                  #       should validate_uniqueness_of(:title).alternatives(['Alternative Title', 'Another Title'])
         | 
| 280 | 
            +
                  #     end
         | 
| 281 | 
            +
                  #
         | 
| 282 | 
            +
                  # @param values [String, Array<String>]
         | 
| 283 | 
            +
                  #   Alternative value(s) to use for testing uniqueness instead of using
         | 
| 284 | 
            +
                  #   the `succ` operator on the existing value.
         | 
| 285 | 
            +
                  #
         | 
| 286 | 
            +
                  # @return [ValidateUniquenessOfMatcher]
         | 
| 287 | 
            +
                  #
         | 
| 288 | 
            +
                  # @example
         | 
| 289 | 
            +
                  #   it { should validate_uniqueness_of(:title).alternatives('Alternative Title') }
         | 
| 290 | 
            +
                  #   it { should validate_uniqueness_of(:title).alternatives(['Title 1', 'Title 2']) }
         | 
| 261 291 | 
             
                  def validate_uniqueness_of(attr)
         | 
| 262 292 | 
             
                    ValidateUniquenessOfMatcher.new(attr)
         | 
| 263 293 | 
             
                  end
         | 
| @@ -286,6 +316,20 @@ module Shoulda | |
| 286 316 | 
             
                      self
         | 
| 287 317 | 
             
                    end
         | 
| 288 318 |  | 
| 319 | 
            +
                    # @param values [String, Array<String>]
         | 
| 320 | 
            +
                    #   Alternative value(s) to use for testing uniqueness instead of using
         | 
| 321 | 
            +
                    #   the `succ` operator on the existing value.
         | 
| 322 | 
            +
                    #
         | 
| 323 | 
            +
                    # @return [ValidateUniquenessOfMatcher]
         | 
| 324 | 
            +
                    #
         | 
| 325 | 
            +
                    # @example
         | 
| 326 | 
            +
                    #   it { should validate_uniqueness_of(:title).alternatives('Alternative Title') }
         | 
| 327 | 
            +
                    #   it { should validate_uniqueness_of(:title).alternatives(['Title 1', 'Title 2']) }
         | 
| 328 | 
            +
                    def alternatives(values)
         | 
| 329 | 
            +
                      @options[:alternatives] = values
         | 
| 330 | 
            +
                      self
         | 
| 331 | 
            +
                    end
         | 
| 332 | 
            +
             | 
| 289 333 | 
             
                    def case_insensitive
         | 
| 290 334 | 
             
                      @options[:case_sensitivity_strategy] = :insensitive
         | 
| 291 335 | 
             
                      self
         | 
| @@ -836,6 +880,9 @@ module Shoulda | |
| 836 880 | 
             
                        available_values.keys.last
         | 
| 837 881 | 
             
                      elsif polymorphic_type_attribute?(scope, previous_value)
         | 
| 838 882 | 
             
                        Uniqueness::TestModels.create(previous_value).to_s
         | 
| 883 | 
            +
                      elsif @options[:alternatives] && scope == @attribute
         | 
| 884 | 
            +
                        alternatives = Array.wrap(@options[:alternatives])
         | 
| 885 | 
            +
                        alternatives.first
         | 
| 839 886 | 
             
                      elsif previous_value.respond_to?(:next)
         | 
| 840 887 | 
             
                        previous_value.next
         | 
| 841 888 | 
             
                      elsif previous_value.respond_to?(:to_datetime)
         | 
| @@ -168,8 +168,27 @@ module Shoulda | |
| 168 168 | 
             
                  #       should delegate_method(:plan).to(:subscription).allow_nil
         | 
| 169 169 | 
             
                  #     end
         | 
| 170 170 | 
             
                  #
         | 
| 171 | 
            -
                  #  | 
| 171 | 
            +
                  # ##### with_private
         | 
| 172 | 
            +
                  #
         | 
| 173 | 
            +
                  # Use `with_private` if the delegation accounts for the fact that your
         | 
| 174 | 
            +
                  # delegation is private. (This is mostly intended as an analogue to
         | 
| 175 | 
            +
                  # the `private` option that Rails' `delegate` helper takes.)
         | 
| 176 | 
            +
                  #
         | 
| 177 | 
            +
                  #     class Account
         | 
| 178 | 
            +
                  #       delegate :plan, to: :subscription, private: true
         | 
| 179 | 
            +
                  #     end
         | 
| 180 | 
            +
                  #
         | 
| 181 | 
            +
                  #     # RSpec
         | 
| 182 | 
            +
                  #     describe Account do
         | 
| 183 | 
            +
                  #       it { should delegate_method(:plan).to(:subscription).with_private }
         | 
| 184 | 
            +
                  #     end
         | 
| 185 | 
            +
                  #
         | 
| 186 | 
            +
                  #     # Minitest
         | 
| 187 | 
            +
                  #     class PageTest < Minitest::Test
         | 
| 188 | 
            +
                  #       should delegate_method(:plan).to(:subscription).with_private
         | 
| 189 | 
            +
                  #     end
         | 
| 172 190 | 
             
                  #
         | 
| 191 | 
            +
                  # @return [DelegateMethodMatcher]
         | 
| 173 192 | 
             
                  def delegate_method(delegating_method)
         | 
| 174 193 | 
             
                    DelegateMethodMatcher.new(delegating_method).in_context(self)
         | 
| 175 194 | 
             
                  end
         | 
| @@ -187,6 +206,7 @@ module Shoulda | |
| 187 206 | 
             
                      @delegate_object_reader_method = nil
         | 
| 188 207 | 
             
                      @delegated_arguments = []
         | 
| 189 208 | 
             
                      @expects_to_allow_nil_delegate_object = false
         | 
| 209 | 
            +
                      @expects_private_delegation = false
         | 
| 190 210 | 
             
                    end
         | 
| 191 211 |  | 
| 192 212 | 
             
                    def in_context(context)
         | 
| @@ -202,7 +222,8 @@ module Shoulda | |
| 202 222 | 
             
                      subject_has_delegating_method? &&
         | 
| 203 223 | 
             
                        subject_has_delegate_object_reader_method? &&
         | 
| 204 224 | 
             
                        subject_delegates_to_delegate_object_correctly? &&
         | 
| 205 | 
            -
                        subject_handles_nil_delegate_object?
         | 
| 225 | 
            +
                        subject_handles_nil_delegate_object? &&
         | 
| 226 | 
            +
                        subject_handles_private_delegation?
         | 
| 206 227 | 
             
                    end
         | 
| 207 228 |  | 
| 208 229 | 
             
                    def description
         | 
| @@ -210,6 +231,10 @@ module Shoulda | |
| 210 231 | 
             
                        "delegate #{formatted_delegating_method_name} to the " +
         | 
| 211 232 | 
             
                        "#{formatted_delegate_object_reader_method_name} object"
         | 
| 212 233 |  | 
| 234 | 
            +
                      if expects_private_delegation?
         | 
| 235 | 
            +
                        string << ' privately'
         | 
| 236 | 
            +
                      end
         | 
| 237 | 
            +
             | 
| 213 238 | 
             
                      if delegated_arguments.any?
         | 
| 214 239 | 
             
                        string << " passing arguments #{delegated_arguments.inspect}"
         | 
| 215 240 | 
             
                      end
         | 
| @@ -254,6 +279,11 @@ module Shoulda | |
| 254 279 | 
             
                      self
         | 
| 255 280 | 
             
                    end
         | 
| 256 281 |  | 
| 282 | 
            +
                    def with_private
         | 
| 283 | 
            +
                      @expects_private_delegation = true
         | 
| 284 | 
            +
                      self
         | 
| 285 | 
            +
                    end
         | 
| 286 | 
            +
             | 
| 257 287 | 
             
                    def build_delegating_method_prefix(prefix)
         | 
| 258 288 | 
             
                      case prefix
         | 
| 259 289 | 
             
                      when true, nil then delegate_object_reader_method
         | 
| @@ -264,14 +294,19 @@ module Shoulda | |
| 264 294 | 
             
                    def failure_message
         | 
| 265 295 | 
             
                      message = "Expected #{class_under_test} to #{description}.\n\n"
         | 
| 266 296 |  | 
| 267 | 
            -
                      if failed_to_allow_nil_delegate_object?
         | 
| 297 | 
            +
                      if failed_to_allow_nil_delegate_object? || failed_to_handle_private_delegation?
         | 
| 268 298 | 
             
                        message << formatted_delegating_method_name(include_module: true)
         | 
| 269 299 | 
             
                        message << ' did delegate to '
         | 
| 270 300 | 
             
                        message << formatted_delegate_object_reader_method_name
         | 
| 301 | 
            +
                      end
         | 
| 302 | 
            +
             | 
| 303 | 
            +
                      if failed_to_allow_nil_delegate_object?
         | 
| 271 304 | 
             
                        message << ' when it was non-nil, but it failed to account '
         | 
| 272 305 | 
             
                        message << 'for when '
         | 
| 273 306 | 
             
                        message << formatted_delegate_object_reader_method_name
         | 
| 274 307 | 
             
                        message << ' *was* nil.'
         | 
| 308 | 
            +
                      elsif failed_to_handle_private_delegation?
         | 
| 309 | 
            +
                        message << ", but 'private: true' is missing."
         | 
| 275 310 | 
             
                      else
         | 
| 276 311 | 
             
                        message << 'Method calls sent to '
         | 
| 277 312 | 
             
                        message << formatted_delegate_object_reader_method_name(
         | 
| @@ -322,6 +357,10 @@ module Shoulda | |
| 322 357 | 
             
                      @expects_to_allow_nil_delegate_object
         | 
| 323 358 | 
             
                    end
         | 
| 324 359 |  | 
| 360 | 
            +
                    def expects_private_delegation?
         | 
| 361 | 
            +
                      @expects_private_delegation
         | 
| 362 | 
            +
                    end
         | 
| 363 | 
            +
             | 
| 325 364 | 
             
                    def formatted_delegate_method(options = {})
         | 
| 326 365 | 
             
                      formatted_method_name_for(delegate_method, options)
         | 
| 327 366 | 
             
                    end
         | 
| @@ -367,7 +406,11 @@ module Shoulda | |
| 367 406 | 
             
                    end
         | 
| 368 407 |  | 
| 369 408 | 
             
                    def subject_has_delegating_method?
         | 
| 370 | 
            -
                       | 
| 409 | 
            +
                      if expects_private_delegation?
         | 
| 410 | 
            +
                        !subject.respond_to?(delegating_method) && subject.respond_to?(delegating_method, true)
         | 
| 411 | 
            +
                      else
         | 
| 412 | 
            +
                        subject.respond_to?(delegating_method)
         | 
| 413 | 
            +
                      end
         | 
| 371 414 | 
             
                    end
         | 
| 372 415 |  | 
| 373 416 | 
             
                    def subject_has_delegate_object_reader_method?
         | 
| @@ -381,7 +424,11 @@ module Shoulda | |
| 381 424 | 
             
                    end
         | 
| 382 425 |  | 
| 383 426 | 
             
                    def subject_delegates_to_delegate_object_correctly?
         | 
| 384 | 
            -
                       | 
| 427 | 
            +
                      if expects_private_delegation?
         | 
| 428 | 
            +
                        privately_call_delegating_method_with_delegate_method_returning(delegate_object)
         | 
| 429 | 
            +
                      else
         | 
| 430 | 
            +
                        call_delegating_method_with_delegate_method_returning(delegate_object)
         | 
| 431 | 
            +
                      end
         | 
| 385 432 |  | 
| 386 433 | 
             
                      if delegated_arguments.any?
         | 
| 387 434 | 
             
                        delegate_object_received_call_with_delegated_arguments?
         | 
| @@ -411,11 +458,37 @@ module Shoulda | |
| 411 458 | 
             
                        end
         | 
| 412 459 | 
             
                    end
         | 
| 413 460 |  | 
| 461 | 
            +
                    def subject_handles_private_delegation?
         | 
| 462 | 
            +
                      @subject_handled_private_delegation =
         | 
| 463 | 
            +
                        if expects_private_delegation?
         | 
| 464 | 
            +
                          begin
         | 
| 465 | 
            +
                            call_delegating_method_with_delegate_method_returning(delegate_object)
         | 
| 466 | 
            +
                            true
         | 
| 467 | 
            +
                          rescue Module::DelegationError
         | 
| 468 | 
            +
                            false
         | 
| 469 | 
            +
                          rescue NoMethodError => e
         | 
| 470 | 
            +
                            if e.message =~
         | 
| 471 | 
            +
                               /private method `#{delegating_method}' called for/
         | 
| 472 | 
            +
                              true
         | 
| 473 | 
            +
                            else
         | 
| 474 | 
            +
                              raise e
         | 
| 475 | 
            +
                            end
         | 
| 476 | 
            +
                          end
         | 
| 477 | 
            +
                        else
         | 
| 478 | 
            +
                          true
         | 
| 479 | 
            +
                        end
         | 
| 480 | 
            +
                    end
         | 
| 481 | 
            +
             | 
| 414 482 | 
             
                    def failed_to_allow_nil_delegate_object?
         | 
| 415 483 | 
             
                      expects_to_allow_nil_delegate_object? &&
         | 
| 416 484 | 
             
                        !@subject_handled_nil_delegate_object
         | 
| 417 485 | 
             
                    end
         | 
| 418 486 |  | 
| 487 | 
            +
                    def failed_to_handle_private_delegation?
         | 
| 488 | 
            +
                      expects_private_delegation? &&
         | 
| 489 | 
            +
                        !@subject_handled_private_delegation
         | 
| 490 | 
            +
                    end
         | 
| 491 | 
            +
             | 
| 419 492 | 
             
                    def call_delegating_method_with_delegate_method_returning(value)
         | 
| 420 493 | 
             
                      register_subject_double_collection_to(value)
         | 
| 421 494 |  | 
| @@ -424,6 +497,14 @@ module Shoulda | |
| 424 497 | 
             
                      end
         | 
| 425 498 | 
             
                    end
         | 
| 426 499 |  | 
| 500 | 
            +
                    def privately_call_delegating_method_with_delegate_method_returning(value)
         | 
| 501 | 
            +
                      register_subject_double_collection_to(value)
         | 
| 502 | 
            +
             | 
| 503 | 
            +
                      Doublespeak.with_doubles_activated do
         | 
| 504 | 
            +
                        subject.__send__(delegating_method, *delegated_arguments)
         | 
| 505 | 
            +
                      end
         | 
| 506 | 
            +
                    end
         | 
| 507 | 
            +
             | 
| 427 508 | 
             
                    def register_subject_double_collection_to(returned_value)
         | 
| 428 509 | 
             
                      double_collection =
         | 
| 429 510 | 
             
                        Doublespeak.double_collection_for(subject.singleton_class)
         | 
| @@ -60,7 +60,7 @@ module Shoulda | |
| 60 60 | 
             
                      attribute_types_for(model).
         | 
| 61 61 | 
             
                        inject({}) do |hash, (attribute_name, attribute_type)|
         | 
| 62 62 | 
             
                          if type_serialized_defined && attribute_type.is_a?(::ActiveRecord::Type::Serialized)
         | 
| 63 | 
            -
                            hash.merge(attribute_name => attribute_type.coder)
         | 
| 63 | 
            +
                            hash.merge!(attribute_name => attribute_type.coder)
         | 
| 64 64 | 
             
                          else
         | 
| 65 65 | 
             
                            hash
         | 
| 66 66 | 
             
                          end
         | 
| @@ -121,7 +121,7 @@ module Shoulda | |
| 121 121 | 
             
                        model.columns.inject({}) do |hash, column|
         | 
| 122 122 | 
             
                          key = column.name.to_s
         | 
| 123 123 | 
             
                          value = model.type_for_attribute(column.name)
         | 
| 124 | 
            -
                          hash.merge(key => value)
         | 
| 124 | 
            +
                          hash.merge!(key => value)
         | 
| 125 125 | 
             
                        end
         | 
| 126 126 | 
             
                      else
         | 
| 127 127 | 
             
                        raise NotImplementedError
         | 
| @@ -169,7 +169,7 @@ module Shoulda | |
| 169 169 | 
             
                      ]
         | 
| 170 170 | 
             
                      primary_translation_key = default_translation_keys.shift
         | 
| 171 171 | 
             
                      translate_options =
         | 
| 172 | 
            -
                        { default: default_translation_keys }.merge(options)
         | 
| 172 | 
            +
                        { default: default_translation_keys }.merge!(options)
         | 
| 173 173 | 
             
                      I18n.translate(primary_translation_key, translate_options)
         | 
| 174 174 | 
             
                    end
         | 
| 175 175 |  | 
    
        metadata
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: shoulda-matchers
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 6. | 
| 4 | 
            +
              version: 6.5.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Tammer Saleh
         | 
| @@ -14,7 +14,7 @@ authors: | |
| 14 14 | 
             
            autorequire:
         | 
| 15 15 | 
             
            bindir: bin
         | 
| 16 16 | 
             
            cert_chain: []
         | 
| 17 | 
            -
            date:  | 
| 17 | 
            +
            date: 2025-04-25 00:00:00.000000000 Z
         | 
| 18 18 | 
             
            dependencies:
         | 
| 19 19 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 20 20 | 
             
              name: activesupport
         |