mspec 1.0.0 → 1.1.0

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.
@@ -22,12 +22,12 @@ describe EqualMatcher do
22
22
  it "provides a useful failure message" do
23
23
  matcher = EqualMatcher.new("red")
24
24
  matcher.matches?("red")
25
- matcher.failure_message.should == ["Expected \"red\"", "to be identical to \"red\""]
25
+ matcher.failure_message.should == ["Expected \"red\"\n", "to be identical to \"red\"\n"]
26
26
  end
27
27
 
28
28
  it "provides a useful negative failure message" do
29
29
  matcher = EqualMatcher.new(1)
30
30
  matcher.matches?(1)
31
- matcher.negative_failure_message.should == ["Expected 1", "not to be identical to 1"]
31
+ matcher.negative_failure_message.should == ["Expected 1\n", "not to be identical to 1\n"]
32
32
  end
33
33
  end
@@ -36,12 +36,12 @@ describe EqualUtf16Matcher do
36
36
  it "provides a useful failure message" do
37
37
  matcher = EqualUtf16Matcher.new("a\0b\0")
38
38
  matcher.matches?("a\0b\0c\0")
39
- matcher.failure_message.should == ["Expected \"a\\000b\\000c\\000\"", "to equal \"a\\000b\\000\" or \"\\000a\\000b\""]
39
+ matcher.failure_message.should == ["Expected \"a\\000b\\000c\\000\"\n", "to equal \"a\\000b\\000\"\n or \"\\000a\\000b\"\n"]
40
40
  end
41
41
 
42
42
  it "provides a useful negative failure message" do
43
43
  matcher = EqualUtf16Matcher.new("a\0b\0")
44
44
  matcher.matches?("\0a\0b")
45
- matcher.negative_failure_message.should == ["Expected \"\\000a\\000b\"", "not to equal \"a\\000b\\000\" nor \"\\000a\\000b\""]
45
+ matcher.negative_failure_message.should == ["Expected \"\\000a\\000b\"\n", "not to equal \"a\\000b\\000\"\n nor \"\\000a\\000b\"\n"]
46
46
  end
47
47
  end
@@ -0,0 +1,39 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'mspec/expectations/expectations'
3
+ require 'mspec/matchers/match_yaml'
4
+
5
+ describe MatchYAMLMatcher do
6
+ before :each do
7
+ @matcher = MatchYAMLMatcher.new("--- \nfoo: bar\n")
8
+ end
9
+
10
+ it "compares YAML documents and matches if they're equivalent" do
11
+ @matcher.matches?("--- \nfoo: bar\n").should == true
12
+ end
13
+
14
+ it "compares YAML documents and does not match if they're not equivalent" do
15
+ @matcher.matches?("--- \nbar: foo\n").should == false
16
+ @matcher.matches?("--- \nfoo: \nbar\n").should == false
17
+ end
18
+
19
+ it "also receives objects that respond_to to_yaml" do
20
+ matcher = MatchYAMLMatcher.new("some string")
21
+ matcher.matches?("some string").should == true
22
+
23
+ matcher = MatchYAMLMatcher.new(['a', 'b'])
24
+ matcher.matches?("--- \n- a\n- b\n").should == true
25
+
26
+ matcher = MatchYAMLMatcher.new("foo" => "bar")
27
+ matcher.matches?("--- \nfoo: bar\n").should == true
28
+ end
29
+
30
+ it "matches documents with trailing whitespace" do
31
+ @matcher.matches?("--- \nfoo: bar \n").should == true
32
+ @matcher.matches?("--- \nfoo: bar \n").should == true
33
+ end
34
+
35
+ it "fails with a descriptive error message" do
36
+ @matcher.matches?("foo").should == false
37
+ @matcher.failure_message.should == ["Expected \"foo\"", " to match \"--- \\nfoo: bar\\n\""]
38
+ end
39
+ end
@@ -7,23 +7,68 @@ require 'mspec/runner/mspec'
7
7
  require 'mspec/mocks/mock'
8
8
  require 'mspec/mocks/proxy'
9
9
 
10
- describe Mock do
11
- after :each do
12
- Mock.cleanup
10
+ describe Mock, ".mocks" do
11
+ it "returns a Hash" do
12
+ Mock.mocks.should be_kind_of(Hash)
13
13
  end
14
+ end
14
15
 
15
- it "provides expects that returns a Hash" do
16
- Mock.expects.should be_an_instance_of(Hash)
16
+ describe Mock, ".stubs" do
17
+ it "returns a Hash" do
18
+ Mock.stubs.should be_kind_of(Hash)
17
19
  end
18
20
  end
19
21
 
20
22
  describe Mock, ".replaced_name" do
21
23
  it "returns the name for a method that is being replaced by a mock method" do
22
- Mock.replaced_name(:method_call).should == :__ms_method_call__
24
+ m = mock('a fake id')
25
+ m.stub!(:__id__).and_return(42)
26
+ Mock.replaced_name(m, :method_call).should == :__ms_42_method_call__
23
27
  end
24
28
  end
25
29
 
26
- describe Mock, ".install_method" do
30
+ describe Mock, ".replaced_key" do
31
+ it "returns a key used internally by Mock" do
32
+ m = mock('a fake id')
33
+ m.stub!(:__id__).and_return(42)
34
+ Mock.replaced_key(m, :method_call).should == [:__ms_42_method_call__, m, :method_call]
35
+ end
36
+ end
37
+
38
+ describe Mock, ".replaced?" do
39
+ before :each do
40
+ @mock = mock('install_method')
41
+ MSpec.stub!(:actions)
42
+ MSpec.stub!(:current).and_return(mock("spec state", :null_object => true))
43
+ end
44
+
45
+ it "returns true if a method has been stubbed on an object" do
46
+ Mock.install_method @mock, :method_call
47
+ Mock.replaced?(Mock.replaced_key(@mock, :method_call)).should be_true
48
+ end
49
+
50
+ it "returns true if a method has been mocked on an object" do
51
+ Mock.install_method @mock, :method_call, :stub
52
+ Mock.replaced?(Mock.replaced_key(@mock, :method_call)).should be_true
53
+ end
54
+
55
+ it "returns false if a method has not been stubbed or mocked" do
56
+ Mock.replaced?(Mock.replaced_key(@mock, :method_call)).should be_false
57
+ end
58
+ end
59
+
60
+ describe Mock, ".name_or_inspect" do
61
+ before :each do
62
+ @mock = mock("I have a #name")
63
+ end
64
+
65
+ it "returns the value of @name if set" do
66
+ @mock.instance_variable_set(:@name, "Myself")
67
+ Mock.name_or_inspect(@mock).should == "Myself"
68
+ end
69
+ end
70
+
71
+ describe Mock, ".install_method for mocks" do
27
72
  before :each do
28
73
  @mock = mock('install_method')
29
74
  MSpec.stub!(:actions)
@@ -38,11 +83,6 @@ describe Mock, ".install_method" do
38
83
  Mock.install_method(@mock, :method_call).should be_an_instance_of(MockProxy)
39
84
  end
40
85
 
41
- it "sets the proxy to expect exactly 1 call" do
42
- proxy = Mock.install_method(@mock, :method_call)
43
- proxy.count.should == [:exactly, 1]
44
- end
45
-
46
86
  it "does not override a previously mocked method with the same name" do
47
87
  Mock.install_method(@mock, :method_call).with(:a, :b).and_return(1)
48
88
  Mock.install_method(@mock, :method_call).with(:c).and_return(2)
@@ -51,6 +91,28 @@ describe Mock, ".install_method" do
51
91
  lambda { @mock.method_call(:d) }.should raise_error(ExpectationNotMetError)
52
92
  end
53
93
 
94
+ # This illustrates RSpec's behavior. This spec fails in mock call count verification
95
+ # on RSpec (i.e. Mock 'foo' expected :foo with (any args) once, but received it 0 times)
96
+ # and we mimic the behavior of RSpec.
97
+ #
98
+ # describe "A mock receiving multiple calls to #should_receive" do
99
+ # it "returns the first value mocked" do
100
+ # m = mock 'multiple #should_receive'
101
+ # m.should_receive(:foo).and_return(true)
102
+ # m.foo.should == true
103
+ # m.should_receive(:foo).and_return(false)
104
+ # m.foo.should == true
105
+ # end
106
+ # end
107
+ #
108
+ it "does not override a previously mocked method having the same arguments" do
109
+ Mock.install_method(@mock, :method_call).with(:a).and_return(true)
110
+ @mock.method_call(:a).should == true
111
+ Mock.install_method(@mock, :method_call).with(:a).and_return(false)
112
+ @mock.method_call(:a).should == true
113
+ lambda { Mock.verify_count }.should raise_error(ExpectationNotMetError)
114
+ end
115
+
54
116
  it "properly sends #respond_to? calls to the aliased respond_to? method when not matching mock expectations" do
55
117
  Mock.install_method(@mock, :respond_to?).with(:to_str).and_return('mock to_str')
56
118
  Mock.install_method(@mock, :respond_to?).with(:to_int).and_return('mock to_int')
@@ -66,6 +128,74 @@ describe Mock, ".install_method" do
66
128
  MSpec.should_receive(:current).and_return(state)
67
129
  MSpec.should_receive(:actions).with(:expectation, state.state)
68
130
  Mock.install_method(@mock, :method_call).and_return(1)
131
+ @mock.method_call.should == 1
132
+ end
133
+ end
134
+
135
+ describe Mock, ".install_method for stubs" do
136
+ before :each do
137
+ @mock = mock('install_method')
138
+ MSpec.stub!(:actions)
139
+ MSpec.stub!(:current).and_return(mock("spec state", :null_object => true))
140
+ end
141
+
142
+ after :each do
143
+ Mock.cleanup
144
+ end
145
+
146
+ it "returns a MockProxy instance" do
147
+ Mock.install_method(@mock, :method_call, :stub).should be_an_instance_of(MockProxy)
148
+ end
149
+
150
+ # This illustrates RSpec's behavior. This spec passes on RSpec and we mimic it
151
+ #
152
+ # describe "A mock receiving multiple calls to #stub!" do
153
+ # it "returns the last value stubbed" do
154
+ # m = mock 'multiple #stub!'
155
+ # m.stub!(:foo).and_return(true)
156
+ # m.foo.should == true
157
+ # m.stub!(:foo).and_return(false)
158
+ # m.foo.should == false
159
+ # end
160
+ # end
161
+ it "inserts new stubs before old stubs" do
162
+ Mock.install_method(@mock, :method_call, :stub).with(:a).and_return(true)
163
+ @mock.method_call(:a).should == true
164
+ Mock.install_method(@mock, :method_call, :stub).with(:a).and_return(false)
165
+ @mock.method_call(:a).should == false
166
+ Mock.verify_count
167
+ end
168
+
169
+ it "does not add to the expectation tally" do
170
+ state = mock("run state", :null_object => true)
171
+ state.stub!(:state).and_return(mock("spec state"))
172
+ MSpec.should_not_receive(:actions)
173
+ Mock.install_method(@mock, :method_call, :stub).and_return(1)
174
+ @mock.method_call.should == 1
175
+ end
176
+ end
177
+
178
+ describe Mock, ".install_method" do
179
+ before :each do
180
+ @mock = mock('install_method')
181
+ MSpec.stub!(:actions)
182
+ MSpec.stub!(:current).and_return(mock("spec state", :null_object => true))
183
+ end
184
+
185
+ after :each do
186
+ Mock.cleanup
187
+ end
188
+
189
+ it "does not alias a mocked or stubbed method when installing a new mock or stub" do
190
+ @mock.should_not respond_to(:method_call)
191
+
192
+ Mock.install_method @mock, :method_call
193
+ @mock.should respond_to(:method_call)
194
+ @mock.should_not respond_to(Mock.replaced_name(@mock, :method_call))
195
+
196
+ Mock.install_method @mock, :method_call, :stub
197
+ @mock.should respond_to(:method_call)
198
+ @mock.should_not respond_to(Mock.replaced_name(@mock, :method_call))
69
199
  end
70
200
  end
71
201
 
@@ -113,25 +243,25 @@ describe Mock, ".verify_call" do
113
243
  @proxy.with(:any_args)
114
244
  Mock.verify_call @mock, :method_call, 1, 2, 3
115
245
  end
116
-
246
+
117
247
  it "yields a passed block when it is expected to" do
118
248
  @proxy.and_yield()
119
- Mock.verify_call @mock, :method_call do
249
+ Mock.verify_call @mock, :method_call do
120
250
  ScratchPad.record true
121
251
  end
122
252
  ScratchPad.recorded.should == true
123
253
  end
124
-
254
+
125
255
  it "does not yield a passed block when it is not expected to" do
126
- Mock.verify_call @mock, :method_call do
256
+ Mock.verify_call @mock, :method_call do
127
257
  ScratchPad.record true
128
258
  end
129
259
  ScratchPad.recorded.should == nil
130
260
  end
131
-
261
+
132
262
  it "can yield subsequently" do
133
263
  @proxy.and_yield(1).and_yield(2).and_yield(3)
134
-
264
+
135
265
  ScratchPad.record []
136
266
  Mock.verify_call @mock, :method_call do |arg|
137
267
  ScratchPad << arg
@@ -141,7 +271,7 @@ describe Mock, ".verify_call" do
141
271
 
142
272
  it "can yield and return an expected value" do
143
273
  @proxy.and_yield(1).and_return(3)
144
-
274
+
145
275
  Mock.verify_call(@mock, :method_call) { |arg| ScratchPad.record arg }.should == 3
146
276
  ScratchPad.recorded.should == 1
147
277
  end
@@ -231,6 +361,38 @@ describe Mock, ".verify_count" do
231
361
  end
232
362
  end
233
363
 
364
+ describe Mock, ".verify_count mixing mocks and stubs" do
365
+ before :each do
366
+ MSpec.stub!(:actions)
367
+ MSpec.stub!(:current).and_return(mock("spec state", :null_object => true))
368
+
369
+ @mock = mock('verify_count')
370
+ end
371
+
372
+ after :each do
373
+ Mock.cleanup
374
+ end
375
+
376
+ it "does not raise an exception for a stubbed method that is never called" do
377
+ Mock.install_method @mock, :method_call, :stub
378
+ Mock.verify_count
379
+ end
380
+
381
+ it "verifies the calls to the mocked method when a mock is defined after a stub" do
382
+ Mock.install_method @mock, :method_call, :stub
383
+ Mock.install_method @mock, :method_call, :mock
384
+ @mock.method_call
385
+ Mock.verify_count
386
+ end
387
+
388
+ it "verifies the calls to the mocked method when a mock is defined before a stub" do
389
+ Mock.install_method @mock, :method_call, :mock
390
+ Mock.install_method @mock, :method_call, :stub
391
+ @mock.method_call
392
+ Mock.verify_count
393
+ end
394
+ end
395
+
234
396
  describe Mock, ".cleanup" do
235
397
  before :each do
236
398
  MSpec.stub!(:actions)
@@ -238,6 +400,7 @@ describe Mock, ".cleanup" do
238
400
 
239
401
  @mock = mock('cleanup')
240
402
  @proxy = Mock.install_method @mock, :method_call
403
+ @stub = Mock.install_method @mock, :method_call, :stub
241
404
  end
242
405
 
243
406
  after :each do
@@ -255,18 +418,23 @@ describe Mock, ".cleanup" do
255
418
  def @mock.already_here() :hey end
256
419
  @mock.should respond_to(:already_here)
257
420
  Mock.install_method @mock, :already_here
258
- @mock.should respond_to(Mock.replaced_name(:already_here))
421
+ @mock.should respond_to(Mock.replaced_name(@mock, :already_here))
259
422
 
260
423
  Mock.cleanup
261
- @mock.should_not respond_to(Mock.replaced_name(:already_here))
424
+ @mock.should_not respond_to(Mock.replaced_name(@mock, :already_here))
262
425
  @mock.should respond_to(:already_here)
263
426
  @mock.already_here.should == :hey
264
427
  end
265
428
 
266
429
  it "removes all mock expectations" do
267
- Mock.expects.should == { [@mock, :method_call] => [@proxy] }
430
+ Mock.mocks.should == { Mock.replaced_key(@mock, :method_call) => [@proxy] }
431
+ Mock.cleanup
432
+ Mock.mocks.should == {}
433
+ end
268
434
 
435
+ it "removes all stubs" do
436
+ Mock.stubs.should == { Mock.replaced_key(@mock, :method_call) => [@stub] }
269
437
  Mock.cleanup
270
- Mock.expects.should == {}
438
+ Mock.stubs.should == {}
271
439
  end
272
440
  end
@@ -1,21 +1,54 @@
1
1
  require File.dirname(__FILE__) + '/../spec_helper'
2
2
  require 'mspec/mocks/proxy'
3
3
 
4
- describe MockProxy, "reporting method" do
4
+ describe MockObject, ".new" do
5
+ it "creates a new mock object" do
6
+ m = MockObject.new('not a null object')
7
+ lambda { m.not_a_method }.should raise_error(NoMethodError)
8
+ end
9
+
10
+ it "creates a new mock object that follows the NullObject pattern" do
11
+ m = MockObject.new('null object', :null_object => true)
12
+ m.not_really_a_method.should equal(m)
13
+ end
14
+ end
15
+
16
+ describe MockProxy, ".new" do
17
+ it "creates a mock proxy by default" do
18
+ MockProxy.new.mock?.should be_true
19
+ end
20
+
21
+ it "creates a stub proxy by request" do
22
+ MockProxy.new(:stub).stub?.should be_true
23
+ end
24
+
25
+ it "sets the call expectation to 1 call for a mock" do
26
+ MockProxy.new.count.should == [:exactly, 1]
27
+ end
28
+
29
+ it "sets the call expectation to any number of times for a stub" do
30
+ MockProxy.new(:stub).count.should == [:any_number_of_times, 0]
31
+ end
32
+ end
33
+
34
+ describe MockProxy, "#count" do
5
35
  before :each do
6
36
  @proxy = MockProxy.new
7
37
  end
8
38
 
9
- it "returns the expected number of calls the mock should receive with #count" do
10
- @proxy.count.should == [:exactly, 0]
39
+ it "returns the expected number of calls the mock should receive" do
40
+ @proxy.count.should == [:exactly, 1]
41
+ @proxy.at_least(3).count.should == [:at_least, 3]
11
42
  end
43
+ end
12
44
 
13
- it "returns the expected arguments with #arguments" do
14
- @proxy.arguments.should == :any_args
45
+ describe MockProxy, "#arguments" do
46
+ before :each do
47
+ @proxy = MockProxy.new
15
48
  end
16
49
 
17
- it "returns the expected return value with #returning" do
18
- @proxy.returning.should == nil
50
+ it "returns the expected arguments" do
51
+ @proxy.arguments.should == :any_args
19
52
  end
20
53
  end
21
54
 
@@ -156,9 +189,9 @@ describe MockProxy, "#any_number_of_times" do
156
189
  @proxy.any_number_of_times.should be_equal(@proxy)
157
190
  end
158
191
 
159
- it "sets the expected calls to at least 0" do
192
+ it "sets the expected calls to any number of times" do
160
193
  @proxy.any_number_of_times
161
- @proxy.count.should == [:at_least, 0]
194
+ @proxy.count.should == [:any_number_of_times, 0]
162
195
  end
163
196
 
164
197
  it "does not accept an argument" do
@@ -172,7 +205,7 @@ describe MockProxy, "#and_return" do
172
205
  end
173
206
 
174
207
  it "returns self" do
175
- @proxy.and_return(false).should be_equal(@proxy)
208
+ @proxy.and_return(false).should equal(@proxy)
176
209
  end
177
210
 
178
211
  it "sets the expected return value" do
@@ -192,7 +225,7 @@ describe MockProxy, "#and_return" do
192
225
  @proxy.count.should == [:exactly, 3]
193
226
  end
194
227
 
195
- it "it only sets the expected number of calls if it is higher than what is already set" do
228
+ it "only sets the expected number of calls if it is higher than what is already set" do
196
229
  @proxy.at_least(5).times.and_return(1, 2, 3)
197
230
  @proxy.count.should == [:at_least, 5]
198
231
 
@@ -201,6 +234,32 @@ describe MockProxy, "#and_return" do
201
234
  end
202
235
  end
203
236
 
237
+ describe MockProxy, "#returning" do
238
+ before :each do
239
+ @proxy = MockProxy.new
240
+ end
241
+
242
+ it "returns nil by default" do
243
+ @proxy.returning.should be_nil
244
+ end
245
+
246
+ it "returns the value set by #and_return" do
247
+ @proxy.and_return(2)
248
+ @proxy.returning.should == 2
249
+ @proxy.returning.should == 2
250
+ end
251
+
252
+ it "returns a sequence of values set by #and_return" do
253
+ @proxy.and_return(1,2,3,4)
254
+ @proxy.returning.should == 1
255
+ @proxy.returning.should == 2
256
+ @proxy.returning.should == 3
257
+ @proxy.returning.should == 4
258
+ @proxy.returning.should == 4
259
+ @proxy.returning.should == 4
260
+ end
261
+ end
262
+
204
263
  describe MockProxy, "#calls" do
205
264
  before :each do
206
265
  @proxy = MockProxy.new
@@ -223,37 +282,85 @@ describe MockProxy, "#called" do
223
282
  end
224
283
  end
225
284
 
226
- describe MockProxy, "#returning" do
285
+ describe MockProxy, "#times" do
227
286
  before :each do
228
287
  @proxy = MockProxy.new
229
288
  end
230
289
 
231
- it "should return nil by default" do
232
- @proxy.returning.should be_nil
290
+ it "is a no-op" do
291
+ @proxy.times.should == @proxy
233
292
  end
293
+ end
234
294
 
235
- it "should return the value set by #and_return" do
236
- @proxy.and_return(2)
237
- @proxy.returning.should == 2
295
+ describe MockProxy, "#stub?" do
296
+ it "returns true if the proxy is created as a stub" do
297
+ MockProxy.new(:stub).stub?.should be_true
238
298
  end
239
299
 
240
- it "should return a sequence of values set by #and_return" do
241
- @proxy.and_return(1,2,3,4)
242
- @proxy.returning.should == 1
243
- @proxy.returning.should == 2
244
- @proxy.returning.should == 3
245
- @proxy.returning.should == 4
246
- @proxy.returning.should == 4
247
- @proxy.returning.should == 4
300
+ it "returns false if the proxy is created as a mock" do
301
+ MockProxy.new(:mock).stub?.should be_false
248
302
  end
249
303
  end
250
304
 
251
- describe MockProxy, "#times" do
305
+ describe MockProxy, "#mock?" do
306
+ it "returns true if the proxy is created as a mock" do
307
+ MockProxy.new(:mock).mock?.should be_true
308
+ end
309
+
310
+ it "returns false if the proxy is created as a stub" do
311
+ MockProxy.new(:stub).mock?.should be_false
312
+ end
313
+ end
314
+
315
+ describe MockProxy, "#and_yield" do
252
316
  before :each do
253
317
  @proxy = MockProxy.new
254
318
  end
255
319
 
256
- it "is a no-op" do
257
- @proxy.times.should == @proxy
320
+ it "returns self" do
321
+ @proxy.and_yield(false).should equal(@proxy)
322
+ end
323
+
324
+ it "sets the expected values to yield" do
325
+ @proxy.and_yield(1).yielding.should == [[1]]
326
+ end
327
+
328
+ it "accepts multiple values to yield" do
329
+ @proxy.and_yield(1, 2, 3).yielding.should == [[1, 2, 3]]
330
+ end
331
+ end
332
+
333
+ describe MockProxy, "#yielding" do
334
+ before :each do
335
+ @proxy = MockProxy.new
336
+ end
337
+
338
+ it "returns an empty array by default" do
339
+ @proxy.yielding.should == []
340
+ end
341
+
342
+ it "returns an array of arrays of values the proxy should yield" do
343
+ @proxy.and_yield(3)
344
+ @proxy.yielding.should == [[3]]
345
+ end
346
+
347
+ it "returns an accumulation of arrays of values the proxy should yield" do
348
+ @proxy.and_yield(1).and_yield(2, 3)
349
+ @proxy.yielding.should == [[1], [2, 3]]
350
+ end
351
+ end
352
+
353
+ describe MockProxy, "#yielding?" do
354
+ before :each do
355
+ @proxy = MockProxy.new
356
+ end
357
+
358
+ it "returns false if the proxy is not yielding" do
359
+ @proxy.yielding?.should be_false
360
+ end
361
+
362
+ it "returns true if the proxy is yielding" do
363
+ @proxy.and_yield(1)
364
+ @proxy.yielding?.should be_true
258
365
  end
259
366
  end