flexmock 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG CHANGED
@@ -1,5 +1,10 @@
1
1
  = Changes for FlexMock
2
2
 
3
+ == Version 0.1.4
4
+
5
+ * Added eq and any methods for argument matching.
6
+ * Added tests for the "first match" argument matching policy.
7
+
3
8
  == Version 0.1.3
4
9
 
5
10
  * Improved the definition of ordered so that it takes group names
data/README CHANGED
@@ -3,7 +3,7 @@
3
3
  FlexMock is a simple mock object for unit testing. The interface is
4
4
  simple, but still provides a good bit of flexibility.
5
5
 
6
- Version :: 0.1.3
6
+ Version :: 0.1.4
7
7
 
8
8
  = Links
9
9
 
@@ -143,9 +143,12 @@ values to figure out what value to return.
143
143
 
144
144
  FlexMock('db').use |db|
145
145
  db.should_receive(:startup).once.ordered
146
- db.should_receive(:query).with("CPWR").and_return(12.3).once.ordered(10)
147
- db.should_receive(:query).with("MSFT").and_return(10.0).once.ordered(10)
148
- db.should_receive(:query).with(/^....$/).and_return(3.3).at_least.once.ordered(10)
146
+ db.should_receive(:query).with("CPWR").and_return(12.3).
147
+ once.ordered(:queries)
148
+ db.should_receive(:query).with("MSFT").and_return(10.0).
149
+ once.ordered(:queries)
150
+ db.should_receive(:query).with(/^....$/).and_return(3.3).
151
+ at_least.once.ordered(:queries)
149
152
  db.should_receive(:finish).once.ordered
150
153
  # test code here
151
154
  end
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ require 'rake/testtask'
8
8
 
9
9
  CLOBBER.include("html", 'pkg')
10
10
 
11
- PKG_VERSION = '0.1.3'
11
+ PKG_VERSION = '0.1.4'
12
12
 
13
13
  PKG_FILES = FileList[
14
14
  '[A-Z]*',
data/lib/flexmock.rb CHANGED
@@ -118,50 +118,54 @@ class FlexMock
118
118
  result
119
119
  end
120
120
 
121
- # Class method to make sure that verify is called at the end of a
122
- # test. One mock object will be created for each name given to the
123
- # use method. The mocks will be passed to the block as arguments.
124
- # If no names are given, then a single anonymous mock object will be
125
- # created.
126
- #
127
- # At the end of the use block, each mock object will be verified to
128
- # make sure the proper number of calls have been made.
129
- #
130
- # Usage:
131
- #
132
- # FlexMock.use("name") do |mock| # Creates a mock named "name"
133
- # mock.should_receive(:meth).
134
- # returns(0).once
135
- # end # mock is verified here
136
- #
137
- def self.use(*names)
138
- names = ["unknown"] if names.empty?
139
- got_excecption = false
140
- mocks = names.collect { |n| new(n) }
141
- yield(*mocks)
142
- rescue Exception => ex
143
- got_exception = true
144
- raise
145
- ensure
146
- mocks.each do |mock|
147
- mock.mock_verify unless got_exception
148
- end
149
- end
121
+ class << self
122
+ include Test::Unit::Assertions
150
123
 
151
-
152
- # Class method to format a method name and argument list as a nice
153
- # looking string.
154
- def self.format_args(sym, args)
155
- if args
156
- "#{sym}(#{args.collect { |a| a.inspect }.join(', ')})"
157
- else
158
- "#{sym}(*args)"
124
+ # Class method to make sure that verify is called at the end of a
125
+ # test. One mock object will be created for each name given to
126
+ # the use method. The mocks will be passed to the block as
127
+ # arguments. If no names are given, then a single anonymous mock
128
+ # object will be created.
129
+ #
130
+ # At the end of the use block, each mock object will be verified
131
+ # to make sure the proper number of calls have been made.
132
+ #
133
+ # Usage:
134
+ #
135
+ # FlexMock.use("name") do |mock| # Creates a mock named "name"
136
+ # mock.should_receive(:meth).
137
+ # returns(0).once
138
+ # end # mock is verified here
139
+ #
140
+ def use(*names)
141
+ names = ["unknown"] if names.empty?
142
+ got_excecption = false
143
+ mocks = names.collect { |n| new(n) }
144
+ yield(*mocks)
145
+ rescue Exception => ex
146
+ got_exception = true
147
+ raise
148
+ ensure
149
+ mocks.each do |mock|
150
+ mock.mock_verify unless got_exception
151
+ end
152
+ end
153
+
154
+ # Class method to format a method name and argument list as a nice
155
+ # looking string.
156
+ def format_args(sym, args)
157
+ if args
158
+ "#{sym}(#{args.collect { |a| a.inspect }.join(', ')})"
159
+ else
160
+ "#{sym}(*args)"
161
+ end
162
+ end
163
+
164
+ # Check will assert the block returns true. If it doesn't, an
165
+ # assertion failure is triggered with the given message.
166
+ def check(msg, &block)
167
+ assert_block(msg, &block)
159
168
  end
160
- end
161
-
162
- # Class method to consistently form failure exceptions
163
- def self.failure(msg)
164
- fail Test::Unit::AssertionFailedError, msg
165
169
  end
166
170
 
167
171
  private
@@ -193,10 +197,8 @@ class FlexMock
193
197
  def call(*args)
194
198
  exp = @expectations.find { |e| e.match_args(args) } ||
195
199
  @expectations.find { |e| e.expected_args.nil? }
196
- if exp.nil?
197
- FlexMock.failure "no matching handler found for " +
198
- FlexMock.format_args(@sym, args)
199
- end
200
+ FlexMock.check("no matching handler found for " +
201
+ FlexMock.format_args(@sym, args)) { ! exp.nil? }
200
202
  exp.verify_call(*args)
201
203
  end
202
204
 
@@ -219,13 +221,58 @@ class FlexMock
219
221
  end
220
222
  end
221
223
 
224
+ ####################################################################
225
+ # Match any object
226
+ class AnyMatcher
227
+ def ===(target)
228
+ true
229
+ end
230
+ def inspect
231
+ "ANY"
232
+ end
233
+ end
234
+
235
+ ####################################################################
236
+ # Match only things that are equal.
237
+ class EqualMatcher
238
+ def initialize(obj)
239
+ @obj = obj
240
+ end
241
+ def ===(target)
242
+ @obj == target
243
+ end
244
+ def inspect
245
+ "==(#{@obj.inspect})"
246
+ end
247
+ end
248
+
249
+ ANY = AnyMatcher.new
250
+
251
+ ####################################################################
252
+ # Include this module in your test class if you wish to use the +eq+
253
+ # and +any+ argument matching methods without a prefix. (Otherwise
254
+ # use <tt>FlexMock.any</tt> and <tt>FlexMock.eq(obj)</tt>.
255
+ #
256
+ module ArgumentTypes
257
+ # Return an argument matcher that matches any argument.
258
+ def any
259
+ ANY
260
+ end
261
+
262
+ # Return an argument matcher that only matches things equal to
263
+ # (==) the given object.
264
+ def eq(obj)
265
+ EqualMatcher.new(obj)
266
+ end
267
+ end
268
+
222
269
  ####################################################################
223
270
  # Base class for all the count validators.
224
271
  #
225
272
  class CountValidator
226
273
  include Test::Unit::Assertions
227
- def initialize(sym, limit)
228
- @sym = sym
274
+ def initialize(expectation, limit)
275
+ @exp = expectation
229
276
  @limit = limit
230
277
  end
231
278
  end
@@ -238,7 +285,7 @@ class FlexMock
238
285
  # times.
239
286
  def validate(n)
240
287
  assert_equal @limit, n,
241
- "method '#{@sym}' called incorrect number of times"
288
+ "method '#{@exp}' called incorrect number of times"
242
289
  end
243
290
  end
244
291
 
@@ -250,7 +297,7 @@ class FlexMock
250
297
  # times.
251
298
  def validate(n)
252
299
  assert n >= @limit,
253
- "Method '#{@sym}' should be called at least #{@limit} times,\n" +
300
+ "Method '#{@exp}' should be called at least #{@limit} times,\n" +
254
301
  "only called #{n} times"
255
302
  end
256
303
  end
@@ -262,7 +309,7 @@ class FlexMock
262
309
  # Validate the method expectation was called at least +n+ times.
263
310
  def validate(n)
264
311
  assert n <= @limit,
265
- "Method '#{@sym}' should be called at most #{@limit} times,\n" +
312
+ "Method '#{@exp}' should be called at most #{@limit} times,\n" +
266
313
  "only called #{n} times"
267
314
  end
268
315
  end
@@ -312,10 +359,10 @@ class FlexMock
312
359
  # Validate that the order
313
360
  def validate_order
314
361
  return if @order_number.nil?
315
- if @order_number < @mock.mock_current_order
316
- FlexMock.failure "method #{to_s} called out of order " +
317
- "(expected order #{@order_number}, was #{@mock.mock_current_order})"
318
- end
362
+ FlexMock.check("method #{to_s} called out of order " +
363
+ "(expected order #{@order_number}, was #{@mock.mock_current_order})") {
364
+ @order_number >= @mock.mock_current_order
365
+ }
319
366
  @mock.mock_current_order = @order_number
320
367
  end
321
368
  private :validate_order
@@ -388,7 +435,7 @@ class FlexMock
388
435
  # declared argument list. This may be modified by the +at_least+
389
436
  # and +at_most+ declarators.
390
437
  def times(limit)
391
- @count_validators << @count_validator_class.new(@sym, limit) unless limit.nil?
438
+ @count_validators << @count_validator_class.new(self, limit) unless limit.nil?
392
439
  @count_validator_class = ExactCountValidator
393
440
  self
394
441
  end
@@ -448,7 +495,7 @@ class FlexMock
448
495
  # If the user needs more fine control over ordering
449
496
  # (e.g. specifying that a group of messages may be received in any
450
497
  # order as long as they all come after another group of messages),
451
- # a _group_ _name__ may be specified in the +ordered+ calls. All
498
+ # a _group_ _name_ may be specified in the +ordered+ calls. All
452
499
  # messages within the same group may be recieved in any order.
453
500
  #
454
501
  # For example, in the following, messages +flip+ and +flop+ may be
@@ -476,4 +523,6 @@ class FlexMock
476
523
  self
477
524
  end
478
525
  end
526
+
527
+ extend ArgumentTypes
479
528
  end
@@ -3,7 +3,7 @@
3
3
  require 'test/unit'
4
4
  require 'flexmock'
5
5
 
6
- class TestFlexMock < Test::Unit::TestCase
6
+ class TestFlexMockShoulds < Test::Unit::TestCase
7
7
 
8
8
  def test_defaults
9
9
  FlexMock.use do |m|
@@ -64,7 +64,7 @@ class TestFlexMock < Test::Unit::TestCase
64
64
  end
65
65
  end
66
66
 
67
- def test__with_any_args
67
+ def test_with_any_args
68
68
  FlexMock.use do |m|
69
69
  m.should_receive(:hi).with_any_args
70
70
  m.hi
@@ -74,6 +74,40 @@ class TestFlexMock < Test::Unit::TestCase
74
74
  end
75
75
  end
76
76
 
77
+ def test_with_any_single_arg_matching
78
+ FlexMock.use('greeter') do |m|
79
+ m.should_receive(:hi).with(1,FlexMock.any).twice
80
+ m.hi(1,2)
81
+ m.hi(1, "this is a test")
82
+ end
83
+ end
84
+
85
+ def test_with_any_single_arg_nonmatching
86
+ FlexMock.use('greeter') do |m|
87
+ m.should_receive(:hi).times(3)
88
+ m.should_receive(:hi).with(1,FlexMock.any).never
89
+ m.hi
90
+ m.hi(1)
91
+ m.hi(1, "hi", nil)
92
+ end
93
+ end
94
+
95
+ def test_with_equal_arg_matching
96
+ FlexMock.use('greeter') do |m|
97
+ m.should_receive(:hi).with(FlexMock.eq(Object)).once
98
+ m.hi(Object)
99
+ end
100
+ end
101
+
102
+ def test_with_equal_arg_nonmatching
103
+ FlexMock.use('greeter') do |m|
104
+ m.should_receive(:hi).with(FlexMock.eq(Object)).never
105
+ m.should_receive(:hi).never
106
+ m.should_receive(:hi).with(1).once
107
+ m.hi(1)
108
+ end
109
+ end
110
+
77
111
  def test_args_matching_with_regex
78
112
  FlexMock.use do |m|
79
113
  m.should_receive(:hi).with(/one/).returns(10)
@@ -113,6 +147,22 @@ class TestFlexMock < Test::Unit::TestCase
113
147
  end
114
148
  end
115
149
 
150
+ def test_arg_matching_precedence_when_best_first
151
+ FlexMock.use("greeter") do |m|
152
+ m.should_receive(:hi).with(1).once
153
+ m.should_receive(:hi).with(FlexMock.any).never
154
+ m.hi(1)
155
+ end
156
+ end
157
+
158
+ def test_arg_matching_precedence_when_best_last_but_still_matches_first
159
+ FlexMock.use("greeter") do |m|
160
+ m.should_receive(:hi).with(FlexMock.any).once
161
+ m.should_receive(:hi).with(1).never
162
+ m.hi(1)
163
+ end
164
+ end
165
+
116
166
  def test_never_and_never_called
117
167
  FlexMock.use do |m|
118
168
  m.should_receive(:hi).with(1).never
@@ -438,3 +488,13 @@ class TestFlexMock < Test::Unit::TestCase
438
488
  end
439
489
 
440
490
  end
491
+
492
+ class TestFlexMockShouldsWithInclude < Test::Unit::TestCase
493
+ include FlexMock::ArgumentTypes
494
+ def test_include
495
+ FlexMock.use("x") do |m|
496
+ m.should_receive(:hi).with(any).once
497
+ m.hi(1)
498
+ end
499
+ end
500
+ end
metadata CHANGED
@@ -1,10 +1,10 @@
1
1
  --- !ruby/object:Gem::Specification
2
- rubygems_version: 0.8.10.100
2
+ rubygems_version: 0.8.11.3
3
3
  specification_version: 1
4
4
  name: flexmock
5
5
  version: !ruby/object:Gem::Version
6
- version: 0.1.3
7
- date: 2005-10-27 00:00:00 -04:00
6
+ version: 0.1.4
7
+ date: 2005-11-02 00:00:00 -05:00
8
8
  summary: Simple and Flexible Mock Objects for Testing
9
9
  require_paths:
10
10
  - lib