quacky 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.2
1
+ 0.2.3
data/lib/quacky.rb CHANGED
@@ -1,2 +1,7 @@
1
1
  require 'quacky/quacky'
2
+ require 'quacky/stub'
3
+ require 'quacky/double'
4
+ require 'quacky/expectations'
5
+ require 'quacky/duck_type_verifier'
2
6
  require 'quacky/rspec_setup'
7
+ require 'quacky/minitest_setup'
@@ -0,0 +1,14 @@
1
+ module Quacky
2
+ class Double
3
+ def initialize(name)
4
+ @name = name
5
+ end
6
+
7
+ def inspect
8
+ "<Quacky::Double :#{name}>"
9
+ end
10
+
11
+ private
12
+ attr_reader :name
13
+ end
14
+ end
@@ -0,0 +1,39 @@
1
+ module Quacky
2
+ class DuckTypeVerificationFailure < RuntimeError; end
3
+
4
+ class DuckTypeVerifier
5
+ def initialize duck_type
6
+ @duck_type = duck_type
7
+ end
8
+
9
+ def verify! object
10
+ duck_type_methods.each do |method|
11
+ raise Quacky::DuckTypeVerificationFailure, "object does not respond to `#{method.name}'" unless object.respond_to?(method.name)
12
+
13
+ target_method = object.public_method(method.name)
14
+ if target_method.parameters.count != method.parameters.count ||
15
+ target_method.parameters.map {|p| p.first } != method.parameters.map {|p| p.first}
16
+ raise Quacky::DuckTypeVerificationFailure, "definitions of method `#{method.name}` differ in parameters accepted."
17
+ end
18
+
19
+ true
20
+ end
21
+ end
22
+
23
+ private
24
+ attr_reader :duck_type
25
+
26
+ def duck_type_methods
27
+ @duck_type_methods ||= (duck_type_object.methods - Object.methods).map do |method_name|
28
+ @duck_type_object.public_method(method_name)
29
+ end
30
+ end
31
+
32
+ def duck_type_object
33
+ return @duck_type_object if @duck_type_object
34
+ duck_type_class = Class.new
35
+ duck_type_class.send :include, duck_type
36
+ @duck_type_object = duck_type_class.new
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,51 @@
1
+ require 'active_support/core_ext/module/aliasing'
2
+
3
+ module Quacky
4
+ class NoMethodError < RuntimeError; end
5
+
6
+ module Expectations
7
+ def quacky_stub method_name
8
+ setup_expectation method_name
9
+ end
10
+
11
+ def should_receive method_name
12
+ quacky_stub(method_name).tap do |expectation|
13
+ Quacky.expectations << expectation
14
+ end
15
+ end
16
+
17
+ private
18
+
19
+ def quacky_expectations
20
+ @expectations ||= {}
21
+ end
22
+
23
+ def setup_expectation method_name
24
+ method_name = method_name.to_sym
25
+ raise Quacky::NoMethodError unless respond_to? method_name
26
+
27
+ quacky_expectations[method_name] = Stub.new(public_method(method_name))
28
+ sanitized_name, postpend = parse_method_name method_name
29
+
30
+ eval <<-EVAL
31
+ class << self
32
+ define_method("#{sanitized_name}_with_expectation#{postpend}") do |*args|
33
+ quacky_expectations[:#{method_name}].call *args
34
+ end
35
+
36
+ alias_method_chain :#{method_name}, :expectation
37
+ end
38
+ EVAL
39
+
40
+ quacky_expectations[method_name]
41
+ end
42
+
43
+ def parse_method_name method_name
44
+ method_name = method_name.to_s
45
+ eol_matcher = /([\!\?])$/
46
+ method_name_postpend = method_name.to_s.match(eol_matcher) ? $1 : ""
47
+ method_name_minus_postpend = method_name.to_s.gsub eol_matcher, ""
48
+ [method_name_minus_postpend, method_name_postpend]
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,32 @@
1
+ if defined? MiniTest
2
+ module Quacky
3
+ module MiniTest
4
+ module Matchers
5
+ def assert_quacks_like object, *modules
6
+ modules.each do |a_module|
7
+ Quacky::DuckTypeVerifier.new(a_module).verify! object
8
+ end
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ module Quacky
15
+ alias :mock :double
16
+ alias :class_mock :class_double
17
+
18
+ module Expectations
19
+ def expect method_name, return_value, with=[]
20
+ should_receive(method_name).and_return(return_value).tap do |expectation|
21
+ expectation.with(*with) unless with.empty?
22
+ end
23
+ end
24
+
25
+ def stub method_name, return_value, with=[]
26
+ quacky_stub(method_name).and_return(return_value).tap do |expectation|
27
+ expectation.with(*with) unless with.empty?
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
data/lib/quacky/quacky.rb CHANGED
@@ -1,66 +1,6 @@
1
- require 'active_support/core_ext/module/aliasing'
2
-
3
- module Quacky
4
- class DuckTypeVerificationFailure < RuntimeError; end
5
-
6
- class DuckTypeVerifier
7
- def initialize duck_type
8
- @duck_type = duck_type
9
- end
10
-
11
- def verify! object
12
- duck_type_methods.each do |method|
13
- raise Quacky::DuckTypeVerificationFailure, "object does not respond to `#{method.name}'" unless object.respond_to?(method.name)
14
-
15
- target_method = object.public_method(method.name)
16
- if target_method.parameters.count != method.parameters.count ||
17
- target_method.parameters.map {|p| p.first } != method.parameters.map {|p| p.first}
18
- raise Quacky::DuckTypeVerificationFailure, "definitions of method `#{method.name}` differ in parameters accepted."
19
- end
20
-
21
- true
22
- end
23
- end
24
-
25
- private
26
- attr_reader :duck_type
27
-
28
- def duck_type_methods
29
- @duck_type_methods ||= (duck_type_object.methods - Object.methods).map do |method_name|
30
- @duck_type_object.public_method(method_name)
31
- end
32
- end
33
-
34
- def duck_type_object
35
- return @duck_type_object if @duck_type_object
36
- duck_type_class = Class.new
37
- duck_type_class.send :include, duck_type
38
- @duck_type_object = duck_type_class.new
39
- end
40
- end
41
- end
42
-
43
1
  module Quacky
44
2
  extend self
45
3
 
46
- class Double
47
- def initialize(name)
48
- @name = name
49
- end
50
-
51
- def inspect
52
- "<Quacky::Double :#{name}>"
53
- end
54
-
55
- private
56
- attr_reader :name
57
- end
58
-
59
- class NoMethodError < RuntimeError; end
60
- class MethodSignatureMismatch < ArgumentError; end
61
- class UnexpectedArguments < ArgumentError; end
62
- class UnsatisfiedExpectation < ArgumentError; end
63
-
64
4
  def expectations
65
5
  @expectations ||= []
66
6
  end
@@ -69,128 +9,12 @@ module Quacky
69
9
  @expectations = nil
70
10
  end
71
11
 
72
- class Stub
73
- def initialize method
74
- @method = method
75
- end
76
-
77
- def with *args
78
- @expected_args = args
79
- call_through *args
80
- self
81
- end
82
-
83
- def and_return value=nil, &block
84
- @return_value = value
85
- @return_block = block
86
- end
87
-
88
- def call *args
89
- @called_args = args
90
- validate_expectation
91
- call_through *args
92
-
93
- if expected_args
94
- return_value if (called_args == expected_args)
95
- else
96
- return_value
97
- end
98
- end
99
-
100
- def validate_satisfaction!
101
- if expected_args
102
- if called_args == expected_args
103
- true
104
- else
105
- raise UnsatisfiedExpectation
106
- end
107
- else
108
- was_called? || raise(UnsatisfiedExpectation, "Expected `#{@method.name}` to be called.")
109
- end
110
- end
111
-
112
- private
113
- attr_reader :called_args, :expected_args
114
-
115
- def was_called?
116
- !!called_args
117
- end
118
-
119
- def validate_expectation
120
- if expected_args && called_args != expected_args
121
- raise(
122
- Quacky::UnexpectedArguments,
123
- "#{@method.name} was called with unexpected arguments: #{called_args.map(&:inspect).join ", "}. expected: #{expected_args.map(&:inspect).join ", "}"
124
- )
125
- end
126
- end
127
-
128
- def return_value
129
- return @return_value if @return_value
130
- @return_block.call if @return_block
131
- end
132
-
133
- def call_through *args
134
- begin
135
- @method.call *args
136
- rescue ArgumentError => e
137
- raise Quacky::MethodSignatureMismatch, "#{@method.receiver}##{@method.name} was called with the #{e.message}"
138
- end
139
- end
140
- end
141
-
142
- module Expectations
143
- def stub method_name
144
- setup_expectation method_name
145
- end
146
-
147
- def should_receive method_name
148
- stub(method_name).tap do |expectation|
149
- Quacky.expectations << expectation
150
- end
151
- end
152
-
153
- private
154
-
155
- def quacky_expectations
156
- @expectations ||= {}
157
- end
158
-
159
- def setup_expectation method_name
160
- method_name = method_name.to_sym
161
- raise Quacky::NoMethodError unless respond_to? method_name
162
-
163
- quacky_expectations[method_name] = Stub.new(public_method(method_name))
164
- sanitized_name, postpend = parse_method_name method_name
165
-
166
- eval <<-EVAL
167
- class << self
168
- define_method("#{sanitized_name}_with_expectation#{postpend}") do |*args|
169
- quacky_expectations[:#{method_name}].call *args
170
- end
171
-
172
- alias_method_chain :#{method_name}, :expectation
173
- end
174
- EVAL
175
-
176
- quacky_expectations[method_name]
177
- end
178
-
179
- def parse_method_name method_name
180
- method_name = method_name.to_s
181
- eol_matcher = /([\!\?])$/
182
- method_name_postpend = method_name.to_s.match(eol_matcher) ? $1 : ""
183
- method_name_minus_postpend = method_name.to_s.gsub eol_matcher, ""
184
- [method_name_minus_postpend, method_name_postpend]
185
- end
186
- end
187
-
188
12
  def double(name, *duck_types)
189
13
  Double.new(name).tap do |object|
190
14
  duck_types.each do |duck_type|
191
15
  object.extend duck_type
192
16
  end
193
- object.extend Quacky::Expectations
17
+ object.extend Expectations
194
18
  end
195
19
  end
196
20
 
@@ -216,6 +40,7 @@ module Quacky
216
40
  class_modules, instance_modules = parse_class_double_options options
217
41
 
218
42
  Class.new do
43
+ extend Expectations
219
44
  extend ClassInspect
220
45
  include InstanceInspect
221
46
  name_class_double name
@@ -2,6 +2,12 @@ if defined? RSpec
2
2
  require 'rspec'
3
3
  require 'rspec/matchers'
4
4
 
5
+ module Quacky
6
+ module Expectations
7
+ alias :stub :quacky_stub
8
+ end
9
+ end
10
+
5
11
  RSpec::Matchers.define :quack_like do |*expected_duck_types|
6
12
  expected_duck_types.each do |expected_duck_type|
7
13
  match do |actual|
@@ -0,0 +1,76 @@
1
+ module Quacky
2
+ class UnexpectedArguments < ArgumentError; end
3
+ class UnsatisfiedExpectation < ArgumentError; end
4
+ class MethodSignatureMismatch < ArgumentError; end
5
+
6
+ class Stub
7
+ def initialize method
8
+ @method = method
9
+ end
10
+
11
+ def with *args
12
+ @expected_args = args
13
+ call_through *args
14
+ self
15
+ end
16
+
17
+ def and_return value=nil, &block
18
+ @return_value = value
19
+ @return_block = block
20
+ self
21
+ end
22
+
23
+ def call *args
24
+ @called_args = args
25
+ validate_expectation
26
+ call_through *args
27
+
28
+ if expected_args
29
+ return_value if (called_args == expected_args)
30
+ else
31
+ return_value
32
+ end
33
+ end
34
+
35
+ def validate_satisfaction!
36
+ if expected_args
37
+ if called_args == expected_args
38
+ true
39
+ else
40
+ raise UnsatisfiedExpectation
41
+ end
42
+ else
43
+ was_called? || raise(UnsatisfiedExpectation, "Expected `#{@method.name}` to be called.")
44
+ end
45
+ end
46
+
47
+ private
48
+ attr_reader :called_args, :expected_args
49
+
50
+ def was_called?
51
+ !!called_args
52
+ end
53
+
54
+ def validate_expectation
55
+ if expected_args && called_args != expected_args
56
+ raise(
57
+ Quacky::UnexpectedArguments,
58
+ "#{@method.name} was called with unexpected arguments: #{called_args.map(&:inspect).join ", "}. expected: #{expected_args.map(&:inspect).join ", "}"
59
+ )
60
+ end
61
+ end
62
+
63
+ def return_value
64
+ return @return_value if @return_value
65
+ @return_block.call if @return_block
66
+ end
67
+
68
+ def call_through *args
69
+ begin
70
+ @method.call *args
71
+ rescue ArgumentError => e
72
+ raise Quacky::MethodSignatureMismatch, "#{@method.receiver}##{@method.name} was called with the #{e.message}"
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe Quacky::Double do
4
+ describe ".inspect" do
5
+ it "should be formatted like `<Quacky::Double :<double_name>>`" do
6
+ Quacky::Double.new(:test).inspect.should == "<Quacky::Double :test>"
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,55 @@
1
+ require 'spec_helper'
2
+
3
+ describe Quacky::DuckTypeVerifier do
4
+ let(:conforming_object) do
5
+ Class.new do
6
+ def quack arg1,arg2,arg3=nil; end
7
+ end.new
8
+ end
9
+
10
+ let(:duck_type_module) do
11
+ Module.new do
12
+ def quack a,b,c=nil; end
13
+ end
14
+ end
15
+
16
+ describe "#verify!" do
17
+ let(:verifier) { Quacky::DuckTypeVerifier.new(duck_type_module) }
18
+
19
+ context "non-conforming objects" do
20
+ context "an object that doesn't even respond to the same methods" do
21
+ let(:non_conforming_object) do
22
+ Class.new.new
23
+ end
24
+
25
+ it "should raise a Quacky::DuckTypeVerificationFailure" do
26
+ expect { verifier.verify! non_conforming_object }.to raise_exception Quacky::DuckTypeVerificationFailure
27
+ end
28
+ end
29
+
30
+ context "an object that has the methods but with different parameters" do
31
+ let(:non_conforming_object) do
32
+ Class.new do
33
+ def quack; end
34
+ end.new
35
+ end
36
+
37
+ it "should raise a Quacky::DuckTypeVerificationFailure" do
38
+ expect { verifier.verify! non_conforming_object }.to raise_exception Quacky::DuckTypeVerificationFailure, "definitions of method `quack` differ in parameters accepted."
39
+ end
40
+ end
41
+ end
42
+
43
+ context "given a conforming object" do
44
+ let(:conforming_object) do
45
+ Class.new do
46
+ def quack arg1,arg2,arg3=nil; end
47
+ end.new
48
+ end
49
+
50
+ it "should return true" do
51
+ expect { verifier.verify! conforming_object }.not_to raise_exception Quacky::DuckTypeVerificationFailure
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Quacky::Double created with Quacky.double" do
4
+ let(:q_double) { Quacky.double :duck, Duck }
5
+ let(:expectation) { double(:expectation) }
6
+
7
+ describe "#stub" do
8
+ it "should raise an exception if the method does not already exist on the double" do
9
+ expect { q_double.quacky_stub("random_method_#{rand 1000000}") }.to raise_exception Quacky::NoMethodError
10
+ end
11
+
12
+ it "should initialize and return a new Quacky::Stub otherwise" do
13
+ Quacky::Stub.should_receive(:new).with(q_double.public_method(:duck!)).and_return expectation
14
+ q_double.quacky_stub(:duck!).should == expectation
15
+ end
16
+
17
+ it "should reroute calls to the original method to call the expectation's call method" do
18
+ Quacky::Stub.stub(:new).with(q_double.public_method(:duck!)).and_return expectation
19
+ q_double.quacky_stub(:duck!)
20
+
21
+ argument = double :argument
22
+ expectation.should_receive(:call).with argument
23
+ q_double.duck!(argument)
24
+ end
25
+
26
+ it "should support methods ending in !, ?, and regular letters" do
27
+ q_double = Quacky.double(:quacky_double, Module.new do
28
+ def bang!; end
29
+ def question?; end
30
+ def regular; end
31
+ end)
32
+
33
+ q_double.should_receive(:bang!).and_return "bang"
34
+ q_double.should_receive(:question?).and_return "question"
35
+ q_double.should_receive(:regular).and_return "regular"
36
+
37
+ q_double.bang!.should == "bang"
38
+ q_double.question?.should == "question"
39
+ q_double.regular.should == "regular"
40
+ end
41
+ end
42
+
43
+ describe "#should_receive" do
44
+ it "should raise an exception if the method does not already exist on the quacky double" do
45
+ expect { q_double.should_receive("random_method_#{rand 1000000}") }.to raise_exception Quacky::NoMethodError
46
+ end
47
+
48
+ it "should initialize and return a new QuackyStub otherwise" do
49
+ Quacky::Stub.should_receive(:new).with(q_double.public_method(:duck!)).and_return expectation
50
+ q_double.should_receive(:duck!).should == expectation
51
+ end
52
+
53
+ it "should add the generated expectation to the list of required expectations" do
54
+ Quacky::Stub.stub(:new).with(q_double.public_method(:duck!)).and_return expectation
55
+ q_double.should_receive(:duck!)
56
+ Quacky.expectations.should include expectation
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,14 @@
1
+ module MiniTest; end
2
+
3
+ require_relative '../../../lib/quacky/minitest_setup'
4
+ require_relative '../../../lib/quacky/quacky'
5
+
6
+ describe Quacky do
7
+ describe ".mock" do
8
+ it "should be an alias for .double" do
9
+ Quacky.public_method(:mock).should == Quacky.public_method(:double)
10
+ end
11
+ end
12
+ end
13
+
14
+ Object.send(:remove_const, :MiniTest)
@@ -1,65 +1,6 @@
1
- require_relative '../../lib/quacky/quacky'
2
-
3
- module Duck
4
- def duck! arg; end
5
- end
6
-
7
- describe Quacky::DuckTypeVerifier do
8
- let(:conforming_object) do
9
- Class.new do
10
- def quack arg1,arg2,arg3=nil; end
11
- end.new
12
- end
13
-
14
- let(:duck_type_module) do
15
- Module.new do
16
- def quack a,b,c=nil; end
17
- end
18
- end
19
-
20
- describe "#verify!" do
21
- let(:verifier) { Quacky::DuckTypeVerifier.new(duck_type_module) }
22
-
23
- context "non-conforming objects" do
24
- context "an object that doesn't even respond to the same methods" do
25
- let(:non_conforming_object) do
26
- Class.new.new
27
- end
28
-
29
- it "should raise a Quacky::DuckTypeVerificationFailure" do
30
- expect { verifier.verify! non_conforming_object }.to raise_exception Quacky::DuckTypeVerificationFailure
31
- end
32
- end
33
-
34
- context "an object that has the methods but with different parameters" do
35
- let(:non_conforming_object) do
36
- Class.new do
37
- def quack; end
38
- end.new
39
- end
40
-
41
- it "should raise a Quacky::DuckTypeVerificationFailure" do
42
- expect { verifier.verify! non_conforming_object }.to raise_exception Quacky::DuckTypeVerificationFailure, "definitions of method `quack` differ in parameters accepted."
43
- end
44
- end
45
- end
46
-
47
- context "given a conforming object" do
48
- let(:conforming_object) do
49
- Class.new do
50
- def quack arg1,arg2,arg3=nil; end
51
- end.new
52
- end
53
-
54
- it "should return true" do
55
- expect { verifier.verify! conforming_object }.not_to raise_exception Quacky::DuckTypeVerificationFailure
56
- end
57
- end
58
- end
59
- end
1
+ require 'spec_helper'
60
2
 
61
3
  describe Quacky do
62
-
63
4
  describe ".clear_expectations!" do
64
5
  it "should reset .expecatations to an empty collection" do
65
6
  Quacky.expectations.should be_empty
@@ -132,154 +73,4 @@ describe Quacky do
132
73
  it_behaves_like "quacky class double"
133
74
  end
134
75
  end
135
-
136
- describe Quacky::Double do
137
- let(:q_double) { Quacky.double :duck, Duck }
138
- let(:expectation) { double(:expectation) }
139
-
140
- describe ".inspect" do
141
- it "should be formatted like `<Quacky::Double :<double_name>>`" do
142
- Quacky::Double.new(:test).inspect.should == "<Quacky::Double :test>"
143
- end
144
- end
145
-
146
- describe ".stub" do
147
- it "should raise an exception if the method does not already exist on the double" do
148
- expect { q_double.stub("random_method_#{rand 1000000}") }.to raise_exception Quacky::NoMethodError
149
- end
150
-
151
- it "should initialize and return a new Quacky::Stub otherwise" do
152
- Quacky::Stub.should_receive(:new).with(q_double.public_method(:duck!)).and_return expectation
153
- q_double.stub(:duck!).should == expectation
154
- end
155
-
156
- it "should reroute calls to the original method to call the expectation's call method" do
157
- Quacky::Stub.stub(:new).with(q_double.public_method(:duck!)).and_return expectation
158
- q_double.stub(:duck!)
159
-
160
- argument = double :argument
161
- expectation.should_receive(:call).with argument
162
- q_double.duck!(argument)
163
- end
164
-
165
- it "should support methods ending in !, ?, and regular letters" do
166
- q_double = Quacky.double(:quacky_double, Module.new do
167
- def bang!; end
168
- def question?; end
169
- def regular; end
170
- end)
171
-
172
- q_double.should_receive(:bang!).and_return "bang"
173
- q_double.should_receive(:question?).and_return "question"
174
- q_double.should_receive(:regular).and_return "regular"
175
-
176
- q_double.bang!.should == "bang"
177
- q_double.question?.should == "question"
178
- q_double.regular.should == "regular"
179
- end
180
- end
181
-
182
- describe "should_receive" do
183
- it "should raise an exception if the method does not already exist on the quacky double" do
184
- expect { q_double.should_receive("random_method_#{rand 1000000}") }.to raise_exception Quacky::NoMethodError
185
- end
186
-
187
- it "should initialize and return a new QuackyStub otherwise" do
188
- Quacky::Stub.should_receive(:new).with(q_double.public_method(:duck!)).and_return expectation
189
- q_double.should_receive(:duck!).should == expectation
190
- end
191
-
192
- it "should add the generated expectation to the list of required expectations" do
193
- Quacky::Stub.stub(:new).with(q_double.public_method(:duck!)).and_return expectation
194
- q_double.should_receive(:duck!)
195
- Quacky.expectations.should include expectation
196
- end
197
- end
198
- end
199
- end
200
-
201
- module Quacky
202
- describe "mocks" do
203
- let(:object) do
204
- Class.new do
205
- include Duck
206
- end.new
207
- end
208
-
209
- describe Stub do
210
- let(:q_expectation) { Quacky::Stub.new(object.public_method(:duck!)) }
211
-
212
- describe "#with" do
213
- it "should raise an exception if the original method's signature mismatches" do
214
- expect { q_expectation.with 1,2,3 }.to raise_exception Quacky::MethodSignatureMismatch, "#{object.inspect}#duck! was called with the wrong number of arguments (3 for 1)"
215
- end
216
- end
217
-
218
- describe "#and_return" do
219
- context "static value" do
220
- it "should return the static value when called" do
221
- return_value = double :return_value
222
- q_expectation.and_return return_value
223
- q_expectation.call(double :argument).should == return_value
224
- end
225
- end
226
-
227
- context "block return value" do
228
- it "should return the value returned by the block" do
229
- return_value = double :return_value
230
- q_expectation.and_return { return_value }
231
- q_expectation.call(double :argument).should == return_value
232
- end
233
- end
234
- end
235
-
236
- describe "#call" do
237
- subject { q_expectation }
238
-
239
- context "with invalid arguments" do
240
- it "should raise an exception" do
241
- expect{ q_expectation.call(1,2,3)}.to raise_exception Quacky::MethodSignatureMismatch
242
- end
243
- end
244
-
245
- context "called with unexpected arguments" do
246
- it "should raise a Quacky::UnexpectedArguments exception" do
247
- q_expectation.with double(:expected_argument)
248
- expect { q_expectation.call double(:unexpected_arguments) }.to raise_exception Quacky::UnexpectedArguments
249
- end
250
- end
251
-
252
- context "called with expected arguments" do
253
- it "should return the configured return value" do
254
- q_expectation.with("foo").and_return "bar"
255
- q_expectation.call("foo").should == "bar"
256
- end
257
- end
258
- end
259
-
260
- describe "validate_satisfaction!" do
261
- subject { q_expectation.validate_satisfaction! }
262
-
263
- context "no with expectation" do
264
- before { q_expectation.call double(:argument) }
265
- specify { expect { subject }.not_to raise_exception }
266
- end
267
-
268
- context "not called at all" do
269
- specify { expect { subject }.to raise_exception Quacky::UnsatisfiedExpectation, "Expected `duck!` to be called." }
270
- end
271
-
272
- context "with expectation" do
273
- let(:argument) { double :argument }
274
-
275
- before { q_expectation.with argument }
276
-
277
- context "called with matching argument" do
278
- before { q_expectation.call argument }
279
- specify { expect { subject }.not_to raise_exception }
280
- end
281
- end
282
- end
283
- end
284
- end
285
76
  end
@@ -0,0 +1,87 @@
1
+ require 'spec_helper'
2
+
3
+ module Quacky
4
+ describe "mocks" do
5
+ let(:object) do
6
+ Class.new do
7
+ include Duck
8
+ end.new
9
+ end
10
+
11
+ describe Stub do
12
+ let(:q_expectation) { Quacky::Stub.new(object.public_method(:duck!)) }
13
+
14
+ describe "#with" do
15
+ it "should raise an exception if the original method's signature mismatches" do
16
+ expect { q_expectation.with 1,2,3 }.to raise_exception Quacky::MethodSignatureMismatch, "#{object.inspect}#duck! was called with the wrong number of arguments (3 for 1)"
17
+ end
18
+ end
19
+
20
+ describe "#and_return" do
21
+ context "static value" do
22
+ it "should return the static value when called" do
23
+ return_value = double :return_value
24
+ q_expectation.and_return return_value
25
+ q_expectation.call(double :argument).should == return_value
26
+ end
27
+ end
28
+
29
+ context "block return value" do
30
+ it "should return the value returned by the block" do
31
+ return_value = double :return_value
32
+ q_expectation.and_return { return_value }
33
+ q_expectation.call(double :argument).should == return_value
34
+ end
35
+ end
36
+ end
37
+
38
+ describe "#call" do
39
+ subject { q_expectation }
40
+
41
+ context "with invalid arguments" do
42
+ it "should raise an exception" do
43
+ expect{ q_expectation.call(1,2,3)}.to raise_exception Quacky::MethodSignatureMismatch
44
+ end
45
+ end
46
+
47
+ context "called with unexpected arguments" do
48
+ it "should raise a Quacky::UnexpectedArguments exception" do
49
+ q_expectation.with double(:expected_argument)
50
+ expect { q_expectation.call double(:unexpected_arguments) }.to raise_exception Quacky::UnexpectedArguments
51
+ end
52
+ end
53
+
54
+ context "called with expected arguments" do
55
+ it "should return the configured return value" do
56
+ q_expectation.with("foo").and_return "bar"
57
+ q_expectation.call("foo").should == "bar"
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "validate_satisfaction!" do
63
+ subject { q_expectation.validate_satisfaction! }
64
+
65
+ context "no with expectation" do
66
+ before { q_expectation.call double(:argument) }
67
+ specify { expect { subject }.not_to raise_exception }
68
+ end
69
+
70
+ context "not called at all" do
71
+ specify { expect { subject }.to raise_exception Quacky::UnsatisfiedExpectation, "Expected `duck!` to be called." }
72
+ end
73
+
74
+ context "with expectation" do
75
+ let(:argument) { double :argument }
76
+
77
+ before { q_expectation.with argument }
78
+
79
+ context "called with matching argument" do
80
+ before { q_expectation.call argument }
81
+ specify { expect { subject }.not_to raise_exception }
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,16 @@
1
+ $LOAD_PATH.unshift '.'
2
+ require 'quacky/quacky'
3
+ require 'quacky/stub'
4
+ require 'quacky/double'
5
+ require 'quacky/expectations'
6
+ require 'quacky/duck_type_verifier'
7
+
8
+ module Duck
9
+ def duck! arg; end
10
+ end
11
+
12
+ RSpec.configure do |c|
13
+ c.before do
14
+ Quacky.clear_expectations!
15
+ end
16
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: quacky
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-03 00:00:00.000000000 Z
12
+ date: 2012-07-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activesupport
16
- requirement: &70131385524940 !ruby/object:Gem::Requirement
16
+ requirement: &70238192808080 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ~>
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: 3.2.5
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *70131385524940
24
+ version_requirements: *70238192808080
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rspec
27
- requirement: &70131385524500 !ruby/object:Gem::Requirement
27
+ requirement: &70238192807680 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70131385524500
35
+ version_requirements: *70238192807680
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: cucumber
38
- requirement: &70131385391320 !ruby/object:Gem::Requirement
38
+ requirement: &70238192805940 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70131385391320
46
+ version_requirements: *70238192805940
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: specdown
49
- requirement: &70131385390880 !ruby/object:Gem::Requirement
49
+ requirement: &70238192805520 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *70131385390880
57
+ version_requirements: *70238192805520
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: rake
60
- requirement: &70131385390460 !ruby/object:Gem::Requirement
60
+ requirement: &70238192805080 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,18 +65,29 @@ dependencies:
65
65
  version: '0'
66
66
  type: :development
67
67
  prerelease: false
68
- version_requirements: *70131385390460
68
+ version_requirements: *70238192805080
69
69
  description:
70
70
  email: moonmaster9000@gmail.com
71
71
  executables: []
72
72
  extensions: []
73
73
  extra_rdoc_files: []
74
74
  files:
75
+ - lib/quacky/double.rb
76
+ - lib/quacky/duck_type_verifier.rb
77
+ - lib/quacky/expectations.rb
78
+ - lib/quacky/minitest_setup.rb
75
79
  - lib/quacky/quacky.rb
76
80
  - lib/quacky/rspec_setup.rb
81
+ - lib/quacky/stub.rb
77
82
  - lib/quacky.rb
78
83
  - VERSION
84
+ - spec/lib/double_spec.rb
85
+ - spec/lib/duck_type_verifier_spec.rb
86
+ - spec/lib/expectations_spec.rb
87
+ - spec/lib/quacky/minitest_setup_spec.rb
79
88
  - spec/lib/quacky_spec.rb
89
+ - spec/lib/stub_spec.rb
90
+ - spec/spec_helper.rb
80
91
  homepage: https://github.com/moonmaster9000/quacky
81
92
  licenses: []
82
93
  post_install_message:
@@ -102,4 +113,10 @@ signing_key:
102
113
  specification_version: 3
103
114
  summary: Ensure your test doubles quack like the real thing.
104
115
  test_files:
116
+ - spec/lib/double_spec.rb
117
+ - spec/lib/duck_type_verifier_spec.rb
118
+ - spec/lib/expectations_spec.rb
119
+ - spec/lib/quacky/minitest_setup_spec.rb
105
120
  - spec/lib/quacky_spec.rb
121
+ - spec/lib/stub_spec.rb
122
+ - spec/spec_helper.rb