gimme 0.1.6 → 0.1.7
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 +6 -4
- data/Rakefile +1 -0
- data/VERSION +1 -1
- data/gimme.gemspec +2 -2
- data/lib/gimme/captor.rb +2 -2
- data/lib/gimme/gives.rb +9 -9
- data/lib/gimme/matchers.rb +8 -8
- data/lib/gimme/method_resolver.rb +17 -7
- data/lib/gimme/test_double.rb +14 -11
- data/lib/gimme/verifies.rb +3 -3
- metadata +16 -16
data/README.markdown
CHANGED
@@ -4,6 +4,8 @@ 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://dougu.tumblr.com/post/6144302027/whats-wrong-with-rubys-test-doubles).
|
8
|
+
|
7
9
|
## Basics (or "What does it Gimme?" ... har.)
|
8
10
|
|
9
11
|
Gimme was originally named (well, for the first five hours of its life) "[Tabula Rasa](http://en.wikipedia.org/wiki/Tabula_rasa)," to very clearly indicate that it generates blank slate test doubles that lack any initial coupling with the concepts associated with specific [test double](http://xunitpatterns.com/Test%20Double.html) subtypes like mocks/stubs/fakes/spies/proxies. But in the end, "gimme" was easier to type than "tabula rasa", and I generally wanted to avoid test pattern lingo from leaking into the context and language of everybody's tests (hence no method named "stub").
|
@@ -104,10 +106,10 @@ Matchers can be used when both stubbing and verifying a method. To verify on any
|
|
104
106
|
|
105
107
|
Other matchers:
|
106
108
|
|
107
|
-
**is_a(class)** — matches any arguments that are `kind_of?` the provided class
|
108
|
-
**any(class)** — same as `is_a`, but also matches nil
|
109
|
-
**boolean** — matches true or false arguments
|
110
|
-
**numeric** — matches numeric arguments
|
109
|
+
* **is_a(class)** — matches any arguments that are `kind_of?` the provided class
|
110
|
+
* **any(class)** — same as `is_a`, but also matches nil
|
111
|
+
* **boolean** — matches true or false arguments
|
112
|
+
* **numeric** — matches numeric arguments
|
111
113
|
|
112
114
|
See the [cucumber feature for examples using these matchers](http://relishapp.com/searls/gimme/stubbing-with-matchers)
|
113
115
|
|
data/Rakefile
CHANGED
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.7
|
data/gimme.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{gimme}
|
8
|
-
s.version = "0.1.
|
8
|
+
s.version = "0.1.7"
|
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 = %q{2011-
|
12
|
+
s.date = %q{2011-06-04}
|
13
13
|
s.description = %q{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 = %q{searls@gmail.com}
|
15
15
|
s.extra_rdoc_files = [
|
data/lib/gimme/captor.rb
CHANGED
data/lib/gimme/gives.rb
CHANGED
@@ -9,19 +9,19 @@ module Gimme
|
|
9
9
|
|
10
10
|
def method_missing(sym, *args, &block)
|
11
11
|
sym = MethodResolver.resolve_sent_method(@double,sym,args,@raises_no_method_error)
|
12
|
-
|
12
|
+
|
13
13
|
@double.stubbings[sym] ||= {}
|
14
14
|
@double.stubbings[sym][args] = block if block
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
def give(double)
|
19
|
-
|
20
|
-
|
19
|
+
Gimme::Gives.new(double)
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
end
|
22
|
+
def give!(double)
|
23
|
+
give = give(double)
|
24
|
+
give.raises_no_method_error = false
|
25
|
+
give
|
26
|
+
end
|
27
|
+
end
|
data/lib/gimme/matchers.rb
CHANGED
@@ -14,7 +14,7 @@ module Gimme
|
|
14
14
|
def anything
|
15
15
|
Gimme::Matchers::Anything.new
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
class IsA < Matcher
|
19
19
|
def initialize(cls)
|
20
20
|
@cls = cls
|
@@ -32,11 +32,11 @@ module Gimme
|
|
32
32
|
def matches?(arg)
|
33
33
|
arg == nil || arg.kind_of?(@cls)
|
34
34
|
end
|
35
|
-
end
|
35
|
+
end
|
36
36
|
def any(cls)
|
37
37
|
Gimme::Matchers::Any.new(cls)
|
38
|
-
end
|
39
|
-
|
38
|
+
end
|
39
|
+
|
40
40
|
class Numeric < Matcher
|
41
41
|
def matches?(arg)
|
42
42
|
arg.kind_of?(Fixnum) || arg.kind_of?(Numeric) || arg.kind_of?(Float)
|
@@ -44,15 +44,15 @@ module Gimme
|
|
44
44
|
end
|
45
45
|
def numeric
|
46
46
|
Gimme::Matchers::Numeric.new
|
47
|
-
end
|
48
|
-
|
47
|
+
end
|
48
|
+
|
49
49
|
class Boolean < Matcher
|
50
50
|
def matches?(arg)
|
51
51
|
arg.kind_of?(TrueClass) || arg.kind_of?(FalseClass)
|
52
|
-
end
|
52
|
+
end
|
53
53
|
end
|
54
54
|
def boolean
|
55
55
|
Gimme::Matchers::Boolean.new
|
56
56
|
end
|
57
57
|
end
|
58
|
-
end
|
58
|
+
end
|
@@ -3,21 +3,31 @@ module Gimme
|
|
3
3
|
class MethodResolver
|
4
4
|
def self.resolve_sent_method(double,sym,args,raises_no_method_error=true)
|
5
5
|
cls = double.cls
|
6
|
-
sym = args.shift if sym == :send
|
6
|
+
sym = args.shift if sym == :send
|
7
7
|
if cls && raises_no_method_error
|
8
|
-
if cls.private_methods.include?(sym
|
8
|
+
if cls.private_methods.include?(named(sym))
|
9
9
|
raise NoMethodError.new("#{sym} is a private method of your #{cls} test double, so stubbing/verifying it
|
10
10
|
might not be a great idea. If you want to try to stub or verify this method anyway, then you can
|
11
|
-
invoke give! or verify! to suppress this error.")
|
12
|
-
elsif !cls.instance_methods.include?(sym
|
13
|
-
raise NoMethodError.new("Your test double of #{cls} may not know how to respond to the '#{sym}' method.
|
11
|
+
invoke give! or verify! to suppress this error.")
|
12
|
+
elsif !cls.instance_methods.include?(named(sym))
|
13
|
+
raise NoMethodError.new("Your test double of #{cls} may not know how to respond to the '#{sym}' method.
|
14
14
|
If you're confident that a real #{cls} will know how to respond to '#{sym}', then you can
|
15
|
-
invoke give! or verify! to suppress this error.")
|
15
|
+
invoke give! or verify! to suppress this error.")
|
16
16
|
end
|
17
17
|
end
|
18
18
|
|
19
19
|
sym
|
20
20
|
end
|
21
|
+
|
22
|
+
if RUBY_VERSION >= "1.9.2"
|
23
|
+
def self.named(sym)
|
24
|
+
sym
|
25
|
+
end
|
26
|
+
else
|
27
|
+
def self.named(sym)
|
28
|
+
sym.to_s
|
29
|
+
end
|
30
|
+
end
|
21
31
|
end
|
22
32
|
|
23
|
-
end
|
33
|
+
end
|
data/lib/gimme/test_double.rb
CHANGED
@@ -1,6 +1,9 @@
|
|
1
1
|
module Gimme
|
2
2
|
class BlankSlate
|
3
|
+
warning_level = $VERBOSE
|
4
|
+
$VERBOSE = nil
|
3
5
|
instance_methods.each { |m| undef_method m unless m =~ /^__/ }
|
6
|
+
$VERBOSE = warning_level
|
4
7
|
end
|
5
8
|
|
6
9
|
class TestDouble < BlankSlate
|
@@ -16,24 +19,24 @@ module Gimme
|
|
16
19
|
|
17
20
|
def method_missing(sym, *args, &block)
|
18
21
|
sym = MethodResolver.resolve_sent_method(self,sym,args,false)
|
19
|
-
|
20
|
-
@invocations[sym] ||= {}
|
22
|
+
|
23
|
+
@invocations[sym] ||= {}
|
21
24
|
@stubbings[sym] ||= {}
|
22
|
-
|
25
|
+
|
23
26
|
@invocations[sym][args] = 1 + (@invocations[sym][args]||0)
|
24
27
|
|
25
28
|
matching_stub_block = nil
|
26
29
|
@stubbings[sym].each do |stub_args,stub_block|
|
27
30
|
matching = args.size == stub_args.size
|
28
|
-
args.each_index do |i|
|
31
|
+
args.each_index do |i|
|
29
32
|
unless args[i] == stub_args[i] || (stub_args[i].respond_to?(:matches?) && stub_args[i].matches?(args[i]))
|
30
33
|
matching = false
|
31
34
|
break
|
32
35
|
end
|
33
|
-
end
|
36
|
+
end
|
34
37
|
matching_stub_block = stub_block if matching
|
35
38
|
end
|
36
|
-
|
39
|
+
|
37
40
|
if matching_stub_block
|
38
41
|
matching_stub_block.call
|
39
42
|
elsif sym.to_s[-1,1] == '?'
|
@@ -43,21 +46,21 @@ module Gimme
|
|
43
46
|
end
|
44
47
|
end
|
45
48
|
end
|
46
|
-
|
49
|
+
|
47
50
|
def gimme(cls=nil)
|
48
51
|
Gimme::TestDouble.new(cls)
|
49
52
|
end
|
50
|
-
|
53
|
+
|
51
54
|
def gimme_next(cls)
|
52
55
|
double = Gimme::TestDouble.new(cls)
|
53
|
-
meta_class = class << cls; self; end
|
56
|
+
meta_class = class << cls; self; end
|
54
57
|
real_new = cls.method(:new)
|
55
58
|
meta_class.send(:define_method,:new) do |*args|
|
56
59
|
double.send(:initialize,*args)
|
57
60
|
meta_class.send(:define_method,:new,real_new) #restore :new on the class
|
58
61
|
double
|
59
|
-
end
|
62
|
+
end
|
60
63
|
double
|
61
64
|
end
|
62
65
|
|
63
|
-
end
|
66
|
+
end
|
data/lib/gimme/verifies.rb
CHANGED
@@ -10,7 +10,7 @@ module Gimme
|
|
10
10
|
|
11
11
|
def method_missing(sym, *args, &block)
|
12
12
|
sym = MethodResolver.resolve_sent_method(@double,sym,args,@raises_no_method_error)
|
13
|
-
|
13
|
+
|
14
14
|
#gosh, this loop sure looks familiar. just like another ugly loop I know. TODO.
|
15
15
|
invoked = 0
|
16
16
|
if @double.invocations[sym]
|
@@ -25,7 +25,7 @@ module Gimme
|
|
25
25
|
invoked += count if matching
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
if invoked != @times
|
30
30
|
raise Errors::VerificationFailedError.new("expected #{sym} to have been called with #{args}")
|
31
31
|
end
|
@@ -41,4 +41,4 @@ module Gimme
|
|
41
41
|
verify.raises_no_method_error = false
|
42
42
|
verify
|
43
43
|
end
|
44
|
-
end
|
44
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gimme
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 7
|
10
|
+
version: 0.1.7
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Justin Searls
|
@@ -15,12 +15,12 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-06-04 00:00:00 -04:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
22
22
|
prerelease: false
|
23
|
-
|
23
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
24
24
|
none: false
|
25
25
|
requirements:
|
26
26
|
- - ~>
|
@@ -32,11 +32,11 @@ dependencies:
|
|
32
32
|
- 0
|
33
33
|
version: 1.0.0
|
34
34
|
type: :development
|
35
|
+
requirement: *id001
|
35
36
|
name: bundler
|
36
|
-
version_requirements: *id001
|
37
37
|
- !ruby/object:Gem::Dependency
|
38
38
|
prerelease: false
|
39
|
-
|
39
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
42
|
- - ~>
|
@@ -48,11 +48,11 @@ dependencies:
|
|
48
48
|
- 2
|
49
49
|
version: 1.5.2
|
50
50
|
type: :development
|
51
|
+
requirement: *id002
|
51
52
|
name: jeweler
|
52
|
-
version_requirements: *id002
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
prerelease: false
|
55
|
-
|
55
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
56
56
|
none: false
|
57
57
|
requirements:
|
58
58
|
- - ">="
|
@@ -64,11 +64,11 @@ dependencies:
|
|
64
64
|
- 1
|
65
65
|
version: 1.3.1
|
66
66
|
type: :development
|
67
|
+
requirement: *id003
|
67
68
|
name: rspec
|
68
|
-
version_requirements: *id003
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
prerelease: false
|
71
|
-
|
71
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
72
72
|
none: false
|
73
73
|
requirements:
|
74
74
|
- - ">="
|
@@ -80,11 +80,11 @@ dependencies:
|
|
80
80
|
- 0
|
81
81
|
version: 0.10.0
|
82
82
|
type: :development
|
83
|
+
requirement: *id004
|
83
84
|
name: cucumber
|
84
|
-
version_requirements: *id004
|
85
85
|
- !ruby/object:Gem::Dependency
|
86
86
|
prerelease: false
|
87
|
-
|
87
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
88
88
|
none: false
|
89
89
|
requirements:
|
90
90
|
- - ">="
|
@@ -96,11 +96,11 @@ dependencies:
|
|
96
96
|
- 1
|
97
97
|
version: 1.3.1
|
98
98
|
type: :development
|
99
|
+
requirement: *id005
|
99
100
|
name: rspec
|
100
|
-
version_requirements: *id005
|
101
101
|
- !ruby/object:Gem::Dependency
|
102
102
|
prerelease: false
|
103
|
-
|
103
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
104
104
|
none: false
|
105
105
|
requirements:
|
106
106
|
- - ">="
|
@@ -112,8 +112,8 @@ dependencies:
|
|
112
112
|
- 0
|
113
113
|
version: 0.10.0
|
114
114
|
type: :development
|
115
|
+
requirement: *id006
|
115
116
|
name: cucumber
|
116
|
-
version_requirements: *id006
|
117
117
|
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). "
|
118
118
|
email: searls@gmail.com
|
119
119
|
executables: []
|