ultra-fast-box 0.0.1
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 +7 -0
- data/shoulda-matchers-8.0.1/LICENSE +22 -0
- data/shoulda-matchers-8.0.1/README.md +567 -0
- data/shoulda-matchers-8.0.1/docs/errors/NonCaseSwappableValueError.md +111 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/callback_matcher.rb +121 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/filter_param_matcher.rb +70 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/flash_store.rb +86 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/permit_matcher.rb +445 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/redirect_to_matcher.rb +96 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/render_template_matcher.rb +84 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb +145 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/rescue_from_matcher.rb +115 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/respond_with_matcher.rb +148 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/route_matcher.rb +207 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/route_params.rb +62 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/session_store.rb +34 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_flash_matcher.rb +228 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_session_matcher.rb +163 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller/set_session_or_flash_matcher.rb +107 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/action_controller.rb +24 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_changed_value_error.rb +45 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_does_not_exist_error.rb +23 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter.rb +232 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setter_and_validator.rb +62 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters.rb +40 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/attribute_setters_and_validators.rb +48 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/successful_check.rb +14 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher/successful_setting.rb +14 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/allow_value_matcher.rb +695 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/comparison_matcher.rb +157 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/disallow_value_matcher.rb +78 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/errors.rb +52 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/have_secure_password_matcher.rb +125 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/helpers.rb +37 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/even_number_matcher.rb +45 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/numeric_type_matcher.rb +67 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/odd_number_matcher.rb +45 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/only_integer_matcher.rb +44 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/range_matcher.rb +71 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers/submatchers.rb +53 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/numericality_matchers.rb +9 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/allow_blank.rb +26 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/allow_nil.rb +26 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/ignore_interference_by_writer.rb +101 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers/ignoring_interference_by_writer.rb +21 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/qualifiers.rb +14 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb +180 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb +128 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_comparison_of_matcher.rb +567 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb +185 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb +272 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb +664 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_length_of_matcher.rb +575 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb +711 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb +428 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_matcher/build_description.rb +62 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_matcher.rb +195 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validation_message_finder.rb +63 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model/validator.rb +127 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_model.rb +96 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb +217 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matcher.rb +2134 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/counter_cache_matcher.rb +74 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/dependent_matcher.rb +62 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/inverse_of_matcher.rb +41 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/join_table_matcher.rb +105 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/model_reflection.rb +101 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/model_reflector.rb +89 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/option_verifier.rb +142 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/optional_matcher.rb +71 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/order_matcher.rb +41 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/required_matcher.rb +76 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/source_matcher.rb +42 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers/through_matcher.rb +65 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/association_matchers.rb +9 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/define_enum_for_matcher.rb +784 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/encrypt_matcher.rb +174 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_attached_matcher.rb +343 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_db_column_matcher.rb +366 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_db_index_matcher.rb +287 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_implicit_order_column.rb +104 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb +95 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_rich_text_matcher.rb +83 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/have_secure_token_matcher.rb +132 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/normalize_matcher.rb +151 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/serialize_matcher.rb +203 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/model.rb +58 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/namespace.rb +39 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/test_model_creator.rb +49 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness/test_models.rb +55 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/uniqueness.rb +14 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb +1197 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/active_record.rb +37 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/configuration.rb +31 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double.rb +103 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double_collection.rb +60 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/double_implementation_registry.rb +31 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/method_call.rb +44 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/object_double.rb +43 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/proxy_implementation.rb +32 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/stub_implementation.rb +31 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak/world.rb +63 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/doublespeak.rb +38 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/error.rb +29 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent/delegate_method_matcher/target_not_defined_error.rb +15 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent/delegate_method_matcher.rb +540 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/independent.rb +11 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/configuration.rb +70 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/configuration_error.rb +9 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/inclusion.rb +20 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/action_controller.rb +33 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/active_model.rb +26 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/active_record.rb +26 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/missing_library.rb +19 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/rails.rb +31 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries/routing.rb +29 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/libraries.rb +16 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/rails.rb +12 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/registry.rb +28 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/active_support_test_case.rb +37 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/minitest_4.rb +36 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/minitest_5.rb +37 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/missing_test_framework.rb +40 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/rspec.rb +29 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks/test_unit.rb +36 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations/test_frameworks.rb +16 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/integrations.rb +43 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/matcher_collection.rb +99 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/matcher_context.rb +36 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/rails_shim.rb +190 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/routing.rb +10 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/util/word_wrap.rb +211 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/util.rb +110 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/version.rb +6 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers/warn.rb +28 -0
- data/shoulda-matchers-8.0.1/lib/shoulda/matchers.rb +25 -0
- data/shoulda-matchers-8.0.1/lib/shoulda-matchers.rb +1 -0
- data/shoulda-matchers-8.0.1/shoulda-matchers.gemspec +43 -0
- data/ultra-fast-box.gemspec +12 -0
- metadata +179 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 604bb37b7dd41bb629ddeb1aabff341485b82f4ebf54f9eb1a57bd70cddd976c
|
|
4
|
+
data.tar.gz: 1ac3b7109a4351f0650e1a8d025e12d1229c1e128b83f90f81dd25c41552295d
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: c9d76338642302f9d98fea8bf592dd8b3b4474fa388cdda4eccf9d42f048328298808e0b82ef9ebecaf76af3af7801054853af8cd5a74d17e110d8f6a8db6750
|
|
7
|
+
data.tar.gz: 02b489774255b27bb9d660c71008877657baefbb939a39075b058c1e28e5c3e7dcfa8cb7c11a73a8d671f5a04931bdd1a303f1406c10a5d3abf884c314d2a7f2
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
Copyright (c) Tammer Saleh and thoughtbot, inc.
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person
|
|
4
|
+
obtaining a copy of this software and associated documentation
|
|
5
|
+
files (the "Software"), to deal in the Software without
|
|
6
|
+
restriction, including without limitation the rights to use,
|
|
7
|
+
copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
8
|
+
copies of the Software, and to permit persons to whom the
|
|
9
|
+
Software is furnished to do so, subject to the following
|
|
10
|
+
conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be
|
|
13
|
+
included in all copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
16
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
17
|
+
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
18
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
19
|
+
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
20
|
+
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
21
|
+
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
# Shoulda Matchers [![Gem Version][version-badge]][rubygems] [![Build Status][github-actions-badge]][github-actions] [![Total Downloads][downloads-total]][rubygems] [![Downloads][downloads-badge]][rubygems]
|
|
2
|
+
|
|
3
|
+
[version-badge]: https://img.shields.io/gem/v/shoulda-matchers.svg
|
|
4
|
+
[rubygems]: https://rubygems.org/gems/shoulda-matchers
|
|
5
|
+
[github-actions-badge]: https://img.shields.io/github/actions/workflow/status/thoughtbot/shoulda-matchers/ci.yml?branch=main
|
|
6
|
+
[github-actions]: https://github.com/thoughtbot/shoulda-matchers/actions
|
|
7
|
+
[downloads-total]: https://img.shields.io/gem/dt/shoulda-matchers.svg
|
|
8
|
+
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-matchers.svg
|
|
9
|
+
[downloads-badge]: https://img.shields.io/gem/dtv/shoulda-matchers.svg
|
|
10
|
+
|
|
11
|
+
[![shoulda-matchers][logo]][website]
|
|
12
|
+
|
|
13
|
+
[logo]: https://matchers.shoulda.io/images/shoulda-matchers-logo.png
|
|
14
|
+
[website]: https://matchers.shoulda.io/
|
|
15
|
+
|
|
16
|
+
Shoulda Matchers provides RSpec and Minitest-compatible one-liners to test
|
|
17
|
+
common Rails functionality that, if written by hand, would be much longer, more
|
|
18
|
+
complex, and error-prone.
|
|
19
|
+
|
|
20
|
+
## Quick links
|
|
21
|
+
|
|
22
|
+
📖 **[Read the documentation for the latest version][rubydocs].**
|
|
23
|
+
📢 **[See what's changed in recent versions][changelog].**
|
|
24
|
+
|
|
25
|
+
[rubydocs]: https://matchers.shoulda.io/docs
|
|
26
|
+
[changelog]: CHANGELOG.md
|
|
27
|
+
|
|
28
|
+
## Table of contents
|
|
29
|
+
|
|
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)
|
|
57
|
+
|
|
58
|
+
## Getting started
|
|
59
|
+
|
|
60
|
+
### RSpec
|
|
61
|
+
|
|
62
|
+
Start by including `shoulda-matchers` in your Gemfile:
|
|
63
|
+
|
|
64
|
+
```ruby
|
|
65
|
+
group :test do
|
|
66
|
+
gem 'shoulda-matchers', '~> 8.0'
|
|
67
|
+
end
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Then run `bundle install`.
|
|
71
|
+
|
|
72
|
+
Now you need to configure the gem by telling it:
|
|
73
|
+
|
|
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
|
|
76
|
+
your example groups
|
|
77
|
+
|
|
78
|
+
#### Rails apps
|
|
79
|
+
|
|
80
|
+
If you're working on a Rails app, simply place this at the bottom of
|
|
81
|
+
`spec/rails_helper.rb` (or in a support file if you so choose):
|
|
82
|
+
|
|
83
|
+
```ruby
|
|
84
|
+
Shoulda::Matchers.configure do |config|
|
|
85
|
+
config.integrate do |with|
|
|
86
|
+
with.test_framework :rspec
|
|
87
|
+
with.library :rails
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
#### Non-Rails apps
|
|
93
|
+
|
|
94
|
+
If you're not working on a Rails app, but you still make use of ActiveRecord or
|
|
95
|
+
ActiveModel in your project, you can still use this gem too! In that case,
|
|
96
|
+
you'll want to place the following configuration at the bottom of
|
|
97
|
+
`spec/spec_helper.rb`:
|
|
98
|
+
|
|
99
|
+
```ruby
|
|
100
|
+
Shoulda::Matchers.configure do |config|
|
|
101
|
+
config.integrate do |with|
|
|
102
|
+
with.test_framework :rspec
|
|
103
|
+
|
|
104
|
+
# Keep as many of these lines as are necessary:
|
|
105
|
+
with.library :active_record
|
|
106
|
+
with.library :active_model
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### Minitest
|
|
112
|
+
|
|
113
|
+
If you're using our umbrella gem [Shoulda], then make sure that you're using the
|
|
114
|
+
latest version:
|
|
115
|
+
|
|
116
|
+
```ruby
|
|
117
|
+
group :test do
|
|
118
|
+
gem 'shoulda', '~> 4.0'
|
|
119
|
+
end
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
[Shoulda]: https://github.com/thoughtbot/shoulda
|
|
123
|
+
|
|
124
|
+
Otherwise, add `shoulda-matchers` to your Gemfile:
|
|
125
|
+
|
|
126
|
+
```ruby
|
|
127
|
+
group :test do
|
|
128
|
+
gem 'shoulda-matchers', '~> 8.0'
|
|
129
|
+
end
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Then run `bundle install`.
|
|
133
|
+
|
|
134
|
+
Now you need to configure the gem by telling it:
|
|
135
|
+
|
|
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
|
|
138
|
+
your test case classes
|
|
139
|
+
|
|
140
|
+
#### Rails apps
|
|
141
|
+
|
|
142
|
+
If you're working on a Rails app, simply place this at the bottom of
|
|
143
|
+
`test/test_helper.rb`:
|
|
144
|
+
|
|
145
|
+
```ruby
|
|
146
|
+
Shoulda::Matchers.configure do |config|
|
|
147
|
+
config.integrate do |with|
|
|
148
|
+
with.test_framework :minitest
|
|
149
|
+
with.library :rails
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
```
|
|
153
|
+
|
|
154
|
+
#### Non-Rails apps
|
|
155
|
+
|
|
156
|
+
If you're not working on a Rails app, but you still make use of ActiveRecord or
|
|
157
|
+
ActiveModel in your project, you can still use this gem too! In that case,
|
|
158
|
+
you'll want to place the following configuration at the bottom of
|
|
159
|
+
`test/test_helper.rb`:
|
|
160
|
+
|
|
161
|
+
```ruby
|
|
162
|
+
Shoulda::Matchers.configure do |config|
|
|
163
|
+
config.integrate do |with|
|
|
164
|
+
with.test_framework :minitest
|
|
165
|
+
|
|
166
|
+
# Keep as many of these lines as are necessary:
|
|
167
|
+
with.library :active_record
|
|
168
|
+
with.library :active_model
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
## Usage
|
|
174
|
+
|
|
175
|
+
Most of the matchers provided by this gem are useful in a Rails context, and as
|
|
176
|
+
such, can be used for different parts of a Rails app:
|
|
177
|
+
|
|
178
|
+
- [database models backed by ActiveRecord](#activerecord-matchers)
|
|
179
|
+
- [non-database models, form objects, etc. backed by
|
|
180
|
+
ActiveModel](#activemodel-matchers)
|
|
181
|
+
- [controllers](#actioncontroller-matchers)
|
|
182
|
+
- [routes](#routing-matchers) (RSpec only)
|
|
183
|
+
- [Rails-specific features like `delegate`](#independent-matchers)
|
|
184
|
+
|
|
185
|
+
As the name of the gem indicates, most matchers are designed to be used in
|
|
186
|
+
"one-liner" form using the `should` macro, a special directive available in both
|
|
187
|
+
RSpec and [Shoulda]. For instance, a model test case may look something like:
|
|
188
|
+
|
|
189
|
+
```ruby
|
|
190
|
+
# RSpec
|
|
191
|
+
RSpec.describe MenuItem, type: :model do
|
|
192
|
+
describe 'associations' do
|
|
193
|
+
it { should belong_to(:category).class_name('MenuCategory') }
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
describe 'validations' do
|
|
197
|
+
it { should validate_presence_of(:name) }
|
|
198
|
+
it { should validate_uniqueness_of(:name).scoped_to(:category_id) }
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Minitest (Shoulda)
|
|
203
|
+
class MenuItemTest < ActiveSupport::TestCase
|
|
204
|
+
context 'associations' do
|
|
205
|
+
should belong_to(:category).class_name('MenuCategory')
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
context 'validations' do
|
|
209
|
+
should validate_presence_of(:name)
|
|
210
|
+
should validate_uniqueness_of(:name).scoped_to(:category_id)
|
|
211
|
+
end
|
|
212
|
+
end
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
[See below](#matchers) for the full set of matchers that you can use.
|
|
216
|
+
|
|
217
|
+
### On the subject of `subject`
|
|
218
|
+
|
|
219
|
+
For both RSpec and Shoulda, the **subject** is an implicit reference to the
|
|
220
|
+
object under test, and through the use of `should` as demonstrated above, all of
|
|
221
|
+
the matchers make use of `subject` internally when they are run. A `subject` is
|
|
222
|
+
always set automatically by your test framework in any given test case; however,
|
|
223
|
+
in certain cases it can be advantageous to override it. For instance, when
|
|
224
|
+
testing validations in a model, it is customary to provide a valid model instead
|
|
225
|
+
of a fresh one:
|
|
226
|
+
|
|
227
|
+
```ruby
|
|
228
|
+
# RSpec
|
|
229
|
+
RSpec.describe Post, type: :model do
|
|
230
|
+
describe 'validations' do
|
|
231
|
+
# Here we're using FactoryBot, but you could use anything
|
|
232
|
+
subject { build(:post) }
|
|
233
|
+
|
|
234
|
+
it { should validate_presence_of(:title) }
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
# Minitest (Shoulda)
|
|
239
|
+
class PostTest < ActiveSupport::TestCase
|
|
240
|
+
context 'validations' do
|
|
241
|
+
subject { build(:post) }
|
|
242
|
+
|
|
243
|
+
should validate_presence_of(:title)
|
|
244
|
+
end
|
|
245
|
+
end
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
When overriding the subject in this manner, then, it's important to provide the
|
|
249
|
+
correct object. **When in doubt, provide an instance of the class under test.**
|
|
250
|
+
This is particularly necessary for controller tests, where it is easy to
|
|
251
|
+
accidentally write something like:
|
|
252
|
+
|
|
253
|
+
```ruby
|
|
254
|
+
RSpec.describe PostsController, type: :controller do
|
|
255
|
+
describe 'GET #index' do
|
|
256
|
+
subject { get :index }
|
|
257
|
+
|
|
258
|
+
# This may work...
|
|
259
|
+
it { should have_http_status(:success) }
|
|
260
|
+
# ...but this will not!
|
|
261
|
+
it { should permit(:title, :body).for(:post) }
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
In this case, you would want to use `before` rather than `subject`:
|
|
267
|
+
|
|
268
|
+
```ruby
|
|
269
|
+
RSpec.describe PostsController, type: :controller do
|
|
270
|
+
describe 'GET #index' do
|
|
271
|
+
before { get :index }
|
|
272
|
+
|
|
273
|
+
# Notice that we have to assert have_http_status on the response here...
|
|
274
|
+
it { expect(response).to have_http_status(:success) }
|
|
275
|
+
# ...but we do not have to provide a subject for render_template
|
|
276
|
+
it { should render_template('index') }
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### Availability of RSpec matchers in example groups
|
|
282
|
+
|
|
283
|
+
#### Rails projects
|
|
284
|
+
|
|
285
|
+
If you're using RSpec, then you're probably familiar with the concept of example
|
|
286
|
+
groups. Example groups can be assigned tags to assign different behaviors
|
|
287
|
+
to different kinds of example groups. This comes into play especially when using
|
|
288
|
+
`rspec-rails`, where, for instance, controller example groups, tagged with
|
|
289
|
+
`type: :controller`, are written differently than request example groups, tagged
|
|
290
|
+
with `type: :request`. This difference in writing style arises because
|
|
291
|
+
`rspec-rails` mixes different behaviors and methods into controller example
|
|
292
|
+
groups vs. request example groups.
|
|
293
|
+
|
|
294
|
+
Relying on this behavior, Shoulda Matchers automatically makes certain matchers
|
|
295
|
+
available in certain kinds of example groups:
|
|
296
|
+
|
|
297
|
+
- ActiveRecord and ActiveModel matchers are available only in model example
|
|
298
|
+
groups, i.e., those tagged with `type: :model` or in files located under
|
|
299
|
+
`spec/models`.
|
|
300
|
+
- ActionController matchers are available only in controller example groups,
|
|
301
|
+
i.e., those tagged with `type: :controller` or in files located under
|
|
302
|
+
`spec/controllers`.
|
|
303
|
+
- The `route` matcher is available in routing example groups, i.e., those
|
|
304
|
+
tagged with `type: :routing` or in files located under `spec/routing`.
|
|
305
|
+
- Independent matchers are available in all example groups.
|
|
306
|
+
|
|
307
|
+
As long as you're using Rails, you don't need to worry about these details —
|
|
308
|
+
everything should "just work".
|
|
309
|
+
|
|
310
|
+
#### Non-Rails projects
|
|
311
|
+
|
|
312
|
+
**What if you are using ActiveModel or ActiveRecord outside of Rails, however,
|
|
313
|
+
and you want to use model matchers in a certain example group?** Then you'll
|
|
314
|
+
need to manually include the module that holds those matchers into that example
|
|
315
|
+
group. For instance, you might have to say:
|
|
316
|
+
|
|
317
|
+
```ruby
|
|
318
|
+
RSpec.describe MySpecialModel do
|
|
319
|
+
include Shoulda::Matchers::ActiveModel
|
|
320
|
+
include Shoulda::Matchers::ActiveRecord
|
|
321
|
+
end
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
If you have a lot of similar example groups in which you need to do this, then
|
|
325
|
+
you might find it more helpful to tag your example groups appropriately, then
|
|
326
|
+
instruct RSpec to mix these modules into any example groups that have that tag.
|
|
327
|
+
For instance, you could add this to your `rails_helper.rb`:
|
|
328
|
+
|
|
329
|
+
```ruby
|
|
330
|
+
RSpec.configure do |config|
|
|
331
|
+
config.include(Shoulda::Matchers::ActiveModel, type: :model)
|
|
332
|
+
config.include(Shoulda::Matchers::ActiveRecord, type: :model)
|
|
333
|
+
end
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
And from then on, you could say:
|
|
337
|
+
|
|
338
|
+
```ruby
|
|
339
|
+
RSpec.describe MySpecialModel, type: :model do
|
|
340
|
+
# ...
|
|
341
|
+
end
|
|
342
|
+
```
|
|
343
|
+
|
|
344
|
+
<a name="should-vs-is_expectedto"></a>
|
|
345
|
+
### `should` vs `is_expected.to`
|
|
346
|
+
|
|
347
|
+
In this README and throughout the documentation, you'll notice that we use the
|
|
348
|
+
`should` form of RSpec's one-liner syntax over `is_expected.to`. Besides being
|
|
349
|
+
the namesake of the gem itself, this is our preferred syntax as it's short and
|
|
350
|
+
sweet. But if you prefer to use `is_expected.to`, you can do that too:
|
|
351
|
+
|
|
352
|
+
```ruby
|
|
353
|
+
RSpec.describe Person, type: :model do
|
|
354
|
+
it { is_expected.to validate_presence_of(:name) }
|
|
355
|
+
end
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
### A Note on Testing Style
|
|
359
|
+
|
|
360
|
+
If you inspect the source code, you'll notice quickly that `shoulda-matchers`
|
|
361
|
+
is largely implemented using reflections and other introspection methods that
|
|
362
|
+
Rails provides. At first sight, this might seem to go against the common
|
|
363
|
+
practice of testing behavior rather than implementation. However, as the
|
|
364
|
+
available matchers indicate, we recommend that you treat `shoulda-matchers` as
|
|
365
|
+
a tool to help you ensure correct configuration and adherence to best practices
|
|
366
|
+
and idiomatic Rails in your models and controllers - especially for aspects
|
|
367
|
+
that in your experience are often insufficiently tested, such as ActiveRecord
|
|
368
|
+
validations or controller callbacks (a.k.a. the "framework-y" parts).
|
|
369
|
+
|
|
370
|
+
For testing your application's unique business logic, however, we recommend focusing on
|
|
371
|
+
behavior and outcomes over implementation details. This approach will better support
|
|
372
|
+
refactoring and ensure that your tests remain resilient to changes in how your code
|
|
373
|
+
is structured. While no generalized testing tool can fully capture the nuances of your
|
|
374
|
+
specific domain, you can draw inspiration from shoulda-matchers to write custom
|
|
375
|
+
matchers that align more closely with your application's needs.
|
|
376
|
+
|
|
377
|
+
## Matchers
|
|
378
|
+
|
|
379
|
+
Here is the full list of matchers that ship with this gem. If you need details
|
|
380
|
+
about any of them, make sure to [consult the documentation][rubydocs]!
|
|
381
|
+
|
|
382
|
+
### ActiveModel matchers
|
|
383
|
+
|
|
384
|
+
- **[allow_value](lib/shoulda/matchers/active_model/allow_value_matcher.rb)**
|
|
385
|
+
tests that an attribute is valid or invalid if set to one or more values.
|
|
386
|
+
_(Aliased as #allow_values.)_
|
|
387
|
+
- **[have_secure_password](lib/shoulda/matchers/active_model/have_secure_password_matcher.rb)**
|
|
388
|
+
tests usage of `has_secure_password`.
|
|
389
|
+
- **[validate_absence_of](lib/shoulda/matchers/active_model/validate_absence_of_matcher.rb)**
|
|
390
|
+
tests usage of `validates_absence_of`.
|
|
391
|
+
- **[validate_acceptance_of](lib/shoulda/matchers/active_model/validate_acceptance_of_matcher.rb)**
|
|
392
|
+
tests usage of `validates_acceptance_of`.
|
|
393
|
+
- **[validate_confirmation_of](lib/shoulda/matchers/active_model/validate_confirmation_of_matcher.rb)**
|
|
394
|
+
tests usage of `validates_confirmation_of`.
|
|
395
|
+
- **[validate_exclusion_of](lib/shoulda/matchers/active_model/validate_exclusion_of_matcher.rb)**
|
|
396
|
+
tests usage of `validates_exclusion_of`.
|
|
397
|
+
- **[validate_inclusion_of](lib/shoulda/matchers/active_model/validate_inclusion_of_matcher.rb)**
|
|
398
|
+
tests usage of `validates_inclusion_of`.
|
|
399
|
+
- **[validate_length_of](lib/shoulda/matchers/active_model/validate_length_of_matcher.rb)**
|
|
400
|
+
tests usage of `validates_length_of`.
|
|
401
|
+
- **[validate_numericality_of](lib/shoulda/matchers/active_model/validate_numericality_of_matcher.rb)**
|
|
402
|
+
tests usage of `validates_numericality_of`.
|
|
403
|
+
- **[validate_presence_of](lib/shoulda/matchers/active_model/validate_presence_of_matcher.rb)**
|
|
404
|
+
tests usage of `validates_presence_of`.
|
|
405
|
+
- **[validate_comparison_of](lib/shoulda/matchers/active_model/validate_comparison_of_matcher.rb)**
|
|
406
|
+
tests usage of `validates_comparison_of`.
|
|
407
|
+
|
|
408
|
+
### ActiveRecord matchers
|
|
409
|
+
|
|
410
|
+
- **[accept_nested_attributes_for](lib/shoulda/matchers/active_record/accept_nested_attributes_for_matcher.rb)**
|
|
411
|
+
tests usage of the `accepts_nested_attributes_for` macro.
|
|
412
|
+
- **[belong_to](lib/shoulda/matchers/active_record/association_matcher.rb)**
|
|
413
|
+
tests your `belongs_to` associations.
|
|
414
|
+
- **[define_enum_for](lib/shoulda/matchers/active_record/define_enum_for_matcher.rb)**
|
|
415
|
+
tests usage of the `enum` macro.
|
|
416
|
+
- **[have_and_belong_to_many](lib/shoulda/matchers/active_record/association_matcher.rb)**
|
|
417
|
+
tests your `has_and_belongs_to_many` associations.
|
|
418
|
+
- **[have_delegated_type](lib/shoulda/matchers/active_record/association_matcher.rb#L687)**
|
|
419
|
+
tests usage of the `delegated_type` macro.
|
|
420
|
+
- **[have_db_column](lib/shoulda/matchers/active_record/have_db_column_matcher.rb)**
|
|
421
|
+
tests that the table that backs your model has a specific column.
|
|
422
|
+
- **[have_db_index](lib/shoulda/matchers/active_record/have_db_index_matcher.rb)**
|
|
423
|
+
tests that the table that backs your model has an index on a specific column.
|
|
424
|
+
- **[have_implicit_order_column](lib/shoulda/matchers/active_record/have_implicit_order_column.rb)**
|
|
425
|
+
tests usage of `implicit_order_column`.
|
|
426
|
+
- **[have_many](lib/shoulda/matchers/active_record/association_matcher.rb#L328)**
|
|
427
|
+
tests your `has_many` associations.
|
|
428
|
+
- **[have_many_attached](lib/shoulda/matchers/active_record/have_attached_matcher.rb)**
|
|
429
|
+
tests your `has_many_attached` associations.
|
|
430
|
+
- **[have_one](lib/shoulda/matchers/active_record/association_matcher.rb#L598)**
|
|
431
|
+
tests your `has_one` associations.
|
|
432
|
+
- **[have_one_attached](lib/shoulda/matchers/active_record/have_attached_matcher.rb)**
|
|
433
|
+
tests your `has_one_attached` associations.
|
|
434
|
+
- **[have_readonly_attribute](lib/shoulda/matchers/active_record/have_readonly_attribute_matcher.rb)**
|
|
435
|
+
tests usage of the `attr_readonly` macro.
|
|
436
|
+
- **[have_rich_text](lib/shoulda/matchers/active_record/have_rich_text_matcher.rb)**
|
|
437
|
+
tests your `has_rich_text` associations.
|
|
438
|
+
- **[serialize](lib/shoulda/matchers/active_record/serialize_matcher.rb)** tests
|
|
439
|
+
usage of the `serialize` macro.
|
|
440
|
+
- **[validate_uniqueness_of](lib/shoulda/matchers/active_record/validate_uniqueness_of_matcher.rb)**
|
|
441
|
+
tests usage of `validates_uniqueness_of`.
|
|
442
|
+
- **[normalize](lib/shoulda/matchers/active_record/normalize_matcher.rb)** tests
|
|
443
|
+
usage of the `normalize` macro
|
|
444
|
+
- **[encrypt](lib/shoulda/matchers/active_record/encrypt_matcher.rb)**
|
|
445
|
+
tests usage of the `encrypts` macro.
|
|
446
|
+
|
|
447
|
+
### ActionController matchers
|
|
448
|
+
|
|
449
|
+
- **[filter_param](lib/shoulda/matchers/action_controller/filter_param_matcher.rb)**
|
|
450
|
+
tests parameter filtering configuration.
|
|
451
|
+
- **[permit](lib/shoulda/matchers/action_controller/permit_matcher.rb)** tests
|
|
452
|
+
that an action restricts the `params` hash.
|
|
453
|
+
- **[redirect_to](lib/shoulda/matchers/action_controller/redirect_to_matcher.rb)**
|
|
454
|
+
tests that an action redirects to a certain location.
|
|
455
|
+
- **[render_template](lib/shoulda/matchers/action_controller/render_template_matcher.rb)**
|
|
456
|
+
tests that an action renders a template.
|
|
457
|
+
- **[render_with_layout](lib/shoulda/matchers/action_controller/render_with_layout_matcher.rb)**
|
|
458
|
+
tests that an action is rendered with a certain layout.
|
|
459
|
+
- **[rescue_from](lib/shoulda/matchers/action_controller/rescue_from_matcher.rb)**
|
|
460
|
+
tests usage of the `rescue_from` macro.
|
|
461
|
+
- **[respond_with](lib/shoulda/matchers/action_controller/respond_with_matcher.rb)**
|
|
462
|
+
tests that an action responds with a certain status code.
|
|
463
|
+
- **[route](lib/shoulda/matchers/action_controller/route_matcher.rb)** tests
|
|
464
|
+
your routes.
|
|
465
|
+
- **[set_session](lib/shoulda/matchers/action_controller/set_session_matcher.rb)**
|
|
466
|
+
makes assertions on the `session` hash.
|
|
467
|
+
- **[set_flash](lib/shoulda/matchers/action_controller/set_flash_matcher.rb)**
|
|
468
|
+
makes assertions on the `flash` hash.
|
|
469
|
+
- **[use_after_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L29)**
|
|
470
|
+
tests that an `after_action` callback is defined in your controller.
|
|
471
|
+
- **[use_around_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L75)**
|
|
472
|
+
tests that an `around_action` callback is defined in your controller.
|
|
473
|
+
- **[use_before_action](lib/shoulda/matchers/action_controller/callback_matcher.rb#L4)**
|
|
474
|
+
tests that a `before_action` callback is defined in your controller.
|
|
475
|
+
|
|
476
|
+
### Routing matchers
|
|
477
|
+
|
|
478
|
+
- **[route](lib/shoulda/matchers/action_controller/route_matcher.rb)** tests
|
|
479
|
+
your routes.
|
|
480
|
+
|
|
481
|
+
### Independent matchers
|
|
482
|
+
|
|
483
|
+
- **[delegate_method](lib/shoulda/matchers/independent/delegate_method_matcher.rb)**
|
|
484
|
+
tests that an object forwards messages to other, internal objects by way of
|
|
485
|
+
delegation.
|
|
486
|
+
|
|
487
|
+
## Extensions
|
|
488
|
+
|
|
489
|
+
Over time our community has created extensions to Shoulda Matchers. If you've
|
|
490
|
+
created something that you want to share, please [let us know][new-issue]!
|
|
491
|
+
|
|
492
|
+
- **[shoulda-matchers-cucumber]** – Adds support for using Shoulda Matchers in
|
|
493
|
+
Cucumber tests.
|
|
494
|
+
|
|
495
|
+
[new-issue]: https://github.com/thoughtbot/shoulda-matchers/issues/new
|
|
496
|
+
[shoulda-matchers-cucumber]: https://github.com/majioa/shoulda-matchers-cucumber
|
|
497
|
+
|
|
498
|
+
## Contributing
|
|
499
|
+
|
|
500
|
+
Have a fix for a problem you've been running into or an idea for a new feature
|
|
501
|
+
you think would be useful? Take a look at the [Contributing
|
|
502
|
+
document](CONTRIBUTING.md) for instructions on setting up the repo on your
|
|
503
|
+
machine, understanding the codebase, and creating a good pull request.
|
|
504
|
+
|
|
505
|
+
## Compatibility
|
|
506
|
+
|
|
507
|
+
Shoulda Matchers is tested and supported against Ruby 3.3+, Rails
|
|
508
|
+
7.2+, RSpec 3.x, and Minitest 5.x.
|
|
509
|
+
|
|
510
|
+
- For Ruby < 2.4 and Rails < 4.1 compatibility, please use [v3.1.3][v3.1.3].
|
|
511
|
+
- For Ruby < 3.0 and Rails < 6.1 compatibility, please use [v4.5.1][v4.5.1].
|
|
512
|
+
- For Rails < 7.1 compatibility, please use [v6.5.0][v6.5.0].
|
|
513
|
+
- For Ruby < 3.3 and Rails < 7.2 compatibility, please use [v7.0.1][v7.0.1].
|
|
514
|
+
|
|
515
|
+
[v3.1.3]: https://github.com/thoughtbot/shoulda-matchers/tree/v3.1.3
|
|
516
|
+
[v4.5.1]: https://github.com/thoughtbot/shoulda-matchers/tree/v4.5.1
|
|
517
|
+
[v6.5.0]: https://github.com/thoughtbot/shoulda-matchers/tree/v6.5.0
|
|
518
|
+
[v7.0.1]: https://github.com/thoughtbot/shoulda-matchers/tree/v7.0.1
|
|
519
|
+
|
|
520
|
+
## Versioning
|
|
521
|
+
|
|
522
|
+
Shoulda Matchers follows Semantic Versioning 2.0 as defined at
|
|
523
|
+
<https://semver.org>.
|
|
524
|
+
|
|
525
|
+
## Team
|
|
526
|
+
|
|
527
|
+
Shoulda Matchers is currently maintained by [Pedro Paiva][VSPPedro] and [Matheus
|
|
528
|
+
Sales][matsales28]. Previous maintainers include [Elliot Winkler][mcmire],
|
|
529
|
+
[Gui Albuk][guialbuk], [Jason Draper][drapergeek], [Melissa Xie][mxie],
|
|
530
|
+
[Gabe Berke-Williams][gabebw], [Ryan McGeary][rmm5t], [Joe Ferris][jferris], and
|
|
531
|
+
[Tammer Saleh][tammersaleh].
|
|
532
|
+
|
|
533
|
+
[VSPPedro]: https://github.com/VSPPedro
|
|
534
|
+
[matsales28]: https://github.com/matsales28
|
|
535
|
+
[mcmire]: https://github.com/mcmire
|
|
536
|
+
[guialbuk]: https://github.com/guialbuk
|
|
537
|
+
[drapergeek]: https://github.com/drapergeek
|
|
538
|
+
[mxie]: https://github.com/mxie
|
|
539
|
+
[gabebw]: https://github.com/gabebw
|
|
540
|
+
[rmm5t]: https://github.com/rmm5t
|
|
541
|
+
[jferris]: https://github.com/jferris
|
|
542
|
+
[tammersaleh]: https://github.com/tammersaleh
|
|
543
|
+
|
|
544
|
+
## Copyright/License
|
|
545
|
+
|
|
546
|
+
Shoulda Matchers is copyright © Tammer Saleh and [thoughtbot,
|
|
547
|
+
inc][thoughtbot-website]. It is free and open-source software and may be
|
|
548
|
+
redistributed under the terms specified in the [LICENSE](LICENSE) file.
|
|
549
|
+
|
|
550
|
+
[thoughtbot-website]: https://thoughtbot.com
|
|
551
|
+
|
|
552
|
+
<!-- START /templates/footer.md -->
|
|
553
|
+
## About thoughtbot
|
|
554
|
+
|
|
555
|
+

|
|
556
|
+
|
|
557
|
+
This repo is maintained and funded by thoughtbot, inc.
|
|
558
|
+
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
|
559
|
+
|
|
560
|
+
We love open source software!
|
|
561
|
+
See [our other projects][community].
|
|
562
|
+
We are [available for hire][hire].
|
|
563
|
+
|
|
564
|
+
[community]: https://thoughtbot.com/community?utm_source=github
|
|
565
|
+
[hire]: https://thoughtbot.com/hire-us?utm_source=github
|
|
566
|
+
|
|
567
|
+
<!-- END /templates/footer.md -->
|