hardmock 1.3.2 → 1.3.3
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.
- data/CHANGES +28 -0
- data/README +19 -0
- data/Rakefile +2 -2
- data/lib/hardmock/method_cleanout.rb +22 -3
- data/lib/hardmock/stubbing.rb +22 -42
- data/lib/hardmock.rb +2 -0
- data/{lib/tasks → rake_tasks}/rdoc.rake +0 -0
- data/{lib/tasks → rake_tasks}/rdoc_options.rb +0 -0
- data/{lib/tasks → rake_tasks}/test.rake +0 -0
- data/test/functional/hardmock_test.rb +8 -0
- data/test/functional/stubbing_test.rb +31 -21
- data/test/unit/method_cleanout_test.rb +2 -1
- metadata +5 -5
data/CHANGES
CHANGED
@@ -1,3 +1,31 @@
|
|
1
|
+
Hardmock 1.3.3
|
2
|
+
|
3
|
+
* stubs! and expects! no longer require that their target methods exist in reality (this used to prevent you from stubbing methods that "exist" by virtue of "method_missing"
|
4
|
+
* Tweaked inner metaclass code to avoid collisions with rspec's "metaid" stuff
|
5
|
+
* Moved this project's Rake tasks into rake_tasks... otherwise Rails will load them, if Hardmock is installed as a Rails plugin
|
6
|
+
* Alias added: 'verify_hardmocks' is now an alias for 'verify_mocks' (some internal projects were using this modified method name as a means of cooexisting with mocha)
|
7
|
+
|
8
|
+
Hardmock 1.3.2
|
9
|
+
|
10
|
+
November 2007
|
11
|
+
|
12
|
+
* adds 'with' as an alternate syntax for specifying argument expectations.
|
13
|
+
|
14
|
+
Hardmock 1.3.1
|
15
|
+
|
16
|
+
October 2007
|
17
|
+
|
18
|
+
* Can use stubs! on a mock object
|
19
|
+
* expects! now generates mocked methods that can safely transfer runtime blocks to the mock instance itself
|
20
|
+
* No longer need to call "prepare_hardmock_control" when using stubs in the absence of mocks
|
21
|
+
* Stubs of concrete class or instance methods are restored to original state in teardown
|
22
|
+
|
23
|
+
Hardmock 1.3.0
|
24
|
+
|
25
|
+
October 2007
|
26
|
+
|
27
|
+
* Adds stubs! and expects! method to all objects and classes to support concrete stubbing/mocking.
|
28
|
+
|
1
29
|
Hardmock 1.2.3
|
2
30
|
|
3
31
|
Sat Apr 28 01:16:15 EDT 2007
|
data/README
CHANGED
@@ -46,6 +46,25 @@ Expects <tt>@garage.open_door</tt>, <tt>@car.start(:choke)</tt> and <tt>@car.dri
|
|
46
46
|
* SVN access: svn co svn://rubyforge.org/var/svn/hardmock/trunk
|
47
47
|
* Developer SVN access: svn co svn://developername@rubyforge.org/var/svn/hardmock/trunk
|
48
48
|
|
49
|
+
== Setup for Test::Unit
|
50
|
+
|
51
|
+
require 'hardmock'
|
52
|
+
require 'assert_error' # OPTIONAL: this adds the TestUnit extension 'assert_error'
|
53
|
+
|
54
|
+
NOTE: If installed as a Rails plugin, init.rb does this for you... nothing else is needed.
|
55
|
+
|
56
|
+
== Setup for RSpec
|
57
|
+
|
58
|
+
Get this into your spec helper or environment or Rakefile or wherever you prefer:
|
59
|
+
|
60
|
+
Spec::Runner.configure do |configuration|
|
61
|
+
configuration.include Hardmock
|
62
|
+
configuration.after(:each) {verify_mocks}
|
63
|
+
end
|
64
|
+
|
65
|
+
This puts the implicit conveniences into your spec context, like "create_mocks" etc, and also provides for automatic
|
66
|
+
"verify_mocks" after each Example is run.
|
67
|
+
|
49
68
|
== Author
|
50
69
|
* David Crosby crosby at http://atomicobject.com
|
51
70
|
* (c) 2006,2007 Atomic Object LLC
|
data/Rakefile
CHANGED
@@ -1,13 +1,32 @@
|
|
1
1
|
|
2
2
|
module Hardmock #:nodoc:
|
3
3
|
module MethodCleanout #:nodoc:
|
4
|
-
SACRED_METHODS = %w
|
4
|
+
SACRED_METHODS = %w{
|
5
|
+
__id__
|
6
|
+
__send__
|
7
|
+
equal?
|
8
|
+
object_id
|
9
|
+
send
|
10
|
+
nil?
|
11
|
+
class
|
12
|
+
kind_of?
|
13
|
+
respond_to?
|
14
|
+
inspect
|
15
|
+
method
|
16
|
+
to_s
|
17
|
+
instance_variables
|
18
|
+
instance_eval
|
19
|
+
==
|
20
|
+
hm_metaclass
|
21
|
+
hm_meta_eval
|
22
|
+
hm_meta_def
|
23
|
+
}
|
5
24
|
|
6
25
|
def self.included(base) #:nodoc:
|
7
26
|
base.class_eval do
|
8
|
-
instance_methods.each
|
27
|
+
instance_methods.each do |m|
|
9
28
|
undef_method m unless SACRED_METHODS.include?(m.to_s)
|
10
|
-
|
29
|
+
end
|
11
30
|
end
|
12
31
|
end
|
13
32
|
end
|
data/lib/hardmock/stubbing.rb
CHANGED
@@ -1,36 +1,25 @@
|
|
1
|
-
|
1
|
+
|
2
|
+
|
2
3
|
# Stubbing support
|
3
4
|
#
|
4
5
|
# Stubs methods on classes and instances
|
5
6
|
#
|
6
7
|
|
7
|
-
# Why's "metaid.rb":
|
8
|
+
# Why's "metaid.rb" stuff crunched down:
|
8
9
|
class Object #:nodoc:#
|
9
|
-
|
10
|
-
def metaclass #:nodoc:#
|
10
|
+
def hm_metaclass #:nodoc:#
|
11
11
|
class << self
|
12
12
|
self
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
metaclass.instance_eval(&blk)
|
16
|
+
def hm_meta_eval(&blk) #:nodoc:#
|
17
|
+
hm_metaclass.instance_eval(&blk)
|
19
18
|
end
|
20
19
|
|
21
|
-
|
22
|
-
|
23
|
-
meta_eval { define_method name, &blk }
|
20
|
+
def hm_meta_def(name, &blk) #:nodoc:#
|
21
|
+
hm_meta_eval { define_method name, &blk }
|
24
22
|
end
|
25
|
-
|
26
|
-
# def meta_eval_string(str)
|
27
|
-
# metaclass.instance_eval(str)
|
28
|
-
# end
|
29
|
-
|
30
|
-
# Defines an instance method within a class
|
31
|
-
# def class_def(name, &blk) #:nodoc:#
|
32
|
-
# class_eval { define_method name, &blk }
|
33
|
-
# end
|
34
23
|
end
|
35
24
|
|
36
25
|
|
@@ -87,13 +76,11 @@ module Hardmock
|
|
87
76
|
def raises(err)
|
88
77
|
err = RuntimeError.new(err) unless err.kind_of?(Exception)
|
89
78
|
@raises = err
|
90
|
-
# puts "Setup to raise #{@raises}"
|
91
79
|
end
|
92
80
|
end
|
93
81
|
|
94
82
|
class ::Object
|
95
83
|
def stubs!(method_name)
|
96
|
-
_ensure_stubbable method_name
|
97
84
|
method_name = method_name.to_s
|
98
85
|
already_stubbed = Hardmock.has_replaced_method?(self, method_name)
|
99
86
|
|
@@ -101,12 +88,14 @@ module Hardmock
|
|
101
88
|
|
102
89
|
|
103
90
|
unless _is_mock? or already_stubbed
|
104
|
-
|
105
|
-
|
91
|
+
if methods.include?(method_name.to_s)
|
92
|
+
hm_meta_eval do
|
93
|
+
alias_method "_hardmock_original_#{method_name}".to_sym, method_name.to_sym
|
94
|
+
end
|
106
95
|
end
|
107
96
|
end
|
108
97
|
|
109
|
-
|
98
|
+
hm_meta_def method_name do |*args|
|
110
99
|
stubbed_method.invoke(args)
|
111
100
|
end
|
112
101
|
|
@@ -117,7 +106,6 @@ module Hardmock
|
|
117
106
|
if self._is_mock?
|
118
107
|
raise Hardmock::StubbingError, "Cannot use 'expects!(:#{method_name})' on a Mock object; try 'expects' instead"
|
119
108
|
end
|
120
|
-
_ensure_stubbable method_name
|
121
109
|
|
122
110
|
method_name = method_name.to_s
|
123
111
|
|
@@ -125,8 +113,10 @@ module Hardmock
|
|
125
113
|
@_my_mock = Mock.new(_my_name, $main_mock_control)
|
126
114
|
Hardmock::ReplacedMethod.new(self, method_name)
|
127
115
|
|
128
|
-
|
129
|
-
|
116
|
+
if methods.include?(method_name.to_s)
|
117
|
+
hm_meta_eval do
|
118
|
+
alias_method "_hardmock_original_#{method_name}".to_sym, method_name.to_sym
|
119
|
+
end
|
130
120
|
end
|
131
121
|
|
132
122
|
begin
|
@@ -147,19 +137,6 @@ module Hardmock
|
|
147
137
|
return @_my_mock.expects(method_name, *args, &block)
|
148
138
|
end
|
149
139
|
|
150
|
-
def _ensure_stubbable(method_name)
|
151
|
-
unless self.respond_to?(method_name.to_sym) or self._is_mock?
|
152
|
-
msg = "Cannot stub non-existant "
|
153
|
-
if self.kind_of?(Class)
|
154
|
-
msg += "class method #{_my_name}."
|
155
|
-
else
|
156
|
-
msg += "method #{_my_name}#"
|
157
|
-
end
|
158
|
-
msg += method_name.to_s
|
159
|
-
raise Hardmock::StubbingError.new(msg)
|
160
|
-
end
|
161
|
-
end
|
162
|
-
|
163
140
|
def _is_mock?
|
164
141
|
self.kind_of?(Mock)
|
165
142
|
end
|
@@ -193,8 +170,11 @@ module Hardmock
|
|
193
170
|
def restore_all_replaced_methods
|
194
171
|
all_replaced_methods.each do |replaced|
|
195
172
|
unless replaced.target._is_mock?
|
196
|
-
replaced.
|
197
|
-
|
173
|
+
backed_up = "_hardmock_original_#{replaced.method_name}"
|
174
|
+
if replaced.target.methods.include?(backed_up)
|
175
|
+
replaced.target.hm_meta_eval do
|
176
|
+
alias_method replaced.method_name.to_sym, backed_up.to_sym
|
177
|
+
end
|
198
178
|
end
|
199
179
|
replaced.target._clear_mock
|
200
180
|
end
|
data/lib/hardmock.rb
CHANGED
File without changes
|
File without changes
|
File without changes
|
@@ -393,6 +393,14 @@ class HardmockTest < Test::Unit::TestCase
|
|
393
393
|
end
|
394
394
|
end
|
395
395
|
|
396
|
+
should "support alias verify_hardmocks" do
|
397
|
+
create_mock :tree
|
398
|
+
@tree.expects(:grow)
|
399
|
+
assert_error VerifyError, /unmet/i do
|
400
|
+
verify_hardmocks
|
401
|
+
end
|
402
|
+
end
|
403
|
+
|
396
404
|
#
|
397
405
|
# HELPERS
|
398
406
|
#
|
@@ -77,16 +77,15 @@ class StubbingTest < Test::Unit::TestCase
|
|
77
77
|
assert_equal "For roads", Concrete.describe, "'describe' class method broken after restore"
|
78
78
|
end
|
79
79
|
|
80
|
-
should "
|
81
|
-
|
82
|
-
|
83
|
-
end
|
80
|
+
should "allow stubbing of nonexistant class methods" do
|
81
|
+
Concrete.stubs!(:funky).returns('juice')
|
82
|
+
assert_equal 'juice', Concrete.funky
|
84
83
|
end
|
85
84
|
|
86
|
-
should "
|
87
|
-
|
88
|
-
|
89
|
-
|
85
|
+
should "allow stubbing of nonexistant instance methods" do
|
86
|
+
chunk = Concrete.new
|
87
|
+
chunk.stubs!(:shark).returns('bite')
|
88
|
+
assert_equal 'bite', chunk.shark
|
90
89
|
end
|
91
90
|
|
92
91
|
should "allow re-stubbing" do
|
@@ -107,7 +106,6 @@ class StubbingTest < Test::Unit::TestCase
|
|
107
106
|
end
|
108
107
|
|
109
108
|
it "does nothing with a runtime block when simply stubbing" do
|
110
|
-
|
111
109
|
slab = Concrete.new
|
112
110
|
slab.stubs!(:hit) do |nothing|
|
113
111
|
raise "BOOOMM!"
|
@@ -117,7 +115,6 @@ class StubbingTest < Test::Unit::TestCase
|
|
117
115
|
end
|
118
116
|
|
119
117
|
it "can raise errors from a stubbed method" do
|
120
|
-
|
121
118
|
Concrete.stubs!(:pour).raises(StandardError.new("no!"))
|
122
119
|
assert_error StandardError, /no!/ do
|
123
120
|
Concrete.pour
|
@@ -125,7 +122,6 @@ class StubbingTest < Test::Unit::TestCase
|
|
125
122
|
end
|
126
123
|
|
127
124
|
it "provides string syntax for convenient raising of RuntimeErrors" do
|
128
|
-
|
129
125
|
Concrete.stubs!(:pour).raises("never!")
|
130
126
|
assert_error RuntimeError, /never!/ do
|
131
127
|
Concrete.pour
|
@@ -192,11 +188,9 @@ class StubbingTest < Test::Unit::TestCase
|
|
192
188
|
clear_expectations
|
193
189
|
end
|
194
190
|
|
195
|
-
should "
|
196
|
-
|
197
|
-
|
198
|
-
Concrete.expects!(:something)
|
199
|
-
end
|
191
|
+
should "allow mocking non-existant class methods" do
|
192
|
+
Concrete.expects!(:something).returns("else")
|
193
|
+
assert_equal "else", Concrete.something
|
200
194
|
end
|
201
195
|
|
202
196
|
it "mocks specific methods on existing instances, then restore them after verify" do
|
@@ -265,12 +259,10 @@ class StubbingTest < Test::Unit::TestCase
|
|
265
259
|
clear_expectations
|
266
260
|
end
|
267
261
|
|
268
|
-
should "
|
269
|
-
|
262
|
+
should "allow mocking non-existant instance methods" do
|
270
263
|
slab = Concrete.new
|
271
|
-
|
272
|
-
|
273
|
-
end
|
264
|
+
slab.expects!(:wholly).returns('happy')
|
265
|
+
assert_equal 'happy', slab.wholly
|
274
266
|
end
|
275
267
|
|
276
268
|
should "support concrete expectations that deal with runtime blocks" do
|
@@ -303,6 +295,23 @@ class StubbingTest < Test::Unit::TestCase
|
|
303
295
|
verify_mocks
|
304
296
|
reset_stubs
|
305
297
|
end
|
298
|
+
|
299
|
+
it "can stub the new method and return values" do
|
300
|
+
Concrete.stubs!(:new).returns("this value")
|
301
|
+
assert_equal "this value", Concrete.new, "did not properly stub new class method"
|
302
|
+
reset_stubs
|
303
|
+
end
|
304
|
+
|
305
|
+
it "can mock the new method and return values" do
|
306
|
+
Concrete.expects!(:new).with("foo").returns("hello")
|
307
|
+
Concrete.expects!(:new).with("bar").returns("world")
|
308
|
+
|
309
|
+
assert_equal "hello", Concrete.new("foo"), "did not properly mock out new class method"
|
310
|
+
assert_equal "world", Concrete.new("bar"), "did not properly mock out new class method"
|
311
|
+
|
312
|
+
verify_mocks
|
313
|
+
reset_stubs
|
314
|
+
end
|
306
315
|
|
307
316
|
it "will not allow expects! to be used on a mock object" do
|
308
317
|
create_mock :cow
|
@@ -316,6 +325,7 @@ class StubbingTest < Test::Unit::TestCase
|
|
316
325
|
#
|
317
326
|
|
318
327
|
class Concrete
|
328
|
+
def initialize; end
|
319
329
|
def self.pour
|
320
330
|
"stones and gravel"
|
321
331
|
end
|
@@ -22,7 +22,8 @@ class MethodCleanoutTest < Test::Unit::TestCase
|
|
22
22
|
|
23
23
|
def test_should_leave_the_sacred_methods_defined
|
24
24
|
Hardmock::MethodCleanout::SACRED_METHODS.each do |m|
|
25
|
-
|
25
|
+
next if m =~ /^hm_/
|
26
|
+
assert @victim.respond_to?(m), "Sacred method '#{m}' was removed unexpectedly"
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hardmock
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.3.
|
4
|
+
version: 1.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Crosby
|
@@ -9,7 +9,7 @@ autorequire: hardmock
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2007-
|
12
|
+
date: 2007-12-05 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
@@ -36,7 +36,6 @@ files:
|
|
36
36
|
- lib/hardmock/trapper.rb
|
37
37
|
- lib/hardmock/utils.rb
|
38
38
|
- lib/hardmock.rb
|
39
|
-
- lib/tasks/rdoc_options.rb
|
40
39
|
- test/functional/assert_error_test.rb
|
41
40
|
- test/functional/auto_verify_test.rb
|
42
41
|
- test/functional/direct_mock_usage_test.rb
|
@@ -53,8 +52,9 @@ files:
|
|
53
52
|
- test/unit/verify_error_test.rb
|
54
53
|
- Rakefile
|
55
54
|
- config/environment.rb
|
56
|
-
-
|
57
|
-
-
|
55
|
+
- rake_tasks/rdoc_options.rb
|
56
|
+
- rake_tasks/rdoc.rake
|
57
|
+
- rake_tasks/test.rake
|
58
58
|
- README
|
59
59
|
- CHANGES
|
60
60
|
- LICENSE
|