redinger-rr 0.10.3
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/CHANGES +221 -0
- data/README.rdoc +343 -0
- data/Rakefile +88 -0
- data/VERSION.yml +4 -0
- data/lib/rr.rb +88 -0
- data/lib/rr/adapters/rr_methods.rb +122 -0
- data/lib/rr/adapters/rspec.rb +59 -0
- data/lib/rr/adapters/test_unit.rb +29 -0
- data/lib/rr/double.rb +152 -0
- data/lib/rr/double_definitions/child_double_definition_creator.rb +27 -0
- data/lib/rr/double_definitions/double_definition.rb +348 -0
- data/lib/rr/double_definitions/double_definition_creator.rb +167 -0
- data/lib/rr/double_definitions/double_definition_creator_proxy.rb +37 -0
- data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +15 -0
- data/lib/rr/double_definitions/strategies/implementation/proxy.rb +62 -0
- data/lib/rr/double_definitions/strategies/implementation/reimplementation.rb +14 -0
- data/lib/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation.rb +17 -0
- data/lib/rr/double_definitions/strategies/scope/instance.rb +15 -0
- data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +50 -0
- data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +15 -0
- data/lib/rr/double_definitions/strategies/strategy.rb +70 -0
- data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +34 -0
- data/lib/rr/double_definitions/strategies/verification/mock.rb +44 -0
- data/lib/rr/double_definitions/strategies/verification/stub.rb +45 -0
- data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +15 -0
- data/lib/rr/double_injection.rb +180 -0
- data/lib/rr/double_matches.rb +51 -0
- data/lib/rr/errors/argument_equality_error.rb +6 -0
- data/lib/rr/errors/double_definition_error.rb +6 -0
- data/lib/rr/errors/double_not_found_error.rb +6 -0
- data/lib/rr/errors/double_order_error.rb +6 -0
- data/lib/rr/errors/rr_error.rb +20 -0
- data/lib/rr/errors/spy_verification_errors/double_injection_not_found_error.rb +8 -0
- data/lib/rr/errors/spy_verification_errors/invocation_count_error.rb +8 -0
- data/lib/rr/errors/spy_verification_errors/spy_verification_error.rb +8 -0
- data/lib/rr/errors/subject_does_not_implement_method_error.rb +6 -0
- data/lib/rr/errors/subject_has_different_arity_error.rb +6 -0
- data/lib/rr/errors/times_called_error.rb +6 -0
- data/lib/rr/expectations/any_argument_expectation.rb +21 -0
- data/lib/rr/expectations/argument_equality_expectation.rb +41 -0
- data/lib/rr/expectations/times_called_expectation.rb +57 -0
- data/lib/rr/hash_with_object_id_key.rb +44 -0
- data/lib/rr/method_dispatches/base_method_dispatch.rb +108 -0
- data/lib/rr/method_dispatches/method_dispatch.rb +61 -0
- data/lib/rr/method_dispatches/method_missing_dispatch.rb +49 -0
- data/lib/rr/proc_from_block.rb +7 -0
- data/lib/rr/recorded_calls.rb +103 -0
- data/lib/rr/space.rb +123 -0
- data/lib/rr/spy_verification.rb +48 -0
- data/lib/rr/spy_verification_proxy.rb +18 -0
- data/lib/rr/times_called_matchers/any_times_matcher.rb +18 -0
- data/lib/rr/times_called_matchers/at_least_matcher.rb +15 -0
- data/lib/rr/times_called_matchers/at_most_matcher.rb +23 -0
- data/lib/rr/times_called_matchers/integer_matcher.rb +19 -0
- data/lib/rr/times_called_matchers/non_terminal.rb +27 -0
- data/lib/rr/times_called_matchers/proc_matcher.rb +11 -0
- data/lib/rr/times_called_matchers/range_matcher.rb +21 -0
- data/lib/rr/times_called_matchers/terminal.rb +20 -0
- data/lib/rr/times_called_matchers/times_called_matcher.rb +44 -0
- data/lib/rr/wildcard_matchers.rb +158 -0
- data/lib/rr/wildcard_matchers/anything.rb +18 -0
- data/lib/rr/wildcard_matchers/boolean.rb +23 -0
- data/lib/rr/wildcard_matchers/duck_type.rb +32 -0
- data/lib/rr/wildcard_matchers/hash_including.rb +29 -0
- data/lib/rr/wildcard_matchers/is_a.rb +25 -0
- data/lib/rr/wildcard_matchers/numeric.rb +13 -0
- data/lib/rr/wildcard_matchers/range.rb +7 -0
- data/lib/rr/wildcard_matchers/regexp.rb +7 -0
- data/lib/rr/wildcard_matchers/satisfy.rb +26 -0
- data/spec/core_spec_suite.rb +19 -0
- data/spec/environment_fixture_setup.rb +7 -0
- data/spec/high_level_spec.rb +398 -0
- data/spec/proc_from_block_spec.rb +14 -0
- data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +67 -0
- data/spec/rr/adapters/rr_methods_creator_spec.rb +149 -0
- data/spec/rr/adapters/rr_methods_space_spec.rb +115 -0
- data/spec/rr/adapters/rr_methods_spec_helper.rb +11 -0
- data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +17 -0
- data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +112 -0
- data/spec/rr/double_definitions/double_definition_creator_proxy_spec.rb +155 -0
- data/spec/rr/double_definitions/double_definition_creator_spec.rb +502 -0
- data/spec/rr/double_definitions/double_definition_spec.rb +1165 -0
- data/spec/rr/double_injection/double_injection_spec.rb +339 -0
- data/spec/rr/double_injection/double_injection_verify_spec.rb +29 -0
- data/spec/rr/double_spec.rb +352 -0
- data/spec/rr/errors/rr_error_spec.rb +67 -0
- data/spec/rr/expectations/any_argument_expectation_spec.rb +47 -0
- data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +14 -0
- data/spec/rr/expectations/argument_equality_expectation_spec.rb +135 -0
- data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +34 -0
- data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
- data/spec/rr/expectations/hash_including_spec.rb +17 -0
- data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +59 -0
- data/spec/rr/expectations/satisfy_spec.rb +14 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +46 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +69 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +71 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +23 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +104 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +81 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +83 -0
- data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +38 -0
- data/spec/rr/rspec/invocation_matcher_spec.rb +279 -0
- data/spec/rr/rspec/rspec_adapter_spec.rb +66 -0
- data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +31 -0
- data/spec/rr/rspec/rspec_backtrace_tweaking_spec_fixture.rb +11 -0
- data/spec/rr/rspec/rspec_usage_spec.rb +86 -0
- data/spec/rr/space/hash_with_object_id_key_spec.rb +88 -0
- data/spec/rr/space/space_spec.rb +550 -0
- data/spec/rr/test_unit/test_helper.rb +7 -0
- data/spec/rr/test_unit/test_unit_backtrace_test.rb +36 -0
- data/spec/rr/test_unit/test_unit_integration_test.rb +57 -0
- data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +47 -0
- data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +55 -0
- data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +70 -0
- data/spec/rr/times_called_matchers/integer_matcher_spec.rb +70 -0
- data/spec/rr/times_called_matchers/proc_matcher_spec.rb +55 -0
- data/spec/rr/times_called_matchers/range_matcher_spec.rb +76 -0
- data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +118 -0
- data/spec/rr/wildcard_matchers/anything_spec.rb +24 -0
- data/spec/rr/wildcard_matchers/boolean_spec.rb +36 -0
- data/spec/rr/wildcard_matchers/duck_type_spec.rb +52 -0
- data/spec/rr/wildcard_matchers/is_a_spec.rb +32 -0
- data/spec/rr/wildcard_matchers/numeric_spec.rb +32 -0
- data/spec/rr/wildcard_matchers/range_spec.rb +35 -0
- data/spec/rr/wildcard_matchers/regexp_spec.rb +43 -0
- data/spec/rr_spec.rb +28 -0
- data/spec/rspec_spec_suite.rb +17 -0
- data/spec/spec_helper.rb +109 -0
- data/spec/spec_suite.rb +31 -0
- data/spec/spy_verification_spec.rb +129 -0
- data/spec/test_unit_spec_suite.rb +21 -0
- metadata +193 -0
@@ -0,0 +1,23 @@
|
|
1
|
+
module RR
|
2
|
+
module WildcardMatchers
|
3
|
+
class Boolean
|
4
|
+
def wildcard_match?(other)
|
5
|
+
self == other || is_a_boolean?(other)
|
6
|
+
end
|
7
|
+
|
8
|
+
def ==(other)
|
9
|
+
other.is_a?(self.class)
|
10
|
+
end
|
11
|
+
alias_method :eql?, :==
|
12
|
+
|
13
|
+
def inspect
|
14
|
+
'boolean'
|
15
|
+
end
|
16
|
+
|
17
|
+
protected
|
18
|
+
def is_a_boolean?(subject)
|
19
|
+
subject.is_a?(TrueClass) || subject.is_a?(FalseClass)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module RR
|
2
|
+
module WildcardMatchers
|
3
|
+
class DuckType
|
4
|
+
attr_accessor :required_methods
|
5
|
+
|
6
|
+
def initialize(*required_methods)
|
7
|
+
@required_methods = required_methods
|
8
|
+
end
|
9
|
+
|
10
|
+
def wildcard_match?(other)
|
11
|
+
return true if self == other
|
12
|
+
required_methods.each do |m|
|
13
|
+
return false unless other.respond_to?(m)
|
14
|
+
end
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
formatted_required_methods = required_methods.collect do |method_name|
|
20
|
+
method_name.inspect
|
21
|
+
end.join(', ')
|
22
|
+
"duck_type(#{formatted_required_methods})"
|
23
|
+
end
|
24
|
+
|
25
|
+
def ==(other)
|
26
|
+
return false unless other.is_a?(self.class)
|
27
|
+
self.required_methods == other.required_methods
|
28
|
+
end
|
29
|
+
alias_method :eql?, :==
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module RR
|
2
|
+
module WildcardMatchers
|
3
|
+
class HashIncluding
|
4
|
+
attr_reader :expected_hash
|
5
|
+
|
6
|
+
def initialize(expected_hash)
|
7
|
+
@expected_hash = expected_hash.clone
|
8
|
+
end
|
9
|
+
|
10
|
+
def wildcard_match?(other)
|
11
|
+
return true if self == other
|
12
|
+
expected_hash.each_pair do |key, value|
|
13
|
+
return false unless other.has_key?(key) && other[key] == expected_hash[key]
|
14
|
+
end
|
15
|
+
return true
|
16
|
+
end
|
17
|
+
|
18
|
+
def inspect
|
19
|
+
"hash_including(#{expected_hash.inspect})"
|
20
|
+
end
|
21
|
+
|
22
|
+
def ==(other)
|
23
|
+
return false unless other.is_a?(self.class)
|
24
|
+
self.expected_hash == other.expected_hash
|
25
|
+
end
|
26
|
+
alias_method :eql?, :==
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module RR
|
2
|
+
module WildcardMatchers
|
3
|
+
class IsA
|
4
|
+
attr_reader :klass
|
5
|
+
|
6
|
+
def initialize(klass)
|
7
|
+
@klass = klass
|
8
|
+
end
|
9
|
+
|
10
|
+
def wildcard_match?(other)
|
11
|
+
self == other || other.is_a?(klass)
|
12
|
+
end
|
13
|
+
|
14
|
+
def inspect
|
15
|
+
"is_a(#{klass})"
|
16
|
+
end
|
17
|
+
|
18
|
+
def ==(other)
|
19
|
+
return false unless other.is_a?(self.class)
|
20
|
+
self.klass == other.klass
|
21
|
+
end
|
22
|
+
alias_method :eql?, :==
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module RR
|
2
|
+
module WildcardMatchers
|
3
|
+
class Satisfy
|
4
|
+
attr_reader :expectation_proc
|
5
|
+
|
6
|
+
def initialize(expectation_proc)
|
7
|
+
@expectation_proc = expectation_proc
|
8
|
+
end
|
9
|
+
|
10
|
+
def wildcard_match?(other)
|
11
|
+
return true if self == other
|
12
|
+
!!expectation_proc.call(other)
|
13
|
+
end
|
14
|
+
|
15
|
+
def inspect
|
16
|
+
"satisfy {block}"
|
17
|
+
end
|
18
|
+
|
19
|
+
def ==(other)
|
20
|
+
return false unless other.is_a?(self.class)
|
21
|
+
self.expectation_proc == other.expectation_proc
|
22
|
+
end
|
23
|
+
alias_method :eql?, :==
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "spec"
|
3
|
+
|
4
|
+
class CoreExampleSuite
|
5
|
+
def run
|
6
|
+
files = Dir["#{File.dirname(__FILE__)}/**/*_spec.rb"]
|
7
|
+
files.delete_if {|file| file.include?('rspec/')}
|
8
|
+
files.delete_if {|file| file.include?('test_unit/')}
|
9
|
+
puts "Running Rspec Example Suite"
|
10
|
+
files.each do |file|
|
11
|
+
require file
|
12
|
+
# puts "require '#{file}'"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
if $0 == __FILE__
|
18
|
+
CoreExampleSuite.new.run
|
19
|
+
end
|
@@ -0,0 +1,398 @@
|
|
1
|
+
require File.expand_path("#{File.dirname(__FILE__)}/spec_helper")
|
2
|
+
|
3
|
+
class HighLevelSpec
|
4
|
+
attr_reader :initialize_arguments
|
5
|
+
|
6
|
+
def initialize(*args)
|
7
|
+
@initialize_arguments = args
|
8
|
+
yield if block_given?
|
9
|
+
method_run_in_initialize
|
10
|
+
end
|
11
|
+
|
12
|
+
def method_run_in_initialize
|
13
|
+
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "RR" do
|
18
|
+
attr_reader :subject
|
19
|
+
before(:each) do
|
20
|
+
@subject = Object.new
|
21
|
+
extend RR::Adapters::RRMethods
|
22
|
+
end
|
23
|
+
|
24
|
+
after(:each) do
|
25
|
+
RR.reset
|
26
|
+
end
|
27
|
+
|
28
|
+
describe "mock" do
|
29
|
+
it "mocks via inline call" do
|
30
|
+
mock(subject).to_s {"a value"}
|
31
|
+
subject.to_s.should == "a value"
|
32
|
+
lambda {subject.to_s}.should raise_error(RR::Errors::TimesCalledError)
|
33
|
+
end
|
34
|
+
|
35
|
+
it "allows ordering" do
|
36
|
+
mock(subject).to_s {"value 1"}.ordered
|
37
|
+
mock(subject).to_s {"value 2"}.twice
|
38
|
+
subject.to_s.should == "value 1"
|
39
|
+
subject.to_s.should == "value 2"
|
40
|
+
subject.to_s.should == "value 2"
|
41
|
+
lambda {subject.to_s}.should raise_error(RR::Errors::TimesCalledError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'allows terse chaining' do
|
45
|
+
mock(subject).first(1) {mock(Object.new).second(2) {mock(Object.new).third(3) {4}}}
|
46
|
+
subject.first(1).second(2).third(3).should == 4
|
47
|
+
|
48
|
+
mock(subject).first(1) {mock!.second(2) {mock!.third(3) {4}}}
|
49
|
+
subject.first(1).second(2).third(3).should == 4
|
50
|
+
|
51
|
+
mock(subject).first(1) {mock!.second(2).mock!.third(3) {4}}
|
52
|
+
subject.first(1).second(2).third(3).should == 4
|
53
|
+
|
54
|
+
mock(subject).first(1) {mock!.second(2).mock! {third(3) {4}}}
|
55
|
+
subject.first(1).second(2).third(3).should == 4
|
56
|
+
|
57
|
+
mock(subject).first(1).mock!.second(2).mock!.third(3) {4}
|
58
|
+
subject.first(1).second(2).third(3).should == 4
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'allows chaining with proxy' do
|
62
|
+
find_return_value = Object.new
|
63
|
+
def find_return_value.child
|
64
|
+
:the_child
|
65
|
+
end
|
66
|
+
(class << subject; self; end).class_eval do
|
67
|
+
define_method(:find) do |id|
|
68
|
+
id == '1' ? find_return_value : raise(ArgumentError)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
mock.proxy(subject).find('1').mock.proxy!.child
|
73
|
+
subject.find('1').child.should == :the_child
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'allows branched chaining' do
|
77
|
+
mock(subject).first do
|
78
|
+
mock! do |expect|
|
79
|
+
expect.branch1 {mock!.branch11 {11}}
|
80
|
+
expect.branch2 {mock!.branch22 {22}}
|
81
|
+
end
|
82
|
+
end
|
83
|
+
o = subject.first
|
84
|
+
o.branch1.branch11.should == 11
|
85
|
+
o.branch2.branch22.should == 22
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'allows chained ordering' do
|
89
|
+
mock(subject).to_s {"value 1"}.then.to_s {"value 2"}.twice.then.to_s {"value 3"}.once
|
90
|
+
subject.to_s.should == "value 1"
|
91
|
+
subject.to_s.should == "value 2"
|
92
|
+
subject.to_s.should == "value 2"
|
93
|
+
subject.to_s.should == "value 3"
|
94
|
+
lambda {subject.to_s}.should raise_error(RR::Errors::TimesCalledError)
|
95
|
+
end
|
96
|
+
|
97
|
+
it "mocks via block with argument" do
|
98
|
+
mock subject do |c|
|
99
|
+
c.to_s {"a value"}
|
100
|
+
c.to_sym {:crazy}
|
101
|
+
end
|
102
|
+
subject.to_s.should == "a value"
|
103
|
+
subject.to_sym.should == :crazy
|
104
|
+
end
|
105
|
+
|
106
|
+
it "mocks via block without argument" do
|
107
|
+
mock subject do
|
108
|
+
to_s {"a value"}
|
109
|
+
to_sym {:crazy}
|
110
|
+
end
|
111
|
+
subject.to_s.should == "a value"
|
112
|
+
subject.to_sym.should == :crazy
|
113
|
+
end
|
114
|
+
|
115
|
+
it "has wildcard matchers" do
|
116
|
+
mock(subject).foobar(
|
117
|
+
is_a(String),
|
118
|
+
anything,
|
119
|
+
numeric,
|
120
|
+
boolean,
|
121
|
+
duck_type(:to_s),
|
122
|
+
/abc/
|
123
|
+
) {"value 1"}.twice
|
124
|
+
subject.foobar(
|
125
|
+
'hello',
|
126
|
+
Object.new,
|
127
|
+
99,
|
128
|
+
false,
|
129
|
+
"My String",
|
130
|
+
"Tabcola"
|
131
|
+
).should == "value 1"
|
132
|
+
lambda do
|
133
|
+
subject.foobar(:failure)
|
134
|
+
end.should raise_error( RR::Errors::DoubleNotFoundError )
|
135
|
+
end
|
136
|
+
|
137
|
+
it "mocks methods without letters" do
|
138
|
+
mock(subject) == 55
|
139
|
+
|
140
|
+
subject == 55
|
141
|
+
lambda do
|
142
|
+
subject == 99
|
143
|
+
end.should raise_error(RR::Errors::DoubleNotFoundError)
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "proxy" do
|
148
|
+
it "proxies via inline call" do
|
149
|
+
expected_to_s_value = subject.to_s
|
150
|
+
mock.proxy(subject).to_s
|
151
|
+
subject.to_s.should == expected_to_s_value
|
152
|
+
lambda {subject.to_s}.should raise_error
|
153
|
+
end
|
154
|
+
|
155
|
+
it "proxy allows ordering" do
|
156
|
+
def subject.to_s(arg)
|
157
|
+
"Original to_s with arg #{arg}"
|
158
|
+
end
|
159
|
+
mock.proxy(subject).to_s(:foo).ordered
|
160
|
+
mock.proxy(subject).to_s(:bar).twice.ordered
|
161
|
+
|
162
|
+
subject.to_s(:foo).should == "Original to_s with arg foo"
|
163
|
+
subject.to_s(:bar).should == "Original to_s with arg bar"
|
164
|
+
subject.to_s(:bar).should == "Original to_s with arg bar"
|
165
|
+
lambda {subject.to_s(:bar)}.should raise_error(RR::Errors::TimesCalledError)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "proxy allows ordering" do
|
169
|
+
def subject.to_s(arg)
|
170
|
+
"Original to_s with arg #{arg}"
|
171
|
+
end
|
172
|
+
mock.proxy(subject).to_s(:foo).ordered
|
173
|
+
mock.proxy(subject).to_s(:bar).twice.ordered
|
174
|
+
|
175
|
+
subject.to_s(:foo).should == "Original to_s with arg foo"
|
176
|
+
subject.to_s(:bar).should == "Original to_s with arg bar"
|
177
|
+
subject.to_s(:bar).should == "Original to_s with arg bar"
|
178
|
+
lambda {subject.to_s(:bar)}.should raise_error(RR::Errors::TimesCalledError)
|
179
|
+
end
|
180
|
+
|
181
|
+
it "proxies via block with argument" do
|
182
|
+
def subject.foobar_1(*args)
|
183
|
+
:original_value_1
|
184
|
+
end
|
185
|
+
|
186
|
+
def subject.foobar_2
|
187
|
+
:original_value_2
|
188
|
+
end
|
189
|
+
|
190
|
+
mock.proxy subject do |c|
|
191
|
+
c.foobar_1(1)
|
192
|
+
c.foobar_2
|
193
|
+
end
|
194
|
+
subject.foobar_1(1).should == :original_value_1
|
195
|
+
lambda {subject.foobar_1(:blah)}.should raise_error
|
196
|
+
|
197
|
+
subject.foobar_2.should == :original_value_2
|
198
|
+
lambda {subject.foobar_2(:blah)}.should raise_error
|
199
|
+
end
|
200
|
+
|
201
|
+
it "proxies via block without argument" do
|
202
|
+
def subject.foobar_1(*args)
|
203
|
+
:original_value_1
|
204
|
+
end
|
205
|
+
|
206
|
+
def subject.foobar_2
|
207
|
+
:original_value_2
|
208
|
+
end
|
209
|
+
|
210
|
+
mock.proxy subject do
|
211
|
+
foobar_1(1)
|
212
|
+
foobar_2
|
213
|
+
end
|
214
|
+
subject.foobar_1(1).should == :original_value_1
|
215
|
+
lambda {subject.foobar_1(:blah)}.should raise_error
|
216
|
+
|
217
|
+
subject.foobar_2.should == :original_value_2
|
218
|
+
lambda {subject.foobar_2(:blah)}.should raise_error
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
describe "stub" do
|
223
|
+
it "stubs via inline call" do
|
224
|
+
stub(subject).to_s {"a value"}
|
225
|
+
subject.to_s.should == "a value"
|
226
|
+
end
|
227
|
+
|
228
|
+
it "allows ordering" do
|
229
|
+
stub(subject).to_s {"value 1"}.once.ordered
|
230
|
+
stub(subject).to_s {"value 2"}.once.ordered
|
231
|
+
|
232
|
+
subject.to_s.should == "value 1"
|
233
|
+
subject.to_s.should == "value 2"
|
234
|
+
end
|
235
|
+
|
236
|
+
it "stubs via block with argument" do
|
237
|
+
stub subject do |d|
|
238
|
+
d.to_s {"a value"}
|
239
|
+
d.to_sym {:crazy}
|
240
|
+
end
|
241
|
+
subject.to_s.should == "a value"
|
242
|
+
subject.to_sym.should == :crazy
|
243
|
+
end
|
244
|
+
|
245
|
+
it "stubs via block without argument" do
|
246
|
+
stub subject do
|
247
|
+
to_s {"a value"}
|
248
|
+
to_sym {:crazy}
|
249
|
+
end
|
250
|
+
subject.to_s.should == "a value"
|
251
|
+
subject.to_sym.should == :crazy
|
252
|
+
end
|
253
|
+
|
254
|
+
it "stubs instance_of" do
|
255
|
+
stub.instance_of(HighLevelSpec) do |o|
|
256
|
+
o.to_s {"High Level Spec"}
|
257
|
+
end
|
258
|
+
HighLevelSpec.new.to_s.should == "High Level Spec"
|
259
|
+
end
|
260
|
+
|
261
|
+
it "stubs methods without letters" do
|
262
|
+
stub(subject).__send__(:==) {:equality}
|
263
|
+
(subject == 55).should == :equality
|
264
|
+
end
|
265
|
+
|
266
|
+
it "stubs methods invoked in #initialize while passing along the #initialize arg" do
|
267
|
+
method_run_in_initialize_stubbed = false
|
268
|
+
stub.instance_of(HighLevelSpec) do |o|
|
269
|
+
o.method_run_in_initialize {method_run_in_initialize_stubbed = true}
|
270
|
+
end
|
271
|
+
HighLevelSpec.new
|
272
|
+
method_run_in_initialize_stubbed.should be_true
|
273
|
+
end
|
274
|
+
|
275
|
+
it "passed the arguments and block passed to #initialize" do
|
276
|
+
block_called = false
|
277
|
+
stub.instance_of(HighLevelSpec) do |o|
|
278
|
+
o.method_run_in_initialize
|
279
|
+
end
|
280
|
+
instance = HighLevelSpec.new(1, 2) {block_called = true}
|
281
|
+
instance.initialize_arguments.should == [1, 2]
|
282
|
+
block_called.should be_true
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
describe "RR recorded_calls" do
|
287
|
+
it "should verify method calls after the fact" do
|
288
|
+
stub(subject).pig_rabbit
|
289
|
+
subject.pig_rabbit("bacon", "bunny meat")
|
290
|
+
#subject.should have_received.pig_rabitt("bacon", "bunny meat")
|
291
|
+
received(subject).pig_rabbit("bacon", "bunny meat").call
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should verify method calls after the fact" do
|
295
|
+
stub(subject).pig_rabbit
|
296
|
+
lambda do
|
297
|
+
received(subject).pig_rabbit("bacon", "bunny meat").call
|
298
|
+
end.should raise_error(RR::Errors::SpyVerificationErrors::SpyVerificationError)
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
class StrongTestObject
|
303
|
+
def method_with_no_arguments
|
304
|
+
end
|
305
|
+
|
306
|
+
def method_with_one_argument(string)
|
307
|
+
end
|
308
|
+
|
309
|
+
def method_with_two_arguments(string, integer)
|
310
|
+
end
|
311
|
+
|
312
|
+
def method_with_three_arguments_including_varargs(string, integer, *args)
|
313
|
+
end
|
314
|
+
|
315
|
+
def method_with_varargs(*args)
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
describe "strong" do
|
320
|
+
context "when the method does not exist" do
|
321
|
+
it "raises an exception" do
|
322
|
+
lambda do
|
323
|
+
strong.stub(StrongTestObject.new).something
|
324
|
+
end.should raise_error(RR::Errors::SubjectDoesNotImplementMethodError)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context "when the method exists with no arguments" do
|
329
|
+
it "does not raise an exception" do
|
330
|
+
strong.stub(StrongTestObject.new).method_with_no_arguments
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
context "when the method has a different arity" do
|
335
|
+
it "raises an exception" do
|
336
|
+
lambda do
|
337
|
+
strong.stub(StrongTestObject.new).method_with_one_argument
|
338
|
+
end.should raise_error(RR::Errors::SubjectHasDifferentArityError)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
context "when the method has accepts a variable number of arguments" do
|
343
|
+
it "does not raise an exception" do
|
344
|
+
strong.stub(StrongTestObject.new).method_with_varargs
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
context "when the method does not provide the required parameters before varargs" do
|
349
|
+
it "raises an exception" do
|
350
|
+
lambda do
|
351
|
+
strong.stub(StrongTestObject.new).method_with_three_arguments_including_varargs
|
352
|
+
end.should raise_error(RR::Errors::SubjectHasDifferentArityError)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
context "when the minimum number of parameters are provided" do
|
357
|
+
it "does not raise an exception" do
|
358
|
+
strong.stub(StrongTestObject.new).method_with_three_arguments_including_varargs("one", 2)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
context "when using instance_of and the method does not exist" do
|
363
|
+
it "raises an exception" do
|
364
|
+
lambda do
|
365
|
+
strong.stub.instance_of(StrongTestObject).something
|
366
|
+
StrongTestObject.new
|
367
|
+
end.should raise_error(RR::Errors::SubjectDoesNotImplementMethodError)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
context "when using instance_of and the method does exist" do
|
372
|
+
it "does not raise an exception" do
|
373
|
+
strong.stub.instance_of(StrongTestObject).method_with_no_arguments
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
describe "spy" do
|
379
|
+
it "should record all method invocations" do
|
380
|
+
subject = Object.new
|
381
|
+
def subject.something
|
382
|
+
end
|
383
|
+
|
384
|
+
def subject.something_else
|
385
|
+
end
|
386
|
+
|
387
|
+
spy(subject)
|
388
|
+
|
389
|
+
subject.something
|
390
|
+
subject.something_else
|
391
|
+
subject.to_s
|
392
|
+
|
393
|
+
received(subject).something.call
|
394
|
+
received(subject).something_else.call
|
395
|
+
received(subject).to_s.call
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|