muack 1.3.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fa632f54941b0ba538198221b3d03ec320e9df35
4
- data.tar.gz: 386833604c697560c445c7df2ec677f5a5159cf2
3
+ metadata.gz: 309cafc82b9f7538884fa099e8ab6827d183afcf
4
+ data.tar.gz: 64a20f3374a9c72abe10c4c7a78f26651c04c09b
5
5
  SHA512:
6
- metadata.gz: 3c3ea805f32a36c9ec6bc82af5a705bae2ff4cbb059ab71c3dd2c1ed638784ee84d98ea244de4c95b72558e9da2256944c5d853aa9c9ea72f4c98b47014909bc
7
- data.tar.gz: ba26968d9d944c7263160bf6583d8a0cfdd1def6711122b90ef59d5af108c5696869d5f283ab40de9120602ca76b4a8c01408bc4fdcf882049a4cc8b26f8db18
6
+ metadata.gz: 312fd3143189a03c2c8d1fbe85a74296ccc71fd8247d09fc83ea8a5fc4ba3407fde7f7507e9c58d611cc476457b02d8b8ad614d1c6f9555694f2037c783eccc9
7
+ data.tar.gz: 658d76b3ddac4ad03c10f643f8e16f996d1250862995037c4460abf586423b1e389e851bf4f376004187dbe1069b765428b8993d9175130db5627be586a50c7c
data/CHANGES.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # CHANGES
2
2
 
3
+ ## Muack 1.4.0 -- 2015-11-21
4
+
5
+ ### Incompatible changes / Enhancement
6
+
7
+ * Spies would now do pattern matching like stubs for matching
8
+ method arguments. This could be an incompatible change if you're
9
+ relying on spies checking the order for the same method calls.
10
+ This change would make spies and stubs more similar. If you are
11
+ really into a specific order, use mocks instead.
12
+
3
13
  ## Muack 1.3.2 -- 2015-06-11
4
14
 
5
15
  * Fixed a bug for `where`, `having`, and `allowing` which should distinguish
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Muack [![Build Status](https://secure.travis-ci.org/godfat/muack.png?branch=master)](http://travis-ci.org/godfat/muack) [![Coverage Status](https://coveralls.io/repos/godfat/muack/badge.png?branch=master)](https://coveralls.io/r/godfat/muack?branch=master)
1
+ # Muack [![Build Status](https://secure.travis-ci.org/godfat/muack.png?branch=master)](http://travis-ci.org/godfat/muack) [![Coverage Status](https://coveralls.io/repos/godfat/muack/badge.png?branch=master)](https://coveralls.io/r/godfat/muack?branch=master) [![Join the chat at https://gitter.im/godfat/muack](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/godfat/muack)
2
2
 
3
3
  by Lin Jen-Shin ([godfat](http://godfat.org))
4
4
 
@@ -39,9 +39,9 @@ Here's a quick example using [Pork][].
39
39
  require 'pork/auto'
40
40
  require 'muack'
41
41
 
42
- include Muack::API
43
-
44
42
  describe 'Hello' do
43
+ include Muack::API
44
+
45
45
  before{ Muack.reset }
46
46
  after { Muack.verify }
47
47
 
@@ -98,7 +98,7 @@ p obj.name # 'obj'
98
98
  p Muack.verify # true
99
99
  ```
100
100
 
101
- Which is roughly semantically equivalent to using a stub with a spy:
101
+ Which is similar to using a stub with a spy:
102
102
 
103
103
  ``` ruby
104
104
  obj = Object.new
@@ -143,6 +143,11 @@ p Muack.verify # true
143
143
  However you should not mix mocks and stubs with the same method, or you
144
144
  might encounter some unexpected result. Jump to _Caveat_ for more detail.
145
145
 
146
+ The other differences for stubs and spies, please check
147
+ [Pattern Matching for stubs and spies][pattern-matching].
148
+ In short, stubs and spies would do some kind of pattern matching,
149
+ making the order of the same method irrelevant.
150
+
146
151
  On the other hand, stubs aren't limited to testing. If we want to monkey
147
152
  patching something, stubs could be useful as we don't care how many times
148
153
  the injected methods are called. Jump to _Muack as a mocky patching library_
@@ -326,7 +331,7 @@ If the order is reversed, then it would always return the original value,
326
331
  because the proxy would always match, and Muack would stop searching the
327
332
  next stub.
328
333
 
329
- [pattern-matching]: #arguments-verifiers-satisfy
334
+ [pattern-matching]: #pattern-matching-for-stubs-and-spies
330
335
 
331
336
  #### any_instance_of mode
332
337
 
@@ -446,7 +451,7 @@ p Muack.verify # true
446
451
 
447
452
  Note that it does not make sense to specify `times` for stubs, because
448
453
  stubs don't care about times. Spies do, though. So this is also
449
- semantically equivalent to below:
454
+ similar to below:
450
455
 
451
456
  ``` ruby
452
457
  obj = Object.new
@@ -708,6 +713,8 @@ obj.say{ |msg| p msg } # 'Hi'
708
713
  p Muack.verify # true
709
714
  ```
710
715
 
716
+ #### Pattern Matching for stubs and spies
717
+
711
718
  Moreover, we could also have stubs on the same method for different
712
719
  arguments. We could think of this as a sort of pattern matching, and Muack
713
720
  would try to find the best matched stub for us.
@@ -722,7 +729,8 @@ p Muack.verify # true
722
729
  ```
723
730
 
724
731
  If `obj.find(2)` is called and Muack cannot find a matched stub, it would
725
- raise a `Muack::Unexpected` and list the candidates for us.
732
+ raise a `Muack::Unexpected` and list the candidates for us. This also
733
+ applies to spies.
726
734
 
727
735
  However, What if we don't want to be so exact? Then we should use verifiers.
728
736
  We'll introduce each of them in next section. Note that verifiers
@@ -1114,7 +1122,7 @@ Consider we have two classes:
1114
1122
 
1115
1123
  ``` ruby
1116
1124
  Food = Class.new
1117
- User = Class.new{ attr_accessor :food }
1125
+ User = Class.new(Struct.new(:food))
1118
1126
  ```
1119
1127
 
1120
1128
  And we could make sure User#food is always a kind of `Food` by putting this
@@ -1141,7 +1149,7 @@ verifiers. For example, we could do this to check if the food is frozen:
1141
1149
 
1142
1150
  ``` ruby
1143
1151
  Food = Class.new
1144
- User = Class.new{ attr_accessor :food }
1152
+ User = Class.new(Struct.new(:food))
1145
1153
 
1146
1154
  FoodFrozen = Class.new(Muack::Satisfying) do
1147
1155
  def match actual_arg
@@ -61,14 +61,7 @@ module Muack
61
61
  Unexpected.new(object, [defi], msg, actual_args))
62
62
  end
63
63
  else
64
- defis = __mock_disps[msg]
65
- if expected = defis.find{ |d| __mock_check_args(d.args, actual_args) }
66
- Mock.__send__(:raise, # Too many times
67
- Expected.new(object, expected, defis.size, defis.size+1))
68
- else
69
- Mock.__send__(:raise, # Wrong argument
70
- Unexpected.new(object, defis, msg, actual_args))
71
- end
64
+ __mock_failed(msg, actual_args)
72
65
  end
73
66
  end
74
67
 
@@ -178,6 +171,17 @@ module Muack
178
171
  target.__send__(privilege, defi.msg)
179
172
  end
180
173
 
174
+ # used for __mock_dispatch
175
+ def __mock_failed msg, actual_args, disps=__mock_disps[msg]
176
+ if expected = __mock_find_checked_difi(disps, actual_args)
177
+ Mock.__send__(:raise, # Too many times
178
+ Expected.new(object, expected, disps.size, disps.size+1))
179
+ else
180
+ Mock.__send__(:raise, # Wrong argument
181
+ Unexpected.new(object, disps, msg, actual_args))
182
+ end
183
+ end
184
+
181
185
  # used for __mock_dispatch_call
182
186
  def __mock_block_call context, block, actual_args, actual_block, splat
183
187
  return unless block
@@ -191,6 +195,10 @@ module Muack
191
195
  end
192
196
  end
193
197
 
198
+ def __mock_find_checked_difi defis, actual_args, meth=:find
199
+ defis.public_send(meth){ |d| __mock_check_args(d.args, actual_args) }
200
+ end
201
+
194
202
  def __mock_check_args expected_args, actual_args
195
203
  if expected_args == [WithAnyArgs]
196
204
  true
@@ -10,10 +10,8 @@ module Muack
10
10
 
11
11
  # used for Muack::Session#verify
12
12
  def __mock_verify
13
- @stub.__mock_disps.values.flatten.each do |defi|
14
- __mock_dispatch(defi.msg, defi.args) if __mock_defis.key?(defi.msg)
15
- end
16
- super # simulate dispatching before passing to mock to verify
13
+ __mock_dispatch_spy
14
+ super
17
15
  end
18
16
 
19
17
  # used for Muack::Session#reset, but spies never leave any track
@@ -21,5 +19,21 @@ module Muack
21
19
 
22
20
  private
23
21
  def __mock_inject_method defi; end # spies don't leave any track
22
+
23
+ # simulate dispatching before passing to mock to verify
24
+ def __mock_dispatch_spy
25
+ @stub.__mock_disps.values.flatten.each do |disp|
26
+ next unless __mock_defis.key?(disp.msg) # ignore undefined spies
27
+
28
+ defis = __mock_defis[disp.msg]
29
+ if idx = __mock_find_checked_difi(defis, disp.args, :index)
30
+ __mock_disps_push(defis.delete_at(idx)) # found, dispatch it
31
+ elsif defis.empty? # show called candidates
32
+ __mock_failed(disp.msg, disp.args)
33
+ else # show expected candidates
34
+ __mock_failed(disp.msg, disp.args, defis)
35
+ end
36
+ end
37
+ end
24
38
  end
25
39
  end
@@ -15,8 +15,7 @@ module Muack
15
15
 
16
16
  # used for mocked object to dispatch mocked method
17
17
  def __mock_dispatch msg, actual_args
18
- if defi = __mock_defis[msg].find{ |d|
19
- __mock_check_args(d.args, actual_args) }
18
+ if defi = __mock_find_checked_difi(__mock_defis[msg], actual_args)
20
19
  # our spies are interested in this
21
20
  __mock_disps_push(Definition.new(msg, actual_args))
22
21
  defi
@@ -1,4 +1,4 @@
1
1
 
2
2
  module Muack
3
- VERSION = '1.3.2'
3
+ VERSION = '1.4.0'
4
4
  end
@@ -1,14 +1,14 @@
1
1
  # -*- encoding: utf-8 -*-
2
- # stub: muack 1.3.2 ruby lib
2
+ # stub: muack 1.4.0 ruby lib
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "muack"
6
- s.version = "1.3.2"
6
+ s.version = "1.4.0"
7
7
 
8
8
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
9
9
  s.require_paths = ["lib"]
10
10
  s.authors = ["Lin Jen-Shin (godfat)"]
11
- s.date = "2015-06-11"
11
+ s.date = "2015-11-21"
12
12
  s.description = "Muack -- A fast, small, yet powerful mocking library.\n\nInspired by [RR][], and it's 32x times faster (750s vs 23s) than RR\nfor running [Rib][] tests.\n\n[RR]: https://github.com/rr/rr\n[Rib]: https://github.com/godfat/rib"
13
13
  s.email = ["godfat (XD) godfat.org"]
14
14
  s.files = [
@@ -45,10 +45,11 @@ Gem::Specification.new do |s|
45
45
  "test/test_modifier.rb",
46
46
  "test/test_proxy.rb",
47
47
  "test/test_satisfying.rb",
48
+ "test/test_spy.rb",
48
49
  "test/test_stub.rb"]
49
50
  s.homepage = "https://github.com/godfat/muack"
50
51
  s.licenses = ["Apache License 2.0"]
51
- s.rubygems_version = "2.4.8"
52
+ s.rubygems_version = "2.5.0"
52
53
  s.summary = "Muack -- A fast, small, yet powerful mocking library."
53
54
  s.test_files = [
54
55
  "test/test_any_instance_of.rb",
@@ -58,5 +59,6 @@ Gem::Specification.new do |s|
58
59
  "test/test_modifier.rb",
59
60
  "test/test_proxy.rb",
60
61
  "test/test_satisfying.rb",
62
+ "test/test_spy.rb",
61
63
  "test/test_stub.rb"]
62
64
  end
@@ -79,6 +79,11 @@ module Gemgem
79
79
  end
80
80
 
81
81
  def gem_check
82
+ unless git('status', '--porcelain').empty?
83
+ puts("\e[35mWorking copy is not clean.\e[0m")
84
+ exit(3)
85
+ end
86
+
82
87
  ver = spec.version.to_s
83
88
 
84
89
  if ENV['VERSION'].nil?
@@ -0,0 +1,149 @@
1
+
2
+ require 'muack/test'
3
+
4
+ describe Muack::Spy do
5
+ describe 'Muack.verify==true' do
6
+ after do
7
+ Muack.verify.should.eq true
8
+ Muack::EnsureReset.call
9
+ end
10
+
11
+ would 'inspect' do
12
+ spy( Obj).inspect.should.eq "Muack::API.spy(obj)"
13
+ end
14
+
15
+ would 'work with spy' do
16
+ stub(Obj).say{0}
17
+ Obj.say.should.eq 0
18
+ spy(Obj).say
19
+ end
20
+
21
+ would 'work with spy twice' do
22
+ stub(Obj).say{}
23
+ 2.times{ Obj.say.should.eq nil }
24
+ spy(Obj).say.times(2)
25
+ end
26
+
27
+ would 'work with spy spy' do
28
+ stub(Obj).say{}
29
+ 2.times{ Obj.say.should.eq nil }
30
+ 2.times{ spy(Obj).say }
31
+ end
32
+
33
+ would 'work with call spy and call spy' do
34
+ stub(Obj).say{}
35
+ 2.times do
36
+ Obj.say.should.eq nil
37
+ spy(Obj).say
38
+ end
39
+ end
40
+
41
+ would 'verify spy arguments' do
42
+ stub(Obj).say(1){|a|a}
43
+ Obj.say(1).should.eq 1
44
+ spy(Obj).say(1)
45
+ end
46
+
47
+ would 'properly verify spy arguments' do
48
+ stub(Obj).say(is_a(String)){|a|a}
49
+ Obj.say('Hi!').should.eq 'Hi!'
50
+ spy(Obj).say(is_a(String))
51
+ end
52
+
53
+ would 'ignore messages spies not interested' do
54
+ stub(Obj).saya{0}
55
+ stub(Obj).sayb{1}
56
+ Obj.saya.should.eq 0
57
+ Obj.sayb.should.eq 1
58
+ spy(Obj).saya
59
+ end
60
+
61
+ would 'not care about the order' do
62
+ stub(Obj).say(is_a(Fixnum)){|i|i} # change to &:itself in the future
63
+ Obj .say(1).should.eq 1
64
+ Obj .say(2).should.eq 2
65
+ spy(Obj).say(2)
66
+ spy(Obj).say(1)
67
+ end
68
+ end
69
+
70
+ describe 'Muack.verify==false' do
71
+ after do
72
+ Muack.reset
73
+ Muack::EnsureReset.call
74
+ end
75
+
76
+ would 'raise Expected if it is not satisfied' do
77
+ stub(Obj).say{}
78
+ spy(Obj).say
79
+ e = should.raise(Muack::Expected){ Muack.verify }
80
+ e.expected .should.eq 'obj.say()'
81
+ e.expected_times.should.eq 1
82
+ e.actual_times .should.eq 0
83
+ e.message .should.eq "\nExpected: obj.say()\n " \
84
+ "called 1 times\n but was 0 times."
85
+ end
86
+
87
+ would 'show correct times for under satisfaction' do
88
+ stub(Obj).say{}
89
+ 2.times{ Obj.say }
90
+ spy(Obj).say.times(3)
91
+ e = should.raise(Muack::Expected){ Muack.verify }
92
+ e.expected .should.eq 'obj.say()'
93
+ e.expected_times.should.eq 3
94
+ e.actual_times .should.eq 2
95
+ e.message .should.eq "\nExpected: obj.say()\n " \
96
+ "called 3 times\n but was 2 times."
97
+ end
98
+
99
+ would 'show correct times for over satisfaction' do
100
+ stub(Obj).say{}
101
+ 2.times{ Obj.say }
102
+ spy(Obj).say
103
+ e = should.raise(Muack::Expected){ Muack.verify }
104
+ e.expected .should.eq 'obj.say()'
105
+ e.expected_times.should.eq 1
106
+ e.actual_times .should.eq 2
107
+ e.message .should.eq "\nExpected: obj.say()\n " \
108
+ "called 1 times\n but was 2 times."
109
+ end
110
+
111
+ would 'raise Expected if arguments do not match' do
112
+ stub(Obj).say(is_a(Fixnum)){}
113
+ Obj .say(1)
114
+ spy(Obj).say(0)
115
+ e = should.raise(Muack::Unexpected){ Muack.verify }
116
+ e.expected.should.eq "obj.say(0)"
117
+ e.was .should.eq 'obj.say(1)'
118
+ e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
119
+ end
120
+
121
+ would 'raise Expected if arguments do not match, show original args' do
122
+ stub(Obj).say(is_a(Fixnum)){}
123
+ Obj .say(0)
124
+ Obj .say(1)
125
+ Obj .say(2)
126
+ spy(Obj).say(within(1..1))
127
+ spy(Obj).say(within(0..0))
128
+ e = should.raise(Muack::Unexpected){ Muack.verify }
129
+ e.expected.should.eq "obj.say(Muack::API.within(0..0))\n" \
130
+ " or: obj.say(Muack::API.within(1..1))"
131
+ e.was .should.eq 'obj.say(2)'
132
+ e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
133
+ end
134
+
135
+ would 'raise Expected if arguments do not match, show original args' do
136
+ stub(Obj).say(is_a(Fixnum)){}
137
+ Obj .say(2)
138
+ Obj .say(0)
139
+ Obj .say(1)
140
+ spy(Obj).say(within(1..1))
141
+ spy(Obj).say(within(0..0))
142
+ e = should.raise(Muack::Unexpected){ Muack.verify }
143
+ e.expected.should.eq "obj.say(Muack::API.within(1..1))\n" \
144
+ " or: obj.say(Muack::API.within(0..0))"
145
+ e.was .should.eq 'obj.say(2)'
146
+ e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
147
+ end
148
+ end
149
+ end
@@ -16,10 +16,6 @@ describe Muack::Stub do
16
16
  stub(Obj).inspect.should.eq "Muack::API.stub(obj)"
17
17
  end
18
18
 
19
- would 'inspect' do
20
- spy( Obj).inspect.should.eq "Muack::API.spy(obj)"
21
- end
22
-
23
19
  would 'stub with regular method' do
24
20
  stub(Obj).say{ 'goo' }
25
21
  3.times{ Obj.say.should.eq 'goo' }
@@ -43,52 +39,6 @@ describe Muack::Stub do
43
39
  Obj.saya.should.eq 1
44
40
  Obj.say .should.eq 0
45
41
  end
46
-
47
- would 'work with spy' do
48
- stub(Obj).say{0}
49
- Obj.say.should.eq 0
50
- spy(Obj).say
51
- end
52
-
53
- would 'work with spy twice' do
54
- stub(Obj).say{}
55
- 2.times{ Obj.say.should.eq nil }
56
- spy(Obj).say.times(2)
57
- end
58
-
59
- would 'work with spy spy' do
60
- stub(Obj).say{}
61
- 2.times{ Obj.say.should.eq nil }
62
- 2.times{ spy(Obj).say }
63
- end
64
-
65
- would 'work with call spy and call spy' do
66
- stub(Obj).say{}
67
- 2.times do
68
- Obj.say.should.eq nil
69
- spy(Obj).say
70
- end
71
- end
72
-
73
- would 'verify spy arguments' do
74
- stub(Obj).say(1){|a|a}
75
- Obj.say(1).should.eq 1
76
- spy(Obj).say(1)
77
- end
78
-
79
- would 'properly verify spy arguments' do
80
- stub(Obj).say(is_a(String)){|a|a}
81
- Obj.say('Hi!').should.eq 'Hi!'
82
- spy(Obj).say(is_a(String))
83
- end
84
-
85
- would 'ignore messages spies not interested' do
86
- stub(Obj).saya{0}
87
- stub(Obj).sayb{1}
88
- Obj.saya.should.eq 0
89
- Obj.sayb.should.eq 1
90
- spy(Obj).saya
91
- end
92
42
  end
93
43
 
94
44
  describe 'Muack.verify==false' do
@@ -113,50 +63,5 @@ describe Muack::Stub do
113
63
  e.was .should.eq 'obj.say(false)'
114
64
  e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
115
65
  end
116
-
117
- would 'raise Expected if the spy is not satisfied' do
118
- stub(Obj).say{}
119
- spy(Obj).say
120
- e = should.raise(Muack::Expected){ Muack.verify }
121
- e.expected .should.eq 'obj.say()'
122
- e.expected_times.should.eq 1
123
- e.actual_times .should.eq 0
124
- e.message .should.eq "\nExpected: obj.say()\n " \
125
- "called 1 times\n but was 0 times."
126
- end
127
-
128
- would 'raise Expected if the spy is not satisfied enough' do
129
- stub(Obj).say{}
130
- Obj.say
131
- spy(Obj).say(0)
132
- e = should.raise(Muack::Unexpected){ Muack.verify }
133
- e.expected.should.eq "obj.say(0)"
134
- e.was .should.eq 'obj.say()'
135
- e.message .should.eq "\nExpected: #{e.expected}\n but was: #{e.was}"
136
- end
137
-
138
- would 'show correct times for under satisfaction' do
139
- stub(Obj).say{}
140
- 2.times{ Obj.say }
141
- spy(Obj).say.times(3)
142
- e = should.raise(Muack::Expected){ Muack.verify }
143
- e.expected .should.eq 'obj.say()'
144
- e.expected_times.should.eq 3
145
- e.actual_times .should.eq 2
146
- e.message .should.eq "\nExpected: obj.say()\n " \
147
- "called 3 times\n but was 2 times."
148
- end
149
-
150
- would 'show correct times for over satisfaction' do
151
- stub(Obj).say{}
152
- 2.times{ Obj.say }
153
- spy(Obj).say
154
- e = should.raise(Muack::Expected){ Muack.verify }
155
- e.expected .should.eq 'obj.say()'
156
- e.expected_times.should.eq 1
157
- e.actual_times .should.eq 2
158
- e.message .should.eq "\nExpected: obj.say()\n " \
159
- "called 1 times\n but was 2 times."
160
- end
161
66
  end
162
67
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: muack
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.2
4
+ version: 1.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lin Jen-Shin (godfat)
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-11 00:00:00.000000000 Z
11
+ date: 2015-11-21 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: |-
14
14
  Muack -- A fast, small, yet powerful mocking library.
@@ -57,6 +57,7 @@ files:
57
57
  - test/test_modifier.rb
58
58
  - test/test_proxy.rb
59
59
  - test/test_satisfying.rb
60
+ - test/test_spy.rb
60
61
  - test/test_stub.rb
61
62
  homepage: https://github.com/godfat/muack
62
63
  licenses:
@@ -78,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
78
79
  version: '0'
79
80
  requirements: []
80
81
  rubyforge_project:
81
- rubygems_version: 2.4.8
82
+ rubygems_version: 2.5.0
82
83
  signing_key:
83
84
  specification_version: 4
84
85
  summary: Muack -- A fast, small, yet powerful mocking library.
@@ -90,4 +91,5 @@ test_files:
90
91
  - test/test_modifier.rb
91
92
  - test/test_proxy.rb
92
93
  - test/test_satisfying.rb
94
+ - test/test_spy.rb
93
95
  - test/test_stub.rb