spy 0.4.1 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.tool-versions +1 -0
- data/.travis.yml +7 -5
- data/CHANGELOG.md +24 -0
- data/README.md +3 -2
- data/Rakefile +1 -1
- data/lib/spy.rb +0 -2
- data/lib/spy/api.rb +2 -2
- data/lib/spy/integration.rb +4 -2
- data/lib/spy/subroutine.rb +79 -24
- data/lib/spy/version.rb +1 -1
- data/spy.gemspec +5 -4
- data/test/integration/test_api.rb +1 -1
- data/test/integration/test_constant_spying.rb +4 -4
- data/test/integration/test_instance_method.rb +7 -1
- data/test/integration/test_mocking.rb +1 -1
- data/test/integration/test_subroutine_spying.rb +3 -3
- data/test/spy/test_mock.rb +3 -3
- data/test/spy/test_subroutine.rb +50 -6
- data/test/support/pen.rb +15 -5
- data/test/test_helper.rb +4 -2
- metadata +42 -28
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: aa89505674a7286f055ee019988cf29debbdd5cb7e525a022864f551d20ae842
|
4
|
+
data.tar.gz: fa61fa5e78f5aea6fab75bcc471bdcc8032182d8e9c7528e9370b91022ef7ae0
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: abb91b0bcef139e03b90cb59f2f1b5d9f0c52c8137beafab301f56a96d44dbcffc203bcf0c69cd7e5376bed68549e0bb9bf407b4f85e07fc91d875d401ce39d0
|
7
|
+
data.tar.gz: 58d355373220b031ba5740b0cfdc2a6d9bb94a7c39166fafae23896342eec3c3b907994f7224e80abc7f2d1ae289048d98cd56a05750569befa62c98f6330a22
|
data/.tool-versions
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
ruby 2.7.0
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
## Spy 1.0.1 (August 20th, 2020) ##
|
2
|
+
|
3
|
+
* Fix call_through w/ instance methods (@lreeves)
|
4
|
+
* Replace implicit Proc.new by explicit given block reference (@Hugo-Hache)
|
5
|
+
* Remove 2.7 warnings (@byroot)
|
6
|
+
|
7
|
+
## Spy 1.0.0 (October 10, 2018) ##
|
8
|
+
|
9
|
+
* drop support for ruby 1.9.3, 2.0. Only support 2.1+ (@dylanahsmith)
|
10
|
+
* support named arguments (@dylanahsmith)
|
11
|
+
* Fix readme (@ignat-z)
|
12
|
+
|
13
|
+
## Spy 0.4.3 (April 14, 2016) ##
|
14
|
+
|
15
|
+
* Double performance of spy lookups (@BlakeMesdag)
|
16
|
+
|
17
|
+
## Spy 0.4.2 ##
|
18
|
+
|
19
|
+
* Support for minitest 5.1
|
20
|
+
|
21
|
+
## Spy 0.4.1 ##
|
22
|
+
|
23
|
+
* Support for minitest 5.0
|
24
|
+
|
1
25
|
## Spy 0.4.0 (May 8, 2013) ##
|
2
26
|
|
3
27
|
* Allow `Spy#have_received_with` to accept a block
|
data/README.md
CHANGED
@@ -9,7 +9,8 @@
|
|
9
9
|
|
10
10
|
Spy is a lightweight stubbing framework with support for method spies, constant stubs, and object mocks.
|
11
11
|
|
12
|
-
Spy
|
12
|
+
Spy supports ruby 2.1.0+.
|
13
|
+
For versions less than 2.1 use v0.4.5
|
13
14
|
|
14
15
|
Spy features that were completed were tested against the rspec-mocks tests so it covers all cases that rspec-mocks does.
|
15
16
|
|
@@ -197,7 +198,7 @@ In your test file
|
|
197
198
|
```ruby
|
198
199
|
def test_title
|
199
200
|
book = Book.new
|
200
|
-
title_spy = Spy.on(book, title)
|
201
|
+
title_spy = Spy.on(book, :title)
|
201
202
|
book.title
|
202
203
|
book.title
|
203
204
|
|
data/Rakefile
CHANGED
data/lib/spy.rb
CHANGED
data/lib/spy/api.rb
CHANGED
data/lib/spy/integration.rb
CHANGED
@@ -10,9 +10,11 @@ module Spy
|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
13
|
-
if defined?(::MiniTest::Unit::TestCase)
|
13
|
+
if defined?(::MiniTest::Unit::TestCase) && !::MiniTest::Unit::TestCase.include?(MiniTestAdapter)
|
14
14
|
::MiniTest::Unit::TestCase.send(:include, MiniTestAdapter)
|
15
|
-
|
15
|
+
end
|
16
|
+
|
17
|
+
if defined?(::Minitest::Test) && !::Minitest::Test.include?(MiniTestAdapter)
|
16
18
|
::Minitest::Test.send(:include, MiniTestAdapter)
|
17
19
|
end
|
18
20
|
end
|
data/lib/spy/subroutine.rb
CHANGED
@@ -32,6 +32,7 @@ module Spy
|
|
32
32
|
def initialize(object, method_name, singleton_method = true)
|
33
33
|
@base_object, @method_name = object, method_name
|
34
34
|
@singleton_method = singleton_method
|
35
|
+
@plan = nil
|
35
36
|
reset!
|
36
37
|
end
|
37
38
|
|
@@ -51,8 +52,21 @@ module Spy
|
|
51
52
|
@original_method = current_method
|
52
53
|
end
|
53
54
|
|
54
|
-
|
55
|
-
|
55
|
+
if original_method && original_method.owner == base_object
|
56
|
+
original_method.owner.send(:remove_method, method_name)
|
57
|
+
end
|
58
|
+
|
59
|
+
if singleton_method
|
60
|
+
if base_object.singleton_class.method_defined?(method_name) || base_object.singleton_class.private_method_defined?(method_name)
|
61
|
+
base_object.singleton_class.alias_method(method_name, method_name)
|
62
|
+
end
|
63
|
+
base_object.define_singleton_method(method_name, override_method)
|
64
|
+
else
|
65
|
+
if base_object.method_defined?(method_name) || base_object.private_method_defined?(method_name)
|
66
|
+
base_object.alias_method(method_name, method_name)
|
67
|
+
end
|
68
|
+
base_object.define_method(method_name, override_method)
|
69
|
+
end
|
56
70
|
|
57
71
|
if [:public, :protected, :private].include? hook_opts[:visibility]
|
58
72
|
method_owner.send(hook_opts[:visibility], method_name)
|
@@ -68,11 +82,10 @@ module Spy
|
|
68
82
|
def unhook
|
69
83
|
raise NeverHookedError, "'#{method_name}' method has not been hooked" unless hooked?
|
70
84
|
|
85
|
+
method_owner.send(:remove_method, method_name)
|
71
86
|
if original_method && method_owner == original_method.owner
|
72
|
-
|
73
|
-
|
74
|
-
else
|
75
|
-
method_owner.send(:remove_method, method_name)
|
87
|
+
original_method.owner.send(:define_method, method_name, original_method)
|
88
|
+
original_method.owner.send(original_method_visibility, method_name) if original_method_visibility
|
76
89
|
end
|
77
90
|
|
78
91
|
clear_method!
|
@@ -104,7 +117,7 @@ module Spy
|
|
104
117
|
# spy.and_return(force: true) { |invalid_arity| true }
|
105
118
|
#
|
106
119
|
# @return [self]
|
107
|
-
def and_return(value = nil)
|
120
|
+
def and_return(value = nil, &block)
|
108
121
|
@do_not_check_plan_arity = false
|
109
122
|
|
110
123
|
if block_given?
|
@@ -114,7 +127,7 @@ module Spy
|
|
114
127
|
raise ArgumentError, "value and block conflict. Choose one"
|
115
128
|
end
|
116
129
|
|
117
|
-
@plan =
|
130
|
+
@plan = block
|
118
131
|
check_for_too_many_arguments!(@plan)
|
119
132
|
else
|
120
133
|
@plan = Proc.new { value }
|
@@ -135,13 +148,29 @@ module Spy
|
|
135
148
|
# tells the spy to call the original method
|
136
149
|
# @return [self]
|
137
150
|
def and_call_through
|
138
|
-
@
|
139
|
-
|
140
|
-
original_method
|
141
|
-
|
142
|
-
|
151
|
+
if @base_object.is_a? Class
|
152
|
+
@plan = Proc.new do |object, *args, &block|
|
153
|
+
if original_method
|
154
|
+
if original_method.is_a? UnboundMethod
|
155
|
+
bound_method = original_method.bind(object)
|
156
|
+
bound_method.call(*args, &block)
|
157
|
+
else
|
158
|
+
original_method.call(*args, &block)
|
159
|
+
end
|
160
|
+
else
|
161
|
+
base_object.send(:method_missing, method_name, *args, &block)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
else
|
165
|
+
@plan = Proc.new do |*args, &block|
|
166
|
+
if original_method
|
167
|
+
original_method.call(*args, &block)
|
168
|
+
else
|
169
|
+
base_object.send(:method_missing, method_name, *args, &block)
|
170
|
+
end
|
143
171
|
end
|
144
172
|
end
|
173
|
+
|
145
174
|
self
|
146
175
|
end
|
147
176
|
|
@@ -167,6 +196,7 @@ module Spy
|
|
167
196
|
end
|
168
197
|
|
169
198
|
@plan = Proc.new { raise exception }
|
199
|
+
self
|
170
200
|
end
|
171
201
|
|
172
202
|
# @overload and_throw(symbol)
|
@@ -191,9 +221,9 @@ module Spy
|
|
191
221
|
# check if the method was called with the exact arguments
|
192
222
|
# @param args Arguments that should have been sent to the method
|
193
223
|
# @return [Boolean]
|
194
|
-
def has_been_called_with?(*args)
|
224
|
+
def has_been_called_with?(*args, &block)
|
195
225
|
raise NeverHookedError unless @was_hooked
|
196
|
-
match = block_given? ?
|
226
|
+
match = block_given? ? block : proc { |call| call.args == args }
|
197
227
|
calls.any?(&match)
|
198
228
|
end
|
199
229
|
|
@@ -201,10 +231,18 @@ module Spy
|
|
201
231
|
# method.
|
202
232
|
def invoke(object, args, block, called_from)
|
203
233
|
check_arity!(args.size)
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
234
|
+
|
235
|
+
if base_object.is_a? Class
|
236
|
+
result = if @plan
|
237
|
+
check_for_too_many_arguments!(@plan)
|
238
|
+
@plan.call(object, *args, &block)
|
239
|
+
end
|
240
|
+
else
|
241
|
+
result = if @plan
|
242
|
+
check_for_too_many_arguments!(@plan)
|
243
|
+
@plan.call(*args, &block)
|
244
|
+
end
|
245
|
+
end
|
208
246
|
ensure
|
209
247
|
calls << CallLog.new(object, called_from, args, block, result)
|
210
248
|
end
|
@@ -222,11 +260,12 @@ module Spy
|
|
222
260
|
# this returns a lambda that calls the spy object.
|
223
261
|
# we use eval to set the spy object id as a parameter so it can be extracted
|
224
262
|
# and looked up later using `Method#parameters`
|
263
|
+
SPY_ARGS_PREFIX='__spy_args_'.freeze
|
225
264
|
def override_method
|
226
265
|
eval <<-METHOD, binding, __FILE__, __LINE__ + 1
|
227
266
|
__method_spy__ = self
|
228
|
-
lambda do
|
229
|
-
__method_spy__.invoke(self,
|
267
|
+
lambda do |*#{SPY_ARGS_PREFIX}#{self.object_id}, &block|
|
268
|
+
__method_spy__.invoke(self, #{SPY_ARGS_PREFIX}#{self.object_id}, block, caller(1)[0])
|
230
269
|
end
|
231
270
|
METHOD
|
232
271
|
end
|
@@ -271,6 +310,8 @@ module Spy
|
|
271
310
|
min_arity = block.arity
|
272
311
|
min_arity = min_arity.abs - 1 if min_arity < 0
|
273
312
|
|
313
|
+
min_arity -=1 if base_object.is_a? Class # Instance-method procs take an extra param for receiving object
|
314
|
+
|
274
315
|
if min_arity > arity_range.max
|
275
316
|
raise ArgumentError.new("block requires #{min_arity} arguments while original_method require a maximum of #{arity_range.max}")
|
276
317
|
end
|
@@ -280,6 +321,8 @@ module Spy
|
|
280
321
|
@arity_range ||=
|
281
322
|
if original_method
|
282
323
|
min = max = 0
|
324
|
+
key_args = false
|
325
|
+
opt_keys = false
|
283
326
|
original_method.parameters.each do |type,_|
|
284
327
|
case type
|
285
328
|
when :req
|
@@ -289,8 +332,17 @@ module Spy
|
|
289
332
|
max += 1
|
290
333
|
when :rest
|
291
334
|
max = Float::INFINITY
|
335
|
+
when :keyreq
|
336
|
+
key_args = true
|
337
|
+
when :keyrest, :key
|
338
|
+
key_args = true
|
339
|
+
opt_keys = true
|
292
340
|
end
|
293
341
|
end
|
342
|
+
if key_args
|
343
|
+
max += 1
|
344
|
+
min += 1 unless opt_keys
|
345
|
+
end
|
294
346
|
(min..max)
|
295
347
|
end
|
296
348
|
end
|
@@ -364,9 +416,12 @@ module Spy
|
|
364
416
|
|
365
417
|
# @private
|
366
418
|
def get_spy_id(method)
|
367
|
-
|
368
|
-
|
369
|
-
|
419
|
+
if method.parameters[0].is_a?(Array) && method.parameters[0][1]
|
420
|
+
raw_id = method.parameters[0][1].to_s
|
421
|
+
if raw_id.start_with?(SPY_ARGS_PREFIX)
|
422
|
+
raw_id[SPY_ARGS_PREFIX.length..-1].to_i
|
423
|
+
end
|
424
|
+
end
|
370
425
|
end
|
371
426
|
end
|
372
427
|
end
|
data/lib/spy/version.rb
CHANGED
data/spy.gemspec
CHANGED
@@ -6,12 +6,12 @@ require 'spy/version'
|
|
6
6
|
Gem::Specification.new do |gem|
|
7
7
|
gem.name = "spy"
|
8
8
|
gem.version = Spy::VERSION
|
9
|
-
gem.required_ruby_version = '>= 1.
|
9
|
+
gem.required_ruby_version = '>= 2.1.0'
|
10
10
|
gem.license = 'MIT'
|
11
11
|
gem.authors = ["Ryan Ong"]
|
12
12
|
gem.email = ["ryanong@gmail.com"]
|
13
|
-
gem.
|
14
|
-
gem.
|
13
|
+
gem.summary = %q{A simple modern mocking library that uses the spy pattern and checks method's existence and arity.}
|
14
|
+
gem.description = %q{Spy is a mocking library that was made for the modern age. It supports only 2.1.0+. Spy by default will raise an error if you attempt to stub a method that doesn't exist or call the stubbed method with the wrong arity.}
|
15
15
|
gem.homepage = "https://github.com/ryanong/spy"
|
16
16
|
|
17
17
|
gem.files = `git ls-files`.split($/)
|
@@ -19,8 +19,9 @@ Gem::Specification.new do |gem|
|
|
19
19
|
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
20
|
gem.require_paths = ["lib"]
|
21
21
|
gem.add_development_dependency('pry')
|
22
|
-
gem.add_development_dependency('pry-
|
22
|
+
gem.add_development_dependency('pry-byebug')
|
23
23
|
gem.add_development_dependency('minitest', '>= 4.5.0')
|
24
|
+
gem.add_development_dependency('minitest-reporters')
|
24
25
|
gem.add_development_dependency('rspec-core')
|
25
26
|
gem.add_development_dependency('rspec-expectations')
|
26
27
|
gem.add_development_dependency('coveralls')
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class TestConstantSpying <
|
3
|
+
class TestConstantSpying < Minitest::Test
|
4
4
|
|
5
5
|
class Foo
|
6
6
|
HELLO = "hello world"
|
@@ -30,7 +30,7 @@ class TestConstantSpying < MiniTest::Unit::TestCase
|
|
30
30
|
assert_equal "hello world", Foo.hello
|
31
31
|
|
32
32
|
spy = Spy.on_const(Foo, :HELLO)
|
33
|
-
|
33
|
+
assert_nil Foo.hello
|
34
34
|
spy.and_return("awesome")
|
35
35
|
assert_equal "awesome", Foo.hello
|
36
36
|
|
@@ -39,7 +39,7 @@ class TestConstantSpying < MiniTest::Unit::TestCase
|
|
39
39
|
|
40
40
|
assert_equal "hello world", Foo::Bar.hello
|
41
41
|
spy = Spy.on_const(Foo, :HELLO)
|
42
|
-
|
42
|
+
assert_nil Foo::Bar.hello
|
43
43
|
spy.and_return("awesome")
|
44
44
|
assert_equal "awesome", Foo::Bar.hello
|
45
45
|
|
@@ -48,7 +48,7 @@ class TestConstantSpying < MiniTest::Unit::TestCase
|
|
48
48
|
|
49
49
|
assert_equal "hello world", ChildFoo.hello
|
50
50
|
spy = Spy.on_const(Foo, :HELLO)
|
51
|
-
|
51
|
+
assert_nil ChildFoo.hello
|
52
52
|
spy.and_return("awesome")
|
53
53
|
assert_equal "awesome", ChildFoo.hello
|
54
54
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class TestAnyInstanceOf <
|
3
|
+
class TestAnyInstanceOf < Minitest::Test
|
4
4
|
class Foo
|
5
5
|
def bar
|
6
6
|
"foobar"
|
@@ -17,6 +17,12 @@ class TestAnyInstanceOf < MiniTest::Unit::TestCase
|
|
17
17
|
Spy::Agency.instance.dissolve!
|
18
18
|
end
|
19
19
|
|
20
|
+
def test_call_through_with_instance_method
|
21
|
+
Spy.on_instance_method(Foo, :bar).and_call_through
|
22
|
+
assert_equal "foobar", Foo.new.bar
|
23
|
+
Spy.off_instance_method(Foo, :bar)
|
24
|
+
end
|
25
|
+
|
20
26
|
def test_it_overides_all_methods
|
21
27
|
assert_equal Foo.new.bar, "foobar"
|
22
28
|
spy = Spy.on_instance_method(Foo, bar: "timshel")
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
|
-
class TestSpy <
|
3
|
+
class TestSpy < Minitest::Test
|
4
4
|
def setup
|
5
5
|
@pen = Pen.new
|
6
6
|
end
|
@@ -16,12 +16,12 @@ class TestSpy < MiniTest::Unit::TestCase
|
|
16
16
|
|
17
17
|
assert_kind_of Spy::Subroutine, pen_write_spy
|
18
18
|
assert_kind_of Spy::Subroutine, pen_write_hello_spy
|
19
|
-
assert_equal [pen_write_spy, pen_write_hello_spy], Spy::Agency.instance.
|
19
|
+
assert_equal [pen_write_spy, pen_write_hello_spy], Spy::Agency.instance.spies
|
20
20
|
assert pen_write_spy.has_been_called?
|
21
21
|
assert pen_write_hello_spy.has_been_called?
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def test_spy_on_hooks_and_saves_spy_with_hash
|
25
25
|
pen_write_spy, pen_write_hello_spy = Spy.on(@pen, write: "hello", write_hello: "world")
|
26
26
|
assert_equal "hello", @pen.write(nil)
|
27
27
|
assert_equal "world", @pen.write_hello
|
data/test/spy/test_mock.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
module Spy
|
4
|
-
class TestMock <
|
4
|
+
class TestMock < Minitest::Test
|
5
5
|
class BluePen < Pen
|
6
6
|
def write_hello(other)
|
7
7
|
end
|
@@ -68,6 +68,7 @@ module Spy
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
+
BUGGY_METHODS = %i(tap pretty_print_inspect trust untrust untrusted? debugger byebug taint untaint tainted?)
|
71
72
|
def test_mocked_methods
|
72
73
|
pen_methods = Pen.public_instance_methods(false) +
|
73
74
|
Pen.protected_instance_methods(false) +
|
@@ -76,8 +77,7 @@ module Spy
|
|
76
77
|
assert_equal pen_methods.sort, @pen_mock.mocked_methods.sort
|
77
78
|
end
|
78
79
|
|
79
|
-
|
80
|
-
methods_to_test = Object.instance_methods - buggy_methods
|
80
|
+
methods_to_test = Object.instance_methods - BUGGY_METHODS
|
81
81
|
methods_to_test.each do |method_name|
|
82
82
|
object_method = Object.instance_method(method_name)
|
83
83
|
if object_method.arity == 0 || (RUBY_ENGINE != "jruby" && object_method.parameters == [])
|
data/test/spy/test_subroutine.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
require 'test_helper'
|
2
2
|
|
3
3
|
module Spy
|
4
|
-
class TestSubroutine <
|
4
|
+
class TestSubroutine < Minitest::Test
|
5
5
|
def spy_on(base_object, method_name)
|
6
6
|
Subroutine.new(base_object, method_name).hook
|
7
7
|
end
|
@@ -40,13 +40,13 @@ module Spy
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_spy_can_hook_and_record_a_meta_method_call_on_a_constant
|
43
|
-
assert_equal "
|
44
|
-
meta_spy = spy_on(Pen, :
|
43
|
+
assert_equal "meta_class_method", Pen.meta_class_method
|
44
|
+
meta_spy = spy_on(Pen, :meta_class_method)
|
45
45
|
refute meta_spy.has_been_called?
|
46
|
-
assert_nil Pen.
|
46
|
+
assert_nil Pen.meta_class_method
|
47
47
|
assert meta_spy.has_been_called?
|
48
48
|
meta_spy.unhook
|
49
|
-
assert_equal "
|
49
|
+
assert_equal "meta_class_method", Pen.meta_class_method
|
50
50
|
end
|
51
51
|
|
52
52
|
def test_spy_can_hook_record_and_unhook_a_meta_method
|
@@ -86,6 +86,18 @@ module Spy
|
|
86
86
|
assert_equal result, @pen.write(nil)
|
87
87
|
end
|
88
88
|
|
89
|
+
def test_spy_and_raise_raises_the_set_exception
|
90
|
+
pen_write_spy = spy_on(@pen, :write).and_raise(ArgumentError, "problems!")
|
91
|
+
assert_kind_of Subroutine, pen_write_spy
|
92
|
+
assert_equal [pen_write_spy], Agency.instance.spies
|
93
|
+
|
94
|
+
e = assert_raises ArgumentError do
|
95
|
+
@pen.write(nil)
|
96
|
+
end
|
97
|
+
assert_equal "problems!", e.message
|
98
|
+
assert pen_write_spy.has_been_called?
|
99
|
+
end
|
100
|
+
|
89
101
|
def test_spy_and_return_can_call_a_block
|
90
102
|
result = "hello world"
|
91
103
|
|
@@ -145,7 +157,7 @@ module Spy
|
|
145
157
|
assert pen_write_spy.has_been_called_with?("hello")
|
146
158
|
end
|
147
159
|
|
148
|
-
def
|
160
|
+
def test_spy_hook_records_number_of_calls2
|
149
161
|
args = ["hello world"]
|
150
162
|
block = Proc.new {}
|
151
163
|
pen_write_spy = spy_on(@pen, :write)
|
@@ -187,6 +199,38 @@ module Spy
|
|
187
199
|
end
|
188
200
|
end
|
189
201
|
|
202
|
+
def test_that_method_spy_keeps_arity_with_optional_keyword_args
|
203
|
+
spy_on(@pen, :opt_kwargs)
|
204
|
+
@pen.opt_kwargs(:pos1)
|
205
|
+
@pen.opt_kwargs(:pos1, opt: 1, opt2: 2)
|
206
|
+
assert_raises ArgumentError do
|
207
|
+
@pen.opt_kwargs
|
208
|
+
end
|
209
|
+
assert_raises ArgumentError do
|
210
|
+
@pen.opt_kwargs(:pos1, :pos2, opt: 1)
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
def test_that_method_spy_keeps_arity_with_keyword_splat
|
215
|
+
spy_on(@pen, :keyrest)
|
216
|
+
@pen.keyrest
|
217
|
+
@pen.keyrest(a: 1, b: 2)
|
218
|
+
assert_raises ArgumentError do
|
219
|
+
@pen.keyrest(:pos1, :pos2)
|
220
|
+
end
|
221
|
+
end
|
222
|
+
|
223
|
+
def test_that_method_spy_keeps_arity_with_required_keyword_args
|
224
|
+
spy_on(@pen, :req_kwargs)
|
225
|
+
@pen.req_kwargs(req1: 1, req2: 2)
|
226
|
+
assert_raises ArgumentError do
|
227
|
+
@pen.req_kwargs
|
228
|
+
end
|
229
|
+
assert_raises ArgumentError do
|
230
|
+
@pen.req_kwargs(:pos1, :pos2)
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
190
234
|
def test_hook_mimics_public_visibility
|
191
235
|
spy_on(@pen, :public_method)
|
192
236
|
assert @pen.singleton_class.public_method_defined? :public_method
|
data/test/support/pen.rb
CHANGED
@@ -38,6 +38,18 @@ class Pen
|
|
38
38
|
"another"
|
39
39
|
end
|
40
40
|
|
41
|
+
def opt_kwargs(required, opt: nil, opt2: nil)
|
42
|
+
[required, opt: opt, opt2: opt2]
|
43
|
+
end
|
44
|
+
|
45
|
+
def keyrest(**kwargs)
|
46
|
+
kwargs
|
47
|
+
end
|
48
|
+
|
49
|
+
def req_kwargs(req1:, req2:)
|
50
|
+
[req1, req2]
|
51
|
+
end
|
52
|
+
|
41
53
|
protected
|
42
54
|
def protected_method
|
43
55
|
end
|
@@ -65,13 +77,11 @@ class Pen
|
|
65
77
|
end
|
66
78
|
end
|
67
79
|
|
68
|
-
|
69
|
-
|
70
|
-
Pen.define_singleton_method(:meta_method) do
|
71
|
-
another
|
80
|
+
Pen.define_singleton_method(:meta_class_method) do
|
81
|
+
"meta_class_method".freeze
|
72
82
|
end
|
73
83
|
|
74
84
|
Pen.send(:define_method, :meta_method) do
|
75
|
-
|
85
|
+
"meta_method".freeze
|
76
86
|
end
|
77
87
|
|
data/test/test_helper.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
1
|
require 'bundler/setup'
|
2
|
-
require 'minitest/autorun'
|
3
2
|
require 'pry'
|
4
|
-
require 'pry-
|
3
|
+
require 'pry-byebug'
|
4
|
+
require 'minitest/autorun'
|
5
|
+
require "minitest/reporters"
|
5
6
|
require 'coveralls'
|
6
7
|
Coveralls.wear!
|
8
|
+
Minitest::Reporters.use!
|
7
9
|
|
8
10
|
require 'spy'
|
9
11
|
|
metadata
CHANGED
@@ -1,110 +1,126 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ryan Ong
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :development
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: pry-
|
28
|
+
name: pry-byebug
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- -
|
31
|
+
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- -
|
38
|
+
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: minitest
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- -
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: 4.5.0
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- -
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: 4.5.0
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: minitest-reporters
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
55
69
|
- !ruby/object:Gem::Dependency
|
56
70
|
name: rspec-core
|
57
71
|
requirement: !ruby/object:Gem::Requirement
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - ">="
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
76
|
type: :development
|
63
77
|
prerelease: false
|
64
78
|
version_requirements: !ruby/object:Gem::Requirement
|
65
79
|
requirements:
|
66
|
-
- -
|
80
|
+
- - ">="
|
67
81
|
- !ruby/object:Gem::Version
|
68
82
|
version: '0'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: rspec-expectations
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
72
86
|
requirements:
|
73
|
-
- -
|
87
|
+
- - ">="
|
74
88
|
- !ruby/object:Gem::Version
|
75
89
|
version: '0'
|
76
90
|
type: :development
|
77
91
|
prerelease: false
|
78
92
|
version_requirements: !ruby/object:Gem::Requirement
|
79
93
|
requirements:
|
80
|
-
- -
|
94
|
+
- - ">="
|
81
95
|
- !ruby/object:Gem::Version
|
82
96
|
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: coveralls
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
86
100
|
requirements:
|
87
|
-
- -
|
101
|
+
- - ">="
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: '0'
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- -
|
108
|
+
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
|
-
description:
|
98
|
-
|
111
|
+
description: Spy is a mocking library that was made for the modern age. It supports
|
112
|
+
only 2.1.0+. Spy by default will raise an error if you attempt to stub a method
|
113
|
+
that doesn't exist or call the stubbed method with the wrong arity.
|
99
114
|
email:
|
100
115
|
- ryanong@gmail.com
|
101
116
|
executables: []
|
102
117
|
extensions: []
|
103
118
|
extra_rdoc_files: []
|
104
119
|
files:
|
105
|
-
- .gitignore
|
106
|
-
- .
|
107
|
-
- .
|
120
|
+
- ".gitignore"
|
121
|
+
- ".tool-versions"
|
122
|
+
- ".travis.yml"
|
123
|
+
- ".yardopts"
|
108
124
|
- CHANGELOG.md
|
109
125
|
- Gemfile
|
110
126
|
- LICENSE.txt
|
@@ -159,22 +175,20 @@ require_paths:
|
|
159
175
|
- lib
|
160
176
|
required_ruby_version: !ruby/object:Gem::Requirement
|
161
177
|
requirements:
|
162
|
-
- -
|
178
|
+
- - ">="
|
163
179
|
- !ruby/object:Gem::Version
|
164
|
-
version: 1.
|
180
|
+
version: 2.1.0
|
165
181
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
166
182
|
requirements:
|
167
|
-
- -
|
183
|
+
- - ">="
|
168
184
|
- !ruby/object:Gem::Version
|
169
185
|
version: '0'
|
170
186
|
requirements: []
|
171
|
-
|
172
|
-
rubygems_version: 2.0.3
|
187
|
+
rubygems_version: 3.1.2
|
173
188
|
signing_key:
|
174
189
|
specification_version: 4
|
175
|
-
summary:
|
176
|
-
|
177
|
-
doesn't exist or call the stubbed method with the wrong arity.
|
190
|
+
summary: A simple modern mocking library that uses the spy pattern and checks method's
|
191
|
+
existence and arity.
|
178
192
|
test_files:
|
179
193
|
- spec/spec_helper.rb
|
180
194
|
- spec/spy/and_call_original_spec.rb
|