matahari 0.3 → 0.3.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.
- data/lib/matahari/invocation_matcher.rb +60 -58
- data/lib/matahari/spy.rb +37 -35
- data/lib/matahari/version.rb +1 -1
- metadata +3 -2
@@ -1,73 +1,75 @@
|
|
1
|
-
|
1
|
+
module Matahari
|
2
|
+
class InvocationMatcher
|
2
3
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
4
|
+
#TODO I can't work out how to disentangle the 2 responsibilities of this class:
|
5
|
+
#1. Inspecting and acting on spy invocations
|
6
|
+
#2. Presenting the results of those inspections.
|
7
|
+
#
|
8
|
+
#One to revisit later when my head is less befuddled.
|
8
9
|
|
9
|
-
|
10
|
-
|
11
|
-
|
10
|
+
def initialize(iterator = nil)
|
11
|
+
@expected_call_count = iterator ? iterator.count : nil
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
14
|
+
def matches?(subject)
|
15
|
+
@subject = subject
|
16
|
+
@invocations_of_method = subject.invocations.select {|i| i[:method] == @call_to_verify}
|
17
|
+
verifying_args = @args_to_verify.size != 0
|
17
18
|
|
18
|
-
|
19
|
-
|
19
|
+
match_passes?(verifying_args)
|
20
|
+
end
|
20
21
|
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
def failure_message_for_should_not
|
23
|
+
"Spy(:#{@subject.name}) expected not to receive :#{@call_to_verify} but received it #{prettify_times(@matching_calls)}"
|
24
|
+
end
|
24
25
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
26
|
+
def failure_message_for_should
|
27
|
+
if @args_to_verify.size > 0
|
28
|
+
"Spy(:#{@subject.name}) expected to receive :#{@call_to_verify}(#{@args_to_verify.map(&:inspect).join(", ")}) #{prettify_times(@expected_call_count)}, received #{prettify_times(@matching_calls)}"
|
29
|
+
else
|
30
|
+
"Spy(:#{@subject.name}) expected to receive :#{@call_to_verify} #{prettify_times(@expected_call_count)}, received #{prettify_times(@matching_calls)}"
|
31
|
+
end
|
30
32
|
end
|
31
|
-
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
34
|
+
#Allows chaining of method calls following has_received?/should have_received,
|
35
|
+
#e.g. spy.should_have received.some_method, where #some_method is handled by
|
36
|
+
#method_missing, its arguments and name being stored until #matches? is called.
|
37
|
+
def method_missing(sym, *args, &block)
|
38
|
+
@call_to_verify = sym
|
39
|
+
@args_to_verify = args
|
40
|
+
self
|
41
|
+
end
|
41
42
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
43
|
+
def prettify_times(times)
|
44
|
+
case times
|
45
|
+
when 1
|
46
|
+
"once"
|
47
|
+
when nil
|
48
|
+
"once"
|
49
|
+
when 2
|
50
|
+
"twice"
|
51
|
+
else
|
52
|
+
"#{times} times"
|
53
|
+
end
|
52
54
|
end
|
53
|
-
|
54
|
-
private :prettify_times
|
55
|
+
private :prettify_times
|
55
56
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
57
|
+
def matching_calls(verifying_args=true)
|
58
|
+
@matching_calls ||= if verifying_args
|
59
|
+
@invocations_of_method.select {|i| i[:args].flatten === @args_to_verify}.size
|
60
|
+
else
|
61
|
+
@invocations_of_method.size
|
62
|
+
end
|
63
|
+
end
|
64
|
+
private :matching_calls
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
66
|
+
def match_passes?(verifying_args)
|
67
|
+
if @expected_call_count
|
68
|
+
matching_calls(verifying_args) == @expected_call_count
|
69
|
+
else
|
70
|
+
matching_calls(verifying_args) > 0
|
71
|
+
end
|
70
72
|
end
|
73
|
+
private :match_passes?
|
71
74
|
end
|
72
|
-
private :match_passes?
|
73
75
|
end
|
data/lib/matahari/spy.rb
CHANGED
@@ -1,45 +1,47 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
module Matahari
|
2
|
+
class Spy
|
3
|
+
attr_reader :name, :invocations
|
3
4
|
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
5
|
+
def initialize(name = nil, opts={})
|
6
|
+
@subject = opts[:subject]
|
7
|
+
@name = name
|
8
|
+
@invocations = []
|
9
|
+
@stubbed_calls = {}
|
10
|
+
class << self
|
11
|
+
instance_methods.each do |meth|
|
12
|
+
whitelist = [:name, :define_method, :stubs, :passes_on, :method_missing, :record_invocation, :invocations, :has_received?, :object_id, :respond_to?, :respond_to_missing?, :instance_eval, :instance_exec, :class_eval, :__send__, :send, :should, :should_not, :__id__, :__send__]
|
13
|
+
next if whitelist.include?(meth) || whitelist.include?(meth.to_sym)
|
14
|
+
undef_method(meth)
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
16
|
-
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
19
|
+
#When a given method call, sym, is invoked on self, call block and return its result
|
20
|
+
def stubs(sym, &block)
|
21
|
+
@stubbed_calls[sym] = block
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
def passes_on(sym)
|
25
|
+
@stubbed_calls[sym] = @subject.method(sym)
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
28
|
+
#Captures the details of any method call and store for later inspection
|
29
|
+
def method_missing(sym, *args, &block)
|
30
|
+
record_invocation(sym, args)
|
31
|
+
@stubbed_calls[sym].call if @stubbed_calls[sym]
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
34
|
+
#Pass an iterator to this method to specify the number of times the method should
|
35
|
+
#have been called. E.g. spy.has_received?(3.times). While other iterators might work,
|
36
|
+
#the idea is to allow this nice DSL-ish way of asserting on the number of calls, hence
|
37
|
+
#the odd method signature.
|
38
|
+
def has_received?(times=nil)
|
39
|
+
InvocationMatcher.new(times)
|
40
|
+
end
|
40
41
|
|
41
|
-
|
42
|
-
|
43
|
-
|
42
|
+
private
|
43
|
+
def record_invocation(sym, *args)
|
44
|
+
@invocations << {:method => sym, :args => args}
|
45
|
+
end
|
44
46
|
end
|
45
47
|
end
|
data/lib/matahari/version.rb
CHANGED
metadata
CHANGED
@@ -5,7 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 3
|
8
|
-
|
8
|
+
- 1
|
9
|
+
version: 0.3.1
|
9
10
|
platform: ruby
|
10
11
|
authors:
|
11
12
|
- Tom Stuart
|
@@ -13,7 +14,7 @@ autorequire:
|
|
13
14
|
bindir: bin
|
14
15
|
cert_chain: []
|
15
16
|
|
16
|
-
date: 2011-06-
|
17
|
+
date: 2011-06-29 00:00:00 +01:00
|
17
18
|
default_executable:
|
18
19
|
dependencies:
|
19
20
|
- !ruby/object:Gem::Dependency
|