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,279 @@
1
+ require "shoulda/context/assertions"
2
+
3
+ module Shoulda
4
+ module Context
5
+ module DSL
6
+ def self.included(base)
7
+ base.class_eval do
8
+ include Assertions
9
+ include InstanceMethods
10
+ end
11
+ base.extend(ClassMethods)
12
+ end
13
+
14
+ module ClassMethods
15
+ # == Should statements
16
+ #
17
+ # Should statements are just syntactic sugar over normal Test::Unit test
18
+ # methods. A should block contains all the normal code and assertions
19
+ # you're used to seeing, with the added benefit that they can be wrapped
20
+ # inside context blocks (see below).
21
+ #
22
+ # === Example:
23
+ #
24
+ # class UserTest < Test::Unit::TestCase
25
+ #
26
+ # def setup
27
+ # @user = User.new("John", "Doe")
28
+ # end
29
+ #
30
+ # should "return its full name"
31
+ # assert_equal 'John Doe', @user.full_name
32
+ # end
33
+ #
34
+ # end
35
+ #
36
+ # ...will produce the following test:
37
+ # * <tt>"test: User should return its full name. "</tt>
38
+ #
39
+ # Note: The part before <tt>should</tt> in the test name is gleamed from the name of the Test::Unit class.
40
+ #
41
+ # Should statements can also take a Proc as a <tt>:before </tt>option. This proc runs after any
42
+ # parent context's setups but before the current context's setup.
43
+ #
44
+ # === Example:
45
+ #
46
+ # context "Some context" do
47
+ # setup { puts("I run after the :before proc") }
48
+ #
49
+ # should "run a :before proc", :before => lambda { puts("I run before the setup") } do
50
+ # assert true
51
+ # end
52
+ # end
53
+ #
54
+ # Should statements can also wrap matchers, making virtually any matcher
55
+ # usable in a macro style. The matcher's description is used to generate a
56
+ # test name and failure message, and the test will pass if the matcher
57
+ # matches the subject.
58
+ #
59
+ # === Example:
60
+ #
61
+ # should validate_presence_of(:first_name).with_message(/gotta be there/)
62
+ #
63
+
64
+ def should(name_or_matcher, options = {}, &blk)
65
+ if Shoulda::Context.current_context
66
+ Shoulda::Context.current_context.should(name_or_matcher, options, &blk)
67
+ else
68
+ context_name = self.name.gsub(/Test$/, "") if name
69
+ context = Shoulda::Context::Context.new(context_name, self) do
70
+ should(name_or_matcher, options, &blk)
71
+ end
72
+ context.build
73
+ end
74
+ end
75
+
76
+ # Allows negative tests using matchers. The matcher's description is used
77
+ # to generate a test name and negative failure message, and the test will
78
+ # pass unless the matcher matches the subject.
79
+ #
80
+ # === Example:
81
+ #
82
+ # should_not set_the_flash
83
+ def should_not(matcher)
84
+ if Shoulda::Context.current_context
85
+ Shoulda::Context.current_context.should_not(matcher)
86
+ else
87
+ context_name = self.name.gsub(/Test$/, "") if name
88
+ context = Shoulda::Context::Context.new(context_name, self) do
89
+ should_not(matcher)
90
+ end
91
+ context.build
92
+ end
93
+ end
94
+
95
+ # == Before statements
96
+ #
97
+ # Before statements are should statements that run before the current
98
+ # context's setup. These are especially useful when setting expectations.
99
+ #
100
+ # === Example:
101
+ #
102
+ # class UserControllerTest < Test::Unit::TestCase
103
+ # context "the index action" do
104
+ # setup do
105
+ # @users = [Factory(:user)]
106
+ # User.stubs(:find).returns(@users)
107
+ # end
108
+ #
109
+ # context "on GET" do
110
+ # setup { get :index }
111
+ #
112
+ # should respond_with(:success)
113
+ #
114
+ # # runs before "get :index"
115
+ # before_should "find all users" do
116
+ # User.expects(:find).with(:all).returns(@users)
117
+ # end
118
+ # end
119
+ # end
120
+ # end
121
+ def before_should(name, &blk)
122
+ should(name, :before => blk) { assert true }
123
+ end
124
+
125
+ # Just like should, but never runs, and instead prints an 'X' in the Test::Unit output.
126
+ def should_eventually(name, options = {}, &blk)
127
+ context_name = self.name.gsub(/Test$/, "")
128
+ context = Shoulda::Context::Context.new(context_name, self) do
129
+ should_eventually(name, &blk)
130
+ end
131
+ context.build
132
+ end
133
+
134
+ # == Contexts
135
+ #
136
+ # A context block groups should statements under a common set of setup/teardown methods.
137
+ # Context blocks can be arbitrarily nested, and can do wonders for improving the maintainability
138
+ # and readability of your test code.
139
+ #
140
+ # A context block can contain setup, should, should_eventually, and teardown blocks.
141
+ #
142
+ # class UserTest < Test::Unit::TestCase
143
+ # context "A User instance" do
144
+ # setup do
145
+ # @user = User.find(:first)
146
+ # end
147
+ #
148
+ # should "return its full name"
149
+ # assert_equal 'John Doe', @user.full_name
150
+ # end
151
+ # end
152
+ # end
153
+ #
154
+ # This code will produce the method <tt>"test: A User instance should return its full name. "</tt>.
155
+ #
156
+ # Contexts may be nested. Nested contexts run their setup blocks from out to in before each
157
+ # should statement. They then run their teardown blocks from in to out after each should statement.
158
+ #
159
+ # class UserTest < Test::Unit::TestCase
160
+ # context "A User instance" do
161
+ # setup do
162
+ # @user = User.find(:first)
163
+ # end
164
+ #
165
+ # should "return its full name"
166
+ # assert_equal 'John Doe', @user.full_name
167
+ # end
168
+ #
169
+ # context "with a profile" do
170
+ # setup do
171
+ # @user.profile = Profile.find(:first)
172
+ # end
173
+ #
174
+ # should "return true when sent :has_profile?"
175
+ # assert @user.has_profile?
176
+ # end
177
+ # end
178
+ # end
179
+ # end
180
+ #
181
+ # This code will produce the following methods
182
+ # * <tt>"test: A User instance should return its full name. "</tt>
183
+ # * <tt>"test: A User instance with a profile should return true when sent :has_profile?. "</tt>
184
+ #
185
+ # <b>Just like should statements, a context block can exist next to normal <tt>def test_the_old_way; end</tt>
186
+ # tests</b>. This means you do not have to fully commit to the context/should syntax in a test file.
187
+
188
+ def context(name, &blk)
189
+ if Shoulda::Context.current_context
190
+ Shoulda::Context.current_context.context(name, &blk)
191
+ else
192
+ context = Shoulda::Context::Context.new(name, self, &blk)
193
+ context.build
194
+ end
195
+ end
196
+
197
+ # Returns the class being tested, as determined by the test class name.
198
+ #
199
+ # class UserTest; described_type; end
200
+ # # => User
201
+ def described_type
202
+ @described_type ||= self.name.
203
+ gsub(/Test$/, '').
204
+ split('::').
205
+ inject(Object) do |parent, local_name|
206
+ parent.const_get(local_name, false)
207
+ end
208
+ end
209
+
210
+ # Sets the return value of the subject instance method:
211
+ #
212
+ # class UserTest < Test::Unit::TestCase
213
+ # subject { User.first }
214
+ #
215
+ # # uses the existing user
216
+ # should validate_uniqueness_of(:email)
217
+ # end
218
+ def subject(&block)
219
+ @subject_block = block
220
+ end
221
+
222
+ def subject_block # :nodoc:
223
+ @subject_block ||= nil
224
+ end
225
+ end
226
+
227
+ module InstanceMethods
228
+ # Returns an instance of the class under test.
229
+ #
230
+ # class UserTest
231
+ # should "be a user" do
232
+ # assert_kind_of User, subject # passes
233
+ # end
234
+ # end
235
+ #
236
+ # The subject can be explicitly set using the subject class method:
237
+ #
238
+ # class UserTest
239
+ # subject { User.first }
240
+ # should "be an existing user" do
241
+ # assert !subject.new_record? # uses the first user
242
+ # end
243
+ # end
244
+ #
245
+ # The subject is used by all macros that require an instance of the class
246
+ # being tested.
247
+ def subject
248
+ @shoulda_subject ||= construct_subject
249
+ end
250
+
251
+ def subject_block # :nodoc:
252
+ (@shoulda_context && @shoulda_context.subject_block) || self.class.subject_block
253
+ end
254
+
255
+ def get_instance_of(object_or_klass) # :nodoc:
256
+ if object_or_klass.is_a?(Class)
257
+ object_or_klass.new
258
+ else
259
+ object_or_klass
260
+ end
261
+ end
262
+
263
+ def instance_variable_name_for(klass) # :nodoc:
264
+ klass.to_s.split('::').last.underscore
265
+ end
266
+
267
+ private
268
+
269
+ def construct_subject
270
+ if subject_block
271
+ instance_eval(&subject_block)
272
+ else
273
+ get_instance_of(self.class.described_type)
274
+ end
275
+ end
276
+ end
277
+ end
278
+ end
279
+ end
@@ -0,0 +1,21 @@
1
+ begin
2
+ require "rails/test_unit/reporter"
3
+
4
+ Rails::TestUnitReporter.class_eval do
5
+ # Fix #format_rerun_snippet so that it works with recent versions of Minitest.
6
+ # This was cribbed from:
7
+ # <https://github.com/rails/rails/commit/ff0d5f14504f1aa29ad908ab15bab66b101427b7#diff-a071a1c8f51ce3b8bcb17ca59c79fc70>
8
+ def format_rerun_snippet(result)
9
+ location, line =
10
+ if result.respond_to?(:source_location)
11
+ result.source_location
12
+ else
13
+ result.method(result.name).source_location
14
+ end
15
+
16
+ "#{executable} #{relative_path_for(location)}:#{line}"
17
+ end
18
+ end
19
+ rescue LoadError
20
+ # Rails::TestUnitReporter was introduced in Rails 5
21
+ end
@@ -0,0 +1,14 @@
1
+ module Shoulda
2
+ module Context
3
+ class Railtie < Rails::Railtie
4
+ initializer "shoulda_context.autoload_macros" do
5
+ if Rails.env.test?
6
+ Shoulda.autoload_macros(
7
+ Rails.root,
8
+ File.join("vendor", "{plugins,gems}", "*")
9
+ )
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -3,10 +3,9 @@ module Shoulda
3
3
  module TestFrameworkDetection
4
4
  def self.possible_test_frameworks
5
5
  [
6
- lambda { ActiveSupport::TestCase },
7
- lambda { Minitest::Test },
8
- lambda { MiniTest::Unit::TestCase },
9
- lambda { Test::Unit::TestCase }
6
+ -> { ActiveSupport::TestCase },
7
+ -> { Minitest::Test },
8
+ -> { Test::Unit::TestCase }
10
9
  ]
11
10
  end
12
11
 
@@ -23,7 +22,7 @@ module Shoulda
23
22
  end
24
23
 
25
24
  def self.test_framework_test_cases
26
- @_test_framework_test_case ||= detected_test_framework_test_cases
25
+ @_test_framework_test_cases ||= detected_test_framework_test_cases
27
26
  end
28
27
  end
29
28
 
@@ -1,5 +1,5 @@
1
1
  module Shoulda
2
2
  module Context
3
- VERSION = '1.2.2'.freeze
3
+ VERSION = "2.0.0".freeze
4
4
  end
5
5
  end
@@ -0,0 +1,22 @@
1
+ module Shoulda
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
+ end
22
+ end
@@ -1,30 +1,23 @@
1
1
  # -*- encoding: utf-8 -*-
2
- $LOAD_PATH << File.join(File.dirname(__FILE__), 'lib')
3
- require 'shoulda/context/version'
2
+
3
+ $LOAD_PATH << File.join(File.dirname(__FILE__), "lib")
4
+ require "shoulda/context/version"
4
5
 
5
6
  Gem::Specification.new do |s|
6
- s.name = %q{shoulda-context}
7
+ s.name = "shoulda-context"
7
8
  s.version = Shoulda::Context::VERSION.dup
8
9
  s.platform = Gem::Platform::RUBY
9
10
  s.authors = ["thoughtbot, inc.", "Tammer Saleh", "Joe Ferris",
10
11
  "Ryan McGeary", "Dan Croak", "Matt Jankowski"]
11
- s.email = %q{support@thoughtbot.com}
12
- s.homepage = %q{http://thoughtbot.com/community/}
13
- s.summary = %q{Context framework extracted from Shoulda}
14
- s.description = %q{Context framework extracted from Shoulda}
15
- s.license = %q{MIT}
12
+ s.email = "support@thoughtbot.com"
13
+ s.homepage = "http://thoughtbot.com/community/"
14
+ s.summary = "Context framework extracted from Shoulda"
15
+ s.description = "Context framework extracted from Shoulda"
16
+ s.license = "MIT"
16
17
 
17
18
  s.files = `git ls-files`.split("\n")
18
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.executables = `git ls-files -- exe/*`.split("\n").map { |f| File.basename(f) }
21
+ s.bindir = "exe"
20
22
  s.require_paths = ["lib"]
21
-
22
- s.add_development_dependency("appraisal", "~> 0.5")
23
- s.add_development_dependency("rails", ">= 3.0")
24
- s.add_development_dependency("mocha", "~> 0.9.10")
25
- s.add_development_dependency("rake")
26
- s.add_development_dependency("test-unit", "~> 2.1.0")
27
- s.add_development_dependency("pry")
28
- s.add_development_dependency("byebug")
29
- s.add_development_dependency("pry-byebug")
30
23
  end
@@ -2,5 +2,5 @@ module CustomMacro
2
2
  def custom_macro
3
3
  end
4
4
  end
5
- Test::Unit::TestCase.extend(CustomMacro)
5
+ PARENT_TEST_CASE.extend(CustomMacro)
6
6
 
@@ -2,5 +2,4 @@ module GemMacro
2
2
  def gem_macro
3
3
  end
4
4
  end
5
- Test::Unit::TestCase.extend(GemMacro)
6
-
5
+ PARENT_TEST_CASE.extend(GemMacro)
@@ -2,5 +2,4 @@ module PluginMacro
2
2
  def plugin_macro
3
3
  end
4
4
  end
5
- Test::Unit::TestCase.extend(PluginMacro)
6
-
5
+ PARENT_TEST_CASE.extend(PluginMacro)
@@ -1,6 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class AutoloadMacroTest < Test::Unit::TestCase # :nodoc:
3
+ class AutoloadMacroTest < PARENT_TEST_CASE
4
4
  context "The macro auto-loader" do
5
5
  should "load macros from the plugins" do
6
6
  assert self.class.respond_to?('plugin_macro')
@@ -1,7 +1,6 @@
1
1
  require 'test_helper'
2
2
 
3
- class ContextTest < Test::Unit::TestCase # :nodoc:
4
-
3
+ class ContextTest < PARENT_TEST_CASE
5
4
  def self.context_macro(&blk)
6
5
  context "with a subcontext made by a macro" do
7
6
  setup { @context_macro = :foo }
@@ -20,7 +19,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
20
19
  end
21
20
 
22
21
  should "have name set right" do
23
- assert_match(/^test: context with setup block/, self.to_s)
22
+ assert_match(/^test: context with setup block/, normalized_name)
24
23
  end
25
24
 
26
25
  context "and a subcontext" do
@@ -29,7 +28,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
29
28
  end
30
29
 
31
30
  should "be named correctly" do
32
- assert_match(/^test: context with setup block and a subcontext should be named correctly/, self.to_s)
31
+ assert_match(/^test: context with setup block and a subcontext should be named correctly/, normalized_name)
33
32
  end
34
33
 
35
34
  should "run the setup blocks in order" do
@@ -39,7 +38,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
39
38
 
40
39
  context_macro do
41
40
  should "have name set right" do
42
- assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/, self.to_s)
41
+ assert_match(/^test: context with setup block with a subcontext made by a macro should have name set right/, normalized_name)
43
42
  end
44
43
 
45
44
  should "run the setup block of that context macro" do
@@ -63,7 +62,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
63
62
  end
64
63
 
65
64
  should "have name set right" do
66
- assert_match(/^test: another context with setup block/, self.to_s)
65
+ assert_match(/^test: another context with setup block/, normalized_name)
67
66
  end
68
67
  end
69
68
 
@@ -77,7 +76,7 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
77
76
  end
78
77
 
79
78
  should "have name set right" do
80
- assert_match(/^test: context with method definition/, self.to_s)
79
+ assert_match(/^test: context with method definition/, normalized_name)
81
80
  end
82
81
  end
83
82
 
@@ -166,19 +165,22 @@ class ContextTest < Test::Unit::TestCase # :nodoc:
166
165
  end
167
166
  end
168
167
 
168
+ def normalized_name
169
+ name.sub("test_:", "test:")
170
+ end
169
171
  end
170
172
 
171
173
  class ::Some
172
174
  class NestedModel; end
173
175
  end
174
176
 
175
- class Some::NestedModelTest < Test::Unit::TestCase
177
+ class Some::NestedModelTest < PARENT_TEST_CASE
176
178
  should "determine the described type for a nested model" do
177
179
  assert_equal Some::NestedModel, self.class.described_type
178
180
  end
179
181
  end
180
182
 
181
- class Some::SomeTest < Test::Unit::TestCase
183
+ class Some::SomeTest < PARENT_TEST_CASE
182
184
  should "not fallback to higher-level constants with same name" do
183
185
  assert_raises(NameError) do
184
186
  assert_equal nil, self.class.described_type
@@ -186,13 +188,13 @@ class Some::SomeTest < Test::Unit::TestCase
186
188
  end
187
189
  end
188
190
 
189
- class ShouldMatcherTest < Test::Unit::TestCase
191
+ class ShouldMatcherTest < PARENT_TEST_CASE
190
192
  class FakeMatcher
191
193
  attr_reader :subject
192
194
  attr_accessor :fail
193
195
 
194
196
  def description
195
- "do something"
197
+ "be a fake matcher"
196
198
  end
197
199
 
198
200
  def matches?(subject)
@@ -200,46 +202,33 @@ class ShouldMatcherTest < Test::Unit::TestCase
200
202
  !@fail
201
203
  end
202
204
 
203
- def failure_message_for_should
204
- "failure message for should"
205
+ def failure_message
206
+ "positive failure message"
205
207
  end
206
208
 
207
- def failure_message_for_should_not
208
- "failure message for should not"
209
+ def failure_message_when_negated
210
+ "negative failure message"
209
211
  end
210
212
  end
211
213
 
212
- def run_test_suite
213
- @test_suite.run(@test_result) { |event, name| }
214
- end
215
-
216
214
  def setup
217
215
  @matcher = FakeMatcher.new
218
- @test_result = Test::Unit::TestResult.new
219
- class << @test_result
220
- def failure_messages
221
- @failures.map { |failure| failure.message }
222
- end
223
- end
224
- end
225
-
226
- def create_test_suite(&definition)
227
- test_class = Class.new(Test::Unit::TestCase, &definition)
228
- test_class.suite
229
216
  end
230
217
 
231
- def assert_failed_with(message, test_result)
232
- assert_equal 1, test_result.failure_count
233
- assert_equal [message], test_result.failure_messages
218
+ def assert_failed_with(message, test_suite)
219
+ assert_equal [message], test_suite.failure_messages
234
220
  end
235
221
 
236
- def assert_passed(test_result)
237
- assert_equal 0, test_result.failure_count
222
+ def assert_passed(test_suite)
223
+ assert_equal [], test_suite.failure_messages
238
224
  end
239
225
 
240
226
  def assert_test_named(expected_name, test_suite)
241
- name = test_suite.tests.map { |test| test.method_name }.first
242
- assert name.include?(expected_name), "Expected #{name} to include #{expected_name}"
227
+ name = test_suite.test_names.first
228
+ assert(
229
+ name.include?(expected_name),
230
+ "Expected #{name} to include #{expected_name}"
231
+ )
243
232
  end
244
233
 
245
234
  def self.should_use_positive_matcher
@@ -249,19 +238,19 @@ class ShouldMatcherTest < Test::Unit::TestCase
249
238
 
250
239
  should "pass with a passing matcher" do
251
240
  @matcher.fail = false
252
- run_test_suite
253
- assert_passed @test_result
241
+ @test_suite.run
242
+ assert_passed @test_suite
254
243
  end
255
244
 
256
245
  should "fail with a failing matcher" do
257
246
  @matcher.fail = true
258
- run_test_suite
259
- assert_failed_with "failure message for should", @test_result
247
+ @test_suite.run
248
+ assert_failed_with "positive failure message", @test_suite
260
249
  end
261
250
 
262
251
  should "provide the subject" do
263
252
  @matcher.fail = false
264
- run_test_suite
253
+ @test_suite.run
265
254
  assert_equal 'a subject', @matcher.subject
266
255
  end
267
256
  end
@@ -273,19 +262,19 @@ class ShouldMatcherTest < Test::Unit::TestCase
273
262
 
274
263
  should "pass with a failing matcher" do
275
264
  @matcher.fail = true
276
- run_test_suite
277
- assert_passed @test_result
265
+ @test_suite.run
266
+ assert_passed @test_suite
278
267
  end
279
268
 
280
269
  should "fail with a passing matcher" do
281
270
  @matcher.fail = false
282
- run_test_suite
283
- assert_failed_with "failure message for should not", @test_result
271
+ @test_suite.run
272
+ assert_failed_with "negative failure message", @test_suite
284
273
  end
285
274
 
286
275
  should "provide the subject" do
287
276
  @matcher.fail = false
288
- run_test_suite
277
+ @test_suite.run
289
278
  assert_equal 'a subject', @matcher.subject
290
279
  end
291
280
  end
@@ -293,7 +282,7 @@ class ShouldMatcherTest < Test::Unit::TestCase
293
282
  context "a should block with a matcher" do
294
283
  setup do
295
284
  matcher = @matcher
296
- @test_suite = create_test_suite do
285
+ @test_suite = TestSuite.create do
297
286
  subject { 'a subject' }
298
287
  should matcher
299
288
  end
@@ -305,7 +294,7 @@ class ShouldMatcherTest < Test::Unit::TestCase
305
294
  context "a should block with a matcher within a context" do
306
295
  setup do
307
296
  matcher = @matcher
308
- @test_suite = create_test_suite do
297
+ @test_suite = TestSuite.create do
309
298
  context "in context" do
310
299
  subject { 'a subject' }
311
300
  should matcher
@@ -319,7 +308,7 @@ class ShouldMatcherTest < Test::Unit::TestCase
319
308
  context "a should_not block with a matcher" do
320
309
  setup do
321
310
  matcher = @matcher
322
- @test_suite = create_test_suite do
311
+ @test_suite = TestSuite.create do
323
312
  subject { 'a subject' }
324
313
  should_not matcher
325
314
  end
@@ -331,7 +320,7 @@ class ShouldMatcherTest < Test::Unit::TestCase
331
320
  context "a should_not block with a matcher within a context" do
332
321
  setup do
333
322
  matcher = @matcher
334
- @test_suite = create_test_suite do
323
+ @test_suite = TestSuite.create do
335
324
  context "in context" do
336
325
  subject { 'a subject' }
337
326
  should_not matcher
@@ -341,11 +330,61 @@ class ShouldMatcherTest < Test::Unit::TestCase
341
330
 
342
331
  should_use_negative_matcher
343
332
  end
333
+
334
+ class TestSuite
335
+ def self.create(&definition)
336
+ if defined?(Test::Unit)
337
+ TestUnitSuite.new(&definition)
338
+ else
339
+ MinitestSuite.new(&definition)
340
+ end
341
+ end
342
+ end
343
+
344
+ class TestUnitSuite
345
+ def initialize(&definition)
346
+ @suite = Class.new(Test::Unit::TestCase, &definition).suite
347
+ @result = Test::Unit::TestResult.new
348
+ end
349
+
350
+ def run
351
+ @suite.run(@result) do |event, name|
352
+ # do nothing
353
+ end
354
+ end
355
+
356
+ def failure_messages
357
+ @result.failures.map(&:message)
358
+ end
359
+
360
+ def test_names
361
+ @suite.tests.map(&:method_name)
362
+ end
363
+ end
364
+
365
+ class MinitestSuite
366
+ def initialize(&definition)
367
+ @test_case_class = Class.new(Minitest::Test, &definition)
368
+ @reporter = Minitest::StatisticsReporter.new(StringIO.new)
369
+ end
370
+
371
+ def run
372
+ @test_case_class.run(@reporter)
373
+ end
374
+
375
+ def failure_messages
376
+ @reporter.results.flat_map(&:failures).map(&:message)
377
+ end
378
+
379
+ def test_names
380
+ @test_case_class.runnable_methods
381
+ end
382
+ end
344
383
  end
345
384
 
346
385
  class Subject; end
347
386
 
348
- class SubjectTest < Test::Unit::TestCase
387
+ class SubjectTest < PARENT_TEST_CASE
349
388
 
350
389
  def setup
351
390
  @expected = Subject.new
@@ -358,7 +397,7 @@ class SubjectTest < Test::Unit::TestCase
358
397
  end
359
398
  end
360
399
 
361
- class SubjectLazinessTest < Test::Unit::TestCase
400
+ class SubjectLazinessTest < PARENT_TEST_CASE
362
401
  subject { Subject.new }
363
402
 
364
403
  should "only build the subject once" do