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 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,8 +1,8 @@
1
1
  require 'rake'
2
2
  require 'rubygems'
3
3
 
4
- HARDMOCK_VERSION = "1.3.2"
4
+ HARDMOCK_VERSION = "1.3.3"
5
5
 
6
- Dir["lib/tasks/*.rake"].each { |f| load f }
6
+ Dir["rake_tasks/*.rake"].each { |f| load f }
7
7
 
8
8
  task :default => [ 'test:all' ]
@@ -1,13 +1,32 @@
1
1
 
2
2
  module Hardmock #:nodoc:
3
3
  module MethodCleanout #:nodoc:
4
- SACRED_METHODS = %w|__id__ __send__ equal? object_id send nil? class kind_of? respond_to? inspect method to_s instance_variables instance_eval ==|
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 { |m|
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
@@ -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
- # The hidden singleton lurks behind everyone
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
- # Evaluate a block of code within the metaclass
17
- def meta_eval(&blk) #:nodoc:#
18
- metaclass.instance_eval(&blk)
16
+ def hm_meta_eval(&blk) #:nodoc:#
17
+ hm_metaclass.instance_eval(&blk)
19
18
  end
20
19
 
21
- # Adds methods to a metaclass
22
- def meta_def(name, &blk) #:nodoc:#
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
- meta_eval do
105
- alias_method "_hardmock_original_#{method_name}".to_sym, method_name.to_sym
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
- meta_def method_name do |*args|
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
- meta_eval do
129
- alias_method "_hardmock_original_#{method_name}".to_sym, method_name.to_sym
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.target.meta_eval do
197
- alias_method replaced.method_name.to_sym, "_hardmock_original_#{replaced.method_name}".to_sym
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
@@ -150,6 +150,8 @@ module Hardmock
150
150
  $main_mock_control = nil
151
151
  reset_stubs
152
152
  end
153
+
154
+ alias :verify_hardmocks :verify_mocks
153
155
 
154
156
  # Purge the main MockControl of all expectations, restore all concrete stubbed/mocked methods
155
157
  def clear_expectations
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 "not allow stubbing of nonexistant class methods" do
81
- assert_error(Hardmock::StubbingError, /cannot stub/i, /class method/i, /Concrete.funky/) do
82
- Concrete.stubs!(:funky)
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 "not allow stubbing of nonexistant instance methods" do
87
- assert_error(Hardmock::StubbingError, /cannot stub/i, /method/i, /Concrete#my_inst_mth/) do
88
- Concrete.new.stubs!(:my_inst_mth)
89
- end
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 "not allow mocking non-existant class methods" do
196
-
197
- assert_error Hardmock::StubbingError, /non-existant/, /something/ do
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 "not allow mocking non-existant instance methods" do
269
-
262
+ should "allow mocking non-existant instance methods" do
270
263
  slab = Concrete.new
271
- assert_error Hardmock::StubbingError, /non-existant/, /something/ do
272
- slab.expects!(:something)
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
- assert @victim.respond_to?(m)
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.2
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-11-28 00:00:00 -05:00
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
- - lib/tasks/rdoc.rake
57
- - lib/tasks/test.rake
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