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