rr 0.4.3 → 0.4.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (40) hide show
  1. data/CHANGES +4 -0
  2. data/README +25 -0
  3. data/Rakefile +1 -1
  4. data/lib/rr/double.rb +10 -10
  5. data/lib/rr/double_creator.rb +5 -5
  6. data/lib/rr/double_injection.rb +7 -7
  7. data/lib/rr/double_method_proxy.rb +1 -2
  8. data/lib/rr/space.rb +21 -21
  9. data/lib/rr/wildcard_matchers/anything.rb +4 -0
  10. data/lib/rr/wildcard_matchers/boolean.rb +4 -0
  11. data/lib/rr/wildcard_matchers/duck_type.rb +7 -0
  12. data/lib/rr/wildcard_matchers/is_a.rb +4 -0
  13. data/lib/rr/wildcard_matchers/numeric.rb +4 -0
  14. data/spec/high_level_spec.rb +14 -0
  15. data/spec/rr/adapters/rr_methods_space_spec.rb +16 -16
  16. data/spec/rr/double/double_injection_bind_spec.rb +47 -20
  17. data/spec/rr/double/double_injection_dispatching_spec.rb +26 -20
  18. data/spec/rr/double/double_injection_has_original_method_spec.rb +10 -11
  19. data/spec/rr/double/double_injection_register_scenario_spec.rb +6 -6
  20. data/spec/rr/double/double_injection_reset_spec.rb +11 -14
  21. data/spec/rr/double/double_injection_spec.rb +18 -12
  22. data/spec/rr/double/double_injection_verify_spec.rb +5 -5
  23. data/spec/rr/double_definition_spec.rb +5 -5
  24. data/spec/rr/double_method_proxy_spec.rb +5 -5
  25. data/spec/rr/double_spec.rb +48 -48
  26. data/spec/rr/expectations/anything_spec.rb +14 -0
  27. data/spec/rr/expectations/boolean_spec.rb +14 -0
  28. data/spec/rr/expectations/duck_type_spec.rb +14 -0
  29. data/spec/rr/expectations/is_a_spec.rb +14 -0
  30. data/spec/rr/expectations/numeric_spec.rb +14 -0
  31. data/spec/rr/expectations/range_spec.rb +10 -0
  32. data/spec/rr/expectations/regexp_spec.rb +10 -0
  33. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +3 -3
  34. data/spec/rr/rspec/rspec_adapter_spec.rb +12 -12
  35. data/spec/rr/space/space_create_spec.rb +27 -37
  36. data/spec/rr/space/space_register_spec.rb +3 -3
  37. data/spec/rr/space/space_reset_spec.rb +24 -24
  38. data/spec/rr/space/space_spec.rb +2 -2
  39. data/spec/rr/space/space_verify_spec.rb +18 -18
  40. metadata +9 -2
data/CHANGES CHANGED
@@ -1,3 +1,7 @@
1
+ * 0.4.4
2
+ - Doc improvements
3
+ - Methods that are not alphabetic, such as ==, can be doubles
4
+
1
5
  * 0.4.3
2
6
  - Doc improvements
3
7
  - Cleanup
data/README CHANGED
@@ -186,6 +186,30 @@ Put double scenarios on instances of a Class.
186
186
  m.system("rake baz") {true}
187
187
  end
188
188
 
189
+ === Wildcard matchers
190
+ ==== anything
191
+ mock(object).foobar(1, anything)
192
+ object.foobar(1, :my_symbol)
193
+
194
+ ==== is_a
195
+ mock(object).foobar(is_a(Time))
196
+ object.foobar(Time.now)
197
+
198
+ ==== numeric
199
+ mock(object).foobar(numeric)
200
+ object.foobar(99)
201
+
202
+ ==== numeric
203
+ mock(object).foobar(boolean)
204
+ object.foobar(false)
205
+
206
+ ==== duck_type
207
+ mock(object).foobar(duck_type(:walk, :talk))
208
+ arg = Object.new
209
+ def arg.walk; 'waddle'; end
210
+ def arg.talk; 'quack'; end
211
+ object.foobar(arg)
212
+
189
213
  == Special Thanks To
190
214
  With any development effort, there are countless people who have contributed
191
215
  to making it possible. We all are standing on the shoulders of giants.
@@ -193,6 +217,7 @@ to making it possible. We all are standing on the shoulders of giants.
193
217
  * Parker Thompson for pairing with me
194
218
  * Felix Morio for pairing with me
195
219
  * Jeff Whitmire for documentation suggestions
220
+ * Nick Kallen for documentation suggestion & bug reports
196
221
  * David Chelimsky for encouragement to make the RR framework, for developing
197
222
  the Rspec mock framework, and syntax ideas
198
223
  * Gerald Meszaros for his excellent book "xUnit Test Patterns"
data/Rakefile CHANGED
@@ -26,7 +26,7 @@ def run_suite
26
26
  end
27
27
 
28
28
  PKG_NAME = "rr"
29
- PKG_VERSION = "0.4.3"
29
+ PKG_VERSION = "0.4.4"
30
30
  PKG_FILES = FileList[
31
31
  '[A-Z]*',
32
32
  '*.rb',
data/lib/rr/double.rb CHANGED
@@ -16,11 +16,11 @@ module RR
16
16
  end
17
17
  end
18
18
 
19
- attr_reader :times_called, :double_insertion, :definition
19
+ attr_reader :times_called, :double_injection, :definition
20
20
 
21
- def initialize(space, double_insertion, definition)
21
+ def initialize(space, double_injection, definition)
22
22
  @space = space
23
- @double_insertion = double_insertion
23
+ @double_injection = double_injection
24
24
  @definition = definition
25
25
  @times_called = 0
26
26
  @times_called_expectation = Expectations::TimesCalledExpectation.new(self)
@@ -216,11 +216,11 @@ module RR
216
216
  #
217
217
  # A TimesCalledError is raised when the times called
218
218
  # exceeds the expected TimesCalledExpectation.
219
- def call(double_insertion, *args, &block)
219
+ def call(double_injection, *args, &block)
220
220
  self.times_called_expectation.attempt! if definition.times_matcher
221
221
  @space.verify_ordered_double(self) if ordered?
222
222
  yields!(block)
223
- return_value = call_implementation(double_insertion, *args, &block)
223
+ return_value = call_implementation(double_injection, *args, &block)
224
224
  return return_value unless definition.after_call_value
225
225
  definition.after_call_value.call(return_value)
226
226
  end
@@ -235,14 +235,14 @@ module RR
235
235
  end
236
236
  protected :yields!
237
237
 
238
- def call_implementation(double_insertion, *args, &block)
238
+ def call_implementation(double_injection, *args, &block)
239
239
  return nil unless implementation
240
240
 
241
241
  if implementation === DoubleDefinition::ORIGINAL_METHOD
242
- if double_insertion.object_has_original_method?
243
- return double_insertion.call_original_method(*args, &block)
242
+ if double_injection.object_has_original_method?
243
+ return double_injection.call_original_method(*args, &block)
244
244
  else
245
- return double_insertion.object.__send__(
245
+ return double_injection.object.__send__(
246
246
  :method_missing,
247
247
  method_name,
248
248
  *args,
@@ -295,7 +295,7 @@ module RR
295
295
 
296
296
  # The method name that this Double is attatched to
297
297
  def method_name
298
- double_insertion.method_name
298
+ double_injection.method_name
299
299
  end
300
300
 
301
301
  # The Arguments that this Double expects
@@ -200,21 +200,21 @@ module RR
200
200
 
201
201
  protected
202
202
  def setup_double(subject, method_name)
203
- @double_insertion = @space.double_insertion(subject, method_name)
204
- @double = @space.double(@double_insertion)
203
+ @double_injection = @space.double_injection(subject, method_name)
204
+ @double = @space.double(@double_injection)
205
205
  @definition = @double.definition
206
206
  end
207
207
 
208
208
  def setup_class_probing_instances(subject, method_name)
209
- class_double = @space.double_insertion(subject, :new)
209
+ class_double = @space.double_injection(subject, :new)
210
210
  class_double = @space.double(class_double)
211
211
 
212
212
  instance_method_name = method_name
213
213
 
214
214
  @definition = @space.double_definition
215
215
  class_handler = proc do |return_value|
216
- double_insertion = @space.double_insertion(return_value, instance_method_name)
217
- @space.double(double_insertion, @definition)
216
+ double_injection = @space.double_injection(return_value, instance_method_name)
217
+ @space.double(double_injection, @definition)
218
218
  return_value
219
219
  end
220
220
 
@@ -1,13 +1,12 @@
1
1
  module RR
2
2
  # RR::DoubleInjection is the binding of an object and a method.
3
- # A double_insertion has 0 to many Double objects. Each Double
3
+ # A double_injection has 0 to many Double objects. Each Double
4
4
  # has Argument Expectations and Times called Expectations.
5
5
  class DoubleInjection
6
6
  MethodArguments = Struct.new(:arguments, :block)
7
- attr_reader :space, :object, :method_name, :doubles
7
+ attr_reader :object, :method_name, :doubles
8
8
 
9
- def initialize(space, object, method_name)
10
- @space = space
9
+ def initialize(object, method_name)
11
10
  @object = object
12
11
  @method_name = method_name.to_sym
13
12
  if object_has_method?(method_name)
@@ -30,7 +29,7 @@ module RR
30
29
  returns_method = <<-METHOD
31
30
  def #{@method_name}(*args, &block)
32
31
  arguments = MethodArguments.new(args, block)
33
- #{placeholder_name}(arguments)
32
+ __send__('#{placeholder_name}', arguments)
34
33
  end
35
34
  METHOD
36
35
  meta.class_eval(returns_method, __FILE__, __LINE__ - 5)
@@ -69,7 +68,7 @@ module RR
69
68
  def define_implementation_placeholder
70
69
  me = self
71
70
  meta.send(:define_method, placeholder_name) do |arguments|
72
- me.send(:call_method, arguments.arguments, arguments.block)
71
+ me.__send__(:call_method, arguments.arguments, arguments.block)
73
72
  end
74
73
  end
75
74
 
@@ -108,7 +107,8 @@ module RR
108
107
  end
109
108
 
110
109
  def double_not_found_error(*args)
111
- message = "Unexpected method invocation #{Double.formatted_name(@method_name, args)}, expected\n"
110
+ message = "On object #{object},\n"
111
+ message << "unexpected method invocation #{Double.formatted_name(@method_name, args)}, expected\n"
112
112
  message << Double.list_message_part(@doubles)
113
113
  raise Errors::DoubleNotFoundError, message
114
114
  end
@@ -1,7 +1,6 @@
1
1
  module RR
2
2
  class DoubleMethodProxy
3
- def initialize(space, creator, object, &block) #:nodoc:
4
- @space = space
3
+ def initialize(creator, object, &block) #:nodoc:
5
4
  @creator = creator
6
5
  @object = object
7
6
  class << self
data/lib/rr/space.rb CHANGED
@@ -15,10 +15,10 @@ module RR
15
15
  end
16
16
  end
17
17
 
18
- attr_reader :double_insertions, :ordered_doubles
18
+ attr_reader :double_injections, :ordered_doubles
19
19
  attr_accessor :trim_backtrace
20
20
  def initialize
21
- @double_insertions = HashWithObjectIdKey.new
21
+ @double_injections = HashWithObjectIdKey.new
22
22
  @ordered_doubles = []
23
23
  @trim_backtrace = false
24
24
  end
@@ -27,7 +27,7 @@ module RR
27
27
  if method_name && definition
28
28
  raise ArgumentError, "Cannot pass in a method name and a block"
29
29
  end
30
- proxy = DoubleMethodProxy.new(self, creator, object, &definition)
30
+ proxy = DoubleMethodProxy.new(creator, object, &definition)
31
31
  return proxy unless method_name
32
32
  proxy.__send__(method_name)
33
33
  end
@@ -38,10 +38,10 @@ module RR
38
38
  end
39
39
 
40
40
  # Creates and registers a Double to be verified.
41
- def double(double_insertion, definition = double_definition)
42
- double = Double.new(self, double_insertion, definition)
41
+ def double(double_injection, definition = double_definition)
42
+ double = Double.new(self, double_injection, definition)
43
43
  double.definition.double = double
44
- double_insertion.register_double double
44
+ double_injection.register_double double
45
45
  double
46
46
  end
47
47
 
@@ -53,14 +53,14 @@ module RR
53
53
  # in object and method_name.
54
54
  # When a DoubleInjection is created, it binds the dispatcher to the
55
55
  # object.
56
- def double_insertion(object, method_name)
57
- double_insertion = @double_insertions[object][method_name.to_sym]
58
- return double_insertion if double_insertion
56
+ def double_injection(object, method_name)
57
+ double_injection = @double_injections[object][method_name.to_sym]
58
+ return double_injection if double_injection
59
59
 
60
- double_insertion = DoubleInjection.new(self, object, method_name.to_sym)
61
- @double_insertions[object][method_name.to_sym] = double_insertion
62
- double_insertion.bind
63
- double_insertion
60
+ double_injection = DoubleInjection.new(object, method_name.to_sym)
61
+ @double_injections[object][method_name.to_sym] = double_injection
62
+ double_injection.bind
63
+ double_injection
64
64
  end
65
65
 
66
66
  # Registers the ordered Double to be verified.
@@ -88,7 +88,7 @@ module RR
88
88
  # Verifies all the DoubleInjection objects have met their
89
89
  # TimesCalledExpectations.
90
90
  def verify_doubles
91
- @double_insertions.each do |object, method_double_map|
91
+ @double_injections.each do |object, method_double_map|
92
92
  method_double_map.keys.each do |method_name|
93
93
  verify_double(object, method_name)
94
94
  end
@@ -98,21 +98,21 @@ module RR
98
98
  # Resets the registered Doubles and ordered Doubles
99
99
  def reset
100
100
  reset_ordered_doubles
101
- reset_double_insertions
101
+ reset_double_injections
102
102
  end
103
103
 
104
104
  # Verifies the DoubleInjection for the passed in object and method_name.
105
105
  def verify_double(object, method_name)
106
- @double_insertions[object][method_name].verify
106
+ @double_injections[object][method_name].verify
107
107
  ensure
108
108
  reset_double object, method_name
109
109
  end
110
110
 
111
111
  # Resets the DoubleInjection for the passed in object and method_name.
112
112
  def reset_double(object, method_name)
113
- double_insertion = @double_insertions[object].delete(method_name)
114
- @double_insertions.delete(object) if @double_insertions[object].empty?
115
- double_insertion.reset
113
+ double_injection = @double_injections[object].delete(method_name)
114
+ @double_injections.delete(object) if @double_injections[object].empty?
115
+ double_injection.reset
116
116
  end
117
117
 
118
118
  protected
@@ -122,8 +122,8 @@ module RR
122
122
  end
123
123
 
124
124
  # Resets the registered Doubles for the next test run.
125
- def reset_double_insertions
126
- @double_insertions.each do |object, method_double_map|
125
+ def reset_double_injections
126
+ @double_injections.each do |object, method_double_map|
127
127
  method_double_map.keys.each do |method_name|
128
128
  reset_double(object, method_name)
129
129
  end
@@ -8,6 +8,10 @@ module RR
8
8
  def ==(other)
9
9
  other.is_a?(self.class)
10
10
  end
11
+
12
+ def inspect
13
+ 'anything'
14
+ end
11
15
  end
12
16
  end
13
17
  end
@@ -9,6 +9,10 @@ module RR
9
9
  other.is_a?(self.class)
10
10
  end
11
11
 
12
+ def inspect
13
+ 'boolean'
14
+ end
15
+
12
16
  protected
13
17
  def is_a_boolean?(subject)
14
18
  subject.is_a?(TrueClass) || subject.is_a?(FalseClass)
@@ -15,6 +15,13 @@ module RR
15
15
  return true
16
16
  end
17
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
+
18
25
  def ==(other)
19
26
  return false unless other.is_a?(self.class)
20
27
  self.required_methods == other.required_methods
@@ -11,6 +11,10 @@ module RR
11
11
  self == other || other.is_a?(klass)
12
12
  end
13
13
 
14
+ def inspect
15
+ "is_a(#{klass})"
16
+ end
17
+
14
18
  def ==(other)
15
19
  return false unless other.is_a?(self.class)
16
20
  self.klass == other.klass
@@ -4,6 +4,10 @@ module RR
4
4
  def initialize
5
5
  @klass = ::Numeric
6
6
  end
7
+
8
+ def inspect
9
+ 'numeric'
10
+ end
7
11
  end
8
12
  end
9
13
  end
@@ -60,6 +60,15 @@ describe "RR mock:" do
60
60
  @obj.foobar(:failure)
61
61
  end.should raise_error( RR::Errors::DoubleNotFoundError )
62
62
  end
63
+
64
+ it "mocks methods without letters" do
65
+ mock(@obj) == 55
66
+
67
+ @obj == 55
68
+ proc do
69
+ @obj == 99
70
+ end.should raise_error(RR::Errors::DoubleNotFoundError)
71
+ end
63
72
  end
64
73
 
65
74
  describe "RR proxy:" do
@@ -170,4 +179,9 @@ describe "RR stub:" do
170
179
  end
171
180
  Date.new.to_s.should == "The Date"
172
181
  end
182
+
183
+ it "stubs methods without letters" do
184
+ stub(@obj).__send__(:==) {:equality}
185
+ (@obj == 55).should == :equality
186
+ end
173
187
  end
@@ -20,16 +20,16 @@ module RR
20
20
  end
21
21
 
22
22
  describe RRMethods, "#verify" do
23
- it "#verify verifies and deletes the double_insertions" do
24
- verifies_all_double_insertions {verify}
23
+ it "#verify verifies and deletes the double_injections" do
24
+ verifies_all_double_injections {verify}
25
25
  end
26
26
 
27
- it "#rr_verify verifies and deletes the double_insertions" do
28
- verifies_all_double_insertions {rr_verify}
27
+ it "#rr_verify verifies and deletes the double_injections" do
28
+ verifies_all_double_injections {rr_verify}
29
29
  end
30
30
 
31
- def verifies_all_double_insertions
32
- double1 = @space.double_insertion(@object1, @method_name)
31
+ def verifies_all_double_injections
32
+ double1 = @space.double_injection(@object1, @method_name)
33
33
  double1_verify_calls = 0
34
34
  double1_reset_calls = 0
35
35
  (
@@ -43,7 +43,7 @@ module RR
43
43
  double1_reset_calls += 1
44
44
  end
45
45
  end
46
- double2 = @space.double_insertion(@object2, @method_name)
46
+ double2 = @space.double_injection(@object2, @method_name)
47
47
  double2_verify_calls = 0
48
48
  double2_reset_calls = 0
49
49
  (
@@ -75,17 +75,17 @@ module RR
75
75
  removes_ordered_doubles {rr_reset}
76
76
  end
77
77
 
78
- it "#reset resets all double_insertions" do
79
- resets_all_double_insertions {reset}
78
+ it "#reset resets all double_injections" do
79
+ resets_all_double_injections {reset}
80
80
  end
81
81
 
82
- it "#rr_reset resets all double_insertions" do
83
- resets_all_double_insertions {rr_reset}
82
+ it "#rr_reset resets all double_injections" do
83
+ resets_all_double_injections {rr_reset}
84
84
  end
85
85
 
86
86
  def removes_ordered_doubles
87
- double1 = @space.double_insertion(@object1, :foobar1)
88
- double2 = @space.double_insertion(@object1, :foobar2)
87
+ double1 = @space.double_injection(@object1, :foobar1)
88
+ double2 = @space.double_injection(@object1, :foobar2)
89
89
 
90
90
  double1 = @space.double(double1)
91
91
  double2 = @space.double(double2)
@@ -99,8 +99,8 @@ module RR
99
99
  @space.ordered_doubles.should be_empty
100
100
  end
101
101
 
102
- def resets_all_double_insertions
103
- double1 = @space.double_insertion(@object1, @method_name)
102
+ def resets_all_double_injections
103
+ double1 = @space.double_injection(@object1, @method_name)
104
104
  double1_reset_calls = 0
105
105
  (
106
106
  class << double1;
@@ -110,7 +110,7 @@ module RR
110
110
  double1_reset_calls += 1
111
111
  end
112
112
  end
113
- double2 = @space.double_insertion(@object2, @method_name)
113
+ double2 = @space.double_injection(@object2, @method_name)
114
114
  double2_reset_calls = 0
115
115
  (
116
116
  class << double2;