shoulda-context 1.2.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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