spy 1.0.0 → 1.0.1
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.
- checksums.yaml +4 -4
- data/.tool-versions +1 -0
- data/.travis.yml +4 -2
- data/CHANGELOG.md +7 -0
- data/lib/spy.rb +0 -2
- data/lib/spy/api.rb +2 -2
- data/lib/spy/subroutine.rb +57 -19
- data/lib/spy/version.rb +1 -1
- data/spy.gemspec +1 -2
- data/test/integration/test_constant_spying.rb +3 -3
- data/test/integration/test_instance_method.rb +6 -0
- data/test/integration/test_subroutine_spying.rb +2 -2
- data/test/spy/test_mock.rb +1 -1
- data/test/spy/test_subroutine.rb +1 -1
- data/test/test_helper.rb +2 -2
- metadata +5 -19
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
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,7 +1,14 @@
|
|
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
|
+
|
1
7
|
## Spy 1.0.0 (October 10, 2018) ##
|
2
8
|
|
3
9
|
* drop support for ruby 1.9.3, 2.0. Only support 2.1+ (@dylanahsmith)
|
4
10
|
* support named arguments (@dylanahsmith)
|
11
|
+
* Fix readme (@ignat-z)
|
5
12
|
|
6
13
|
## Spy 0.4.3 (April 14, 2016) ##
|
7
14
|
|
data/lib/spy.rb
CHANGED
data/lib/spy/api.rb
CHANGED
data/lib/spy/subroutine.rb
CHANGED
@@ -52,8 +52,21 @@ module Spy
|
|
52
52
|
@original_method = current_method
|
53
53
|
end
|
54
54
|
|
55
|
-
|
56
|
-
|
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
|
57
70
|
|
58
71
|
if [:public, :protected, :private].include? hook_opts[:visibility]
|
59
72
|
method_owner.send(hook_opts[:visibility], method_name)
|
@@ -69,11 +82,10 @@ module Spy
|
|
69
82
|
def unhook
|
70
83
|
raise NeverHookedError, "'#{method_name}' method has not been hooked" unless hooked?
|
71
84
|
|
85
|
+
method_owner.send(:remove_method, method_name)
|
72
86
|
if original_method && method_owner == original_method.owner
|
73
|
-
|
74
|
-
|
75
|
-
else
|
76
|
-
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
|
77
89
|
end
|
78
90
|
|
79
91
|
clear_method!
|
@@ -105,7 +117,7 @@ module Spy
|
|
105
117
|
# spy.and_return(force: true) { |invalid_arity| true }
|
106
118
|
#
|
107
119
|
# @return [self]
|
108
|
-
def and_return(value = nil)
|
120
|
+
def and_return(value = nil, &block)
|
109
121
|
@do_not_check_plan_arity = false
|
110
122
|
|
111
123
|
if block_given?
|
@@ -115,7 +127,7 @@ module Spy
|
|
115
127
|
raise ArgumentError, "value and block conflict. Choose one"
|
116
128
|
end
|
117
129
|
|
118
|
-
@plan =
|
130
|
+
@plan = block
|
119
131
|
check_for_too_many_arguments!(@plan)
|
120
132
|
else
|
121
133
|
@plan = Proc.new { value }
|
@@ -136,13 +148,29 @@ module Spy
|
|
136
148
|
# tells the spy to call the original method
|
137
149
|
# @return [self]
|
138
150
|
def and_call_through
|
139
|
-
@
|
140
|
-
|
141
|
-
original_method
|
142
|
-
|
143
|
-
|
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
|
144
171
|
end
|
145
172
|
end
|
173
|
+
|
146
174
|
self
|
147
175
|
end
|
148
176
|
|
@@ -193,9 +221,9 @@ module Spy
|
|
193
221
|
# check if the method was called with the exact arguments
|
194
222
|
# @param args Arguments that should have been sent to the method
|
195
223
|
# @return [Boolean]
|
196
|
-
def has_been_called_with?(*args)
|
224
|
+
def has_been_called_with?(*args, &block)
|
197
225
|
raise NeverHookedError unless @was_hooked
|
198
|
-
match = block_given? ?
|
226
|
+
match = block_given? ? block : proc { |call| call.args == args }
|
199
227
|
calls.any?(&match)
|
200
228
|
end
|
201
229
|
|
@@ -203,10 +231,18 @@ module Spy
|
|
203
231
|
# method.
|
204
232
|
def invoke(object, args, block, called_from)
|
205
233
|
check_arity!(args.size)
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
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
|
210
246
|
ensure
|
211
247
|
calls << CallLog.new(object, called_from, args, block, result)
|
212
248
|
end
|
@@ -274,6 +310,8 @@ module Spy
|
|
274
310
|
min_arity = block.arity
|
275
311
|
min_arity = min_arity.abs - 1 if min_arity < 0
|
276
312
|
|
313
|
+
min_arity -=1 if base_object.is_a? Class # Instance-method procs take an extra param for receiving object
|
314
|
+
|
277
315
|
if min_arity > arity_range.max
|
278
316
|
raise ArgumentError.new("block requires #{min_arity} arguments while original_method require a maximum of #{arity_range.max}")
|
279
317
|
end
|
data/lib/spy/version.rb
CHANGED
data/spy.gemspec
CHANGED
@@ -19,8 +19,7 @@ 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-
|
23
|
-
gem.add_development_dependency('pry-stack_explorer')
|
22
|
+
gem.add_development_dependency('pry-byebug')
|
24
23
|
gem.add_development_dependency('minitest', '>= 4.5.0')
|
25
24
|
gem.add_development_dependency('minitest-reporters')
|
26
25
|
gem.add_development_dependency('rspec-core')
|
@@ -30,7 +30,7 @@ class TestConstantSpying < Minitest::Test
|
|
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::Test
|
|
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::Test
|
|
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
|
|
@@ -17,6 +17,12 @@ class TestAnyInstanceOf < Minitest::Test
|
|
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")
|
@@ -16,12 +16,12 @@ class TestSpy < Minitest::Test
|
|
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
@@ -68,7 +68,7 @@ module Spy
|
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
71
|
-
BUGGY_METHODS = %i(tap pretty_print_inspect trust untrust untrusted?)
|
71
|
+
BUGGY_METHODS = %i(tap pretty_print_inspect trust untrust untrusted? debugger byebug taint untaint tainted?)
|
72
72
|
def test_mocked_methods
|
73
73
|
pen_methods = Pen.public_instance_methods(false) +
|
74
74
|
Pen.protected_instance_methods(false) +
|
data/test/spy/test_subroutine.rb
CHANGED
@@ -157,7 +157,7 @@ module Spy
|
|
157
157
|
assert pen_write_spy.has_been_called_with?("hello")
|
158
158
|
end
|
159
159
|
|
160
|
-
def
|
160
|
+
def test_spy_hook_records_number_of_calls2
|
161
161
|
args = ["hello world"]
|
162
162
|
block = Proc.new {}
|
163
163
|
pen_write_spy = spy_on(@pen, :write)
|
data/test/test_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.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
|
@@ -25,21 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: pry-
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - ">="
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '0'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - ">="
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '0'
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
|
-
name: pry-stack_explorer
|
28
|
+
name: pry-byebug
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
44
30
|
requirements:
|
45
31
|
- - ">="
|
@@ -132,6 +118,7 @@ extensions: []
|
|
132
118
|
extra_rdoc_files: []
|
133
119
|
files:
|
134
120
|
- ".gitignore"
|
121
|
+
- ".tool-versions"
|
135
122
|
- ".travis.yml"
|
136
123
|
- ".yardopts"
|
137
124
|
- CHANGELOG.md
|
@@ -197,8 +184,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
197
184
|
- !ruby/object:Gem::Version
|
198
185
|
version: '0'
|
199
186
|
requirements: []
|
200
|
-
|
201
|
-
rubygems_version: 2.7.6
|
187
|
+
rubygems_version: 3.1.2
|
202
188
|
signing_key:
|
203
189
|
specification_version: 4
|
204
190
|
summary: A simple modern mocking library that uses the spy pattern and checks method's
|