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.
Files changed (133) hide show
  1. data/CHANGES +221 -0
  2. data/README.rdoc +343 -0
  3. data/Rakefile +88 -0
  4. data/VERSION.yml +4 -0
  5. data/lib/rr.rb +88 -0
  6. data/lib/rr/adapters/rr_methods.rb +122 -0
  7. data/lib/rr/adapters/rspec.rb +59 -0
  8. data/lib/rr/adapters/test_unit.rb +29 -0
  9. data/lib/rr/double.rb +152 -0
  10. data/lib/rr/double_definitions/child_double_definition_creator.rb +27 -0
  11. data/lib/rr/double_definitions/double_definition.rb +348 -0
  12. data/lib/rr/double_definitions/double_definition_creator.rb +167 -0
  13. data/lib/rr/double_definitions/double_definition_creator_proxy.rb +37 -0
  14. data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +15 -0
  15. data/lib/rr/double_definitions/strategies/implementation/proxy.rb +62 -0
  16. data/lib/rr/double_definitions/strategies/implementation/reimplementation.rb +14 -0
  17. data/lib/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation.rb +17 -0
  18. data/lib/rr/double_definitions/strategies/scope/instance.rb +15 -0
  19. data/lib/rr/double_definitions/strategies/scope/instance_of_class.rb +50 -0
  20. data/lib/rr/double_definitions/strategies/scope/scope_strategy.rb +15 -0
  21. data/lib/rr/double_definitions/strategies/strategy.rb +70 -0
  22. data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +34 -0
  23. data/lib/rr/double_definitions/strategies/verification/mock.rb +44 -0
  24. data/lib/rr/double_definitions/strategies/verification/stub.rb +45 -0
  25. data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +15 -0
  26. data/lib/rr/double_injection.rb +180 -0
  27. data/lib/rr/double_matches.rb +51 -0
  28. data/lib/rr/errors/argument_equality_error.rb +6 -0
  29. data/lib/rr/errors/double_definition_error.rb +6 -0
  30. data/lib/rr/errors/double_not_found_error.rb +6 -0
  31. data/lib/rr/errors/double_order_error.rb +6 -0
  32. data/lib/rr/errors/rr_error.rb +20 -0
  33. data/lib/rr/errors/spy_verification_errors/double_injection_not_found_error.rb +8 -0
  34. data/lib/rr/errors/spy_verification_errors/invocation_count_error.rb +8 -0
  35. data/lib/rr/errors/spy_verification_errors/spy_verification_error.rb +8 -0
  36. data/lib/rr/errors/subject_does_not_implement_method_error.rb +6 -0
  37. data/lib/rr/errors/subject_has_different_arity_error.rb +6 -0
  38. data/lib/rr/errors/times_called_error.rb +6 -0
  39. data/lib/rr/expectations/any_argument_expectation.rb +21 -0
  40. data/lib/rr/expectations/argument_equality_expectation.rb +41 -0
  41. data/lib/rr/expectations/times_called_expectation.rb +57 -0
  42. data/lib/rr/hash_with_object_id_key.rb +44 -0
  43. data/lib/rr/method_dispatches/base_method_dispatch.rb +108 -0
  44. data/lib/rr/method_dispatches/method_dispatch.rb +61 -0
  45. data/lib/rr/method_dispatches/method_missing_dispatch.rb +49 -0
  46. data/lib/rr/proc_from_block.rb +7 -0
  47. data/lib/rr/recorded_calls.rb +103 -0
  48. data/lib/rr/space.rb +123 -0
  49. data/lib/rr/spy_verification.rb +48 -0
  50. data/lib/rr/spy_verification_proxy.rb +18 -0
  51. data/lib/rr/times_called_matchers/any_times_matcher.rb +18 -0
  52. data/lib/rr/times_called_matchers/at_least_matcher.rb +15 -0
  53. data/lib/rr/times_called_matchers/at_most_matcher.rb +23 -0
  54. data/lib/rr/times_called_matchers/integer_matcher.rb +19 -0
  55. data/lib/rr/times_called_matchers/non_terminal.rb +27 -0
  56. data/lib/rr/times_called_matchers/proc_matcher.rb +11 -0
  57. data/lib/rr/times_called_matchers/range_matcher.rb +21 -0
  58. data/lib/rr/times_called_matchers/terminal.rb +20 -0
  59. data/lib/rr/times_called_matchers/times_called_matcher.rb +44 -0
  60. data/lib/rr/wildcard_matchers.rb +158 -0
  61. data/lib/rr/wildcard_matchers/anything.rb +18 -0
  62. data/lib/rr/wildcard_matchers/boolean.rb +23 -0
  63. data/lib/rr/wildcard_matchers/duck_type.rb +32 -0
  64. data/lib/rr/wildcard_matchers/hash_including.rb +29 -0
  65. data/lib/rr/wildcard_matchers/is_a.rb +25 -0
  66. data/lib/rr/wildcard_matchers/numeric.rb +13 -0
  67. data/lib/rr/wildcard_matchers/range.rb +7 -0
  68. data/lib/rr/wildcard_matchers/regexp.rb +7 -0
  69. data/lib/rr/wildcard_matchers/satisfy.rb +26 -0
  70. data/spec/core_spec_suite.rb +19 -0
  71. data/spec/environment_fixture_setup.rb +7 -0
  72. data/spec/high_level_spec.rb +398 -0
  73. data/spec/proc_from_block_spec.rb +14 -0
  74. data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +67 -0
  75. data/spec/rr/adapters/rr_methods_creator_spec.rb +149 -0
  76. data/spec/rr/adapters/rr_methods_space_spec.rb +115 -0
  77. data/spec/rr/adapters/rr_methods_spec_helper.rb +11 -0
  78. data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +17 -0
  79. data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +112 -0
  80. data/spec/rr/double_definitions/double_definition_creator_proxy_spec.rb +155 -0
  81. data/spec/rr/double_definitions/double_definition_creator_spec.rb +502 -0
  82. data/spec/rr/double_definitions/double_definition_spec.rb +1165 -0
  83. data/spec/rr/double_injection/double_injection_spec.rb +339 -0
  84. data/spec/rr/double_injection/double_injection_verify_spec.rb +29 -0
  85. data/spec/rr/double_spec.rb +352 -0
  86. data/spec/rr/errors/rr_error_spec.rb +67 -0
  87. data/spec/rr/expectations/any_argument_expectation_spec.rb +47 -0
  88. data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +14 -0
  89. data/spec/rr/expectations/argument_equality_expectation_spec.rb +135 -0
  90. data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +34 -0
  91. data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
  92. data/spec/rr/expectations/hash_including_spec.rb +17 -0
  93. data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +59 -0
  94. data/spec/rr/expectations/satisfy_spec.rb +14 -0
  95. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +46 -0
  96. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +69 -0
  97. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +71 -0
  98. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +23 -0
  99. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +104 -0
  100. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +81 -0
  101. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +83 -0
  102. data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +38 -0
  103. data/spec/rr/rspec/invocation_matcher_spec.rb +279 -0
  104. data/spec/rr/rspec/rspec_adapter_spec.rb +66 -0
  105. data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +31 -0
  106. data/spec/rr/rspec/rspec_backtrace_tweaking_spec_fixture.rb +11 -0
  107. data/spec/rr/rspec/rspec_usage_spec.rb +86 -0
  108. data/spec/rr/space/hash_with_object_id_key_spec.rb +88 -0
  109. data/spec/rr/space/space_spec.rb +550 -0
  110. data/spec/rr/test_unit/test_helper.rb +7 -0
  111. data/spec/rr/test_unit/test_unit_backtrace_test.rb +36 -0
  112. data/spec/rr/test_unit/test_unit_integration_test.rb +57 -0
  113. data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +47 -0
  114. data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +55 -0
  115. data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +70 -0
  116. data/spec/rr/times_called_matchers/integer_matcher_spec.rb +70 -0
  117. data/spec/rr/times_called_matchers/proc_matcher_spec.rb +55 -0
  118. data/spec/rr/times_called_matchers/range_matcher_spec.rb +76 -0
  119. data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +118 -0
  120. data/spec/rr/wildcard_matchers/anything_spec.rb +24 -0
  121. data/spec/rr/wildcard_matchers/boolean_spec.rb +36 -0
  122. data/spec/rr/wildcard_matchers/duck_type_spec.rb +52 -0
  123. data/spec/rr/wildcard_matchers/is_a_spec.rb +32 -0
  124. data/spec/rr/wildcard_matchers/numeric_spec.rb +32 -0
  125. data/spec/rr/wildcard_matchers/range_spec.rb +35 -0
  126. data/spec/rr/wildcard_matchers/regexp_spec.rb +43 -0
  127. data/spec/rr_spec.rb +28 -0
  128. data/spec/rspec_spec_suite.rb +17 -0
  129. data/spec/spec_helper.rb +109 -0
  130. data/spec/spec_suite.rb +31 -0
  131. data/spec/spy_verification_spec.rb +129 -0
  132. data/spec/test_unit_spec_suite.rb +21 -0
  133. 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,13 @@
1
+ module RR
2
+ module WildcardMatchers
3
+ class Numeric < IsA
4
+ def initialize
5
+ @klass = ::Numeric
6
+ end
7
+
8
+ def inspect
9
+ 'numeric'
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,7 @@
1
+ class Range
2
+ def wildcard_match?(other)
3
+ return true if self == other
4
+ return false unless other.is_a?(Numeric)
5
+ self.include?(other)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ class Regexp
2
+ def wildcard_match?(other)
3
+ return true if self == other
4
+ return false unless other.is_a?(String)
5
+ (other =~ self) ? true : false
6
+ end
7
+ 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,7 @@
1
+ require "rubygems"
2
+ require "spec"
3
+ require "spec/autorun"
4
+ dir = File.dirname(__FILE__)
5
+ $LOAD_PATH.unshift "#{dir}/../lib"
6
+ require "rr"
7
+ require "pp"
@@ -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