shoulda 3.6.0 → 4.0.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (61) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rubocop.yml +181 -2
  4. data/.ruby-version +1 -0
  5. data/.travis.yml +24 -9
  6. data/Appraisals +108 -10
  7. data/Gemfile +9 -5
  8. data/README.md +24 -17
  9. data/Rakefile +18 -13
  10. data/gemfiles/rails_4_2.gemfile +31 -0
  11. data/gemfiles/rails_4_2.gemfile.lock +240 -0
  12. data/gemfiles/rails_5_0.gemfile +29 -0
  13. data/gemfiles/rails_5_0.gemfile.lock +232 -0
  14. data/gemfiles/rails_5_1.gemfile +30 -0
  15. data/gemfiles/rails_5_1.gemfile.lock +249 -0
  16. data/gemfiles/rails_5_2.gemfile +32 -0
  17. data/gemfiles/rails_5_2.gemfile.lock +268 -0
  18. data/gemfiles/rails_6_0.gemfile +34 -0
  19. data/gemfiles/rails_6_0.gemfile.lock +285 -0
  20. data/lib/shoulda/version.rb +1 -1
  21. data/script/install_gems_in_all_appraisals +16 -0
  22. data/script/run_all_tests +16 -0
  23. data/script/supported_ruby_versions +7 -0
  24. data/script/update_gem_in_all_appraisals +17 -0
  25. data/script/update_gems_in_all_appraisals +16 -0
  26. data/shoulda.gemspec +3 -3
  27. data/test/acceptance/integrates_with_rails_test.rb +580 -0
  28. data/test/acceptance_test_helper.rb +32 -6
  29. data/test/support/acceptance/add_shoulda_to_project.rb +13 -18
  30. data/test/support/acceptance/matchers/have_output.rb +2 -0
  31. data/test/support/acceptance/matchers/indicate_that_tests_were_run.rb +109 -0
  32. data/test/support/acceptance/rails_application_with_shoulda.rb +47 -0
  33. data/test/support/{tests/current_bundle.rb → current_bundle.rb} +4 -4
  34. data/test/support/snowglobe.rb +5 -0
  35. data/test/test_helper.rb +9 -4
  36. metadata +37 -65
  37. data/.hound/ruby.yml +0 -1042
  38. data/gemfiles/4.2.gemfile +0 -17
  39. data/gemfiles/4.2.gemfile.lock +0 -174
  40. data/gemfiles/5.0.gemfile +0 -17
  41. data/gemfiles/5.0.gemfile.lock +0 -179
  42. data/test/acceptance/rails_integration_test.rb +0 -76
  43. data/test/report_warnings.rb +0 -7
  44. data/test/support/acceptance/helpers.rb +0 -19
  45. data/test/support/acceptance/helpers/active_model_helpers.rb +0 -11
  46. data/test/support/acceptance/helpers/base_helpers.rb +0 -14
  47. data/test/support/acceptance/helpers/command_helpers.rb +0 -54
  48. data/test/support/acceptance/helpers/file_helpers.rb +0 -19
  49. data/test/support/acceptance/helpers/gem_helpers.rb +0 -31
  50. data/test/support/acceptance/helpers/step_helpers.rb +0 -69
  51. data/test/support/acceptance/matchers/indicate_number_of_tests_was_run_matcher.rb +0 -54
  52. data/test/support/acceptance/matchers/indicate_that_tests_were_run_matcher.rb +0 -75
  53. data/test/support/tests/bundle.rb +0 -94
  54. data/test/support/tests/command_runner.rb +0 -230
  55. data/test/support/tests/filesystem.rb +0 -100
  56. data/test/support/tests/version.rb +0 -45
  57. data/test/warnings_spy.rb +0 -62
  58. data/test/warnings_spy/filesystem.rb +0 -45
  59. data/test/warnings_spy/partitioner.rb +0 -36
  60. data/test/warnings_spy/reader.rb +0 -53
  61. data/test/warnings_spy/reporter.rb +0 -88
@@ -0,0 +1,34 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal", "~> 2.1"
6
+ gem "bundler", "~> 1.0"
7
+ gem "m"
8
+ gem "minitest", "~> 5.0"
9
+ gem "minitest-reporters"
10
+ gem "mry"
11
+ gem "pry-byebug"
12
+ gem "rubocop"
13
+ gem "snowglobe"
14
+ gem "warnings_logger"
15
+ gem "sqlite3", platform: :ruby
16
+ gem "spring"
17
+ gem "spring-commands-rspec"
18
+ gem "rails", "~> 6.0.2"
19
+ gem "puma", "~> 4.1"
20
+ gem "sass-rails", ">= 6"
21
+ gem "webpacker", "~> 4.0"
22
+ gem "turbolinks", "~> 5"
23
+ gem "jbuilder", "~> 2.7"
24
+ gem "bcrypt", "~> 3.1.7"
25
+ gem "bootsnap", ">= 1.4.2", require: false
26
+ gem "listen", ">= 3.0.5", "< 3.2"
27
+ gem "spring-watcher-listen", "~> 2.0.0"
28
+ gem "capybara", ">= 2.15"
29
+ gem "selenium-webdriver"
30
+ gem "webdrivers"
31
+ gem "rails-controller-testing", ">= 1.0.4"
32
+ gem "pg", "~> 1.1", platform: :ruby
33
+
34
+ gemspec path: "../"
@@ -0,0 +1,285 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ shoulda (4.0.0.rc1)
5
+ shoulda-context (= 2.0.0.rc2)
6
+ shoulda-matchers (~> 4.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ actioncable (6.0.2)
12
+ actionpack (= 6.0.2)
13
+ nio4r (~> 2.0)
14
+ websocket-driver (>= 0.6.1)
15
+ actionmailbox (6.0.2)
16
+ actionpack (= 6.0.2)
17
+ activejob (= 6.0.2)
18
+ activerecord (= 6.0.2)
19
+ activestorage (= 6.0.2)
20
+ activesupport (= 6.0.2)
21
+ mail (>= 2.7.1)
22
+ actionmailer (6.0.2)
23
+ actionpack (= 6.0.2)
24
+ actionview (= 6.0.2)
25
+ activejob (= 6.0.2)
26
+ mail (~> 2.5, >= 2.5.4)
27
+ rails-dom-testing (~> 2.0)
28
+ actionpack (6.0.2)
29
+ actionview (= 6.0.2)
30
+ activesupport (= 6.0.2)
31
+ rack (~> 2.0)
32
+ rack-test (>= 0.6.3)
33
+ rails-dom-testing (~> 2.0)
34
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
35
+ actiontext (6.0.2)
36
+ actionpack (= 6.0.2)
37
+ activerecord (= 6.0.2)
38
+ activestorage (= 6.0.2)
39
+ activesupport (= 6.0.2)
40
+ nokogiri (>= 1.8.5)
41
+ actionview (6.0.2)
42
+ activesupport (= 6.0.2)
43
+ builder (~> 3.1)
44
+ erubi (~> 1.4)
45
+ rails-dom-testing (~> 2.0)
46
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
47
+ activejob (6.0.2)
48
+ activesupport (= 6.0.2)
49
+ globalid (>= 0.3.6)
50
+ activemodel (6.0.2)
51
+ activesupport (= 6.0.2)
52
+ activerecord (6.0.2)
53
+ activemodel (= 6.0.2)
54
+ activesupport (= 6.0.2)
55
+ activestorage (6.0.2)
56
+ actionpack (= 6.0.2)
57
+ activejob (= 6.0.2)
58
+ activerecord (= 6.0.2)
59
+ marcel (~> 0.3.1)
60
+ activesupport (6.0.2)
61
+ concurrent-ruby (~> 1.0, >= 1.0.2)
62
+ i18n (>= 0.7, < 2)
63
+ minitest (~> 5.1)
64
+ tzinfo (~> 1.1)
65
+ zeitwerk (~> 2.2)
66
+ addressable (2.7.0)
67
+ public_suffix (>= 2.0.2, < 5.0)
68
+ ansi (1.5.0)
69
+ appraisal (2.2.0)
70
+ bundler
71
+ rake
72
+ thor (>= 0.14.0)
73
+ ast (2.4.0)
74
+ bcrypt (3.1.13)
75
+ bootsnap (1.4.5)
76
+ msgpack (~> 1.0)
77
+ builder (3.2.4)
78
+ byebug (11.0.1)
79
+ capybara (3.29.0)
80
+ addressable
81
+ mini_mime (>= 0.1.3)
82
+ nokogiri (~> 1.8)
83
+ rack (>= 1.6.0)
84
+ rack-test (>= 0.6.3)
85
+ regexp_parser (~> 1.5)
86
+ xpath (~> 3.2)
87
+ childprocess (3.0.0)
88
+ coderay (1.1.2)
89
+ concurrent-ruby (1.1.5)
90
+ crass (1.0.5)
91
+ erubi (1.9.0)
92
+ ffi (1.11.3)
93
+ globalid (0.4.2)
94
+ activesupport (>= 4.2.0)
95
+ i18n (1.7.0)
96
+ concurrent-ruby (~> 1.0)
97
+ jaro_winkler (1.5.4)
98
+ jbuilder (2.9.1)
99
+ activesupport (>= 4.2.0)
100
+ listen (3.1.5)
101
+ rb-fsevent (~> 0.9, >= 0.9.4)
102
+ rb-inotify (~> 0.9, >= 0.9.7)
103
+ ruby_dep (~> 1.2)
104
+ loofah (2.4.0)
105
+ crass (~> 1.0.2)
106
+ nokogiri (>= 1.5.9)
107
+ m (1.5.1)
108
+ method_source (>= 0.6.7)
109
+ rake (>= 0.9.2.2)
110
+ mail (2.7.1)
111
+ mini_mime (>= 0.1.1)
112
+ marcel (0.3.3)
113
+ mimemagic (~> 0.3.2)
114
+ method_source (0.9.2)
115
+ mimemagic (0.3.3)
116
+ mini_mime (1.0.2)
117
+ mini_portile2 (2.4.0)
118
+ minitest (5.13.0)
119
+ minitest-reporters (1.4.2)
120
+ ansi
121
+ builder
122
+ minitest (>= 5.0)
123
+ ruby-progressbar
124
+ mry (0.77.0.2)
125
+ rubocop (>= 0.41.0)
126
+ msgpack (1.3.1)
127
+ nio4r (2.5.2)
128
+ nokogiri (1.10.7)
129
+ mini_portile2 (~> 2.4.0)
130
+ parallel (1.19.1)
131
+ parser (2.6.5.0)
132
+ ast (~> 2.4.0)
133
+ pg (1.1.4)
134
+ pry (0.12.2)
135
+ coderay (~> 1.1.0)
136
+ method_source (~> 0.9.0)
137
+ pry-byebug (3.7.0)
138
+ byebug (~> 11.0)
139
+ pry (~> 0.10)
140
+ public_suffix (4.0.1)
141
+ puma (4.3.1)
142
+ nio4r (~> 2.0)
143
+ rack (2.0.7)
144
+ rack-proxy (0.6.5)
145
+ rack
146
+ rack-test (1.1.0)
147
+ rack (>= 1.0, < 3)
148
+ rails (6.0.2)
149
+ actioncable (= 6.0.2)
150
+ actionmailbox (= 6.0.2)
151
+ actionmailer (= 6.0.2)
152
+ actionpack (= 6.0.2)
153
+ actiontext (= 6.0.2)
154
+ actionview (= 6.0.2)
155
+ activejob (= 6.0.2)
156
+ activemodel (= 6.0.2)
157
+ activerecord (= 6.0.2)
158
+ activestorage (= 6.0.2)
159
+ activesupport (= 6.0.2)
160
+ bundler (>= 1.3.0)
161
+ railties (= 6.0.2)
162
+ sprockets-rails (>= 2.0.0)
163
+ rails-controller-testing (1.0.4)
164
+ actionpack (>= 5.0.1.x)
165
+ actionview (>= 5.0.1.x)
166
+ activesupport (>= 5.0.1.x)
167
+ rails-dom-testing (2.0.3)
168
+ activesupport (>= 4.2.0)
169
+ nokogiri (>= 1.6)
170
+ rails-html-sanitizer (1.3.0)
171
+ loofah (~> 2.3)
172
+ railties (6.0.2)
173
+ actionpack (= 6.0.2)
174
+ activesupport (= 6.0.2)
175
+ method_source
176
+ rake (>= 0.8.7)
177
+ thor (>= 0.20.3, < 2.0)
178
+ rainbow (3.0.0)
179
+ rake (13.0.1)
180
+ rb-fsevent (0.10.3)
181
+ rb-inotify (0.10.0)
182
+ ffi (~> 1.0)
183
+ regexp_parser (1.6.0)
184
+ rubocop (0.77.0)
185
+ jaro_winkler (~> 1.5.1)
186
+ parallel (~> 1.10)
187
+ parser (>= 2.6)
188
+ rainbow (>= 2.2.2, < 4.0)
189
+ ruby-progressbar (~> 1.7)
190
+ unicode-display_width (>= 1.4.0, < 1.7)
191
+ ruby-progressbar (1.10.1)
192
+ ruby_dep (1.5.0)
193
+ rubyzip (2.0.0)
194
+ sass-rails (6.0.0)
195
+ sassc-rails (~> 2.1, >= 2.1.1)
196
+ sassc (2.2.1)
197
+ ffi (~> 1.9)
198
+ sassc-rails (2.1.2)
199
+ railties (>= 4.0.0)
200
+ sassc (>= 2.0)
201
+ sprockets (> 3.0)
202
+ sprockets-rails
203
+ tilt
204
+ selenium-webdriver (3.142.6)
205
+ childprocess (>= 0.5, < 4.0)
206
+ rubyzip (>= 1.2.2)
207
+ shoulda-context (2.0.0.rc2)
208
+ shoulda-matchers (4.1.2)
209
+ activesupport (>= 4.2.0)
210
+ snowglobe (0.3.0)
211
+ spring (2.1.0)
212
+ spring-commands-rspec (1.0.4)
213
+ spring (>= 0.9.1)
214
+ spring-watcher-listen (2.0.1)
215
+ listen (>= 2.7, < 4.0)
216
+ spring (>= 1.2, < 3.0)
217
+ sprockets (4.0.0)
218
+ concurrent-ruby (~> 1.0)
219
+ rack (> 1, < 3)
220
+ sprockets-rails (3.2.1)
221
+ actionpack (>= 4.0)
222
+ activesupport (>= 4.0)
223
+ sprockets (>= 3.0.0)
224
+ sqlite3 (1.4.1)
225
+ thor (1.0.1)
226
+ thread_safe (0.3.6)
227
+ tilt (2.0.10)
228
+ turbolinks (5.2.1)
229
+ turbolinks-source (~> 5.2)
230
+ turbolinks-source (5.2.0)
231
+ tzinfo (1.2.5)
232
+ thread_safe (~> 0.1)
233
+ unicode-display_width (1.6.0)
234
+ warnings_logger (0.1.0)
235
+ webdrivers (4.1.3)
236
+ nokogiri (~> 1.6)
237
+ rubyzip (>= 1.3.0)
238
+ selenium-webdriver (>= 3.0, < 4.0)
239
+ webpacker (4.2.2)
240
+ activesupport (>= 4.2)
241
+ rack-proxy (>= 0.6.1)
242
+ railties (>= 4.2)
243
+ websocket-driver (0.7.1)
244
+ websocket-extensions (>= 0.1.0)
245
+ websocket-extensions (0.1.4)
246
+ xpath (3.2.0)
247
+ nokogiri (~> 1.8)
248
+ zeitwerk (2.2.2)
249
+
250
+ PLATFORMS
251
+ ruby
252
+
253
+ DEPENDENCIES
254
+ appraisal (~> 2.1)
255
+ bcrypt (~> 3.1.7)
256
+ bootsnap (>= 1.4.2)
257
+ bundler (~> 1.0)
258
+ capybara (>= 2.15)
259
+ jbuilder (~> 2.7)
260
+ listen (>= 3.0.5, < 3.2)
261
+ m
262
+ minitest (~> 5.0)
263
+ minitest-reporters
264
+ mry
265
+ pg (~> 1.1)
266
+ pry-byebug
267
+ puma (~> 4.1)
268
+ rails (~> 6.0.2)
269
+ rails-controller-testing (>= 1.0.4)
270
+ rubocop
271
+ sass-rails (>= 6)
272
+ selenium-webdriver
273
+ shoulda!
274
+ snowglobe
275
+ spring
276
+ spring-commands-rspec
277
+ spring-watcher-listen (~> 2.0.0)
278
+ sqlite3
279
+ turbolinks (~> 5)
280
+ warnings_logger
281
+ webdrivers
282
+ webpacker (~> 4.0)
283
+
284
+ BUNDLED WITH
285
+ 1.17.3
@@ -1,3 +1,3 @@
1
1
  module Shoulda
2
- VERSION = "3.6.0".freeze
2
+ VERSION = '4.0.0.rc1'.freeze
3
3
  end
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ SUPPORTED_VERSIONS=$(script/supported_ruby_versions)
6
+
7
+ install-gems-for-version() {
8
+ local version="$1"
9
+ (export RBENV_VERSION=$version; bundle && bundle exec appraisal install)
10
+ }
11
+
12
+ for version in $SUPPORTED_VERSIONS; do
13
+ echo
14
+ echo "*** Installing gems for $version ***"
15
+ install-gems-for-version $version
16
+ done
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ SUPPORTED_VERSIONS=$(script/supported_ruby_versions)
6
+
7
+ run-tests-for-version() {
8
+ local version="$1"
9
+ (export RBENV_VERSION=$version; bundle exec rake)
10
+ }
11
+
12
+ for version in $SUPPORTED_VERSIONS; do
13
+ echo
14
+ echo "*** Running tests for $version ***"
15
+ run-tests-for-version $version
16
+ done
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'yaml'
4
+
5
+ travis_config_path = File.expand_path('../../.travis.yml', __FILE__)
6
+ travis_config = YAML.load_file(travis_config_path)
7
+ puts travis_config.fetch('rvm').join(' ')
@@ -0,0 +1,17 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ SUPPORTED_VERSIONS=$(script/supported_ruby_versions)
6
+ gem="$1"
7
+
8
+ update-gem-for-version() {
9
+ local version="$1"
10
+ (export RBENV_VERSION=$version; bundle update "$gem"; bundle exec appraisal update "$gem")
11
+ }
12
+
13
+ for version in $SUPPORTED_VERSIONS; do
14
+ echo
15
+ echo "*** Updating $gem for $version ***"
16
+ update-gem-for-version $version
17
+ done
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ set -euo pipefail
4
+
5
+ SUPPORTED_VERSIONS=$(script/supported_ruby_versions)
6
+
7
+ update-gems-for-version() {
8
+ local version="$1"
9
+ (export RBENV_VERSION=$version; bundle update "${@:2}"; bundle exec appraisal update "${@:2}")
10
+ }
11
+
12
+ for version in $SUPPORTED_VERSIONS; do
13
+ echo
14
+ echo "*** Updating gems for $version ***"
15
+ update-gems-for-version "$version" "$@"
16
+ done
@@ -10,7 +10,7 @@ Gem::Specification.new do |s|
10
10
  'Joe Ferris',
11
11
  'Ryan McGeary',
12
12
  'Dan Croak',
13
- 'Matt Jankowski'
13
+ 'Matt Jankowski',
14
14
  ]
15
15
  s.email = 'support@thoughtbot.com'
16
16
  s.homepage = 'https://github.com/thoughtbot/shoulda'
@@ -25,6 +25,6 @@ Gem::Specification.new do |s|
25
25
  end
26
26
  s.require_paths = ['lib']
27
27
 
28
- s.add_dependency('shoulda-context', ['~> 1.0', '>= 1.0.1'])
29
- s.add_dependency('shoulda-matchers', '~> 3.0')
28
+ s.add_dependency('shoulda-context', '2.0.0.rc2')
29
+ s.add_dependency('shoulda-matchers', '~> 4.0')
30
30
  end
@@ -0,0 +1,580 @@
1
+ require 'acceptance_test_helper'
2
+
3
+ class ShouldaIntegratesWithRailsTest < AcceptanceTest
4
+ # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
5
+ def setup
6
+ app.create
7
+
8
+ app.write_file 'db/migrate/1_create_users.rb', <<-FILE
9
+ class CreateUsers < #{app.migration_class_name}
10
+ def self.up
11
+ create_table :categories_users do |t|
12
+ t.integer :category_id
13
+ t.integer :user_id
14
+ end
15
+
16
+ create_table :categories do |t|
17
+ end
18
+
19
+ create_table :cities do |t|
20
+ end
21
+
22
+ create_table :lives do |t|
23
+ t.integer :user_id
24
+ end
25
+
26
+ create_table :issues do |t|
27
+ t.integer :user_id
28
+ end
29
+
30
+ create_table :users do |t|
31
+ t.integer :account_id
32
+ t.integer :city_id
33
+ t.string :email
34
+ t.integer :age
35
+ t.integer :status
36
+ t.string :aspects
37
+ end
38
+
39
+ add_index :users, :account_id
40
+ end
41
+ end
42
+ FILE
43
+
44
+ app.run_migrations!
45
+
46
+ app.write_file 'app/models/category.rb', <<-FILE
47
+ class Category < ActiveRecord::Base
48
+ end
49
+ FILE
50
+
51
+ app.write_file 'app/models/city.rb', <<-FILE
52
+ class City < ActiveRecord::Base
53
+ end
54
+ FILE
55
+
56
+ app.write_file 'app/models/issue.rb', <<-FILE
57
+ class Issue < ActiveRecord::Base
58
+ end
59
+ FILE
60
+
61
+ app.write_file 'app/models/life.rb', <<-FILE
62
+ class Life < ActiveRecord::Base
63
+ end
64
+ FILE
65
+
66
+ app.write_file 'app/models/person.rb', <<-FILE
67
+ class Person
68
+ # Note: All of these validations are listed in the same order as what's
69
+ # defined in the test (see below)
70
+
71
+ include ActiveModel::Model
72
+ include ActiveModel::SecurePassword
73
+
74
+ attr_accessor(
75
+ :age,
76
+ :card_number,
77
+ :email,
78
+ :foods,
79
+ :nothing,
80
+ :password_digest,
81
+ :some_other_attribute,
82
+ :some_other_attribute_confirmation,
83
+ :something,
84
+ :terms_of_service,
85
+ :workouts,
86
+ :some_other_attribute,
87
+ )
88
+
89
+ validate :email_looks_like_an_email
90
+
91
+ delegate :a_method, to: :some_delegate_object
92
+
93
+ has_secure_password
94
+
95
+ validates_absence_of :nothing
96
+ validates_acceptance_of :terms_of_service
97
+ validates_confirmation_of :password
98
+ validates_exclusion_of :workouts, in: ["biceps"]
99
+ validates_inclusion_of :foods, in: ["spaghetti"]
100
+ validates_length_of :card_number, maximum: 16
101
+ validates_numericality_of :age
102
+ validates_presence_of :something
103
+
104
+ def some_delegate_object
105
+ Object.new.instance_eval do
106
+ def a_method; end
107
+ end
108
+ end
109
+
110
+ private
111
+
112
+ def email_looks_like_an_email
113
+ if email !~ /@/
114
+ errors.add :email, "invalid"
115
+ end
116
+ end
117
+ end
118
+ FILE
119
+
120
+ app.write_file 'app/models/user.rb', <<-FILE
121
+ class User < ActiveRecord::Base
122
+ # Note: All of these validations are listed in the same order as what's
123
+ # defined in the test (see below)
124
+
125
+ belongs_to :city
126
+ enum status: { inactive: 0, active: 1 }
127
+ attr_readonly :username
128
+ has_and_belongs_to_many :categories
129
+ has_many :issues
130
+ has_one :life
131
+ serialize :aspects
132
+ validates_uniqueness_of :email
133
+ accepts_nested_attributes_for :issues
134
+ end
135
+ FILE
136
+
137
+ app.write_file 'app/controllers/examples_controller.rb', <<-FILE
138
+ class ExamplesController < ApplicationController
139
+ # Note: All of these validations are listed in the same order as what's
140
+ # defined in the test (see below)
141
+
142
+ before_action :some_before_action
143
+ after_action :some_after_action
144
+ around_action :some_around_action
145
+
146
+ rescue_from ActiveRecord::RecordNotFound, with: :handle_not_found
147
+
148
+ layout "application"
149
+
150
+ def index
151
+ render :index
152
+ head :ok
153
+ end
154
+
155
+ def create
156
+ create_params
157
+ flash[:success] = "Example created"
158
+ session[:some_key] = "some value"
159
+ redirect_to action: :index
160
+ end
161
+
162
+ def handle_not_found
163
+ end
164
+
165
+ private
166
+
167
+ def some_before_action
168
+ end
169
+
170
+ def some_after_action
171
+ end
172
+
173
+ def some_around_action
174
+ yield
175
+ end
176
+
177
+ def create_params
178
+ params.require(:user).permit(:email, :password)
179
+ end
180
+ end
181
+ FILE
182
+
183
+ app.write_file 'app/views/examples/index.html.erb', <<-FILE
184
+ Some content here
185
+ FILE
186
+
187
+ app.write_file 'config/routes.rb', <<-FILE
188
+ Rails.application.routes.draw do
189
+ resources :examples, only: [:index, :create]
190
+ end
191
+ FILE
192
+ end
193
+
194
+ def test_succeeding_assertions_for_active_model
195
+ app.write_file 'test/models/person_test.rb', <<-FILE
196
+ require 'test_helper'
197
+
198
+ class PersonTest < ActiveSupport::TestCase
199
+ # Note: All of these matchers are listed in alphabetical order so we can
200
+ # compare with what is listed inside of the shoulda-matchers README
201
+
202
+ should allow_value("john@smith.com").for(:email)
203
+ should_not allow_value("john").for(:email)
204
+
205
+ should delegate_method(:a_method).to(:some_delegate_object)
206
+ should_not delegate_method(:some_other_method).to(:some_other_object)
207
+
208
+ should have_secure_password
209
+
210
+ should validate_absence_of(:nothing)
211
+ should_not validate_absence_of(:some_other_attribute)
212
+
213
+ should validate_acceptance_of(:terms_of_service)
214
+ should_not validate_acceptance_of(:some_other_attribute)
215
+
216
+ should validate_confirmation_of(:password)
217
+ should_not validate_confirmation_of(:some_other_attribute)
218
+
219
+ should validate_exclusion_of(:workouts).in_array(["biceps"])
220
+ should_not validate_exclusion_of(:some_other_attribute).
221
+ in_array(["whatever"])
222
+
223
+ should validate_inclusion_of(:foods).in_array(["spaghetti"])
224
+ should_not validate_inclusion_of(:some_other_attribute).
225
+ in_array(["whatever"])
226
+
227
+ should validate_length_of(:card_number).is_at_most(16)
228
+ should_not validate_length_of(:some_other_attribute).is_at_most(16)
229
+
230
+ should validate_numericality_of(:age)
231
+ should_not validate_numericality_of(:some_other_attribute)
232
+
233
+ should validate_presence_of(:something)
234
+ should_not validate_presence_of(:some_other_attribute)
235
+ end
236
+ FILE
237
+
238
+ result = app.run_n_unit_test_suite
239
+
240
+ assert_accepts indicate_that_tests_were_run(failures: 0), result
241
+ end
242
+
243
+ def test_succeeding_assertions_for_active_record
244
+ app.write_file 'test/models/user_test.rb', <<-FILE
245
+ require 'test_helper'
246
+
247
+ class UserTest < ActiveSupport::TestCase
248
+ # Note: All of these matchers are listed in alphabetical order so we can
249
+ # compare with what is listed inside of the shoulda-matchers README
250
+
251
+ should belong_to(:city)
252
+ should_not belong_to(:some_other_attribute)
253
+
254
+ should define_enum_for(:status).with_values(inactive: 0, active: 1)
255
+ should_not define_enum_for(:status).with_values(foo: "bar")
256
+
257
+ should have_db_column(:age)
258
+ should_not have_db_column(:some_other_attribute)
259
+
260
+ should have_db_index(:account_id)
261
+ should_not have_db_index(:some_other_attribute)
262
+
263
+ should have_readonly_attribute(:username)
264
+ should_not have_readonly_attribute(:some_other_attribute)
265
+
266
+ should have_and_belong_to_many(:categories)
267
+ should_not have_and_belong_to_many(:whatevers)
268
+
269
+ should have_many(:issues)
270
+ should_not have_many(:whatevers)
271
+
272
+ should have_one(:life)
273
+ should_not have_one(:whatever)
274
+
275
+ should serialize(:aspects)
276
+ should_not serialize(:age)
277
+
278
+ should validate_uniqueness_of(:email)
279
+ should_not validate_uniqueness_of(:some_other_attribute)
280
+
281
+ should accept_nested_attributes_for(:issues)
282
+ should_not accept_nested_attributes_for(:some_other_attribute)
283
+ end
284
+ FILE
285
+
286
+ result = app.run_n_unit_test_suite
287
+
288
+ assert_accepts indicate_that_tests_were_run(failures: 0), result
289
+ end
290
+
291
+ def test_succeeding_assertions_for_action_controller
292
+ app.write_file 'test/controllers/examples_controller_test.rb', <<-FILE
293
+ require 'test_helper'
294
+
295
+ class ExamplesControllerTest < ActionController::TestCase
296
+ context "GET #index" do
297
+ setup do
298
+ get :index
299
+ end
300
+
301
+ # Note: All of these matchers are listed in alphabetical order so we
302
+ # can compare with what is listed inside of the shoulda-matchers
303
+ # README
304
+
305
+ should use_before_action(:some_before_action)
306
+ should_not use_before_action(:some_other_before_action)
307
+ should use_after_action(:some_after_action)
308
+ should_not use_after_action(:some_other_after_action)
309
+ should use_around_action(:some_around_action)
310
+ should_not use_around_action(:some_other_around_action)
311
+
312
+ # This is one of the defaults for Rails
313
+ should filter_param(:password)
314
+ should_not filter_param(:some_other_param)
315
+
316
+ should rescue_from(ActiveRecord::RecordNotFound).
317
+ with(:handle_not_found)
318
+ should_not rescue_from(ActiveRecord::RecordNotFound).
319
+ with(:some_other_method)
320
+
321
+ should render_template(:index)
322
+ should_not render_template(:some_other_action)
323
+
324
+ should render_with_layout("application")
325
+ should_not render_with_layout("some_other_layout")
326
+
327
+ should respond_with(:ok)
328
+ should_not respond_with(:some_other_status)
329
+
330
+ should route(:get, "/examples").to(action: :index)
331
+ should_not route(:get, "/examples").to(action: :something_else)
332
+ end
333
+
334
+ context "POST #create" do
335
+ setup do
336
+ if ActionPack::VERSION::STRING.start_with?("4.")
337
+ post :create, {
338
+ user: {
339
+ email: "some@email.com",
340
+ password: "somepassword"
341
+ }
342
+ }
343
+ else
344
+ post :create, params: {
345
+ user: {
346
+ email: "some@email.com",
347
+ password: "somepassword"
348
+ }
349
+ }
350
+ end
351
+ end
352
+
353
+ should permit(:email, :password).
354
+ for(:create, params: {
355
+ user: {
356
+ email: "some@email.com",
357
+ password: "somepassword"
358
+ }
359
+ }).
360
+ on(:user)
361
+ should_not permit(:foo, :bar).
362
+ for(:create, params: {
363
+ user: {
364
+ email: "some@email.com",
365
+ password: "somepassword"
366
+ }
367
+ }).
368
+ on(:user)
369
+
370
+ should redirect_to("/examples")
371
+ should_not redirect_to("/something_else")
372
+
373
+ should set_flash[:success].to("Example created")
374
+ should_not set_flash[:success].to("Something else")
375
+
376
+ should set_session[:some_key].to("some value")
377
+ should_not set_session[:some_key].to("some other value")
378
+ end
379
+ end
380
+ FILE
381
+
382
+ result = app.run_n_unit_test_suite
383
+
384
+ assert_accepts indicate_that_tests_were_run(failures: 0), result
385
+ end
386
+
387
+ def test_failing_assertions_for_active_model
388
+ app.write_file 'test/models/person_test.rb', <<-FILE
389
+ require 'test_helper'
390
+
391
+ class PersonTest < ActiveSupport::TestCase
392
+ # Note: All of these matchers are listed in alphabetical order so we can
393
+ # compare with what is listed inside of the shoulda-matchers README
394
+
395
+ should_not allow_value("john@smith.com").for(:email)
396
+ should allow_value("john").for(:email)
397
+
398
+ # FIXME: See #1187 in shoulda-matchers
399
+ #should_not have_secure_password
400
+
401
+ should_not validate_absence_of(:nothing)
402
+ should validate_absence_of(:some_other_attribute)
403
+
404
+ should_not validate_acceptance_of(:terms_of_service)
405
+ should validate_acceptance_of(:some_other_attribute)
406
+
407
+ should_not validate_confirmation_of(:password)
408
+ should validate_confirmation_of(:some_other_attribute)
409
+
410
+ should_not validate_exclusion_of(:workouts).in_array(["biceps"])
411
+ should validate_exclusion_of(:some_other_attribute).
412
+ in_array(["whatever"])
413
+
414
+ should_not validate_inclusion_of(:foods).in_array(["spaghetti"])
415
+ should validate_inclusion_of(:some_other_attribute).
416
+ in_array(["whatever"])
417
+
418
+ should_not validate_length_of(:card_number).is_at_most(16)
419
+ should validate_length_of(:some_other_attribute).is_at_most(16)
420
+
421
+ should_not validate_numericality_of(:age)
422
+ should validate_numericality_of(:some_other_attribute)
423
+
424
+ should_not validate_presence_of(:something)
425
+ should validate_presence_of(:some_other_attribute)
426
+
427
+ should_not delegate_method(:a_method).to(:some_delegate_object)
428
+ should delegate_method(:some_other_method).to(:some_other_object)
429
+ end
430
+ FILE
431
+
432
+ result = app.run_n_unit_test_suite
433
+
434
+ assert_accepts indicate_that_tests_were_run(failures: 20), result
435
+ end
436
+
437
+ def test_failing_assertions_for_active_record
438
+ app.write_file 'test/models/user_test.rb', <<-FILE
439
+ require 'test_helper'
440
+
441
+ class UserTest < ActiveSupport::TestCase
442
+ # Note: All of these matchers are listed in alphabetical order so we can
443
+ # compare with what is listed inside of the shoulda-matchers README
444
+
445
+ should_not belong_to(:city)
446
+ should belong_to(:some_other_attribute)
447
+
448
+ should_not define_enum_for(:status).with_values(inactive: 0, active: 1)
449
+ should define_enum_for(:status).with_values(foo: "bar")
450
+
451
+ should_not have_db_column(:age)
452
+ should have_db_column(:some_other_attribute)
453
+
454
+ should_not have_db_index(:account_id)
455
+ should have_db_index(:some_other_attribute)
456
+
457
+ should_not have_readonly_attribute(:username)
458
+ should have_readonly_attribute(:some_other_attribute)
459
+
460
+ should_not have_and_belong_to_many(:categories)
461
+ should have_and_belong_to_many(:whatevers)
462
+
463
+ should_not have_many(:issues)
464
+ should have_many(:whatevers)
465
+
466
+ should_not have_one(:life)
467
+ should have_one(:whatever)
468
+
469
+ should_not serialize(:aspects)
470
+ should serialize(:age)
471
+
472
+ should_not validate_uniqueness_of(:email)
473
+ should validate_uniqueness_of(:some_other_attribute)
474
+
475
+ should_not accept_nested_attributes_for(:issues)
476
+ should accept_nested_attributes_for(:some_other_attribute)
477
+ end
478
+ FILE
479
+
480
+ result = app.run_n_unit_test_suite
481
+
482
+ assert_accepts indicate_that_tests_were_run(failures: 22), result
483
+ end
484
+
485
+ def test_failing_assertions_for_action_controller
486
+ app.write_file 'test/controllers/examples_controller_test.rb', <<-FILE
487
+ require 'test_helper'
488
+
489
+ class ExamplesControllerTest < ActionController::TestCase
490
+ context "GET #index" do
491
+ setup do
492
+ get :index
493
+ end
494
+
495
+ # Note: All of these matchers are listed in alphabetical order so we
496
+ # can compare with what is listed inside of the shoulda-matchers
497
+ # README
498
+
499
+ should_not use_before_action(:some_before_action)
500
+ should use_before_action(:some_other_before_action)
501
+ should_not use_after_action(:some_after_action)
502
+ should use_after_action(:some_other_after_action)
503
+ should_not use_around_action(:some_around_action)
504
+ should use_around_action(:some_other_around_action)
505
+
506
+ should_not filter_param(:password)
507
+ should filter_param(:some_other_param)
508
+
509
+ should_not rescue_from(ActiveRecord::RecordNotFound).
510
+ with(:handle_not_found)
511
+ should rescue_from(ActiveRecord::RecordNotFound).
512
+ with(:some_other_method)
513
+
514
+ should_not render_template(:index)
515
+ should render_template(:some_other_action)
516
+
517
+ should_not render_with_layout("application")
518
+ should render_with_layout("some_other_layout")
519
+
520
+ should_not respond_with(:ok)
521
+ should respond_with(:some_other_status)
522
+
523
+ should_not route(:get, "/examples").to(action: :index)
524
+ should route(:get, "/examples").to(action: :something_else)
525
+ end
526
+
527
+ context "POST #create" do
528
+ setup do
529
+ if ActionPack::VERSION::STRING.start_with?("4.")
530
+ post :create, {
531
+ user: {
532
+ email: "some@email.com",
533
+ password: "somepassword"
534
+ }
535
+ }
536
+ else
537
+ post :create, params: {
538
+ user: {
539
+ email: "some@email.com",
540
+ password: "somepassword"
541
+ }
542
+ }
543
+ end
544
+ end
545
+
546
+ should_not permit(:email, :password).
547
+ for(:create, params: {
548
+ user: {
549
+ email: "some@email.com",
550
+ password: "somepassword"
551
+ }
552
+ }).
553
+ on(:user)
554
+ should permit(:foo, :bar).
555
+ for(:create, params: {
556
+ user: {
557
+ email: "some@email.com",
558
+ password: "somepassword"
559
+ }
560
+ }).
561
+ on(:user)
562
+
563
+ should_not redirect_to("/examples")
564
+ should redirect_to("/something_else")
565
+
566
+ should_not set_flash[:success].to("Example created")
567
+ should set_flash[:success].to("Something else")
568
+
569
+ should_not set_session[:some_key].to("some value")
570
+ should set_session[:some_key].to("some other value")
571
+ end
572
+ end
573
+ FILE
574
+
575
+ result = app.run_n_unit_test_suite
576
+
577
+ assert_accepts indicate_that_tests_were_run(failures: 26), result
578
+ end
579
+ # rubocop:enable Metrics/AbcSize, Metrics/MethodLength
580
+ end