gimme 0.3.3 → 0.3.4
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/README.markdown +2 -2
- data/VERSION +1 -1
- data/features/basics.feature +47 -14
- data/features/class_methods.feature +1 -1
- data/features/matchers.feature +1 -1
- data/features/messages.feature +47 -0
- data/features/old/stub_basic.feature +11 -5
- data/features/step_definitions/doc_steps.rb +67 -1
- data/features/support/hooks.rb +3 -0
- data/gimme.gemspec +7 -2
- data/lib/gimme.rb +3 -1
- data/lib/gimme/compares_args.rb +30 -0
- data/lib/gimme/finds_stubbings.rb +21 -0
- data/lib/gimme/gives_class_methods.rb +1 -1
- data/lib/gimme/invokes_satisfied_stubbing.rb +4 -24
- data/lib/gimme/test_double.rb +47 -9
- data/lib/gimme/verifies.rb +20 -23
- data/spec/gimme/invocation_store_spec.rb +10 -0
- data/spec/gimme/test_double_spec.rb +24 -5
- metadata +7 -5
data/README.markdown
CHANGED
@@ -4,7 +4,7 @@ Gimme is a very lightweight test double library for ruby. Written to be an opini
|
|
4
4
|
|
5
5
|
You can read the (possibly stale) documentation below or the (fresh) [gimme Cucumber features on Relish](http://relishapp.com/searls/gimme)
|
6
6
|
|
7
|
-
And here's a [blog post outlining the case for gimme](http://searls.
|
7
|
+
And here's a [blog post outlining the case for gimme](http://searls.testdouble.com/2011/06/03/whats-wrong-with-rubys-test-doubles/).
|
8
8
|
|
9
9
|
## Basics (or "What does it Gimme?" ... har.)
|
10
10
|
|
@@ -235,4 +235,4 @@ This way we can clearly specify the SUT's interaction with the Marker class whil
|
|
235
235
|
## About
|
236
236
|
|
237
237
|
### Maintainers
|
238
|
-
* [Justin Searls](http://about.me/searls), [test double](http://
|
238
|
+
* [Justin Searls](http://about.me/searls), [test double](http://testdouble.com)
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.3.
|
1
|
+
0.3.4
|
data/features/basics.feature
CHANGED
@@ -15,7 +15,7 @@ Feature: basic usage
|
|
15
15
|
of the Chef's job without actually calling through to a real Apprentice or a real Stove.
|
16
16
|
|
17
17
|
Scenario:
|
18
|
-
Given we have this
|
18
|
+
Given we have this production code:
|
19
19
|
"""
|
20
20
|
class Apprentice
|
21
21
|
def slice(thing)
|
@@ -40,27 +40,60 @@ Feature: basic usage
|
|
40
40
|
@slicer = slicer
|
41
41
|
@stove = stove
|
42
42
|
end
|
43
|
-
end
|
44
|
-
|
45
|
-
"""
|
46
43
|
|
47
|
-
When we want to write some tests to help us write this method:
|
48
|
-
"""
|
49
|
-
class Chef
|
50
44
|
def cook
|
51
45
|
slices = @slicer.slice("tomato")
|
52
46
|
@stove.simmer(slices)
|
53
47
|
end
|
54
48
|
end
|
49
|
+
|
50
|
+
"""
|
51
|
+
Then this RSpec will pass:
|
52
|
+
"""
|
53
|
+
describe Chef do
|
54
|
+
describe "#cook" do
|
55
|
+
Given!(:slicer) { gimme_next(Apprentice) }
|
56
|
+
Given!(:stove) { gimme_next(Stove) }
|
57
|
+
Given { give(slicer).slice("tomato") { "some slices" } }
|
58
|
+
When { subject.cook }
|
59
|
+
Then { verify(stove).simmer("some slices") }
|
60
|
+
end
|
61
|
+
end
|
55
62
|
"""
|
56
63
|
|
57
|
-
|
64
|
+
Scenario: using rspec
|
65
|
+
Given we have this production code:
|
58
66
|
"""
|
59
|
-
|
60
|
-
|
61
|
-
|
67
|
+
class Spaceship
|
68
|
+
def initialize(thruster = Thruster.new)
|
69
|
+
@thruster = thruster
|
70
|
+
end
|
62
71
|
|
63
|
-
|
72
|
+
def take_off
|
73
|
+
@thruster.fire
|
74
|
+
end
|
75
|
+
end
|
64
76
|
|
65
|
-
|
66
|
-
|
77
|
+
class Thruster
|
78
|
+
def fire
|
79
|
+
raise "LOLTHRUSTER"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
"""
|
83
|
+
Then this RSpec will pass:
|
84
|
+
"""
|
85
|
+
describe Spaceship do
|
86
|
+
context "an injected double" do
|
87
|
+
Given(:thruster) { gimme(Thruster) }
|
88
|
+
subject { Spaceship.new(thruster) }
|
89
|
+
When { subject.take_off }
|
90
|
+
Then { verify(thruster).fire }
|
91
|
+
end
|
92
|
+
|
93
|
+
context "a gimme_next double" do
|
94
|
+
Given!(:thruster) { gimme_next(Thruster) }
|
95
|
+
When { subject.take_off }
|
96
|
+
Then { verify(thruster).fire }
|
97
|
+
end
|
98
|
+
end
|
99
|
+
"""
|
data/features/matchers.feature
CHANGED
@@ -0,0 +1,47 @@
|
|
1
|
+
Feature: messages from test doubles
|
2
|
+
|
3
|
+
Test doubles need to output sufficient messages
|
4
|
+
(particularly on failure)
|
5
|
+
|
6
|
+
Scenario: inspect/to_s for arguments
|
7
|
+
Given we have this production code:
|
8
|
+
"""
|
9
|
+
class Chair
|
10
|
+
end
|
11
|
+
|
12
|
+
class Person
|
13
|
+
def
|
14
|
+
sit_on(thing)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
"""
|
18
|
+
When we write a test we expect to fail:
|
19
|
+
"""
|
20
|
+
chair = gimme(Chair)
|
21
|
+
person = gimme(Person)
|
22
|
+
|
23
|
+
person.sit_on() #<--oops! forgot the chair
|
24
|
+
|
25
|
+
verify(person).sit_on(chair)
|
26
|
+
"""
|
27
|
+
Then we should see a failure message that includes:
|
28
|
+
"""
|
29
|
+
expected Person#sit_on to have been called with arguments [<#Gimme:1 Chair>]
|
30
|
+
"""
|
31
|
+
Then we should see a failure message that includes:
|
32
|
+
"""
|
33
|
+
was actually called 1 times with arguments []
|
34
|
+
"""
|
35
|
+
|
36
|
+
Scenario: naming mocks
|
37
|
+
Given we have this production code:
|
38
|
+
"""
|
39
|
+
class Panda
|
40
|
+
end
|
41
|
+
"""
|
42
|
+
Then this should work:
|
43
|
+
"""
|
44
|
+
gimme(Panda).to_s.should == "<#Gimme:1 Panda>"
|
45
|
+
gimme(Panda).inspect.should == "<#Gimme:2 Panda>"
|
46
|
+
gimme("a bear thing").inspect.should == "<#Gimme:3 a bear thing>"
|
47
|
+
"""
|
@@ -8,27 +8,33 @@ Feature: basic stubbing
|
|
8
8
|
Given a new Dog test double
|
9
9
|
When I stub <method> to return <gives>
|
10
10
|
Then invoking <invocation> returns <returns>
|
11
|
-
|
11
|
+
|
12
12
|
Scenarios: no-arg methods
|
13
13
|
| method | gives | invocation | returns |
|
14
14
|
| to_s | 'something' | to_s | 'something' |
|
15
|
+
| inspect | 'a' | inspect | 'a' |
|
16
|
+
| hash | 'b' | hash | 'b' |
|
17
|
+
| to_s | nil | to_s | nil |
|
15
18
|
| purebred? | true | purebred? | true |
|
16
|
-
|
19
|
+
|
20
|
+
|
17
21
|
Scenarios: one-arg methods
|
18
22
|
| method | gives | invocation | returns |
|
19
23
|
| holler_at(true) | :ruff | holler_at(true) | :ruff |
|
20
24
|
| holler_at(true) | :ruff | holler_at(false) | nil |
|
21
25
|
| holler_at(true) | :ruff | holler_at(:panda) | nil |
|
22
26
|
| holler_at(true) | :ruff | holler_at(nil) | nil |
|
23
|
-
|
27
|
+
| eql?(:a) | :c | eql?(:a) | :c |
|
28
|
+
| ==(:b) | :d | ==(:b) | :d |
|
29
|
+
|
24
30
|
Scenarios: two-arg methods
|
25
31
|
| method | gives | invocation | returns |
|
26
32
|
| walk_to(1,2) | :park | walk_to(1,2) | :park |
|
27
33
|
| walk_to(1,2) | :park | walk_to(0.9,2) | nil |
|
28
34
|
| walk_to(1,2) | :park | walk_to(1,2.1) | nil |
|
29
35
|
| walk_to([1,5],[2,7]) | :park | walk_to([1],[5,2,7]) | nil |
|
30
|
-
|
36
|
+
|
31
37
|
Scenario:
|
32
38
|
Given a new Dog test double
|
33
39
|
When I stub purebred? to raise StandardError
|
34
|
-
Then invoking purebred? raises a StandardError
|
40
|
+
Then invoking purebred? raises a StandardError
|
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
Given /^we have this
|
2
|
+
Given /^we have this production code:$/ do |string|
|
3
3
|
eval(string)
|
4
4
|
end
|
5
5
|
|
@@ -7,6 +7,72 @@ When /^we want to write some tests to help us write this method:$/ do |string|
|
|
7
7
|
eval(string)
|
8
8
|
end
|
9
9
|
|
10
|
+
When /^we write a test we expect to fail:$/ do |string|
|
11
|
+
begin
|
12
|
+
eval(string)
|
13
|
+
rescue
|
14
|
+
@last_error = $!
|
15
|
+
end
|
16
|
+
|
17
|
+
unless @last_error
|
18
|
+
fail "\nexpected this step's code to raise error, but it did not.\n\n"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
10
22
|
Then /^we can use gimme to isolate the unit under test:$/ do |string|
|
11
23
|
eval(string)
|
12
24
|
end
|
25
|
+
|
26
|
+
Then /^this should work:$/ do |string|
|
27
|
+
eval(string)
|
28
|
+
end
|
29
|
+
|
30
|
+
Then /^we should see a failure message that includes:$/ do |string|
|
31
|
+
fail "expected a prior step to have raised error" unless @last_error
|
32
|
+
@last_error.message.should include(string)
|
33
|
+
end
|
34
|
+
|
35
|
+
Given /^this RSpec will pass:$/ do |spec_code|
|
36
|
+
run_spec_for(create_spec_file_for(spec_code))
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_spec_file_for(spec_code)
|
40
|
+
require 'tempfile'
|
41
|
+
Tempfile.new('spec').tap do |file|
|
42
|
+
file.write <<-RUBY
|
43
|
+
require 'rspec'
|
44
|
+
require 'rspec/given'
|
45
|
+
require 'gimme'
|
46
|
+
|
47
|
+
#{spec_code}
|
48
|
+
RUBY
|
49
|
+
file.close
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class Output
|
54
|
+
attr_reader :output
|
55
|
+
def initialize
|
56
|
+
@output = ""
|
57
|
+
end
|
58
|
+
def puts(stuff="")
|
59
|
+
@output += stuff + "\n"
|
60
|
+
end
|
61
|
+
def print(stuff="")
|
62
|
+
@output += stuff
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def run_spec_for(file)
|
67
|
+
require 'rspec'
|
68
|
+
out = Output.new
|
69
|
+
unless RSpec::Core::Runner.run([file.path], out, out) == 0
|
70
|
+
fail <<-RSPEC
|
71
|
+
***********************************
|
72
|
+
RSpec execution failed with output:
|
73
|
+
***********************************
|
74
|
+
|
75
|
+
#{out.output}
|
76
|
+
RSPEC
|
77
|
+
end
|
78
|
+
end
|
data/gimme.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "gimme"
|
8
|
-
s.version = "0.3.
|
8
|
+
s.version = "0.3.4"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Justin Searls"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-09-29"
|
13
13
|
s.description = "gimme attempts to bring to Ruby a test double workflow akin to Mockito in Java. Major distinctions include preserving arrange-act-assert in tests, fast feedback for methods the double's real counterpart may not know how to respond to, no string/symbolic representations of methods, argument captors, and strong opinions (weakly held). "
|
14
14
|
s.email = "searls@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -31,6 +31,7 @@ Gem::Specification.new do |s|
|
|
31
31
|
"features/basics.feature",
|
32
32
|
"features/class_methods.feature",
|
33
33
|
"features/matchers.feature",
|
34
|
+
"features/messages.feature",
|
34
35
|
"features/old/argument_captors.feature",
|
35
36
|
"features/old/gimme_next.feature",
|
36
37
|
"features/old/stub_basic.feature",
|
@@ -46,13 +47,16 @@ Gem::Specification.new do |s|
|
|
46
47
|
"features/step_definitions/gimme_steps.rb",
|
47
48
|
"features/support/animals.rb",
|
48
49
|
"features/support/env.rb",
|
50
|
+
"features/support/hooks.rb",
|
49
51
|
"gimme.gemspec",
|
50
52
|
"lib/gimme-double.rb",
|
51
53
|
"lib/gimme.rb",
|
52
54
|
"lib/gimme/captor.rb",
|
55
|
+
"lib/gimme/compares_args.rb",
|
53
56
|
"lib/gimme/dsl.rb",
|
54
57
|
"lib/gimme/ensures_class_method_restoration.rb",
|
55
58
|
"lib/gimme/errors.rb",
|
59
|
+
"lib/gimme/finds_stubbings.rb",
|
56
60
|
"lib/gimme/gives.rb",
|
57
61
|
"lib/gimme/gives_class_methods.rb",
|
58
62
|
"lib/gimme/invocation_store.rb",
|
@@ -72,6 +76,7 @@ Gem::Specification.new do |s|
|
|
72
76
|
"spec/gimme/errors_spec.rb",
|
73
77
|
"spec/gimme/gives_class_methods_spec.rb",
|
74
78
|
"spec/gimme/gives_spec.rb",
|
79
|
+
"spec/gimme/invocation_store_spec.rb",
|
75
80
|
"spec/gimme/matchers_spec.rb",
|
76
81
|
"spec/gimme/resolves_methods_spec.rb",
|
77
82
|
"spec/gimme/rspec_adapter_spec.rb",
|
data/lib/gimme.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'gimme/reset'
|
1
2
|
require 'gimme/test_double'
|
2
3
|
require 'gimme/resolves_methods'
|
3
4
|
require 'gimme/errors'
|
@@ -10,12 +11,13 @@ require 'gimme/verifies_class_methods'
|
|
10
11
|
require 'gimme/matchers'
|
11
12
|
require 'gimme/captor'
|
12
13
|
require 'gimme/invokes_satisfied_stubbing'
|
13
|
-
require 'gimme/reset'
|
14
14
|
require 'gimme/dsl'
|
15
15
|
require 'gimme/store'
|
16
16
|
require 'gimme/stubbing_store'
|
17
|
+
require 'gimme/finds_stubbings'
|
17
18
|
require 'gimme/invocation_store'
|
18
19
|
require 'gimme/method_store'
|
20
|
+
require 'gimme/compares_args'
|
19
21
|
|
20
22
|
require 'gimme/rspec_adapter'
|
21
23
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Gimme
|
2
|
+
class ComparesArgs
|
3
|
+
|
4
|
+
def initialize(actual, expected)
|
5
|
+
@actual = actual
|
6
|
+
@expected = expected
|
7
|
+
end
|
8
|
+
|
9
|
+
def match?
|
10
|
+
same_size? && same_args?
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def same_size?
|
16
|
+
@actual.size == @expected.size
|
17
|
+
end
|
18
|
+
|
19
|
+
def same_args?
|
20
|
+
@actual.each_index.all? do |i|
|
21
|
+
@actual[i] == @expected[i] || matchers?(@expected[i], @actual[i])
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def matchers?(matcher, arg)
|
26
|
+
matcher.respond_to?(:matches?) && matcher.matches?(arg)
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Gimme
|
2
|
+
class FindsStubbings
|
3
|
+
def initialize(stubbed_thing)
|
4
|
+
@stubbings = Gimme.stubbings.get(stubbed_thing) || {}
|
5
|
+
end
|
6
|
+
|
7
|
+
def count(method, args)
|
8
|
+
stubbings_for(method, args).size
|
9
|
+
end
|
10
|
+
|
11
|
+
def find(method, args)
|
12
|
+
stubbings_for(method, args).last
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
def stubbings_for(method, args)
|
17
|
+
return [] unless @stubbings[method]
|
18
|
+
@stubbings[method].find { |(stub_args, blk)| ComparesArgs.new(args, stub_args).match? } || []
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -18,7 +18,7 @@ module Gimme
|
|
18
18
|
#TODO this will be redundantly overwritten
|
19
19
|
meta_class.instance_eval do
|
20
20
|
define_method method do |*actual_args|
|
21
|
-
InvokesSatisfiedStubbing.new(
|
21
|
+
InvokesSatisfiedStubbing.new(cls).invoke(method, actual_args)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Gimme
|
2
2
|
class InvokesSatisfiedStubbing
|
3
|
-
def initialize(
|
4
|
-
@
|
3
|
+
def initialize(stubbed_thing)
|
4
|
+
@finder = FindsStubbings.new(stubbed_thing)
|
5
5
|
end
|
6
6
|
|
7
7
|
def invoke(method, args)
|
8
|
-
if
|
8
|
+
if blk = @finder.find(method, args)
|
9
9
|
blk.call
|
10
10
|
elsif method.to_s[-1,1] == '?'
|
11
11
|
false
|
@@ -13,25 +13,5 @@ module Gimme
|
|
13
13
|
nil
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
17
|
-
private
|
18
|
-
|
19
|
-
def find_matching_stubbing(method, args)
|
20
|
-
match = nil
|
21
|
-
|
22
|
-
@stubbings[method].each do |stub_args,stub_block|
|
23
|
-
matching = args.size == stub_args.size
|
24
|
-
args.each_index do |i|
|
25
|
-
unless args[i] == stub_args[i] || (stub_args[i].respond_to?(:matches?) && stub_args[i].matches?(args[i]))
|
26
|
-
matching = false
|
27
|
-
break
|
28
|
-
end
|
29
|
-
end
|
30
|
-
match = stub_block if matching
|
31
|
-
end
|
32
|
-
|
33
|
-
match
|
34
|
-
end
|
35
|
-
|
36
16
|
end
|
37
|
-
end
|
17
|
+
end
|
data/lib/gimme/test_double.rb
CHANGED
@@ -9,26 +9,64 @@ module Gimme
|
|
9
9
|
class TestDouble < BlankSlate
|
10
10
|
attr_accessor :cls
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
@@gimme_count = 0
|
13
|
+
Gimme.on_reset(:every) { @@gimme_count = 0 }
|
14
|
+
|
15
|
+
def initialize(cls_or_name=nil)
|
16
|
+
@name = cls_or_name
|
17
|
+
@cls = cls_or_name if cls_or_name.kind_of?(Class)
|
18
|
+
@gimme_id = (@@gimme_count += 1)
|
14
19
|
end
|
15
20
|
|
16
21
|
def method_missing(method, *args, &block)
|
17
22
|
method = ResolvesMethods.new(self.cls, method, args).resolve(false)
|
18
23
|
Gimme.invocations.increment(self, method, args)
|
19
|
-
InvokesSatisfiedStubbing.new(
|
24
|
+
InvokesSatisfiedStubbing.new(self).invoke(method, args)
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect(*args, &blk)
|
28
|
+
if stubbed?(:inspect, *args, &blk)
|
29
|
+
method_missing(:inspect, *args, &blk)
|
30
|
+
else
|
31
|
+
"<#Gimme:#{@gimme_id} #{@name}>"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s(*args, &blk)
|
36
|
+
if stubbed?(:to_s, *args, &blk)
|
37
|
+
method_missing(:to_s, *args, &blk)
|
38
|
+
else
|
39
|
+
inspect
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def hash(*args, &blk)
|
44
|
+
if stubbed?(:hash, *args, &blk)
|
45
|
+
method_missing(:hash, *args, &blk)
|
46
|
+
else
|
47
|
+
__id__
|
48
|
+
end
|
20
49
|
end
|
21
50
|
|
22
|
-
def
|
23
|
-
|
51
|
+
def eql?(other, *args, &blk)
|
52
|
+
if stubbed?(:eql?, other, *args, &blk)
|
53
|
+
method_missing(:eql?, other, *args, &blk)
|
54
|
+
else
|
55
|
+
__id__ == other.__id__
|
56
|
+
end
|
24
57
|
end
|
25
58
|
|
26
|
-
def
|
27
|
-
|
59
|
+
def ==(other, *args, &blk)
|
60
|
+
if stubbed?(:==, other, *args, &blk)
|
61
|
+
method_missing(:==, other, *args, &blk)
|
62
|
+
else
|
63
|
+
eql?(other)
|
64
|
+
end
|
28
65
|
end
|
29
66
|
|
30
|
-
|
31
|
-
|
67
|
+
private
|
68
|
+
def stubbed?(method, *args, &blk)
|
69
|
+
FindsStubbings.new(self).count(method, args) > 0
|
32
70
|
end
|
33
71
|
end
|
34
72
|
|
data/lib/gimme/verifies.rb
CHANGED
@@ -15,32 +15,29 @@ module Gimme
|
|
15
15
|
def method_missing(sym, *args, &block)
|
16
16
|
sym = ResolvesMethods.new(__gimme__cls,sym,args).resolve(@raises_no_method_error)
|
17
17
|
|
18
|
-
|
19
|
-
|
20
|
-
if Gimme.invocations.get(@double, sym)
|
21
|
-
Gimme.invocations.get(@double, sym).each do |invoke_args,count|
|
22
|
-
matching = args.size == invoke_args.size
|
23
|
-
invoke_args.each_index do |i|
|
24
|
-
unless invoke_args[i] == args[i] || (args[i].respond_to?(:matches?) && args[i].matches?(invoke_args[i]))
|
25
|
-
matching = false
|
26
|
-
break
|
27
|
-
end
|
28
|
-
end
|
29
|
-
invoked += count if matching
|
30
|
-
end
|
18
|
+
if @times != invocation_count(sym, args)
|
19
|
+
raise Errors::VerificationFailedError.new(message_for(sym, args))
|
31
20
|
end
|
21
|
+
end
|
32
22
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
23
|
+
private
|
24
|
+
|
25
|
+
def invocation_count(sym, args)
|
26
|
+
invocations = Gimme.invocations.get(@double, sym)
|
27
|
+
return 0 unless invocations
|
28
|
+
invocations.inject(0) do |memo, (invoke_args, count)|
|
29
|
+
ComparesArgs.new(invoke_args, args).match? ? memo + count : memo
|
30
|
+
end
|
31
|
+
end
|
42
32
|
|
43
|
-
|
33
|
+
def message_for(sym, args)
|
34
|
+
msg = "expected #{__gimme__cls || @double}##{sym} to have been called with arguments #{args}"
|
35
|
+
if !Gimme.invocations.get(@double, sym) || Gimme.invocations.get(@double, sym).empty?
|
36
|
+
msg << "\n but was never called"
|
37
|
+
else
|
38
|
+
msg = Gimme.invocations.get(@double, sym).inject msg do |memo, actual|
|
39
|
+
memo + "\n was actually called #{actual[1]} times with arguments #{actual[0]}"
|
40
|
+
end
|
44
41
|
end
|
45
42
|
end
|
46
43
|
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Gimme
|
4
|
+
describe InvocationStore do
|
5
|
+
describe "incrementing calls" do
|
6
|
+
When { 3.times { subject.increment(:some_double, :some_method, :some_args) } }
|
7
|
+
Then { subject.get(:some_double, :some_method, :some_args).should == 3 }
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -2,13 +2,13 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
module Gimme
|
4
4
|
describe TestDouble do
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
describe "#gimme_next" do
|
6
|
+
class MassiveDamage
|
7
|
+
def boom
|
8
|
+
:asplode
|
9
|
+
end
|
8
10
|
end
|
9
|
-
end
|
10
11
|
|
11
|
-
describe "#gimme_next" do
|
12
12
|
Given(:test_double) { gimme_next(MassiveDamage) }
|
13
13
|
Given(:subject) { MassiveDamage.new }
|
14
14
|
|
@@ -23,5 +23,24 @@ module Gimme
|
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
26
|
+
describe "#gimme" do
|
27
|
+
context "of a class" do
|
28
|
+
subject { gimme(Object) }
|
29
|
+
Then { subject.should == subject }
|
30
|
+
Then { subject.eql?(subject).should == true }
|
31
|
+
Then { subject.to_s.should == "<#Gimme:1 Object>" }
|
32
|
+
Then { subject.inspect.should == "<#Gimme:1 Object>" }
|
33
|
+
Then { {}.tap {|h| h[subject] = subject }[subject].should == subject }
|
34
|
+
end
|
35
|
+
|
36
|
+
context "with a string name" do
|
37
|
+
subject { gimme("pants") }
|
38
|
+
Given { give(subject).name { "pants" } }
|
39
|
+
Then { subject.to_s.should == "<#Gimme:1 pants>" }
|
40
|
+
Then { subject.name.should == "pants" }
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
|
26
45
|
end
|
27
46
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gimme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-09-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: pry
|
@@ -261,6 +261,7 @@ files:
|
|
261
261
|
- features/basics.feature
|
262
262
|
- features/class_methods.feature
|
263
263
|
- features/matchers.feature
|
264
|
+
- features/messages.feature
|
264
265
|
- features/old/argument_captors.feature
|
265
266
|
- features/old/gimme_next.feature
|
266
267
|
- features/old/stub_basic.feature
|
@@ -276,13 +277,16 @@ files:
|
|
276
277
|
- features/step_definitions/gimme_steps.rb
|
277
278
|
- features/support/animals.rb
|
278
279
|
- features/support/env.rb
|
280
|
+
- features/support/hooks.rb
|
279
281
|
- gimme.gemspec
|
280
282
|
- lib/gimme-double.rb
|
281
283
|
- lib/gimme.rb
|
282
284
|
- lib/gimme/captor.rb
|
285
|
+
- lib/gimme/compares_args.rb
|
283
286
|
- lib/gimme/dsl.rb
|
284
287
|
- lib/gimme/ensures_class_method_restoration.rb
|
285
288
|
- lib/gimme/errors.rb
|
289
|
+
- lib/gimme/finds_stubbings.rb
|
286
290
|
- lib/gimme/gives.rb
|
287
291
|
- lib/gimme/gives_class_methods.rb
|
288
292
|
- lib/gimme/invocation_store.rb
|
@@ -302,6 +306,7 @@ files:
|
|
302
306
|
- spec/gimme/errors_spec.rb
|
303
307
|
- spec/gimme/gives_class_methods_spec.rb
|
304
308
|
- spec/gimme/gives_spec.rb
|
309
|
+
- spec/gimme/invocation_store_spec.rb
|
305
310
|
- spec/gimme/matchers_spec.rb
|
306
311
|
- spec/gimme/resolves_methods_spec.rb
|
307
312
|
- spec/gimme/rspec_adapter_spec.rb
|
@@ -325,9 +330,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
325
330
|
- - ! '>='
|
326
331
|
- !ruby/object:Gem::Version
|
327
332
|
version: '0'
|
328
|
-
segments:
|
329
|
-
- 0
|
330
|
-
hash: 2557097271096030919
|
331
333
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
332
334
|
none: false
|
333
335
|
requirements:
|