hardmock 1.3.5 → 1.3.6

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ Hardmock 1.3.6
2
+
3
+ * BUG FIX: In Rails apps (and others) Hardmock and Fixtures battled viciously over "setup" and "teardown" and "method_added" (and any other clever test enhancement tool, namely Mocha) causing unpredictable results, notably failure to auto-verify mocks after teardown (leading to false positive tests).
4
+ ** The newly-added TestUnitBeforeAfter provides TestCase.before_setup and TestCase.after_teardown -- formal test wrapping hooks -- lets Hardmock provide its preparation and auto-verify behavior without contending for setup/teardown supremacy.
5
+
1
6
  Hardmock 1.3.5
2
7
 
3
8
  * Aliased should_receive => expects and and_return => returns for easier transition from rspec mock and flexmock users.
data/Rakefile CHANGED
@@ -1,7 +1,7 @@
1
1
  require 'rake'
2
2
  require 'rubygems'
3
3
 
4
- HARDMOCK_VERSION = "1.3.5"
4
+ HARDMOCK_VERSION = "1.3.6"
5
5
 
6
6
  Dir["rake_tasks/*.rake"].each { |f| load f }
7
7
 
@@ -0,0 +1,14 @@
1
+
2
+ require 'test/unit/testcase'
3
+ class Test::Unit::TestCase
4
+ include Hardmock
5
+ end
6
+
7
+ require 'test_unit_before_after'
8
+ Test::Unit::TestCase.before_setup do |test|
9
+ test.prepare_hardmock_control
10
+ end
11
+
12
+ Test::Unit::TestCase.after_teardown do |test|
13
+ test.verify_mocks
14
+ end
data/lib/hardmock.rb CHANGED
@@ -9,92 +9,8 @@ require 'hardmock/expectation'
9
9
  require 'hardmock/expectation_builder'
10
10
  require 'hardmock/stubbing'
11
11
 
12
-
13
12
  module Hardmock
14
13
 
15
- # Setup auto mock verification on teardown, being careful not to interfere
16
- # with inherited, pre-mixed or post-added user teardowns.
17
- def self.included(base) #:nodoc:#
18
- base.class_eval do
19
- # Core of our actual setup behavior
20
- def hardmock_setup
21
- prepare_hardmock_control
22
- end
23
-
24
- # Core of our actual teardown behavior
25
- def hardmock_teardown
26
- verify_mocks
27
- end
28
-
29
- # disable until later:
30
- def self.method_added(symbol) #:nodoc:
31
- end
32
-
33
- if method_defined?(:setup) then
34
- # Wrap existing setup
35
- alias_method :old_setup, :setup
36
- define_method(:new_setup) do
37
- begin
38
- hardmock_setup
39
- ensure
40
- old_setup
41
- end
42
- end
43
- else
44
- # We don't need to account for previous setup
45
- define_method(:new_setup) do
46
- hardmock_setup
47
- end
48
- end
49
- alias_method :setup, :new_setup
50
-
51
- if method_defined?(:teardown) then
52
- # Wrap existing teardown
53
- alias_method :old_teardown, :teardown
54
- define_method(:new_teardown) do
55
- begin
56
- hardmock_teardown
57
- ensure
58
- old_teardown
59
- end
60
- end
61
- else
62
- # We don't need to account for previous teardown
63
- define_method(:new_teardown) do
64
- hardmock_teardown
65
- end
66
- end
67
- alias_method :teardown, :new_teardown
68
-
69
- def self.method_added(method) #:nodoc:
70
- case method
71
- when :teardown
72
- unless method_defined?(:user_teardown)
73
- alias_method :user_teardown, :teardown
74
- define_method(:teardown) do
75
- begin
76
- new_teardown
77
- ensure
78
- user_teardown
79
- end
80
- end
81
- end
82
- when :setup
83
- unless method_defined?(:user_setup)
84
- alias_method :user_setup, :setup
85
- define_method(:setup) do
86
- begin
87
- new_setup
88
- ensure
89
- user_setup
90
- end
91
- end
92
- end
93
- end
94
- end
95
- end
96
- end
97
-
98
14
  # Create one or more new Mock instances in your test suite.
99
15
  # Once created, the Mocks are accessible as instance variables in your test.
100
16
  # Newly built Mocks are added to the full set of Mocks for this test, which will
@@ -167,10 +83,4 @@ module Hardmock
167
83
 
168
84
  end
169
85
 
170
- # Insert Hardmock functionality into the TestCase base class
171
- require 'test/unit/testcase'
172
- unless Test::Unit::TestCase.instance_methods.include?('hardmock_teardown')
173
- class Test::Unit::TestCase #:nodoc:#
174
- include Hardmock
175
- end
176
- end
86
+ require 'extend_test_unit'
@@ -0,0 +1,170 @@
1
+ require 'test/unit'
2
+ require 'test/unit/testcase'
3
+ require 'test/unit/assertions'
4
+
5
+ module Test #:nodoc:#
6
+ module Unit #:nodoc:#
7
+
8
+ # == TestCase Modifications
9
+ #
10
+ # Monkey-patch to provide a formal mechanism for appending actions to be executed after teardown.
11
+ # Use after_teardown to define one or more actions to be executed after teardown for ALL tests.
12
+ #
13
+ # COMING SOON?
14
+ # * Hook for running actions prior to setup
15
+ # * Hooks for before_teardown, after_setup, on_error
16
+ # * Options for positional control, eg, after_teardown :before_other_actions
17
+ # * Provide tagging/filtering so action execution can be controlled specifically?
18
+ #
19
+ # == Usage
20
+ #
21
+ # Invoke TestCase.after_teardown with optional parameter, which will be invoked with a reference
22
+ # to the test instance that has just been torn down.
23
+ #
24
+ # Example:
25
+ #
26
+ # Test::Unit::TestCase.after_teardown do |test|
27
+ # test.verify_mocks
28
+ # end
29
+ #
30
+ # == Justification
31
+ #
32
+ # There are a number of tools and libraries that play fast-n-loose with setup and teardown by
33
+ # wrapping them, and by overriding method_added as a means of upholding special setup/teardown
34
+ # behavior, usually by re-wrapping newly defined user-level setup/teardown methods.
35
+ # mocha and active_record/fixtures (and previously, hardmock) will fight for this
36
+ # territory with often unpredictable results.
37
+ #
38
+ # We wouldn't have to battle if Test::Unit provided a formal pre- and post- hook mechanism.
39
+ #
40
+ class TestCase
41
+
42
+ class << self
43
+
44
+ # Define an action to be run after teardown. Subsequent calls result in
45
+ # multiple actions. The block will be given a reference to the test
46
+ # being executed.
47
+ #
48
+ # Example:
49
+ #
50
+ # Test::Unit::TestCase.after_teardown do |test|
51
+ # test.verify_mocks
52
+ # end
53
+ def after_teardown(&block)
54
+ post_teardown_actions << block
55
+ end
56
+
57
+ # Used internally. Access the list of post teardown actions for to be
58
+ # used by all tests.
59
+ def post_teardown_actions
60
+ @@post_teardown_actions ||= []
61
+ end
62
+
63
+ # Define an action to be run before setup. Subsequent calls result in
64
+ # multiple actions, EACH BEING PREPENDED TO THE PREVIOUS.
65
+ # The block will be given a reference to the test being executed.
66
+ #
67
+ # Example:
68
+ #
69
+ # Test::Unit::TestCase.before_setup do |test|
70
+ # test.prepare_hardmock_control
71
+ # end
72
+ def before_setup(&block)
73
+ pre_setup_actions.unshift block
74
+ end
75
+
76
+ # Used internally. Access the list of post teardown actions for to be
77
+ # used by all tests.
78
+ def pre_setup_actions
79
+ @@pre_setup_actions ||= []
80
+ end
81
+ end
82
+
83
+ # OVERRIDE: This is a reimplementation of the default "run", updated to
84
+ # execute actions after teardown.
85
+ def run(result)
86
+ yield(STARTED, name)
87
+ @_result = result
88
+ begin
89
+ execute_pre_setup_actions(self)
90
+ setup
91
+ __send__(@method_name)
92
+ rescue Test::Unit::AssertionFailedError => e
93
+ add_failure(e.message, auxiliary_backtrace_filter(e.backtrace))
94
+ rescue Exception
95
+ raise if should_passthru_exception($!) # See implementation; this is for pre-1.8.6 compat
96
+ add_error($!)
97
+ ensure
98
+ begin
99
+ teardown
100
+ rescue Test::Unit::AssertionFailedError => e
101
+ add_failure(e.message, auxiliary_backtrace_filter(e.backtrace))
102
+ rescue Exception
103
+ raise if should_passthru_exception($!) # See implementation; this is for pre-1.8.6 compat
104
+ add_error($!)
105
+ ensure
106
+ execute_post_teardown_actions(self)
107
+ end
108
+ end
109
+ result.add_run
110
+ yield(FINISHED, name)
111
+ end
112
+
113
+ private
114
+
115
+ # Run through the after_teardown actions, treating failures and errors
116
+ # in the same way that "run" does: they are reported, and the remaining
117
+ # actions are executed.
118
+ def execute_post_teardown_actions(test_instance)
119
+ self.class.post_teardown_actions.each do |action|
120
+ begin
121
+ action.call test_instance
122
+ rescue Test::Unit::AssertionFailedError => e
123
+ add_failure(e.message, auxiliary_backtrace_filter(e.backtrace))
124
+ rescue Exception
125
+ raise if should_passthru_exception($!)
126
+ add_error($!)
127
+ end
128
+ end
129
+ end
130
+
131
+ # Run through the before_setup actions.
132
+ # Failures or errors cause execution to stop.
133
+ def execute_pre_setup_actions(test_instance)
134
+ self.class.pre_setup_actions.each do |action|
135
+ # begin
136
+ action.call test_instance
137
+ # rescue Test::Unit::AssertionFailedError => e
138
+ # add_failure(e.message, auxiliary_backtrace_filter(e.backtrace))
139
+ # rescue Exception
140
+ # raise if should_passthru_exception($!)
141
+ # add_error($!)
142
+ # end
143
+ end
144
+ end
145
+
146
+ # Make sure that this extension doesn't show up in failure backtraces
147
+ def auxiliary_backtrace_filter(trace)
148
+ trace.reject { |x| x =~ /test_unit_before_after/ }
149
+ end
150
+
151
+ # Is the given error of the type that we allow to fly out (rather than catching it)?
152
+ def should_passthru_exception(ex)
153
+ return passthrough_exception_types.include?($!.class)
154
+ end
155
+
156
+ # Provide a list of exception types that are to be allowed to explode out.
157
+ # Pre-ruby-1.8.6 doesn't use this functionality, so the PASSTHROUGH_EXCEPTIONS
158
+ # constant won't be defined. This methods defends against that and returns
159
+ # an empty list instead.
160
+ def passthrough_exception_types
161
+ begin
162
+ return PASSTHROUGH_EXCEPTIONS
163
+ rescue NameError
164
+ # older versions of test/unit do not have PASSTHROUGH_EXCEPTIONS constant
165
+ return []
166
+ end
167
+ end
168
+ end
169
+ end
170
+ end
@@ -51,7 +51,6 @@ class AutoVerifyTest < Test::Unit::TestCase
51
51
  end
52
52
 
53
53
  it "is quiet when verification is ok" do
54
- # def test_should_not_raise_error_if_verification_goes_according_to_plan
55
54
  @test_code =<<-EOM
56
55
  def test_ok
57
56
  create_mock :automobile
@@ -71,14 +70,13 @@ class AutoVerifyTest < Test::Unit::TestCase
71
70
  assert_output_contains(/User teardown/)
72
71
  end
73
72
 
74
- should "not auto-verify if user teardown explodes" do
75
- # def test_should_not_do_verification_if_user_teardown_explodes
73
+ should "auto-verify even if user teardown explodes" do
76
74
  @teardown_code =<<-EOM
77
75
  def teardown
78
76
  raise "self destruct"
79
77
  end
80
78
  EOM
81
- @expect_unmet_expectations = false
79
+ @expect_errors = 2
82
80
  write_and_execute_test
83
81
  assert_output_contains(/self destruct/)
84
82
  end
@@ -103,29 +101,6 @@ class AutoVerifyTest < Test::Unit::TestCase
103
101
  assert_output_contains(/Test helper teardown/)
104
102
  end
105
103
 
106
- it "plays nice with inherited and user-defined teardowns at the same time" do
107
- @full_code ||=<<-EOTEST
108
- require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
109
- class Test::Unit::TestCase
110
- def teardown
111
- puts "Test helper teardown"
112
- end
113
- end
114
- require 'hardmock' # IMPORTANT TO DO THIS HERE, between the old and new teardown defs
115
- class DummyTest < Test::Unit::TestCase
116
- def teardown
117
- puts "User teardown"
118
- end
119
- def test_prepare_to_die
120
- create_mock :automobile
121
- @automobile.expects.start
122
- end
123
- end
124
- EOTEST
125
- write_and_execute_test
126
- assert_output_contains(/Test helper teardown/, /User teardown/)
127
- end
128
-
129
104
  #
130
105
  # HELPERS
131
106
  #
@@ -139,18 +114,29 @@ class AutoVerifyTest < Test::Unit::TestCase
139
114
  @test_output = `ruby #{temp_test_file} 2>&1`
140
115
  end
141
116
 
117
+ def formatted_test_output
118
+ if @test_output
119
+ @test_output.split(/\n/).map { |line| "> #{line}" }.join("\n")
120
+ else
121
+ "(NO TEST OUTPUT!)"
122
+ end
123
+ end
124
+
142
125
  def remove_temp_test_file
143
126
  FileUtils::rm_f temp_test_file
144
127
  end
145
128
 
146
129
  def assert_results(h)
147
- assert_match(/#{h[:tests]} tests, [0-9]+ assertions, #{h[:failures]} failures, #{h[:errors]} errors/,
148
- @test_output)
130
+ if @test_output !~ /#{h[:tests]} tests, [0-9]+ assertions, #{h[:failures]} failures, #{h[:errors]} errors/
131
+ flunk "Test results didn't match #{h.inspect}:\n#{formatted_test_output}"
132
+ end
149
133
  end
150
134
 
151
135
  def assert_output_contains(*patterns)
152
136
  patterns.each do |pattern|
153
- assert_match(pattern,@test_output)
137
+ if @test_output !~ pattern
138
+ flunk "Test output didn't match #{pattern.inspect}:\n#{formatted_test_output}"
139
+ end
154
140
  end
155
141
  end
156
142
 
data/test/test_helper.rb CHANGED
@@ -33,9 +33,6 @@ class Test::Unit::TestCase
33
33
  tname = self.name.sub(/Test$/,'')
34
34
  if block
35
35
  define_method "test #{prefix} #{str}" do
36
- # phrase = str
37
- # phrase = prefix + " " + phrase unless prefix == "it"
38
- # puts "#{tname} #{phrase}..."
39
36
  instance_eval &block
40
37
  end
41
38
  else
@@ -0,0 +1,452 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../test_helper")
2
+
3
+ class TestUnitBeforeAfter < Test::Unit::TestCase
4
+
5
+ #
6
+ # after_teardown
7
+ #
8
+
9
+ it "adds TestCase.after_teardown hook for appending post-teardown actions" do
10
+ write_and_run_test :use_after_teardown => true
11
+
12
+ see_in_order "Loaded suite",
13
+ "THE SETUP",
14
+ "A TEST",
15
+ "THE TEARDOWN",
16
+ "1st after_teardown",
17
+ "2nd after_teardown",
18
+ "Finished in"
19
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 0
20
+ end
21
+
22
+ should "execute all after_teardowns, even if the main teardown flunks" do
23
+ write_and_run_test :use_after_teardown => true, :flunk_in_teardown => true
24
+ see_in_order "Loaded suite",
25
+ "THE SETUP",
26
+ "A TEST",
27
+ "F",
28
+ "1st after_teardown",
29
+ "2nd after_teardown",
30
+ "Finished in",
31
+ "1) Failure:",
32
+ "test_something(MyExampleTest) [_test_file_temp.rb:20]:",
33
+ "FLUNK IN TEARDOWN"
34
+ see_results :tests => 1, :assertions => 1, :failures => 1, :errors => 0
35
+ end
36
+
37
+ should "execute all after_teardowns, even if the main teardown explodes" do
38
+ write_and_run_test :use_after_teardown => true, :raise_in_teardown => true
39
+ see_in_order "Loaded suite",
40
+ "THE SETUP",
41
+ "A TEST",
42
+ "E",
43
+ "1st after_teardown",
44
+ "2nd after_teardown",
45
+ "Finished in",
46
+ "RuntimeError: ERROR IN TEARDOWN"
47
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 1
48
+ end
49
+
50
+ should "execute all after_teardowns, even if some of them flunk" do
51
+ write_and_run_test :use_after_teardown => true, :flunk_in_after_teardown => true
52
+ see_in_order "Loaded suite",
53
+ "THE SETUP",
54
+ "A TEST",
55
+ "THE TEARDOWN",
56
+ "1st after_teardown",
57
+ "F",
58
+ "2nd after_teardown",
59
+ "Finished in",
60
+ "1) Failure:",
61
+ "test_something(MyExampleTest) [_test_file_temp.rb:7]:",
62
+ "Flunk in first after_teardown",
63
+ "2) Failure:",
64
+ "test_something(MyExampleTest) [_test_file_temp.rb:10]:",
65
+ "Flunk in second after_teardown"
66
+ see_results :tests => 1, :assertions => 2, :failures => 2, :errors => 0
67
+ end
68
+
69
+ should "execute all after_teardowns, even if some of them explode" do
70
+ write_and_run_test :use_after_teardown => true, :raise_in_after_teardown => true
71
+ see_in_order "Loaded suite",
72
+ "THE SETUP",
73
+ "A TEST",
74
+ "THE TEARDOWN",
75
+ "1st after_teardown",
76
+ "E",
77
+ "2nd after_teardown",
78
+ "Finished in",
79
+ "RuntimeError: Error in first after_teardown",
80
+ "RuntimeError: Error in second after_teardown"
81
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 2
82
+ end
83
+
84
+ it "will run after_teardowns in the absence of a regular teardown" do
85
+ write_and_run_test :omit_teardown => true, :use_after_teardown => true
86
+ see_in_order "Loaded suite",
87
+ "THE SETUP",
88
+ "A TEST",
89
+ "1st after_teardown",
90
+ "2nd after_teardown",
91
+ "Finished in"
92
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 0
93
+ end
94
+
95
+ should "not interfere with normal test writing" do
96
+ write_and_run_test
97
+ see_in_order "Loaded suite",
98
+ "THE SETUP",
99
+ "A TEST",
100
+ "THE TEARDOWN",
101
+ "Finished in"
102
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 0
103
+ end
104
+
105
+ it "provides a cleaned-up backtrace" do
106
+ write_and_run_test :with_failure => true
107
+ see_in_order "Loaded suite",
108
+ "THE SETUP",
109
+ "A FAILING TEST",
110
+ "F", "THE TEARDOWN",
111
+ "Finished in",
112
+ "1) Failure:",
113
+ "test_something(MyExampleTest) [_test_file_temp.rb:17]:",
114
+ "Instrumented failure.",
115
+ "<false> is not true."
116
+ see_results :tests => 1, :assertions => 1, :failures => 1, :errors => 0
117
+ end
118
+
119
+ it "provides a cleaned-up backtrace, but not TOO cleaned up" do
120
+ write_and_run_test :with_failure => true, :use_helpers => true
121
+ see_in_order "Loaded suite",
122
+ "THE SETUP",
123
+ "A FAILING TEST",
124
+ "F", "THE TEARDOWN",
125
+ "Finished in",
126
+ "1) Failure:",
127
+ "test_something(MyExampleTest)\n",
128
+ "[_test_file_temp.rb:25:in `tripwire'",
129
+ "_test_file_temp.rb:21:in `my_helper'",
130
+ "_test_file_temp.rb:17:in `test_something']:",
131
+ "Instrumented failure.",
132
+ "<false> is not true."
133
+ see_results :tests => 1, :assertions => 1, :failures => 1, :errors => 0
134
+ end
135
+
136
+ should "not interfere with passthrough exception types" do
137
+ if is_modern_test_unit?
138
+ write_and_run_test :raise_nasty_in_test => true
139
+ see_in_no_particular_order "Loaded suite",
140
+ "THE TEARDOWN",
141
+ "_test_file_temp.rb:16:in `test_something': NASTY ERROR (NoMemoryError)"
142
+ see_no_results
143
+ end
144
+ end
145
+
146
+ #
147
+ # before_setup
148
+ #
149
+
150
+ it "adds TestCase.before_setup hook for prepending pre-setup actions" do
151
+ write_and_run_test :use_before_setup => true
152
+ see_in_order "Loaded suite",
153
+ "3rd before_setup",
154
+ "2nd before_setup",
155
+ "1st before_setup",
156
+ "THE SETUP",
157
+ "A TEST",
158
+ "THE TEARDOWN",
159
+ "Finished in"
160
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 0
161
+ end
162
+
163
+ should "stop executing the test on the first failure withing a before_setup action" do
164
+ write_and_run_test :use_before_setup => true, :flunk_in_before_setup => true
165
+ see_in_order "Loaded suite",
166
+ "3rd before_setup",
167
+ "2nd before_setup",
168
+ "FTHE TEARDOWN",
169
+ "1) Failure:",
170
+ "test_something(MyExampleTest) [_test_file_temp.rb:10]:",
171
+ "Flunk in 2nd before_setup."
172
+ see_results :tests => 1, :assertions => 1, :failures => 1, :errors => 0
173
+ end
174
+
175
+ should "stop executing the test on the first error within a before_setup action" do
176
+ write_and_run_test :use_before_setup => true, :raise_in_before_setup => true
177
+ see_in_order "Loaded suite",
178
+ "3rd before_setup",
179
+ "2nd before_setup",
180
+ "ETHE TEARDOWN",
181
+ "Finished in",
182
+ "test_something(MyExampleTest):",
183
+ "RuntimeError: Error in 2nd before_setup",
184
+ "_test_file_temp.rb:10",
185
+ "/hardmock/lib/test_unit_before_after.rb:136:in `call'"
186
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 1
187
+ end
188
+
189
+ it "will run before_setup actions in the absence of a regular setup" do
190
+ write_and_run_test :omit_setup => true, :use_before_setup => true
191
+ see_in_order "Loaded suite",
192
+ "3rd before_setup",
193
+ "2nd before_setup",
194
+ "1st before_setup",
195
+ "A TEST",
196
+ "THE TEARDOWN",
197
+ "Finished in"
198
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 0
199
+ end
200
+
201
+ it "allows before_setup and after_teardown to be used at the same time" do
202
+ write_and_run_test :use_before_setup => true, :use_after_teardown => true
203
+ see_in_order "Loaded suite",
204
+ "3rd before_setup",
205
+ "2nd before_setup",
206
+ "1st before_setup",
207
+ "A TEST",
208
+ "THE TEARDOWN",
209
+ "1st after_teardown",
210
+ "2nd after_teardown",
211
+ "Finished in"
212
+ see_results :tests => 1, :assertions => 0, :failures => 0, :errors => 0
213
+ end
214
+
215
+ #
216
+ # HELPERS
217
+ #
218
+
219
+ def teardown
220
+ remove_test
221
+ end
222
+
223
+ def test_filename
224
+ "_test_file_temp.rb"
225
+ end
226
+
227
+ def remove_test
228
+ rm_f test_filename
229
+ end
230
+
231
+ def write_and_run_test(opts={})
232
+ write(test_filename, generate_test_code(opts))
233
+ run_test
234
+ end
235
+
236
+ def run_test
237
+ @output = `ruby #{test_filename} 2>&1`
238
+ end
239
+
240
+
241
+ def write(fname, code)
242
+ File.open(fname,"w") do |f|
243
+ f.print code
244
+ end
245
+ end
246
+
247
+ def show_output
248
+ puts "-- BEGIN TEST OUTPUT"
249
+ puts @output
250
+ puts "-- END TEST OUTPUT"
251
+ end
252
+
253
+ def see_in_order(*phrases)
254
+ idx = 0
255
+ phrases.each do |txt|
256
+ idx = @output.index(txt, idx)
257
+ if idx.nil?
258
+ if @output.index(txt)
259
+ flunk "Phrase '#{txt}' is out-of-order in test output:\n#{@output}"
260
+ else
261
+ flunk "Phrase '#{txt}' not found in test output:\n#{@output}"
262
+ end
263
+ end
264
+ end
265
+ end
266
+
267
+ def see_in_no_particular_order(*phrases)
268
+ phrases.each do |txt|
269
+ assert_not_nil @output.index(txt), "Didn't see '#{txt}' in test output:\n#{@output}"
270
+ end
271
+ end
272
+
273
+ def see_results(opts)
274
+ if @output =~ /(\d+) tests, (\d+) assertions, (\d+) failures, (\d+) errors/
275
+ tests, assertions, failures, errors = [ $1, $2, $3, $4 ]
276
+ [:tests, :assertions, :failures, :errors].each do |key|
277
+ eval %{assert_equal(opts[:#{key}].to_s, #{key}, "Wrong number of #{key} in report") if opts[:#{key}]}
278
+ end
279
+ else
280
+ flunk "Didn't see the test results report line"
281
+ end
282
+ end
283
+
284
+ def see_no_results
285
+ if @output =~ /\d+ tests, \d+ assertions, \d+ failures, \d+ errors/
286
+ flunk "Should not have had a results line:\n#{@output}"
287
+ end
288
+ end
289
+
290
+ def lib_dir
291
+ File.expand_path(File.dirname(__FILE__) + "/../../lib")
292
+ end
293
+
294
+ def generate_test_code(opts={})
295
+
296
+ if opts[:with_failure] or opts[:raise_nasty_in_test]
297
+ test_method_code = generate_failing_test("test_something", opts)
298
+ else
299
+ test_method_code = generate_passing_test("test_something")
300
+ end
301
+
302
+
303
+ requires_for_ext = ''
304
+ if opts[:use_before_setup] or opts[:use_after_teardown]
305
+ requires_for_ext =<<-RFE
306
+ $: << "#{lib_dir}"
307
+ require 'test_unit_before_after'
308
+ RFE
309
+ end
310
+
311
+ before_setups = ''
312
+ if opts[:use_before_setup]
313
+ add_on_two = ""
314
+ if opts[:flunk_in_before_setup]
315
+ add_on_two = %{; test.flunk "Flunk in 2nd before_setup"}
316
+ elsif opts[:raise_in_before_setup]
317
+ add_on_two = %{; raise "Error in 2nd before_setup"}
318
+ end
319
+ before_setups =<<-BSTS
320
+ Test::Unit::TestCase.before_setup do |test|
321
+ puts "1st before_setup"
322
+ end
323
+ Test::Unit::TestCase.before_setup do |test|
324
+ puts "2nd before_setup" #{add_on_two}
325
+ end
326
+ Test::Unit::TestCase.before_setup do |test|
327
+ puts "3rd before_setup"
328
+ end
329
+
330
+ BSTS
331
+ end
332
+
333
+
334
+ setup_code =<<-SC
335
+ def setup
336
+ puts "THE SETUP"
337
+ end
338
+ SC
339
+ if opts[:omit_setup]
340
+ setup_code = ""
341
+ end
342
+
343
+ after_teardowns = ''
344
+ if opts[:use_after_teardown]
345
+ add_on_one = ""
346
+ add_on_two = ""
347
+ if opts[:flunk_in_after_teardown]
348
+ add_on_one = %{; test.flunk "Flunk in first after_teardown"}
349
+ add_on_two = %{; test.flunk "Flunk in second after_teardown"}
350
+ elsif opts[:raise_in_after_teardown]
351
+ add_on_one = %{; raise "Error in first after_teardown"}
352
+ add_on_two = %{; raise "Error in second after_teardown"}
353
+ end
354
+ after_teardowns =<<-ATDS
355
+ Test::Unit::TestCase.after_teardown do |test|
356
+ puts "1st after_teardown" #{add_on_one}
357
+ end
358
+ Test::Unit::TestCase.after_teardown do |test|
359
+ puts "2nd after_teardown" #{add_on_two}
360
+ end
361
+ ATDS
362
+ end
363
+
364
+ teardown_code =<<-TDC
365
+ def teardown
366
+ puts "THE TEARDOWN"
367
+ end
368
+ TDC
369
+ if opts[:flunk_in_teardown]
370
+ teardown_code =<<-TDC
371
+ def teardown
372
+ flunk "FLUNK IN TEARDOWN"
373
+ end
374
+ TDC
375
+ elsif opts[:raise_in_teardown]
376
+ teardown_code =<<-TDC
377
+ def teardown
378
+ raise "ERROR IN TEARDOWN"
379
+ end
380
+ TDC
381
+ end
382
+ if opts[:omit_teardown]
383
+ teardown_code = ""
384
+ end
385
+
386
+ str = <<-TCODE
387
+ require 'test/unit'
388
+ #{requires_for_ext}
389
+
390
+ #{before_setups} #{after_teardowns}
391
+
392
+ class MyExampleTest < Test::Unit::TestCase
393
+ #{setup_code}
394
+ #{teardown_code}
395
+ #{test_method_code}
396
+ end
397
+ TCODE
398
+ end
399
+
400
+ def generate_passing_test(tname)
401
+ str = <<-TMETH
402
+ def #{tname}
403
+ puts "A TEST"
404
+ end
405
+ TMETH
406
+ end
407
+
408
+ def generate_failing_test(tname, opts={})
409
+ str = "NOT DEFINED?"
410
+ if opts[:raise_nasty_in_test]
411
+ str = <<-TMETH
412
+ def #{tname}
413
+ raise NoMemoryError, "NASTY ERROR"
414
+ end
415
+ TMETH
416
+
417
+ elsif opts[:use_helpers]
418
+ str = <<-TMETH
419
+ def #{tname}
420
+ puts "A FAILING TEST"
421
+ my_helper
422
+ end
423
+
424
+ def my_helper
425
+ tripwire
426
+ end
427
+
428
+ def tripwire
429
+ assert false, "Instrumented failure"
430
+ end
431
+ TMETH
432
+ else
433
+ str = <<-TMETH
434
+ def #{tname}
435
+ puts "A FAILING TEST"
436
+ assert false, "Instrumented failure"
437
+ end
438
+ TMETH
439
+ end
440
+ return str
441
+ end
442
+
443
+ def is_modern_test_unit?
444
+ begin
445
+ Test::Unit::TestCase::PASSTHROUGH_EXCEPTIONS
446
+ return true
447
+ rescue NameError
448
+ return false
449
+ end
450
+ end
451
+
452
+ end
metadata CHANGED
@@ -1,36 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.9.0
3
- specification_version: 1
4
2
  name: hardmock
5
3
  version: !ruby/object:Gem::Version
6
- version: 1.3.5
7
- date: 2007-12-10 00:00:00 -05:00
8
- summary: A strict, ordered, expectation-oriented mock object library.
9
- require_paths:
10
- - lib
11
- email: crosby@atomicobject.com
12
- homepage: http://hardmock.rubyforge.org
13
- rubyforge_project: hardmock
14
- description:
15
- autorequire: hardmock
16
- default_executable:
17
- bindir: bin
18
- has_rdoc: true
19
- required_ruby_version: !ruby/object:Gem::Version::Requirement
20
- requirements:
21
- - - ">"
22
- - !ruby/object:Gem::Version
23
- version: 0.0.0
24
- version:
4
+ version: 1.3.6
25
5
  platform: ruby
26
- signing_key:
27
- cert_chain:
28
- post_install_message:
29
6
  authors:
30
7
  - David Crosby
8
+ autorequire: hardmock
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2007-12-11 00:00:00 -05:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description:
17
+ email: crosby@atomicobject.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README
24
+ - CHANGES
25
+ - LICENSE
31
26
  files:
32
27
  - lib/assert_error.rb
33
- - lib/hardmock.rb
28
+ - lib/extend_test_unit.rb
34
29
  - lib/hardmock/errors.rb
35
30
  - lib/hardmock/expectation.rb
36
31
  - lib/hardmock/expectation_builder.rb
@@ -41,18 +36,21 @@ files:
41
36
  - lib/hardmock/stubbing.rb
42
37
  - lib/hardmock/trapper.rb
43
38
  - lib/hardmock/utils.rb
44
- - test/test_helper.rb
39
+ - lib/hardmock.rb
40
+ - lib/test_unit_before_after.rb
45
41
  - test/functional/assert_error_test.rb
46
42
  - test/functional/auto_verify_test.rb
47
43
  - test/functional/direct_mock_usage_test.rb
48
44
  - test/functional/hardmock_test.rb
49
45
  - test/functional/stubbing_test.rb
46
+ - test/test_helper.rb
50
47
  - test/unit/expectation_builder_test.rb
51
48
  - test/unit/expectation_test.rb
52
49
  - test/unit/expector_test.rb
53
50
  - test/unit/method_cleanout_test.rb
54
51
  - test/unit/mock_control_test.rb
55
52
  - test/unit/mock_test.rb
53
+ - test/unit/test_unit_before_after_test.rb
56
54
  - test/unit/trapper_test.rb
57
55
  - test/unit/verify_error_test.rb
58
56
  - Rakefile
@@ -63,6 +61,37 @@ files:
63
61
  - README
64
62
  - CHANGES
65
63
  - LICENSE
64
+ has_rdoc: true
65
+ homepage: http://hardmock.rubyforge.org
66
+ post_install_message:
67
+ rdoc_options:
68
+ - --line-numbers
69
+ - --inline-source
70
+ - --main
71
+ - README
72
+ - --title
73
+ - Hardmock
74
+ require_paths:
75
+ - lib
76
+ required_ruby_version: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ version: "0"
81
+ version:
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ version: "0"
87
+ version:
88
+ requirements: []
89
+
90
+ rubyforge_project: hardmock
91
+ rubygems_version: 0.9.5
92
+ signing_key:
93
+ specification_version: 2
94
+ summary: A strict, ordered, expectation-oriented mock object library.
66
95
  test_files:
67
96
  - test/functional/assert_error_test.rb
68
97
  - test/functional/auto_verify_test.rb
@@ -75,24 +104,6 @@ test_files:
75
104
  - test/unit/method_cleanout_test.rb
76
105
  - test/unit/mock_control_test.rb
77
106
  - test/unit/mock_test.rb
107
+ - test/unit/test_unit_before_after_test.rb
78
108
  - test/unit/trapper_test.rb
79
109
  - test/unit/verify_error_test.rb
80
- rdoc_options:
81
- - --line-numbers
82
- - --inline-source
83
- - --main
84
- - README
85
- - --title
86
- - Hardmock
87
- extra_rdoc_files:
88
- - README
89
- - CHANGES
90
- - LICENSE
91
- executables: []
92
-
93
- extensions: []
94
-
95
- requirements: []
96
-
97
- dependencies: []
98
-