shoulda 3.4.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -7
  3. data/.hound.yml +3 -0
  4. data/.rubocop.yml +192 -0
  5. data/.ruby-version +1 -0
  6. data/.travis.yml +33 -2
  7. data/Appraisals +109 -8
  8. data/CHANGELOG.md +10 -0
  9. data/CONTRIBUTING.md +6 -1
  10. data/Gemfile +13 -0
  11. data/README.md +67 -74
  12. data/Rakefile +24 -10
  13. data/gemfiles/rails_4_2.gemfile +34 -0
  14. data/gemfiles/rails_4_2.gemfile.lock +240 -0
  15. data/gemfiles/rails_5_0.gemfile +32 -0
  16. data/gemfiles/rails_5_0.gemfile.lock +232 -0
  17. data/gemfiles/rails_5_1.gemfile +33 -0
  18. data/gemfiles/rails_5_1.gemfile.lock +247 -0
  19. data/gemfiles/rails_5_2.gemfile +35 -0
  20. data/gemfiles/rails_5_2.gemfile.lock +266 -0
  21. data/gemfiles/rails_6_0.gemfile +37 -0
  22. data/gemfiles/rails_6_0.gemfile.lock +291 -0
  23. data/lib/shoulda/version.rb +1 -1
  24. data/script/install_gems_in_all_appraisals +16 -0
  25. data/script/run_all_tests +16 -0
  26. data/script/supported_ruby_versions +7 -0
  27. data/script/update_gem_in_all_appraisals +17 -0
  28. data/script/update_gems_in_all_appraisals +16 -0
  29. data/shoulda.gemspec +23 -23
  30. data/test/acceptance/integrates_with_rails_test.rb +580 -0
  31. data/test/acceptance_test_helper.rb +43 -0
  32. data/test/support/acceptance/add_shoulda_to_project.rb +73 -0
  33. data/test/support/acceptance/helpers/array_helpers.rb +13 -0
  34. data/test/support/acceptance/helpers/pluralization_helpers.rb +13 -0
  35. data/test/support/acceptance/matchers/have_output.rb +33 -0
  36. data/test/support/acceptance/matchers/indicate_that_tests_were_run.rb +109 -0
  37. data/test/support/acceptance/rails_application_with_shoulda.rb +47 -0
  38. data/test/support/current_bundle.rb +61 -0
  39. data/test/support/snowglobe.rb +5 -0
  40. data/test/test_helper.rb +23 -0
  41. metadata +61 -153
  42. data/features/rails_integration.feature +0 -87
  43. data/features/step_definitions/rails_steps.rb +0 -77
  44. data/features/support/env.rb +0 -14
  45. data/gemfiles/3.0.gemfile +0 -7
  46. data/gemfiles/3.0.gemfile.lock +0 -127
  47. data/gemfiles/3.1.gemfile +0 -9
  48. data/gemfiles/3.1.gemfile.lock +0 -149
  49. data/gemfiles/3.2.gemfile +0 -9
  50. data/gemfiles/3.2.gemfile.lock +0 -146
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: addcbdbe54c194c8f2c709efb65ac0f82f0a8bbca33f32c3fd8cf4128f3a0d15
4
+ data.tar.gz: f27dceb02f6f6be6bec42de624d8b5285b99dcc8164c54654e6178f9fbff5c75
5
+ SHA512:
6
+ metadata.gz: 4b99b87c67f5dce9f8bbf4952e48f79035b81b8590a2a10c00de595a04a8c31e10d019728914970a15bf2c7f4b4f35987e9cdd371afa780ff559ab4901d3b6e0
7
+ data.tar.gz: ca299a965486164a222563acdec871481a0ddb070c17a2ffc517784db956a7cfd7f9de4a6a7761b7288a4311df105f2b14a5777f4618466caf116fee15f4a013
data/.gitignore CHANGED
@@ -1,11 +1,13 @@
1
- test/*/log/*.log
2
- doc
3
- coverage
1
+ *.swo
2
+ *.swp
3
+ .DS_Store
4
+ .byebug_history
5
+ .bundle
4
6
  .svn/
7
+ Gemfile.lock
8
+ coverage
9
+ doc
5
10
  pkg
6
- *.swp
7
- *.swo
8
11
  tags
12
+ test/*/log/*.log
9
13
  tmp
10
- .bundle
11
- Gemfile.lock
@@ -0,0 +1,3 @@
1
+ ruby:
2
+ enabled: true
3
+ config_file: .rubocop.yml
@@ -0,0 +1,192 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.4
3
+ Layout/ParameterAlignment:
4
+ EnforcedStyle: with_fixed_indentation
5
+ Layout/ConditionPosition:
6
+ Enabled: false
7
+ Layout/DotPosition:
8
+ EnforcedStyle: trailing
9
+ Layout/HeredocIndentation:
10
+ Enabled: false
11
+ Layout/MultilineMethodCallIndentation:
12
+ EnforcedStyle: indented
13
+ Lint/AmbiguousOperator:
14
+ Enabled: false
15
+ Lint/AmbiguousRegexpLiteral:
16
+ Enabled: false
17
+ Lint/AssignmentInCondition:
18
+ Enabled: false
19
+ Lint/DeprecatedClassMethods:
20
+ Enabled: false
21
+ Lint/ElseLayout:
22
+ Enabled: false
23
+ Lint/SuppressedException:
24
+ Enabled: false
25
+ Lint/LiteralInInterpolation:
26
+ Enabled: false
27
+ Lint/Loop:
28
+ Enabled: false
29
+ Lint/ParenthesesAsGroupedExpression:
30
+ Enabled: false
31
+ Lint/RequireParentheses:
32
+ Enabled: false
33
+ Lint/UnderscorePrefixedVariableName:
34
+ Enabled: false
35
+ Lint/Void:
36
+ Enabled: false
37
+ Metrics/BlockLength:
38
+ Enabled: false
39
+ Metrics/ClassLength:
40
+ Enabled: false
41
+ Metrics/LineLength:
42
+ IgnoredPatterns:
43
+ - "^[ ]*describe.+$"
44
+ - "^[ ]*context.+$"
45
+ - "^[ ]*shared_context.+$"
46
+ - "^[ ]*shared_examples_for.+$"
47
+ - "^[ ]*it.+$"
48
+ - "^[ ]*'.+?' => '.+?',?$"
49
+ - "^[ ]*\".+?\" => \".+?\",?$"
50
+ - "^[ ]*.+?: .+?$"
51
+ Metrics/MethodLength:
52
+ Max: 30
53
+ Naming/AccessorMethodName:
54
+ Enabled: false
55
+ Naming/AsciiIdentifiers:
56
+ Enabled: false
57
+ Naming/BinaryOperatorParameterName:
58
+ Enabled: false
59
+ Style/ClassVars:
60
+ Enabled: false
61
+ Style/ColonMethodCall:
62
+ Enabled: false
63
+ Naming/FileName:
64
+ Enabled: false
65
+ Rails:
66
+ Enabled: true
67
+ Rails/Delegate:
68
+ Enabled: false
69
+ Rails/HttpPositionalArguments:
70
+ Enabled: false
71
+ Style/Alias:
72
+ Enabled: false
73
+ Style/ArrayJoin:
74
+ Enabled: false
75
+ Style/AsciiComments:
76
+ Enabled: false
77
+ Style/Attr:
78
+ Enabled: false
79
+ Style/CaseEquality:
80
+ Enabled: false
81
+ Style/CharacterLiteral:
82
+ Enabled: false
83
+ Style/ClassAndModuleChildren:
84
+ Enabled: false
85
+ Style/CollectionMethods:
86
+ PreferredMethods:
87
+ find: detect
88
+ reduce: inject
89
+ collect: map
90
+ find_all: select
91
+ Style/CommentAnnotation:
92
+ Enabled: false
93
+ Style/Documentation:
94
+ Enabled: false
95
+ Style/DoubleNegation:
96
+ Enabled: false
97
+ Style/EachWithObject:
98
+ Enabled: false
99
+ Style/EmptyLiteral:
100
+ Enabled: false
101
+ Style/Encoding:
102
+ Enabled: false
103
+ Style/EvenOdd:
104
+ Enabled: false
105
+ Lint/FlipFlop:
106
+ Enabled: false
107
+ Style/FormatString:
108
+ Enabled: false
109
+ Style/FrozenStringLiteralComment:
110
+ Enabled: false
111
+ Style/GlobalVars:
112
+ Enabled: false
113
+ Style/GuardClause:
114
+ Enabled: false
115
+ Style/IfUnlessModifier:
116
+ Enabled: false
117
+ Style/IfWithSemicolon:
118
+ Enabled: false
119
+ Style/InlineComment:
120
+ Enabled: false
121
+ Style/Lambda:
122
+ Enabled: false
123
+ Style/LambdaCall:
124
+ Enabled: false
125
+ Style/LineEndConcatenation:
126
+ Enabled: false
127
+ Style/MethodCalledOnDoEndBlock:
128
+ Enabled: false
129
+ Style/ModuleFunction:
130
+ Enabled: false
131
+ Style/NegatedIf:
132
+ Enabled: false
133
+ Style/NegatedWhile:
134
+ Enabled: false
135
+ Style/Next:
136
+ Enabled: false
137
+ Style/NilComparison:
138
+ Enabled: false
139
+ Style/Not:
140
+ Enabled: false
141
+ Style/NumericLiterals:
142
+ Enabled: false
143
+ Style/NumericPredicate:
144
+ Enabled: false
145
+ Style/OneLineConditional:
146
+ Enabled: false
147
+ Style/ParenthesesAroundCondition:
148
+ Enabled: false
149
+ Style/PercentLiteralDelimiters:
150
+ Enabled: false
151
+ Style/PerlBackrefs:
152
+ Enabled: false
153
+ Style/PreferredHashMethods:
154
+ Enabled: false
155
+ Style/Proc:
156
+ Enabled: false
157
+ Style/RaiseArgs:
158
+ Enabled: false
159
+ Style/RedundantParentheses:
160
+ Enabled: false
161
+ Style/RegexpLiteral:
162
+ Enabled: false
163
+ Style/SelfAssignment:
164
+ Enabled: false
165
+ Style/SignalException:
166
+ Enabled: false
167
+ Style/SingleLineBlockParams:
168
+ Enabled: false
169
+ Style/SingleLineMethods:
170
+ Enabled: false
171
+ Style/SpecialGlobalVars:
172
+ Enabled: false
173
+ Style/StringLiterals:
174
+ EnforcedStyle: single_quotes
175
+ Style/SymbolArray:
176
+ Enabled: false
177
+ Style/TrailingCommaInArguments:
178
+ EnforcedStyleForMultiline: consistent_comma
179
+ Style/TrailingCommaInArrayLiteral:
180
+ EnforcedStyleForMultiline: consistent_comma
181
+ Style/TrailingCommaInHashLiteral:
182
+ EnforcedStyleForMultiline: consistent_comma
183
+ Style/TrivialAccessors:
184
+ Enabled: false
185
+ Style/WhenThen:
186
+ Enabled: false
187
+ Style/WhileUntilModifier:
188
+ Enabled: false
189
+ Style/WordArray:
190
+ Enabled: false
191
+ Style/VariableInterpolation:
192
+ Enabled: false
@@ -0,0 +1 @@
1
+ 2.7.1
@@ -1,3 +1,34 @@
1
+ language: ruby
2
+ dist: xenial
3
+ os: linux
4
+ cache:
5
+ directories:
6
+ - vendor/bundle
7
+ # Source: <https://docs.travis-ci.com/user/languages/ruby/#bundler-20>
8
+ before_install:
9
+ - gem update --system '3.1.2' --no-document
10
+ - gem uninstall -v '< 2' -i $(rvm gemdir)@global -ax bundler || true
11
+ - gem install bundler -v '< 2' --no-document
12
+ - nvm use v11.0.0
13
+ - bundle config set path vendor/bundle
14
+ install: "bundle install --jobs=3 --retry=3"
15
+ script: "bundle exec rake"
1
16
  rvm:
2
- - 1.8.7
3
- - 1.9.2
17
+ - 2.4.9
18
+ - 2.5.8
19
+ - 2.6.6
20
+ - 2.7.1
21
+ gemfile:
22
+ - gemfiles/rails_4_2.gemfile
23
+ - gemfiles/rails_5_0.gemfile
24
+ - gemfiles/rails_5_1.gemfile
25
+ - gemfiles/rails_5_2.gemfile
26
+ - gemfiles/rails_6_0.gemfile
27
+ matrix:
28
+ exclude:
29
+ - rvm: 2.4.9
30
+ gemfile: gemfiles/rails_6_0.gemfile
31
+ - rvm: 2.6.6
32
+ gemfile: gemfiles/rails_4_2.gemfile
33
+ - rvm: 2.7.1
34
+ gemfile: gemfiles/rails_4_2.gemfile
data/Appraisals CHANGED
@@ -1,15 +1,116 @@
1
- appraise '3.0' do
2
- gem 'rails', '3.0.12'
1
+ # Note: All of the dependencies here were obtained by running `rails new` with
2
+ # various versions of Rails and copying lines from the generated Gemfile. It's
3
+ # best to keep the gems here in the same order as they're listed there so you
4
+ # can compare them more easily.
5
+
6
+ shared_rails_dependencies = proc do
7
+ gem 'sqlite3', '~> 1.3.6'
8
+ gem 'rubyzip', '~> 1.3.0'
9
+ end
10
+
11
+ shared_spring_dependencies = proc do
12
+ gem 'spring'
13
+ gem 'spring-commands-rspec'
14
+ end
15
+
16
+ shared_test_dependencies = proc do
17
+ gem 'minitest-reporters'
3
18
  end
4
19
 
5
- appraise '3.1' do
6
- gem 'rails', '3.1.4'
20
+ shared_dependencies = proc do
21
+ instance_eval(&shared_rails_dependencies)
22
+ instance_eval(&shared_spring_dependencies)
23
+ instance_eval(&shared_test_dependencies)
24
+ end
25
+
26
+ appraise 'rails_4_2' do
27
+ instance_eval(&shared_dependencies)
28
+
29
+ gem 'rails', '~> 4.2.10'
30
+ gem 'sass-rails', '~> 5.0'
31
+ gem 'uglifier', '>= 1.3.0'
32
+ gem 'coffee-rails', '~> 4.1.0'
7
33
  gem 'jquery-rails'
8
- gem 'sass-rails'
34
+ gem 'turbolinks'
35
+ gem 'jbuilder', '~> 2.0'
36
+ gem 'sdoc', '~> 0.4.0', group: :doc
37
+ gem 'bcrypt', '~> 3.1.7'
38
+
39
+ # Other dependencies we use
40
+ gem 'activeresource', '4.0.0'
41
+ gem 'json', '~> 1.4'
42
+ gem 'protected_attributes', '~> 1.0.6'
9
43
  end
10
44
 
11
- appraise '3.2' do
12
- gem 'rails', '3.2.3'
45
+ appraise 'rails_5_0' do
46
+ instance_eval(&shared_dependencies)
47
+
48
+ gem 'rails', '~> 5.0.7'
49
+ gem 'rails-controller-testing', '>= 1.0.1'
50
+ gem 'puma', '~> 3.0'
51
+ gem 'sass-rails', '~> 5.0'
13
52
  gem 'jquery-rails'
14
- gem 'sass-rails'
53
+ gem 'turbolinks', '~> 5'
54
+ gem 'jbuilder', '~> 2.5'
55
+ gem 'bcrypt', '~> 3.1.7'
56
+ gem 'listen', '~> 3.0.5'
57
+ gem 'spring-watcher-listen', '~> 2.0.0'
58
+ end
59
+
60
+ appraise 'rails_5_1' do
61
+ instance_eval(&shared_dependencies)
62
+ gem 'rails', '~> 5.1.6'
63
+ gem 'rails-controller-testing', '>= 1.0.1'
64
+ gem 'puma', '~> 3.7'
65
+ gem 'sass-rails', '~> 5.0'
66
+ gem 'turbolinks', '~> 5'
67
+ gem 'jbuilder', '~> 2.5'
68
+ gem 'bcrypt', '~> 3.1.7'
69
+ gem 'capybara', '~> 2.13'
70
+ gem 'selenium-webdriver'
71
+ gem 'listen', '>= 3.0.5', '< 3.2'
72
+ gem 'spring-watcher-listen', '~> 2.0.0'
73
+ end
74
+
75
+ appraise 'rails_5_2' do
76
+ instance_eval(&shared_dependencies)
77
+
78
+ gem 'rails', '~> 5.2.2'
79
+ gem 'rails-controller-testing', '>= 1.0.1'
80
+ gem 'puma', '~> 3.11'
81
+ gem 'bootsnap', '>= 1.1.0', require: false
82
+ gem 'sass-rails', '~> 5.0'
83
+ gem 'turbolinks', '~> 5'
84
+ gem 'jbuilder', '~> 2.5'
85
+ gem 'bcrypt', '~> 3.1.7'
86
+ gem 'capybara', '~> 3.1.1'
87
+ gem 'selenium-webdriver'
88
+ gem 'chromedriver-helper'
89
+ gem 'listen', '>= 3.0.5', '< 3.2'
90
+ gem 'spring-watcher-listen', '~> 2.0.0'
91
+ end
92
+
93
+ if Gem::Requirement.new('>= 2.5.0').satisfied_by?(Gem::Version.new(RUBY_VERSION))
94
+ appraise 'rails_6_0' do
95
+ instance_eval(&shared_dependencies)
96
+
97
+ gem 'rails', '~> 6.0.2'
98
+ gem 'puma', '~> 4.1'
99
+ gem 'sass-rails', '>= 6'
100
+ gem 'webpacker', '~> 4.0'
101
+ gem 'turbolinks', '~> 5'
102
+ gem 'jbuilder', '~> 2.7'
103
+ gem 'bcrypt', '~> 3.1.7'
104
+ gem 'bootsnap', '>= 1.4.2', require: false
105
+ gem 'listen', '>= 3.0.5', '< 3.2'
106
+ gem 'spring-watcher-listen', '~> 2.0.0'
107
+ gem 'capybara', '>= 2.15'
108
+ gem 'selenium-webdriver'
109
+ gem "sqlite3", "~> 1.4.0"
110
+ gem 'webdrivers'
111
+
112
+ # Other dependencies
113
+ gem 'rails-controller-testing', '>= 1.0.4'
114
+ gem 'pg', '~> 1.1', platform: :ruby
115
+ end
15
116
  end
@@ -0,0 +1,10 @@
1
+ # Changelog
2
+
3
+ ## 4.0.0 (2020-06-13)
4
+
5
+ * `shoulda` now brings in `shoulda-context` 2.0.0, which adds compatibility for
6
+ Ruby 2.7, Rails 6.0, and shoulda-matchers 4.0! Note that there are some
7
+ backward incompatible changes, so please see the [changelog
8
+ entry][shoulda-context-2-0-0] for this release to learn more.
9
+
10
+ [shoulda-context-2-0-0]: https://github.com/thoughtbot/shoulda-context/blob/master/CHANGELOG.md#200-2020-06-13
@@ -1,4 +1,9 @@
1
- We love pull requests. Here's a quick guide:
1
+ We love pull requests from everyone. By participating in this project, you
2
+ agree to abide by the thoughtbot [code of conduct].
3
+
4
+ [code of conduct]: https://thoughtbot.com/open-source-code-of-conduct
5
+
6
+ Here's a quick guide:
2
7
 
3
8
  1. Fork the repo.
4
9
 
data/Gemfile CHANGED
@@ -1,3 +1,16 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
+
5
+ gem 'appraisal', '~> 2.1'
6
+ gem 'bundler', '~> 1.0'
7
+ gem 'm'
8
+ gem 'minitest', '~> 5.0'
9
+ gem 'minitest-reporters', '~> 1.0'
10
+ gem 'mry'
11
+ gem 'pry', '~> 0.12.0'
12
+ gem 'pry-byebug', '~> 3.6.0'
13
+ gem 'rubocop', '0.71.0', require: false
14
+ gem 'rubocop-rails', require: false
15
+ gem 'snowglobe', '>= 0.3.0'
16
+ gem 'warnings_logger'
data/README.md CHANGED
@@ -1,108 +1,101 @@
1
- # shoulda [![Gem Version](https://badge.fury.io/rb/shoulda.png)](http://badge.fury.io/rb/shoulda) [![Build Status](https://secure.travis-ci.org/thoughtbot/shoulda.png)](http://travis-ci.org/thoughtbot/shoulda)
1
+ # Shoulda [![Gem Version][version-badge]][rubygems] [![Build Status][travis-badge]][travis] ![Downloads][downloads-badge] [![Hound][hound-badge]][hound]
2
2
 
3
- The shoulda gem is a meta gem with two dependencies:
3
+ [version-badge]: http://img.shields.io/gem/v/shoulda.svg
4
+ [rubygems]: http://rubygems.org/gems/shoulda
5
+ [travis-badge]: http://img.shields.io/travis/thoughtbot/shoulda/master.svg
6
+ [travis]: http://travis-ci.org/thoughtbot/shoulda
7
+ [downloads-badge]: http://img.shields.io/gem/dtv/shoulda.svg
8
+ [hound-badge]: https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg
9
+ [hound]: https://houndci.com
4
10
 
5
- * [shoulda-context](https://github.com/thoughtbot/shoulda-context)
6
- * [shoulda-matchers](https://github.com/thoughtbot/shoulda-matchers)
11
+ Shoulda helps you write more understandable, maintainable Rails-specific tests
12
+ under Minitest and Test::Unit.
7
13
 
8
- Official documentation for each gem:
14
+ ## Quick links
9
15
 
10
- * [shoulda-context](http://rubydoc.info/github/thoughtbot/shoulda-context/master/frames)
11
- * [shoulda-matchers](http://rubydoc.info/github/thoughtbot/shoulda-matchers/master/frames)
16
+ 📢 **[See what's changed in recent versions.][changelog]**
12
17
 
13
- The following describes different use cases and combinations.
18
+ [changelog]: CHANGELOG.md
14
19
 
15
- rspec with shoulda-matchers
16
- ---------------------------
20
+ ## Overview
17
21
 
18
- This is what thoughtbot currently does. We write tests like:
22
+ As a meta gem, the `shoulda` gem doesn't contain any code of its own but rather
23
+ brings in behavior from two other gems:
19
24
 
20
- ```ruby
21
- describe Post do
22
- it { should belong_to(:user) }
23
- it { should validate_presence_of(:title) }
24
- end
25
- ```
25
+ * [Shoulda Context]
26
+ * [Shoulda Matchers]
26
27
 
27
- The belong_to and validate_presence_of methods are the matchers.
28
- All matchers are Rails 3-specific.
28
+ [Shoulda Context]: https://github.com/thoughtbot/shoulda-context
29
+ [Shoulda Matchers]: https://github.com/thoughtbot/shoulda-matchers
29
30
 
30
- Add rspec-rails and shoulda-matchers to the project's Gemfile:
31
+ For instance:
31
32
 
32
33
  ```ruby
33
- group :test do
34
- gem 'rspec-rails'
35
- gem 'shoulda-matchers'
36
- end
37
- ```
34
+ require "test_helper"
38
35
 
39
- test/unit with shoulda
40
- ----------------------
36
+ class UserTest < ActiveSupport::TestCase
37
+ context "associations" do
38
+ should have_many(:posts)
39
+ end
41
40
 
42
- For the folks who prefer Test::Unit, they'd write tests like:
41
+ context "validations" do
42
+ should validate_presence_of(:email)
43
+ should allow_value("user@example.com").for(:email)
44
+ should_not allow_value("not-an-email").for(:email)
45
+ end
43
46
 
44
- ```ruby
45
- class UserTest < Test::Unit::TestCase
46
- should have_many(:posts)
47
- should_not allow_value("blah").for(:email)
47
+ context "#name" do
48
+ should "consist of first and last name" do
49
+ user = User.new(first_name: "John", last_name: "Smith")
50
+ assert_equal "John Smith", user.name
51
+ end
52
+ end
48
53
  end
49
54
  ```
50
55
 
51
- The have_many and allow_value methods are the same kind of matchers
52
- seen in the RSpec example. They come from the shoulda-matchers gem.
56
+ Here, the `context` and `should` methods come from Shoulda Context; matchers
57
+ (e.g. `have_many`, `allow_value`) come from Shoulda Matchers.
53
58
 
54
- Add shoulda to the project's Gemfile:
59
+ See the READMEs for these projects for more information.
55
60
 
56
- ```ruby
57
- group :test do
58
- gem 'shoulda'
59
- end
60
- ```
61
+ ## Compatibility
61
62
 
62
- test/unit with shoulda-context
63
- ------------------------------
63
+ Shoulda Matchers is [tested][travis] and supported against Ruby 2.4+, Rails
64
+ 4.2.x+, RSpec 3.x, and Minitest 5.x.
64
65
 
65
- If you're not testing a Rails project or don't want to use the matchers,
66
- you can use shoulda-context independently to write tests like:
66
+ ## Contributing
67
67
 
68
- ```ruby
69
- class CalculatorTest < Test::Unit::TestCase
70
- context "a calculator" do
71
- setup do
72
- @calculator = Calculator.new
73
- end
68
+ Shoulda is open source, and we are grateful for [everyone][contributors] who's
69
+ contributed so far.
74
70
 
75
- should "add two numbers for the sum" do
76
- assert_equal 4, @calculator.sum(2, 2)
77
- end
71
+ [contributors]: https://github.com/thoughtbot/shoulda/contributors
78
72
 
79
- should "multiply two numbers for the product" do
80
- assert_equal 10, @calculator.product(2, 5)
81
- end
82
- end
83
- end
84
- ```
73
+ If you'd like to contribute, please take a look at the
74
+ [instructions](CONTRIBUTING.md) for installing dependencies and crafting a good
75
+ pull request.
85
76
 
86
- Add shoulda-context to the project's Gemfile:
77
+ ## Versioning
87
78
 
88
- ```ruby
89
- group :test do
90
- gem 'shoulda-context'
91
- end
92
- ```
79
+ Shoulda follows Semantic Versioning 2.0 as defined at <http://semver.org>.
80
+
81
+ ## License
93
82
 
94
- Credits
95
- -------
83
+ Shoulda is copyright © 2006-2019 thoughtbot, inc. It is free software, and may
84
+ be redistributed under the terms specified in the [MIT-LICENSE](MIT-LICENSE)
85
+ file.
96
86
 
97
- ![thoughtbot](http://thoughtbot.com/assets/tm/logo.png)
87
+ ## About thoughtbot
98
88
 
99
- Shoulda is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community)
89
+ ![thoughtbot][thoughtbot-logo]
100
90
 
101
- Thank you to all [the contributors](https://github.com/thoughtbot/shoulda/contributors)!
91
+ [thoughtbot-logo]: https://thoughtbot.com/brand_assets/93:44.svg
102
92
 
103
- The names and logos for thoughtbot are trademarks of thoughtbot, inc.
93
+ Shoulda is maintained and funded by thoughtbot, inc. The names and logos for
94
+ thoughtbot are trademarks of thoughtbot, inc.
104
95
 
105
- License
106
- -------
96
+ We love open source software! See [our other projects][community] or [hire
97
+ us][hire] to design, develop, and grow your product.
107
98
 
108
- Shoulda is Copyright © 2006-2013 Tammer Saleh and thoughtbot, inc. It is free software, and may be redistributed under the terms specified in the MIT-LICENSE file.
99
+ [community]: https://thoughtbot.com/community?utm_source=github
100
+ [hire]: https://thoughtbot.com/hire-us?utm_source=github
101
+ [thoughtbot]: https://thoughtbot.com?utm_source=github