shoulda-context 1.2.2 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -1
  3. data/.hound.yml +3 -0
  4. data/.rubocop.yml +190 -0
  5. data/.ruby-version +1 -1
  6. data/.travis.yml +36 -2
  7. data/Appraisals +100 -29
  8. data/CHANGELOG.md +29 -0
  9. data/Gemfile +15 -1
  10. data/Gemfile.lock +70 -0
  11. data/MIT-LICENSE +1 -1
  12. data/README.md +140 -29
  13. data/Rakefile +20 -15
  14. data/bin/install_gems_in_all_appraisals +16 -0
  15. data/bin/run_all_tests +16 -0
  16. data/bin/setup +190 -0
  17. data/bin/supported_ruby_versions +7 -0
  18. data/bin/update_gem_in_all_appraisals +17 -0
  19. data/bin/update_gems_in_all_appraisals +16 -0
  20. data/{bin → exe}/convert_to_should_syntax +0 -0
  21. data/gemfiles/rails_4_2.gemfile +35 -0
  22. data/gemfiles/rails_4_2.gemfile.lock +234 -0
  23. data/gemfiles/rails_5_0.gemfile +33 -0
  24. data/gemfiles/rails_5_0.gemfile.lock +226 -0
  25. data/gemfiles/rails_5_1.gemfile +34 -0
  26. data/gemfiles/rails_5_1.gemfile.lock +242 -0
  27. data/gemfiles/rails_5_2.gemfile +36 -0
  28. data/gemfiles/rails_5_2.gemfile.lock +261 -0
  29. data/gemfiles/rails_6_0.gemfile +38 -0
  30. data/gemfiles/rails_6_0.gemfile.lock +286 -0
  31. data/lib/shoulda/context.rb +13 -16
  32. data/lib/shoulda/context/assertions.rb +16 -13
  33. data/lib/shoulda/context/configuration.rb +19 -0
  34. data/lib/shoulda/context/context.rb +33 -307
  35. data/lib/shoulda/context/dsl.rb +279 -0
  36. data/lib/shoulda/context/rails_test_unit_reporter_patch.rb +21 -0
  37. data/lib/shoulda/context/railtie.rb +14 -0
  38. data/lib/shoulda/context/test_framework_detection.rb +4 -5
  39. data/lib/shoulda/context/version.rb +1 -1
  40. data/lib/shoulda/context/world.rb +22 -0
  41. data/shoulda-context.gemspec +11 -18
  42. data/test/fake_rails_root/test/shoulda_macros/custom_macro.rb +1 -1
  43. data/test/fake_rails_root/vendor/gems/gem_with_macro-0.0.1/shoulda_macros/gem_macro.rb +1 -2
  44. data/test/fake_rails_root/vendor/plugins/plugin_with_macro/shoulda_macros/plugin_macro.rb +1 -2
  45. data/test/shoulda/autoload_macro_test.rb +1 -1
  46. data/test/shoulda/context_test.rb +92 -53
  47. data/test/shoulda/convert_to_should_syntax_test.rb +5 -7
  48. data/test/shoulda/helpers_test.rb +24 -59
  49. data/test/shoulda/railtie_test.rb +43 -0
  50. data/test/shoulda/rerun_snippet_test.rb +45 -0
  51. data/test/shoulda/should_test.rb +163 -24
  52. data/test/shoulda/test_framework_detection_test.rb +64 -71
  53. data/test/support/current_bundle.rb +61 -0
  54. data/test/support/rails_application_with_shoulda_context.rb +46 -0
  55. data/test/support/snowglobe.rb +5 -0
  56. data/test/test_helper.rb +43 -11
  57. metadata +46 -142
  58. data/gemfiles/minitest_4_x.gemfile +0 -7
  59. data/gemfiles/minitest_4_x.gemfile.lock +0 -96
  60. data/gemfiles/minitest_5_x.gemfile +0 -7
  61. data/gemfiles/minitest_5_x.gemfile.lock +0 -102
  62. data/gemfiles/rails_3_0.gemfile +0 -8
  63. data/gemfiles/rails_3_0.gemfile.lock +0 -93
  64. data/gemfiles/rails_3_1.gemfile +0 -10
  65. data/gemfiles/rails_3_1.gemfile.lock +0 -114
  66. data/gemfiles/rails_3_2.gemfile +0 -10
  67. data/gemfiles/rails_3_2.gemfile.lock +0 -112
  68. data/gemfiles/rails_4_0.gemfile +0 -10
  69. data/gemfiles/rails_4_0.gemfile.lock +0 -107
  70. data/gemfiles/rails_4_1.gemfile +0 -10
  71. data/gemfiles/rails_4_1.gemfile.lock +0 -119
  72. data/gemfiles/test_unit.gemfile +0 -7
  73. data/gemfiles/test_unit.gemfile.lock +0 -95
  74. data/init.rb +0 -1
  75. data/rails/init.rb +0 -4
@@ -0,0 +1,38 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "appraisal"
6
+ gem "bundler", "~> 1.0"
7
+ gem "byebug"
8
+ gem "m"
9
+ gem "minitest"
10
+ gem "mocha"
11
+ gem "pry", "~> 0.12.0"
12
+ gem "pry-byebug", "~> 3.6.0"
13
+ gem "rake"
14
+ gem "rubocop", "0.71.0"
15
+ gem "snowglobe", ">= 0.3.0"
16
+ gem "test-unit"
17
+ gem "warnings_logger"
18
+ gem "sqlite3", "~> 1.4.0"
19
+ gem "spring"
20
+ gem "spring-commands-rspec"
21
+ gem "minitest-reporters"
22
+ gem "rails", "~> 6.0.2"
23
+ gem "puma", "~> 4.1"
24
+ gem "sass-rails", ">= 6"
25
+ gem "webpacker", "~> 4.0"
26
+ gem "turbolinks", "~> 5"
27
+ gem "jbuilder", "~> 2.7"
28
+ gem "bcrypt", "~> 3.1.7"
29
+ gem "bootsnap", ">= 1.4.2", require: false
30
+ gem "listen", ">= 3.0.5", "< 3.2"
31
+ gem "spring-watcher-listen", "~> 2.0.0"
32
+ gem "capybara", ">= 2.15"
33
+ gem "selenium-webdriver"
34
+ gem "webdrivers"
35
+ gem "rails-controller-testing", ">= 1.0.4"
36
+ gem "pg", "~> 1.1", platform: :ruby
37
+
38
+ gemspec path: "../"
@@ -0,0 +1,286 @@
1
+ PATH
2
+ remote: ..
3
+ specs:
4
+ shoulda-context (2.0.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ actioncable (6.0.2.2)
10
+ actionpack (= 6.0.2.2)
11
+ nio4r (~> 2.0)
12
+ websocket-driver (>= 0.6.1)
13
+ actionmailbox (6.0.2.2)
14
+ actionpack (= 6.0.2.2)
15
+ activejob (= 6.0.2.2)
16
+ activerecord (= 6.0.2.2)
17
+ activestorage (= 6.0.2.2)
18
+ activesupport (= 6.0.2.2)
19
+ mail (>= 2.7.1)
20
+ actionmailer (6.0.2.2)
21
+ actionpack (= 6.0.2.2)
22
+ actionview (= 6.0.2.2)
23
+ activejob (= 6.0.2.2)
24
+ mail (~> 2.5, >= 2.5.4)
25
+ rails-dom-testing (~> 2.0)
26
+ actionpack (6.0.2.2)
27
+ actionview (= 6.0.2.2)
28
+ activesupport (= 6.0.2.2)
29
+ rack (~> 2.0, >= 2.0.8)
30
+ rack-test (>= 0.6.3)
31
+ rails-dom-testing (~> 2.0)
32
+ rails-html-sanitizer (~> 1.0, >= 1.2.0)
33
+ actiontext (6.0.2.2)
34
+ actionpack (= 6.0.2.2)
35
+ activerecord (= 6.0.2.2)
36
+ activestorage (= 6.0.2.2)
37
+ activesupport (= 6.0.2.2)
38
+ nokogiri (>= 1.8.5)
39
+ actionview (6.0.2.2)
40
+ activesupport (= 6.0.2.2)
41
+ builder (~> 3.1)
42
+ erubi (~> 1.4)
43
+ rails-dom-testing (~> 2.0)
44
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
45
+ activejob (6.0.2.2)
46
+ activesupport (= 6.0.2.2)
47
+ globalid (>= 0.3.6)
48
+ activemodel (6.0.2.2)
49
+ activesupport (= 6.0.2.2)
50
+ activerecord (6.0.2.2)
51
+ activemodel (= 6.0.2.2)
52
+ activesupport (= 6.0.2.2)
53
+ activestorage (6.0.2.2)
54
+ actionpack (= 6.0.2.2)
55
+ activejob (= 6.0.2.2)
56
+ activerecord (= 6.0.2.2)
57
+ marcel (~> 0.3.1)
58
+ activesupport (6.0.2.2)
59
+ concurrent-ruby (~> 1.0, >= 1.0.2)
60
+ i18n (>= 0.7, < 2)
61
+ minitest (~> 5.1)
62
+ tzinfo (~> 1.1)
63
+ zeitwerk (~> 2.2)
64
+ addressable (2.7.0)
65
+ public_suffix (>= 2.0.2, < 5.0)
66
+ ansi (1.5.0)
67
+ appraisal (2.2.0)
68
+ bundler
69
+ rake
70
+ thor (>= 0.14.0)
71
+ ast (2.4.0)
72
+ bcrypt (3.1.13)
73
+ bootsnap (1.4.6)
74
+ msgpack (~> 1.0)
75
+ builder (3.2.4)
76
+ byebug (10.0.2)
77
+ capybara (3.32.0)
78
+ addressable
79
+ mini_mime (>= 0.1.3)
80
+ nokogiri (~> 1.8)
81
+ rack (>= 1.6.0)
82
+ rack-test (>= 0.6.3)
83
+ regexp_parser (~> 1.5)
84
+ xpath (~> 3.2)
85
+ childprocess (3.0.0)
86
+ coderay (1.1.2)
87
+ concurrent-ruby (1.1.6)
88
+ crass (1.0.6)
89
+ erubi (1.9.0)
90
+ ffi (1.12.2)
91
+ globalid (0.4.2)
92
+ activesupport (>= 4.2.0)
93
+ i18n (1.8.2)
94
+ concurrent-ruby (~> 1.0)
95
+ jaro_winkler (1.5.4)
96
+ jbuilder (2.10.0)
97
+ activesupport (>= 5.0.0)
98
+ listen (3.1.5)
99
+ rb-fsevent (~> 0.9, >= 0.9.4)
100
+ rb-inotify (~> 0.9, >= 0.9.7)
101
+ ruby_dep (~> 1.2)
102
+ loofah (2.4.0)
103
+ crass (~> 1.0.2)
104
+ nokogiri (>= 1.5.9)
105
+ m (1.5.1)
106
+ method_source (>= 0.6.7)
107
+ rake (>= 0.9.2.2)
108
+ mail (2.7.1)
109
+ mini_mime (>= 0.1.1)
110
+ marcel (0.3.3)
111
+ mimemagic (~> 0.3.2)
112
+ method_source (0.9.2)
113
+ mimemagic (0.3.4)
114
+ mini_mime (1.0.2)
115
+ mini_portile2 (2.4.0)
116
+ minitest (5.14.0)
117
+ minitest-reporters (1.4.2)
118
+ ansi
119
+ builder
120
+ minitest (>= 5.0)
121
+ ruby-progressbar
122
+ mocha (1.11.2)
123
+ msgpack (1.3.3)
124
+ nio4r (2.5.2)
125
+ nokogiri (1.10.9)
126
+ mini_portile2 (~> 2.4.0)
127
+ parallel (1.19.1)
128
+ parser (2.7.1.0)
129
+ ast (~> 2.4.0)
130
+ pg (1.2.3)
131
+ power_assert (1.1.7)
132
+ pry (0.12.2)
133
+ coderay (~> 1.1.0)
134
+ method_source (~> 0.9.0)
135
+ pry-byebug (3.6.0)
136
+ byebug (~> 10.0)
137
+ pry (~> 0.10)
138
+ public_suffix (4.0.3)
139
+ puma (4.3.3)
140
+ nio4r (~> 2.0)
141
+ rack (2.2.2)
142
+ rack-proxy (0.6.5)
143
+ rack
144
+ rack-test (1.1.0)
145
+ rack (>= 1.0, < 3)
146
+ rails (6.0.2.2)
147
+ actioncable (= 6.0.2.2)
148
+ actionmailbox (= 6.0.2.2)
149
+ actionmailer (= 6.0.2.2)
150
+ actionpack (= 6.0.2.2)
151
+ actiontext (= 6.0.2.2)
152
+ actionview (= 6.0.2.2)
153
+ activejob (= 6.0.2.2)
154
+ activemodel (= 6.0.2.2)
155
+ activerecord (= 6.0.2.2)
156
+ activestorage (= 6.0.2.2)
157
+ activesupport (= 6.0.2.2)
158
+ bundler (>= 1.3.0)
159
+ railties (= 6.0.2.2)
160
+ sprockets-rails (>= 2.0.0)
161
+ rails-controller-testing (1.0.4)
162
+ actionpack (>= 5.0.1.x)
163
+ actionview (>= 5.0.1.x)
164
+ activesupport (>= 5.0.1.x)
165
+ rails-dom-testing (2.0.3)
166
+ activesupport (>= 4.2.0)
167
+ nokogiri (>= 1.6)
168
+ rails-html-sanitizer (1.3.0)
169
+ loofah (~> 2.3)
170
+ railties (6.0.2.2)
171
+ actionpack (= 6.0.2.2)
172
+ activesupport (= 6.0.2.2)
173
+ method_source
174
+ rake (>= 0.8.7)
175
+ thor (>= 0.20.3, < 2.0)
176
+ rainbow (3.0.0)
177
+ rake (13.0.1)
178
+ rb-fsevent (0.10.3)
179
+ rb-inotify (0.10.1)
180
+ ffi (~> 1.0)
181
+ regexp_parser (1.7.0)
182
+ rubocop (0.71.0)
183
+ jaro_winkler (~> 1.5.1)
184
+ parallel (~> 1.10)
185
+ parser (>= 2.6)
186
+ rainbow (>= 2.2.2, < 4.0)
187
+ ruby-progressbar (~> 1.7)
188
+ unicode-display_width (>= 1.4.0, < 1.7)
189
+ ruby-progressbar (1.10.1)
190
+ ruby_dep (1.5.0)
191
+ rubyzip (2.3.0)
192
+ sass-rails (6.0.0)
193
+ sassc-rails (~> 2.1, >= 2.1.1)
194
+ sassc (2.2.1)
195
+ ffi (~> 1.9)
196
+ sassc-rails (2.1.2)
197
+ railties (>= 4.0.0)
198
+ sassc (>= 2.0)
199
+ sprockets (> 3.0)
200
+ sprockets-rails
201
+ tilt
202
+ selenium-webdriver (3.142.7)
203
+ childprocess (>= 0.5, < 4.0)
204
+ rubyzip (>= 1.2.2)
205
+ snowglobe (0.3.0)
206
+ spring (2.1.0)
207
+ spring-commands-rspec (1.0.4)
208
+ spring (>= 0.9.1)
209
+ spring-watcher-listen (2.0.1)
210
+ listen (>= 2.7, < 4.0)
211
+ spring (>= 1.2, < 3.0)
212
+ sprockets (4.0.0)
213
+ concurrent-ruby (~> 1.0)
214
+ rack (> 1, < 3)
215
+ sprockets-rails (3.2.1)
216
+ actionpack (>= 4.0)
217
+ activesupport (>= 4.0)
218
+ sprockets (>= 3.0.0)
219
+ sqlite3 (1.4.2)
220
+ test-unit (3.3.5)
221
+ power_assert
222
+ thor (1.0.1)
223
+ thread_safe (0.3.6)
224
+ tilt (2.0.10)
225
+ turbolinks (5.2.1)
226
+ turbolinks-source (~> 5.2)
227
+ turbolinks-source (5.2.0)
228
+ tzinfo (1.2.7)
229
+ thread_safe (~> 0.1)
230
+ unicode-display_width (1.6.1)
231
+ warnings_logger (0.1.0)
232
+ webdrivers (4.2.0)
233
+ nokogiri (~> 1.6)
234
+ rubyzip (>= 1.3.0)
235
+ selenium-webdriver (>= 3.0, < 4.0)
236
+ webpacker (4.2.2)
237
+ activesupport (>= 4.2)
238
+ rack-proxy (>= 0.6.1)
239
+ railties (>= 4.2)
240
+ websocket-driver (0.7.1)
241
+ websocket-extensions (>= 0.1.0)
242
+ websocket-extensions (0.1.4)
243
+ xpath (3.2.0)
244
+ nokogiri (~> 1.8)
245
+ zeitwerk (2.3.0)
246
+
247
+ PLATFORMS
248
+ ruby
249
+
250
+ DEPENDENCIES
251
+ appraisal
252
+ bcrypt (~> 3.1.7)
253
+ bootsnap (>= 1.4.2)
254
+ bundler (~> 1.0)
255
+ byebug
256
+ capybara (>= 2.15)
257
+ jbuilder (~> 2.7)
258
+ listen (>= 3.0.5, < 3.2)
259
+ m
260
+ minitest
261
+ minitest-reporters
262
+ mocha
263
+ pg (~> 1.1)
264
+ pry (~> 0.12.0)
265
+ pry-byebug (~> 3.6.0)
266
+ puma (~> 4.1)
267
+ rails (~> 6.0.2)
268
+ rails-controller-testing (>= 1.0.4)
269
+ rake
270
+ rubocop (= 0.71.0)
271
+ sass-rails (>= 6)
272
+ selenium-webdriver
273
+ shoulda-context!
274
+ snowglobe (>= 0.3.0)
275
+ spring
276
+ spring-commands-rspec
277
+ spring-watcher-listen (~> 2.0.0)
278
+ sqlite3 (~> 1.4.0)
279
+ test-unit
280
+ turbolinks (~> 5)
281
+ warnings_logger
282
+ webdrivers
283
+ webpacker (~> 4.0)
284
+
285
+ BUNDLED WITH
286
+ 1.17.3
@@ -1,20 +1,17 @@
1
- require 'shoulda/context/test_framework_detection'
2
- require 'shoulda/context/version'
3
- require 'shoulda/context/proc_extensions'
4
- require 'shoulda/context/assertions'
5
- require 'shoulda/context/context'
6
- require 'shoulda/context/autoload_macros'
1
+ require "shoulda/context/autoload_macros"
2
+ require "shoulda/context/configuration"
3
+ require "shoulda/context/context"
4
+ require "shoulda/context/dsl"
5
+ require "shoulda/context/proc_extensions"
6
+ require "shoulda/context/test_framework_detection"
7
+ require "shoulda/context/version"
8
+ require "shoulda/context/world"
7
9
 
8
- module ShouldaContextLoadable
9
- def self.included(base)
10
- base.class_eval do
11
- include Shoulda::Context::Assertions
12
- include Shoulda::Context::InstanceMethods
13
- end
14
- base.extend(Shoulda::Context::ClassMethods)
15
- end
10
+ if defined?(Rails)
11
+ require "shoulda/context/railtie"
12
+ require "shoulda/context/rails_test_unit_reporter_patch"
16
13
  end
17
14
 
18
- Shoulda::Context.test_framework_test_cases.each do |test_case|
19
- test_case.class_eval { include ShouldaContextLoadable }
15
+ Shoulda::Context.configure do |config|
16
+ config.include(Shoulda::Context::DSL)
20
17
  end
@@ -3,7 +3,7 @@ module Shoulda # :nodoc:
3
3
  module Assertions
4
4
  # Asserts that two arrays contain the same elements, the same number of times. Essentially ==, but unordered.
5
5
  #
6
- # assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes
6
+ # assert_same_elements([:a, :b, :c], [:c, :a, :b]) => passes)
7
7
  def assert_same_elements(a1, a2, msg = nil)
8
8
  [:select, :inject, :size].each do |m|
9
9
  [a1, a2].each {|a| assert_respond_to(a, m, "Are you sure that #{a.inspect} is an array? It doesn't respond to #{m}.") }
@@ -45,7 +45,8 @@ module Shoulda # :nodoc:
45
45
  end
46
46
  end
47
47
 
48
- # Asserts that the given matcher returns true when +target+ is passed to #matches?
48
+ # Asserts that the given matcher returns true when +target+ is passed to
49
+ # #matches?
49
50
  def assert_accepts(matcher, target, options = {})
50
51
  if matcher.respond_to?(:in_context)
51
52
  matcher.in_context(self)
@@ -54,33 +55,35 @@ module Shoulda # :nodoc:
54
55
  if matcher.matches?(target)
55
56
  safe_assert_block { true }
56
57
  if options[:message]
57
- message = matcher.respond_to?(:failure_message_for_should_not) ? matcher.failure_message_for_should_not : matcher.negative_failure_message
58
- assert_match options[:message], message
58
+ assert_match options[:message], matcher.failure_message_when_negated
59
59
  end
60
60
  else
61
- message = matcher.respond_to?(:failure_message_for_should) ? matcher.failure_message_for_should : matcher.failure_message
62
- safe_assert_block(message) { false }
61
+ safe_assert_block(matcher.failure_message) { false }
63
62
  end
64
63
  end
65
64
 
66
- # Asserts that the given matcher returns true when +target+ is passed to #does_not_match?
67
- # or false when +target+ is passed to #matches? if #does_not_match? is not implemented
65
+ # Asserts that the given matcher returns true when +target+ is passed to
66
+ # #does_not_match? or false when +target+ is passed to #matches? if
67
+ # #does_not_match? is not implemented
68
68
  def assert_rejects(matcher, target, options = {})
69
69
  if matcher.respond_to?(:in_context)
70
70
  matcher.in_context(self)
71
71
  end
72
72
 
73
- not_match = matcher.respond_to?(:does_not_match?) ? matcher.does_not_match?(target) : !matcher.matches?(target)
73
+ not_match =
74
+ if matcher.respond_to?(:does_not_match?)
75
+ matcher.does_not_match?(target)
76
+ else
77
+ !matcher.matches?(target)
78
+ end
74
79
 
75
80
  if not_match
76
81
  safe_assert_block { true }
77
82
  if options[:message]
78
- message = matcher.respond_to?(:failure_message_for_should) ? matcher.failure_message_for_should : matcher.failure_message
79
- assert_match options[:message], message
83
+ assert_match options[:message], matcher.failure_message
80
84
  end
81
85
  else
82
- message = matcher.respond_to?(:failure_message_for_should_not) ? matcher.failure_message_for_should_not : matcher.negative_failure_message
83
- safe_assert_block(message) { false }
86
+ safe_assert_block(matcher.failure_message_when_negated) { false }
84
87
  end
85
88
  end
86
89
 
@@ -0,0 +1,19 @@
1
+ module Shoulda
2
+ module Context
3
+ def self.configure
4
+ yield self
5
+ end
6
+
7
+ def self.include(mod)
8
+ test_framework_test_cases.each do |test_case|
9
+ test_case.class_eval { include mod }
10
+ end
11
+ end
12
+
13
+ def self.extend(mod)
14
+ test_framework_test_cases.each do |test_case|
15
+ test_case.extend(mod)
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,290 +1,6 @@
1
1
  module Shoulda
2
2
  module Context
3
- class << self
4
- def contexts # :nodoc:
5
- @contexts ||= []
6
- end
7
- attr_writer :contexts
8
-
9
- def current_context # :nodoc:
10
- self.contexts.last
11
- end
12
-
13
- def add_context(context) # :nodoc:
14
- self.contexts.push(context)
15
- end
16
-
17
- def remove_context # :nodoc:
18
- self.contexts.pop
19
- end
20
- end
21
-
22
- module ClassMethods
23
- # == Should statements
24
- #
25
- # Should statements are just syntactic sugar over normal Test::Unit test
26
- # methods. A should block contains all the normal code and assertions
27
- # you're used to seeing, with the added benefit that they can be wrapped
28
- # inside context blocks (see below).
29
- #
30
- # === Example:
31
- #
32
- # class UserTest < Test::Unit::TestCase
33
- #
34
- # def setup
35
- # @user = User.new("John", "Doe")
36
- # end
37
- #
38
- # should "return its full name"
39
- # assert_equal 'John Doe', @user.full_name
40
- # end
41
- #
42
- # end
43
- #
44
- # ...will produce the following test:
45
- # * <tt>"test: User should return its full name. "</tt>
46
- #
47
- # Note: The part before <tt>should</tt> in the test name is gleamed from the name of the Test::Unit class.
48
- #
49
- # Should statements can also take a Proc as a <tt>:before </tt>option. This proc runs after any
50
- # parent context's setups but before the current context's setup.
51
- #
52
- # === Example:
53
- #
54
- # context "Some context" do
55
- # setup { puts("I run after the :before proc") }
56
- #
57
- # should "run a :before proc", :before => lambda { puts("I run before the setup") } do
58
- # assert true
59
- # end
60
- # end
61
- #
62
- # Should statements can also wrap matchers, making virtually any matcher
63
- # usable in a macro style. The matcher's description is used to generate a
64
- # test name and failure message, and the test will pass if the matcher
65
- # matches the subject.
66
- #
67
- # === Example:
68
- #
69
- # should validate_presence_of(:first_name).with_message(/gotta be there/)
70
- #
71
-
72
- def should(name_or_matcher, options = {}, &blk)
73
- if Shoulda::Context.current_context
74
- Shoulda::Context.current_context.should(name_or_matcher, options, &blk)
75
- else
76
- context_name = self.name.gsub(/Test/, "") if self.name
77
- context = Shoulda::Context::Context.new(context_name, self) do
78
- should(name_or_matcher, options, &blk)
79
- end
80
- context.build
81
- end
82
- end
83
-
84
- # Allows negative tests using matchers. The matcher's description is used
85
- # to generate a test name and negative failure message, and the test will
86
- # pass unless the matcher matches the subject.
87
- #
88
- # === Example:
89
- #
90
- # should_not set_the_flash
91
- def should_not(matcher)
92
- if Shoulda::Context.current_context
93
- Shoulda::Context.current_context.should_not(matcher)
94
- else
95
- context_name = self.name.gsub(/Test/, "") if self.name
96
- context = Shoulda::Context::Context.new(context_name, self) do
97
- should_not(matcher)
98
- end
99
- context.build
100
- end
101
- end
102
-
103
- # == Before statements
104
- #
105
- # Before statements are should statements that run before the current
106
- # context's setup. These are especially useful when setting expectations.
107
- #
108
- # === Example:
109
- #
110
- # class UserControllerTest < Test::Unit::TestCase
111
- # context "the index action" do
112
- # setup do
113
- # @users = [Factory(:user)]
114
- # User.stubs(:find).returns(@users)
115
- # end
116
- #
117
- # context "on GET" do
118
- # setup { get :index }
119
- #
120
- # should respond_with(:success)
121
- #
122
- # # runs before "get :index"
123
- # before_should "find all users" do
124
- # User.expects(:find).with(:all).returns(@users)
125
- # end
126
- # end
127
- # end
128
- # end
129
- def before_should(name, &blk)
130
- should(name, :before => blk) { assert true }
131
- end
132
-
133
- # Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
134
- def should_eventually(name, options = {}, &blk)
135
- context_name = self.name.gsub(/Test/, "")
136
- context = Shoulda::Context::Context.new(context_name, self) do
137
- should_eventually(name, &blk)
138
- end
139
- context.build
140
- end
141
-
142
- # == Contexts
143
- #
144
- # A context block groups should statements under a common set of setup/teardown methods.
145
- # Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
146
- # and readability of your test code.
147
- #
148
- # A context block can contain setup, should, should_eventually, and teardown blocks.
149
- #
150
- # class UserTest < Test::Unit::TestCase
151
- # context "A User instance" do
152
- # setup do
153
- # @user = User.find(:first)
154
- # end
155
- #
156
- # should "return its full name"
157
- # assert_equal 'John Doe', @user.full_name
158
- # end
159
- # end
160
- # end
161
- #
162
- # This code will produce the method <tt>"test: A User instance should return its full name. "</tt>.
163
- #
164
- # Contexts may be nested. Nested contexts run their setup blocks from out to in before each
165
- # should statement. They then run their teardown blocks from in to out after each should statement.
166
- #
167
- # class UserTest < Test::Unit::TestCase
168
- # context "A User instance" do
169
- # setup do
170
- # @user = User.find(:first)
171
- # end
172
- #
173
- # should "return its full name"
174
- # assert_equal 'John Doe', @user.full_name
175
- # end
176
- #
177
- # context "with a profile" do
178
- # setup do
179
- # @user.profile = Profile.find(:first)
180
- # end
181
- #
182
- # should "return true when sent :has_profile?"
183
- # assert @user.has_profile?
184
- # end
185
- # end
186
- # end
187
- # end
188
- #
189
- # This code will produce the following methods
190
- # * <tt>"test: A User instance should return its full name. "</tt>
191
- # * <tt>"test: A User instance with a profile should return true when sent :has_profile?. "</tt>
192
- #
193
- # <b>Just like should statements, a context block can exist next to normal <tt>def test_the_old_way; end</tt>
194
- # tests</b>. This means you do not have to fully commit to the context/should syntax in a test file.
195
-
196
- def context(name, &blk)
197
- if Shoulda::Context.current_context
198
- Shoulda::Context.current_context.context(name, &blk)
199
- else
200
- context = Shoulda::Context::Context.new(name, self, &blk)
201
- context.build
202
- end
203
- end
204
-
205
- # Returns the class being tested, as determined by the test class name.
206
- #
207
- # class UserTest; described_type; end
208
- # # => User
209
- def described_type
210
- @described_type ||= self.name.
211
- gsub(/Test$/, '').
212
- split('::').
213
- inject(Object) do |parent, local_name|
214
- parent.const_get(local_name, false)
215
- end
216
- end
217
-
218
- # Sets the return value of the subject instance method:
219
- #
220
- # class UserTest < Test::Unit::TestCase
221
- # subject { User.first }
222
- #
223
- # # uses the existing user
224
- # should validate_uniqueness_of(:email)
225
- # end
226
- def subject(&block)
227
- @subject_block = block
228
- end
229
-
230
- def subject_block # :nodoc:
231
- @subject_block ||= nil
232
- end
233
- end
234
-
235
- module InstanceMethods
236
- # Returns an instance of the class under test.
237
- #
238
- # class UserTest
239
- # should "be a user" do
240
- # assert_kind_of User, subject # passes
241
- # end
242
- # end
243
- #
244
- # The subject can be explicitly set using the subject class method:
245
- #
246
- # class UserTest
247
- # subject { User.first }
248
- # should "be an existing user" do
249
- # assert !subject.new_record? # uses the first user
250
- # end
251
- # end
252
- #
253
- # The subject is used by all macros that require an instance of the class
254
- # being tested.
255
- def subject
256
- @shoulda_subject ||= construct_subject
257
- end
258
-
259
- def subject_block # :nodoc:
260
- (@shoulda_context && @shoulda_context.subject_block) || self.class.subject_block
261
- end
262
-
263
- def get_instance_of(object_or_klass) # :nodoc:
264
- if object_or_klass.is_a?(Class)
265
- object_or_klass.new
266
- else
267
- object_or_klass
268
- end
269
- end
270
-
271
- def instance_variable_name_for(klass) # :nodoc:
272
- klass.to_s.split('::').last.underscore
273
- end
274
-
275
- private
276
-
277
- def construct_subject
278
- if subject_block
279
- instance_eval(&subject_block)
280
- else
281
- get_instance_of(self.class.described_type)
282
- end
283
- end
284
- end
285
-
286
3
  class Context # :nodoc:
287
-
288
4
  attr_accessor :name # my name
289
5
  attr_accessor :parent # may be another context, or the original test::unit class.
290
6
  attr_accessor :subcontexts # array of contexts nested under myself
@@ -389,40 +105,49 @@ module Shoulda
389
105
  end
390
106
 
391
107
  def create_test_from_should_hash(should)
392
- test_name = [test_name_prefix, full_name, "should", "#{should[:name]}. "].flatten.join(' ').to_sym
108
+ test_name = build_test_name_from(should)
393
109
 
394
- if test_methods[test_unit_class][test_name.to_s] then
395
- raise DuplicateTestError, "'#{test_name}' is defined more than once."
110
+ if test_methods[test_unit_class][test_name.to_s]
111
+ raise Shoulda::Context::DuplicateTestError.new(
112
+ "'#{test_name}' is defined more than once."
113
+ )
396
114
  end
397
115
 
398
116
  test_methods[test_unit_class][test_name.to_s] = true
399
117
  file, line_no = should[:block].source_location
400
- context = self
118
+
119
+ # Ruby doesn't know that we are referring to this variable inside of the
120
+ # eval, so it will emit a warning that it's "assigned but unused".
121
+ # However, making a double assignment places `context` on the right hand
122
+ # side of the assignment, thereby putting it into use.
123
+ context = context = self
124
+
401
125
  test_unit_class.class_eval <<-end_eval, file, line_no
402
126
  define_method test_name do
403
- @shoulda_context = context
404
- begin
405
- context.run_parent_setup_blocks(self)
406
- if should[:before]
407
- if self.respond_to?(:instance_exec)
408
- self.instance_exec(&should[:before])
409
- else
410
- should[:before].bind(self).call
127
+ @shoulda_context = context
128
+ begin
129
+ context.run_parent_setup_blocks(self)
130
+ if should[:before]
131
+ instance_exec(&should[:before])
411
132
  end
133
+ context.run_current_setup_blocks(self)
134
+ instance_exec(&should[:block])
135
+ ensure
136
+ context.run_all_teardown_blocks(self)
412
137
  end
413
- context.run_current_setup_blocks(self)
414
- if self.respond_to?(:instance_exec)
415
- self.instance_exec(&should[:block])
416
- else
417
- should[:block].bind(self).call
418
- end
419
- ensure
420
- context.run_all_teardown_blocks(self)
421
- end
422
138
  end
423
139
  end_eval
424
140
  end
425
141
 
142
+ def build_test_name_from(should)
143
+ [
144
+ test_name_prefix,
145
+ full_name,
146
+ "should",
147
+ "#{should[:name]}. "
148
+ ].flatten.join(' ').to_sym
149
+ end
150
+
426
151
  def run_all_setup_blocks(binding)
427
152
  run_parent_setup_blocks(binding)
428
153
  run_current_setup_blocks(binding)
@@ -473,7 +198,7 @@ module Shoulda
473
198
  end
474
199
 
475
200
  def test_name_prefix
476
- if defined?(Minitest) || defined?(MiniTest)
201
+ if defined?(Minitest)
477
202
  'test_:'
478
203
  else
479
204
  'test:'
@@ -484,7 +209,8 @@ module Shoulda
484
209
  test_unit_class.send(method, *args, &blk)
485
210
  end
486
211
  end
212
+
213
+ class DuplicateTestError < RuntimeError; end
487
214
  end
488
215
  end
489
216
 
490
- class DuplicateTestError < RuntimeError; end