spy_rb 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/spy/api.rb +20 -20
- data/lib/spy/instance.rb +28 -15
- data/lib/spy/instance/api/internal.rb +75 -0
- data/lib/spy/instance/strategy/intercept.rb +1 -12
- data/lib/spy/instance/strategy/wrap.rb +1 -12
- data/lib/spy/method_call.rb +11 -0
- data/lib/spy/version.rb +1 -1
- metadata +4 -4
- data/lib/spy/callbacks/when.rb +0 -13
- data/lib/spy/callbacks/with_args.rb +0 -14
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47b608d05670cc1e49baec91115ecfdf0e87feb6
|
4
|
+
data.tar.gz: a7519779804fa1ac600149a87bfed851cacca168
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8a3853df7bcb3ae2440b6585ea519d4466b7130ddb061a2d29db1ba88a9e31a410c1a22adb614782c337a035356d82d8350d9024aeabb1b588ae00c97cc04078
|
7
|
+
data.tar.gz: dc92ea6560aa6b5fbfbc260cdbc9b2cdb2acae4bc92b0662b56b65b40c34dd149c0a195cf18872f41f5a05284dce90eaf514ea9ca973979828ffecbd025e3f47
|
data/lib/spy/api.rb
CHANGED
@@ -2,23 +2,22 @@ require 'spy/core'
|
|
2
2
|
|
3
3
|
module Spy
|
4
4
|
module API
|
5
|
-
#
|
5
|
+
# Spies on calls to a method made on an object
|
6
6
|
#
|
7
|
-
#
|
8
|
-
# @param
|
9
|
-
|
10
|
-
|
11
|
-
case args.length
|
12
|
-
when 2
|
13
|
-
spied, msg = *args
|
14
|
-
return core.add_spy(spied, spied.method(msg))
|
15
|
-
end
|
16
|
-
raise ArgumentError
|
7
|
+
# @param target - the object you want to spy on
|
8
|
+
# @param msg - the name of the method to spy on
|
9
|
+
def on(target, msg)
|
10
|
+
core.add_spy(target, target.method(msg))
|
17
11
|
end
|
18
12
|
|
19
|
-
#
|
20
|
-
|
21
|
-
|
13
|
+
# Spies on calls to a method made on any instance of some class or module
|
14
|
+
#
|
15
|
+
# @param target - class or module to spy on
|
16
|
+
# @param msg - name of the method to spy on
|
17
|
+
# @returns [Spy::Instance]
|
18
|
+
def on_any_instance(target, msg)
|
19
|
+
raise ArgumentError unless target.respond_to?(:instance_method)
|
20
|
+
core.add_spy(target, target.instance_method(msg))
|
22
21
|
end
|
23
22
|
|
24
23
|
# Stops spying on the method and restores its original functionality
|
@@ -36,15 +35,16 @@ module Spy
|
|
36
35
|
def restore(*args)
|
37
36
|
case args.length
|
38
37
|
when 1
|
39
|
-
|
38
|
+
core.remove_all_spies if args.first == :all
|
40
39
|
when 2
|
41
|
-
|
42
|
-
|
40
|
+
target, msg = *args
|
41
|
+
core.remove_spy(target, target.method(msg))
|
43
42
|
when 3
|
44
|
-
|
45
|
-
|
43
|
+
target, msg, method_type = *args
|
44
|
+
core.remove_spy(target, target.send(method_type, msg))
|
45
|
+
else
|
46
|
+
raise ArgumentError
|
46
47
|
end
|
47
|
-
raise ArgumentError
|
48
48
|
end
|
49
49
|
|
50
50
|
private
|
data/lib/spy/instance.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
|
-
require 'spy/callbacks/with_args'
|
2
|
-
require 'spy/callbacks/when'
|
3
1
|
require 'spy/instance/strategy'
|
2
|
+
require 'spy/instance/api/internal'
|
4
3
|
|
5
4
|
# An instance of a spied method
|
6
5
|
# - Holds a reference to the original method
|
@@ -8,17 +7,26 @@ require 'spy/instance/strategy'
|
|
8
7
|
# - Provides hooks for callbacks
|
9
8
|
module Spy
|
10
9
|
class Instance
|
11
|
-
|
10
|
+
include API::Internal
|
11
|
+
|
12
|
+
attr_reader :original, :spied, :strategy, :visibility, :call_history
|
12
13
|
|
13
14
|
def initialize(spied, original)
|
14
15
|
@spied = spied
|
15
16
|
@original = original
|
16
17
|
@visibility = extract_visibility
|
17
|
-
@
|
18
|
-
@
|
18
|
+
@conditional_filters = []
|
19
|
+
@before_callbacks = []
|
20
|
+
@after_callbacks = []
|
21
|
+
@around_procs = []
|
22
|
+
@call_history = []
|
19
23
|
@strategy = Strategy.factory_build(self)
|
20
24
|
end
|
21
25
|
|
26
|
+
def call_count
|
27
|
+
@call_history.size
|
28
|
+
end
|
29
|
+
|
22
30
|
def start
|
23
31
|
@strategy.apply
|
24
32
|
self
|
@@ -29,25 +37,30 @@ module Spy
|
|
29
37
|
self
|
30
38
|
end
|
31
39
|
|
32
|
-
def
|
33
|
-
@
|
40
|
+
def when(&block)
|
41
|
+
@conditional_filters << block
|
42
|
+
self
|
34
43
|
end
|
35
44
|
|
36
|
-
|
37
|
-
|
45
|
+
# Expect block to yield. Call the rest of the chain
|
46
|
+
# when it does
|
47
|
+
def wrap(&block)
|
48
|
+
@around_procs << block
|
49
|
+
self
|
38
50
|
end
|
39
51
|
|
40
|
-
def
|
41
|
-
|
52
|
+
def before(&block)
|
53
|
+
@before_callbacks << block
|
54
|
+
self
|
42
55
|
end
|
43
56
|
|
44
|
-
|
45
|
-
|
46
|
-
def add_before_filter(filter)
|
47
|
-
@before_filters << filter
|
57
|
+
def after(&block)
|
58
|
+
@after_callbacks << block
|
48
59
|
self
|
49
60
|
end
|
50
61
|
|
62
|
+
private
|
63
|
+
|
51
64
|
def extract_visibility
|
52
65
|
owner = @original.owner
|
53
66
|
[:public, :protected, :private].each do |vis|
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spy/method_call'
|
2
|
+
|
3
|
+
module Spy
|
4
|
+
class Instance
|
5
|
+
module API
|
6
|
+
# The API we expose internally to our collaborators
|
7
|
+
module Internal
|
8
|
+
# TODO: Not sure if this is the best place for this
|
9
|
+
#
|
10
|
+
# Defines the spy on the target object
|
11
|
+
def attach_to(target)
|
12
|
+
spy = self
|
13
|
+
target.class_eval do
|
14
|
+
define_method spy.original.name do |*args|
|
15
|
+
spy.call(self, *args)
|
16
|
+
end
|
17
|
+
send(spy.visibility, spy.original.name)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
# Call the spied method using the given context and arguments.
|
22
|
+
#
|
23
|
+
# Context is required for calling UnboundMethods such as
|
24
|
+
# instance methods defined on a Class
|
25
|
+
def call(context, *args)
|
26
|
+
is_active = @conditional_filters.all? {|f| f.call(*args)}
|
27
|
+
|
28
|
+
if is_active
|
29
|
+
@before_callbacks.each {|f| f.call(*args)}
|
30
|
+
end
|
31
|
+
|
32
|
+
if @around_procs.any?
|
33
|
+
# Procify the original call
|
34
|
+
original_proc = Proc.new do
|
35
|
+
record = track_call(context, *args) if is_active
|
36
|
+
result = call_original(context, *args)
|
37
|
+
record.result = result if is_active
|
38
|
+
end
|
39
|
+
|
40
|
+
# Keep wrapping the original proc with each around_proc
|
41
|
+
@around_procs.reduce(original_proc) do |p, wrapper|
|
42
|
+
Proc.new { wrapper.call context, *args, &p }
|
43
|
+
end.call
|
44
|
+
else
|
45
|
+
record = track_call(context, *args) if is_active
|
46
|
+
result = call_original(context, *args)
|
47
|
+
record.result = result if is_active
|
48
|
+
end
|
49
|
+
|
50
|
+
if is_active
|
51
|
+
@after_callbacks.each {|f| f.call(*args)}
|
52
|
+
end
|
53
|
+
|
54
|
+
result
|
55
|
+
end
|
56
|
+
|
57
|
+
private
|
58
|
+
|
59
|
+
def track_call(context, *args)
|
60
|
+
record = Spy::MethodCall.new(context, *args)
|
61
|
+
@call_history << record
|
62
|
+
record
|
63
|
+
end
|
64
|
+
|
65
|
+
def call_original(context, *args)
|
66
|
+
if original.is_a?(UnboundMethod)
|
67
|
+
original.bind(context).call(*args)
|
68
|
+
else
|
69
|
+
original.call(*args)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -8,18 +8,7 @@ module Spy
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def apply
|
11
|
-
spy
|
12
|
-
@intercept_target.class_eval do
|
13
|
-
define_method spy.original.name do |*args|
|
14
|
-
spy.before_call(*args)
|
15
|
-
if spy.original.is_a?(UnboundMethod)
|
16
|
-
spy.original.bind(self).call(*args)
|
17
|
-
else
|
18
|
-
spy.original.call(*args)
|
19
|
-
end
|
20
|
-
end
|
21
|
-
send(spy.visibility, spy.original.name)
|
22
|
-
end
|
11
|
+
@spy.attach_to(@intercept_target)
|
23
12
|
end
|
24
13
|
|
25
14
|
def undo
|
@@ -7,18 +7,7 @@ module Spy
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def apply
|
10
|
-
spy
|
11
|
-
spy.original.owner.class_eval do
|
12
|
-
define_method spy.original.name do |*args|
|
13
|
-
spy.before_call(*args)
|
14
|
-
if spy.original.is_a?(UnboundMethod)
|
15
|
-
spy.original.bind(self).call(*args)
|
16
|
-
else
|
17
|
-
spy.original.call(*args)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
send(spy.visibility, spy.original.name)
|
21
|
-
end
|
10
|
+
@spy.attach_to(@spy.original.owner)
|
22
11
|
end
|
23
12
|
|
24
13
|
def undo
|
data/lib/spy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spy_rb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Josh Bodah
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-05-20 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Spy brings everything that's great about Sinon.JS to Ruby. Mocking frameworks
|
14
14
|
work by stubbing out functionality. Spy works by listening in on functionality and
|
@@ -21,16 +21,16 @@ extra_rdoc_files: []
|
|
21
21
|
files:
|
22
22
|
- lib/spy.rb
|
23
23
|
- lib/spy/api.rb
|
24
|
-
- lib/spy/callbacks/when.rb
|
25
|
-
- lib/spy/callbacks/with_args.rb
|
26
24
|
- lib/spy/collection.rb
|
27
25
|
- lib/spy/collection/entry.rb
|
28
26
|
- lib/spy/core.rb
|
29
27
|
- lib/spy/errors.rb
|
30
28
|
- lib/spy/instance.rb
|
29
|
+
- lib/spy/instance/api/internal.rb
|
31
30
|
- lib/spy/instance/strategy.rb
|
32
31
|
- lib/spy/instance/strategy/intercept.rb
|
33
32
|
- lib/spy/instance/strategy/wrap.rb
|
33
|
+
- lib/spy/method_call.rb
|
34
34
|
- lib/spy/version.rb
|
35
35
|
homepage: https://github.com/jbodah/spy_rb
|
36
36
|
licenses:
|
data/lib/spy/callbacks/when.rb
DELETED
@@ -1,14 +0,0 @@
|
|
1
|
-
module Spy
|
2
|
-
module Callbacks
|
3
|
-
class WithArgs
|
4
|
-
def initialize(*args)
|
5
|
-
puts 'Spy::Callbacks::WithArgs is deprecated; use Spy::Callbacks::When instead'
|
6
|
-
@match_args = args
|
7
|
-
end
|
8
|
-
|
9
|
-
def before_call(*args)
|
10
|
-
@match_args == args
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|