rr 0.3.11 → 0.4.0

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 (150) hide show
  1. data/CHANGES +8 -3
  2. data/README +130 -39
  3. data/Rakefile +6 -5
  4. data/lib/rr.rb +8 -8
  5. data/lib/rr/adapters/rr_methods.rb +228 -0
  6. data/lib/rr/adapters/rspec.rb +1 -1
  7. data/lib/rr/adapters/test_unit.rb +1 -1
  8. data/lib/rr/double.rb +294 -89
  9. data/lib/rr/{scenario_creator.rb → double_creator.rb} +65 -66
  10. data/lib/rr/{scenario_definition.rb → double_definition.rb} +36 -36
  11. data/lib/rr/{scenario_definition_builder.rb → double_definition_builder.rb} +3 -3
  12. data/lib/rr/double_insertion.rb +132 -0
  13. data/lib/rr/{scenario_matches.rb → double_matches.rb} +2 -2
  14. data/lib/rr/{scenario_method_proxy.rb → double_method_proxy.rb} +2 -2
  15. data/lib/rr/errors/argument_equality_error.rb +3 -3
  16. data/lib/rr/errors/rr_error.rb +13 -13
  17. data/lib/rr/errors/scenario_definition_error.rb +3 -3
  18. data/lib/rr/errors/scenario_not_found_error.rb +3 -3
  19. data/lib/rr/errors/scenario_order_error.rb +3 -3
  20. data/lib/rr/errors/times_called_error.rb +3 -3
  21. data/lib/rr/expectations/any_argument_expectation.rb +1 -1
  22. data/lib/rr/expectations/argument_equality_expectation.rb +1 -1
  23. data/lib/rr/expectations/times_called_expectation.rb +1 -1
  24. data/lib/rr/hash_with_object_id_key.rb +1 -1
  25. data/lib/rr/space.rb +40 -40
  26. data/lib/rr/times_called_matchers/any_times_matcher.rb +13 -13
  27. data/lib/rr/times_called_matchers/at_least_matcher.rb +11 -11
  28. data/lib/rr/times_called_matchers/at_most_matcher.rb +16 -16
  29. data/lib/rr/times_called_matchers/integer_matcher.rb +13 -13
  30. data/lib/rr/times_called_matchers/non_terminal.rb +21 -21
  31. data/lib/rr/times_called_matchers/proc_matcher.rb +7 -7
  32. data/lib/rr/times_called_matchers/range_matcher.rb +14 -14
  33. data/lib/rr/times_called_matchers/terminal.rb +16 -16
  34. data/lib/rr/times_called_matchers/times_called_matcher.rb +32 -32
  35. data/spec/core_spec_suite.rb +18 -0
  36. data/{examples → spec}/environment_fixture_setup.rb +0 -1
  37. data/{examples/high_level_example.rb → spec/high_level_spec.rb} +11 -11
  38. data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +67 -0
  39. data/spec/rr/adapters/rr_methods_creator_spec.rb +365 -0
  40. data/spec/rr/adapters/rr_methods_space_spec.rb +134 -0
  41. data/spec/rr/adapters/rr_methods_spec_helper.rb +11 -0
  42. data/{examples/rr/extensions/instance_methods_times_matcher_example.rb → spec/rr/adapters/rr_methods_times_matcher_spec.rb} +4 -4
  43. data/spec/rr/double/double_insertion_bind_spec.rb +78 -0
  44. data/spec/rr/double/double_insertion_dispatching_spec.rb +221 -0
  45. data/spec/rr/double/double_insertion_has_original_method_spec.rb +56 -0
  46. data/spec/rr/double/double_insertion_register_scenario_spec.rb +24 -0
  47. data/spec/rr/double/double_insertion_reset_spec.rb +89 -0
  48. data/spec/rr/double/double_insertion_spec.rb +66 -0
  49. data/spec/rr/double/double_insertion_verify_spec.rb +23 -0
  50. data/spec/rr/double_creator_spec.rb +454 -0
  51. data/{examples/rr/scenario_definition_example.rb → spec/rr/double_definition_spec.rb} +143 -143
  52. data/spec/rr/double_method_proxy_spec.rb +71 -0
  53. data/spec/rr/double_spec.rb +654 -0
  54. data/spec/rr/errors/rr_error_spec.rb +65 -0
  55. data/spec/rr/expectations/any_argument_expectation_spec.rb +47 -0
  56. data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +38 -0
  57. data/spec/rr/expectations/argument_equality_expectation_spec.rb +58 -0
  58. data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +53 -0
  59. data/spec/rr/expectations/duck_type_argument_equality_expectation_spec.rb +71 -0
  60. data/spec/rr/expectations/is_a_argument_equality_expectation_spec.rb +51 -0
  61. data/spec/rr/expectations/numeric_argument_equality_expectation_spec.rb +47 -0
  62. data/spec/rr/expectations/range_argument_equality_expectation_spec.rb +59 -0
  63. data/spec/rr/expectations/regexp_argument_equality_expectation_spec.rb +72 -0
  64. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +43 -0
  65. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +67 -0
  66. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +71 -0
  67. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +21 -0
  68. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +103 -0
  69. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +79 -0
  70. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +81 -0
  71. data/spec/rr/expectations/times_called_expectation/times_called_expectation_spec.rb +40 -0
  72. data/spec/rr/rspec/rspec_adapter_spec.rb +65 -0
  73. data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +52 -0
  74. data/spec/rr/rspec/rspec_usage_spec.rb +67 -0
  75. data/spec/rr/space/hash_with_object_id_key_spec.rb +88 -0
  76. data/spec/rr/space/space_create_spec.rb +278 -0
  77. data/spec/rr/space/space_helper.rb +7 -0
  78. data/spec/rr/space/space_register_spec.rb +32 -0
  79. data/spec/rr/space/space_reset_spec.rb +131 -0
  80. data/spec/rr/space/space_spec.rb +32 -0
  81. data/spec/rr/space/space_verify_spec.rb +181 -0
  82. data/{examples → spec}/rr/test_unit/test_helper.rb +1 -1
  83. data/{examples → spec}/rr/test_unit/test_unit_backtrace_test.rb +0 -0
  84. data/{examples → spec}/rr/test_unit/test_unit_integration_test.rb +4 -4
  85. data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +47 -0
  86. data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +55 -0
  87. data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +70 -0
  88. data/spec/rr/times_called_matchers/integer_matcher_spec.rb +70 -0
  89. data/spec/rr/times_called_matchers/proc_matcher_spec.rb +55 -0
  90. data/spec/rr/times_called_matchers/range_matcher_spec.rb +76 -0
  91. data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +118 -0
  92. data/spec/rspec_spec_suite.rb +16 -0
  93. data/spec/spec_helper.rb +9 -0
  94. data/{examples/example_suite.rb → spec/spec_suite.rb} +3 -3
  95. data/{examples/test_unit_example_suite.rb → spec/test_unit_spec_suite.rb} +0 -0
  96. metadata +93 -93
  97. data/examples/core_example_suite.rb +0 -31
  98. data/examples/example_helper.rb +0 -9
  99. data/examples/rr/double/double_bind_example.rb +0 -70
  100. data/examples/rr/double/double_dispatching_example.rb +0 -236
  101. data/examples/rr/double/double_example.rb +0 -66
  102. data/examples/rr/double/double_has_original_method_example.rb +0 -56
  103. data/examples/rr/double/double_register_scenario_example.rb +0 -24
  104. data/examples/rr/double/double_reset_example.rb +0 -89
  105. data/examples/rr/double/double_verify_example.rb +0 -23
  106. data/examples/rr/errors/rr_error_example.rb +0 -65
  107. data/examples/rr/expectations/any_argument_expectation_example.rb +0 -52
  108. data/examples/rr/expectations/anything_argument_equality_expectation_example.rb +0 -38
  109. data/examples/rr/expectations/argument_equality_expectation_example.rb +0 -62
  110. data/examples/rr/expectations/boolean_argument_equality_expectation_example.rb +0 -48
  111. data/examples/rr/expectations/duck_type_argument_equality_expectation_example.rb +0 -67
  112. data/examples/rr/expectations/is_a_argument_equality_expectation_example.rb +0 -50
  113. data/examples/rr/expectations/numeric_argument_equality_expectation_example.rb +0 -46
  114. data/examples/rr/expectations/range_argument_equality_expectation_example.rb +0 -59
  115. data/examples/rr/expectations/regexp_argument_equality_expectation_example.rb +0 -67
  116. data/examples/rr/expectations/times_called_expectation/times_called_expectation_any_times_example.rb +0 -50
  117. data/examples/rr/expectations/times_called_expectation/times_called_expectation_at_least_example.rb +0 -73
  118. data/examples/rr/expectations/times_called_expectation/times_called_expectation_at_most_example.rb +0 -77
  119. data/examples/rr/expectations/times_called_expectation/times_called_expectation_example.rb +0 -42
  120. data/examples/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +0 -20
  121. data/examples/rr/expectations/times_called_expectation/times_called_expectation_integer_example.rb +0 -111
  122. data/examples/rr/expectations/times_called_expectation/times_called_expectation_proc_example.rb +0 -88
  123. data/examples/rr/expectations/times_called_expectation/times_called_expectation_range_example.rb +0 -90
  124. data/examples/rr/extensions/instance_methods_argument_matcher_example.rb +0 -65
  125. data/examples/rr/extensions/instance_methods_creator_example.rb +0 -363
  126. data/examples/rr/extensions/instance_methods_example_helper.rb +0 -11
  127. data/examples/rr/extensions/instance_methods_space_example.rb +0 -122
  128. data/examples/rr/rspec/rspec_adapter_example.rb +0 -63
  129. data/examples/rr/rspec/rspec_backtrace_tweaking_example.rb +0 -36
  130. data/examples/rr/rspec/rspec_usage_example.rb +0 -65
  131. data/examples/rr/scenario_creator_example.rb +0 -459
  132. data/examples/rr/scenario_example.rb +0 -701
  133. data/examples/rr/scenario_method_proxy_example.rb +0 -71
  134. data/examples/rr/space/hash_with_object_id_key_example.rb +0 -86
  135. data/examples/rr/space/space_create_example.rb +0 -278
  136. data/examples/rr/space/space_example.rb +0 -29
  137. data/examples/rr/space/space_helper.rb +0 -7
  138. data/examples/rr/space/space_register_example.rb +0 -32
  139. data/examples/rr/space/space_reset_example.rb +0 -120
  140. data/examples/rr/space/space_verify_example.rb +0 -169
  141. data/examples/rr/times_called_matchers/any_times_matcher_example.rb +0 -63
  142. data/examples/rr/times_called_matchers/at_least_matcher_example.rb +0 -70
  143. data/examples/rr/times_called_matchers/at_most_matcher_example.rb +0 -85
  144. data/examples/rr/times_called_matchers/integer_matcher_example.rb +0 -91
  145. data/examples/rr/times_called_matchers/proc_matcher_example.rb +0 -77
  146. data/examples/rr/times_called_matchers/range_matcher_example.rb +0 -97
  147. data/examples/rr/times_called_matchers/times_called_matcher_example.rb +0 -53
  148. data/examples/rspec_example_suite.rb +0 -25
  149. data/lib/rr/extensions/instance_methods.rb +0 -228
  150. data/lib/rr/scenario.rb +0 -337
@@ -0,0 +1,134 @@
1
+ require "spec/spec_helper"
2
+
3
+ module RR
4
+ module Adapters
5
+ describe RRMethods, " Space interactions" do
6
+ describe RRMethods, " space example" do
7
+ it_should_behave_like "RR::Adapters::RRMethods"
8
+ before do
9
+ @old_space = Space.instance
10
+
11
+ @space = Space.new
12
+ Space.instance = @space
13
+ @object1 = Object.new
14
+ @object2 = Object.new
15
+ @method_name = :foobar
16
+ end
17
+
18
+ after do
19
+ Space.instance = @old_space
20
+ end
21
+
22
+ describe RRMethods, "#verify" do
23
+ it "#verify verifies and deletes the double_insertions" do
24
+ verifies_all_double_insertions {verify}
25
+ end
26
+
27
+ it "#rr_verify verifies and deletes the double_insertions" do
28
+ verifies_all_double_insertions {rr_verify}
29
+ end
30
+
31
+ def verifies_all_double_insertions
32
+ double1 = @space.double_insertion(@object1, @method_name)
33
+ double1_verify_calls = 0
34
+ double1_reset_calls = 0
35
+ (
36
+ class << double1;
37
+ self;
38
+ end).class_eval do
39
+ define_method(:verify) do ||
40
+ double1_verify_calls += 1
41
+ end
42
+ define_method(:reset) do ||
43
+ double1_reset_calls += 1
44
+ end
45
+ end
46
+ double2 = @space.double_insertion(@object2, @method_name)
47
+ double2_verify_calls = 0
48
+ double2_reset_calls = 0
49
+ (
50
+ class << double2;
51
+ self;
52
+ end).class_eval do
53
+ define_method(:verify) do ||
54
+ double2_verify_calls += 1
55
+ end
56
+ define_method(:reset) do ||
57
+ double2_reset_calls += 1
58
+ end
59
+ end
60
+
61
+ yield
62
+ double1_verify_calls.should == 1
63
+ double2_verify_calls.should == 1
64
+ double1_reset_calls.should == 1
65
+ double1_reset_calls.should == 1
66
+ end
67
+ end
68
+
69
+ describe RRMethods, "#reset" do
70
+ it "#reset removes the ordered scenarios" do
71
+ removes_ordered_scenarios {reset}
72
+ end
73
+
74
+ it "#rr_reset removes the ordered scenarios" do
75
+ removes_ordered_scenarios {rr_reset}
76
+ end
77
+
78
+ it "#reset resets all double_insertions" do
79
+ resets_all_double_insertions {reset}
80
+ end
81
+
82
+ it "#rr_reset resets all double_insertions" do
83
+ resets_all_double_insertions {rr_reset}
84
+ end
85
+
86
+ def removes_ordered_scenarios
87
+ double1 = @space.double_insertion(@object1, :foobar1)
88
+ double2 = @space.double_insertion(@object1, :foobar2)
89
+
90
+ scenario1 = @space.scenario(double1)
91
+ scenario2 = @space.scenario(double2)
92
+
93
+ scenario1.ordered
94
+ scenario2.ordered
95
+
96
+ @space.ordered_scenarios.should_not be_empty
97
+
98
+ yield
99
+ @space.ordered_scenarios.should be_empty
100
+ end
101
+
102
+ def resets_all_double_insertions
103
+ double1 = @space.double_insertion(@object1, @method_name)
104
+ double1_reset_calls = 0
105
+ (
106
+ class << double1;
107
+ self;
108
+ end).class_eval do
109
+ define_method(:reset) do ||
110
+ double1_reset_calls += 1
111
+ end
112
+ end
113
+ double2 = @space.double_insertion(@object2, @method_name)
114
+ double2_reset_calls = 0
115
+ (
116
+ class << double2;
117
+ self;
118
+ end).class_eval do
119
+ define_method(:reset) do ||
120
+ double2_reset_calls += 1
121
+ end
122
+ end
123
+
124
+ yield
125
+ double1_reset_calls.should == 1
126
+ double2_reset_calls.should == 1
127
+ end
128
+ end
129
+ end
130
+ end
131
+
132
+
133
+ end
134
+ end
@@ -0,0 +1,11 @@
1
+ require "spec/spec_helper"
2
+
3
+ module RR
4
+ module Adapters
5
+ describe RRMethods, :shared => true do
6
+ before do
7
+ extend RR::Adapters::RRMethods
8
+ end
9
+ end
10
+ end
11
+ end
@@ -1,9 +1,9 @@
1
- require "examples/example_helper"
1
+ require "spec/spec_helper"
2
2
 
3
3
  module RR
4
- module Extensions
5
- describe InstanceMethods, "#any_times" do
6
- it_should_behave_like "RR::Extensions::InstanceMethods"
4
+ module Adapters
5
+ describe RRMethods, "#any_times" do
6
+ it_should_behave_like "RR::Adapters::RRMethods"
7
7
 
8
8
  it "returns an AnyTimesMatcher" do
9
9
  any_times.should == TimesCalledMatchers::AnyTimesMatcher.new
@@ -0,0 +1,78 @@
1
+ require "spec/spec_helper"
2
+
3
+ module RR
4
+ describe DoubleInsertion, "#bind with an existing method" do
5
+ before do
6
+ @space = Space.new
7
+ @object = Object.new
8
+ @method_name = :foobar
9
+ def @object.foobar;
10
+ :original_foobar;
11
+ end
12
+ @original_method = @object.method(:foobar)
13
+ @object.methods.should include(@method_name.to_s)
14
+ @double_insertion = DoubleInsertion.new(@space, @object, @method_name)
15
+ end
16
+
17
+ it "overrides the original method with the double_insertion's dispatching methods" do
18
+ @object.respond_to?(:__rr__foobar).should == false
19
+ @double_insertion.bind
20
+ @object.respond_to?(:__rr__foobar).should == true
21
+
22
+ rr_foobar_called = false
23
+ (
24
+ class << @object;
25
+ self;
26
+ end).class_eval do
27
+ define_method :__rr__foobar do
28
+ rr_foobar_called = true
29
+ end
30
+ end
31
+
32
+ rr_foobar_called.should == false
33
+ @object.foobar
34
+ rr_foobar_called.should == true
35
+ end
36
+
37
+ it "stores original method in __rr__original_method_name" do
38
+ @double_insertion.bind
39
+ @object.respond_to?(:__rr__original_foobar).should == true
40
+ @object.method(:__rr__original_foobar).should == @original_method
41
+ end
42
+ end
43
+
44
+ describe DoubleInsertion, "#bind without an existing method" do
45
+ before do
46
+ @space = Space.new
47
+ @object = Object.new
48
+ @method_name = :foobar
49
+ @object.methods.should_not include(@method_name.to_s)
50
+ @double_insertion = DoubleInsertion.new(@space, @object, @method_name)
51
+ end
52
+
53
+ it "overrides the original method with the double_insertion's dispatching methods" do
54
+ @object.respond_to?(:__rr__foobar).should == false
55
+ @double_insertion.bind
56
+ @object.respond_to?(:__rr__foobar).should == true
57
+
58
+ rr_foobar_called = false
59
+ (
60
+ class << @object;
61
+ self;
62
+ end).class_eval do
63
+ define_method :__rr__foobar do
64
+ rr_foobar_called = true
65
+ end
66
+ end
67
+
68
+ rr_foobar_called.should == false
69
+ @object.foobar
70
+ rr_foobar_called.should == true
71
+ end
72
+
73
+ it "stores original method in __rr__original_method_name" do
74
+ @double_insertion.bind
75
+ @object.respond_to?(:__rr__original_foobar).should == false
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,221 @@
1
+ require "spec/spec_helper"
2
+
3
+ module RR
4
+ describe DoubleInsertion do
5
+ before do
6
+ @space = Space.new
7
+ @object = Object.new
8
+ @object.methods.should_not include(method_name.to_s)
9
+ @double_insertion = @space.double_insertion(@object, method_name)
10
+ end
11
+
12
+ describe "normal methods" do
13
+ def method_name
14
+ :foobar
15
+ end
16
+
17
+ describe "where the scenario takes a block" do
18
+ it "executes the block" do
19
+ method_fixture = Object.new
20
+ class << method_fixture
21
+ def method_with_block(a, b)
22
+ yield(a, b)
23
+ end
24
+ end
25
+ scenario = @space.scenario(@double_insertion)
26
+ scenario.with(1, 2).implemented_by(method_fixture.method(:method_with_block))
27
+ @object.foobar(1, 2) {|a, b| [b, a]}.should == [2, 1]
28
+ end
29
+ end
30
+
31
+ describe "where there are no scenarios with duplicate ArgumentExpectations" do
32
+ it "dispatches to Double that have an exact match" do
33
+ scenario1_with_exact_match = @space.scenario(@double_insertion)
34
+ scenario1_with_exact_match.with(:exact_match_1).returns {:return_1}
35
+ scenario_with_no_match = @space.scenario(@double_insertion)
36
+ scenario_with_no_match.with("nothing that matches").returns {:no_match}
37
+ scenario2_with_exact_match = @space.scenario(@double_insertion)
38
+ scenario2_with_exact_match.with(:exact_match_2).returns {:return_2}
39
+
40
+ @object.foobar(:exact_match_1).should == :return_1
41
+ @object.foobar(:exact_match_2).should == :return_2
42
+ end
43
+
44
+ it "dispatches to Double that have a wildcard match" do
45
+ scenario_with_wildcard_match = @space.scenario(@double_insertion)
46
+ scenario_with_wildcard_match.with_any_args.returns {:wild_card_value}
47
+ scenario_with_no_match = @space.scenario(@double_insertion)
48
+ scenario_with_no_match.with("nothing that matches").returns {:no_match}
49
+
50
+ @object.foobar(:wildcard_match_1).should == :wild_card_value
51
+ @object.foobar(:wildcard_match_2, 3).should == :wild_card_value
52
+ end
53
+ end
54
+
55
+ describe "where there are scenarios" do
56
+ it "raises DoubleNotFoundError error when arguments do not match a scenario" do
57
+ scenario_1 = @space.scenario(@double_insertion)
58
+ scenario_1.with(1, 2)
59
+
60
+ scenario_2 = @space.scenario(@double_insertion)
61
+ scenario_2.with(3)
62
+
63
+ proc {@object.foobar(:arg1, :arg2)}.should raise_error(
64
+ Errors::DoubleNotFoundError,
65
+ "Unexpected method invocation foobar(:arg1, :arg2), expected\n" <<
66
+ "- foobar(1, 2)\n" <<
67
+ "- foobar(3)"
68
+ )
69
+ end
70
+ end
71
+
72
+ describe "where there are Doubles with NonTerminal TimesCalledMatchers" do
73
+ it "dispatches to Double with exact match" do
74
+ scenario = scenario(1, 2) {:return_value}
75
+ @object.foobar(1, 2).should == :return_value
76
+ end
77
+
78
+ it "matches to the last Double that was registered with an exact match" do
79
+ scenario_1 = scenario(1, 2) {:value_1}
80
+ scenario_2 = scenario(1, 2) {:value_2}
81
+
82
+ @object.foobar(1, 2).should == :value_2
83
+ end
84
+
85
+ it "dispatches to Double with wildcard match" do
86
+ scenario = scenario(anything) {:return_value}
87
+ @object.foobar(:dont_care).should == :return_value
88
+ end
89
+
90
+ it "matches to the last Double that was registered with a wildcard match" do
91
+ scenario_1 = scenario(anything) {:value_1}
92
+ scenario_2 = scenario(anything) {:value_2}
93
+
94
+ @object.foobar(:dont_care).should == :value_2
95
+ end
96
+
97
+ it "matches to Double with exact match Double even when a Double with wildcard match was registered later" do
98
+ exact_scenario_registered_first = scenario(1, 2) {:exact_first}
99
+ wildcard_scenario_registered_last = scenario(anything, anything) {:wildcard_last}
100
+
101
+ @object.foobar(1, 2).should == :exact_first
102
+ end
103
+
104
+ def scenario(*arguments, &return_value)
105
+ scenario = @space.scenario(@double_insertion)
106
+ scenario.with(*arguments).any_number_of_times.returns(&return_value)
107
+ scenario.should_not be_terminal
108
+ scenario
109
+ end
110
+ end
111
+
112
+ describe "where there are Terminal Doubles with duplicate Exact Match ArgumentExpectations" do
113
+ it "dispatches to Double that have an exact match" do
114
+ scenario1_with_exact_match = scenario(:exact_match) {:return_1}
115
+
116
+ @object.foobar(:exact_match).should == :return_1
117
+ end
118
+
119
+ it "dispatches to the first Double that have an exact match" do
120
+ scenario1_with_exact_match = scenario(:exact_match) {:return_1}
121
+ scenario2_with_exact_match = scenario(:exact_match) {:return_2}
122
+
123
+ @object.foobar(:exact_match).should == :return_1
124
+ end
125
+
126
+ it "dispatches the second Double with an exact match
127
+ when the first scenario's Times Called expectation is satisfied" do
128
+ scenario1_with_exact_match = scenario(:exact_match) {:return_1}
129
+ scenario2_with_exact_match = scenario(:exact_match) {:return_2}
130
+
131
+ @object.foobar(:exact_match)
132
+ @object.foobar(:exact_match).should == :return_2
133
+ end
134
+
135
+ it "raises TimesCalledError when all of the scenarios Times Called expectation is satisfied" do
136
+ scenario1_with_exact_match = scenario(:exact_match) {:return_1}
137
+ scenario2_with_exact_match = scenario(:exact_match) {:return_2}
138
+
139
+ @object.foobar(:exact_match)
140
+ @object.foobar(:exact_match)
141
+ proc do
142
+ @object.foobar(:exact_match)
143
+ end.should raise_error(Errors::TimesCalledError)
144
+ end
145
+
146
+ def scenario(*arguments, &return_value)
147
+ scenario = @space.scenario(@double_insertion)
148
+ scenario.with(*arguments).once.returns(&return_value)
149
+ scenario.should be_terminal
150
+ scenario
151
+ end
152
+ end
153
+
154
+ describe "where there are scenarios with duplicate Wildcard Match ArgumentExpectations" do
155
+ it "dispatches to Double that have a wildcard match" do
156
+ scenario_1 = scenario {:return_1}
157
+
158
+ @object.foobar(:anything).should == :return_1
159
+ end
160
+
161
+ it "dispatches to the first Double that has a wildcard match" do
162
+ scenario_1 = scenario {:return_1}
163
+ scenario_2 = scenario {:return_2}
164
+
165
+ @object.foobar(:anything).should == :return_1
166
+ end
167
+
168
+ it "dispatches the second Double with a wildcard match
169
+ when the first scenario's Times Called expectation is satisfied" do
170
+ scenario_1 = scenario {:return_1}
171
+ scenario_2 = scenario {:return_2}
172
+
173
+ @object.foobar(:anything)
174
+ @object.foobar(:anything).should == :return_2
175
+ end
176
+
177
+ it "raises TimesCalledError when all of the scenarios Times Called expectation is satisfied" do
178
+ scenario_1 = scenario {:return_1}
179
+ scenario_2 = scenario {:return_2}
180
+
181
+ @object.foobar(:anything)
182
+ @object.foobar(:anything)
183
+ proc do
184
+ @object.foobar(:anything)
185
+ end.should raise_error(Errors::TimesCalledError)
186
+ end
187
+
188
+ def scenario(&return_value)
189
+ scenario = @space.scenario(@double_insertion)
190
+ scenario.with_any_args.once.returns(&return_value)
191
+ scenario.should be_terminal
192
+ scenario
193
+ end
194
+ end
195
+ end
196
+
197
+ describe "method names with !" do
198
+ def method_name
199
+ :foobar!
200
+ end
201
+
202
+ it "executes the block" do
203
+ scenario = @space.scenario(@double_insertion)
204
+ scenario.with(1, 2) {:return_value}
205
+ @object.foobar!(1, 2).should == :return_value
206
+ end
207
+ end
208
+
209
+ describe "method names with ?" do
210
+ def method_name
211
+ :foobar?
212
+ end
213
+
214
+ it "executes the block" do
215
+ scenario = @space.scenario(@double_insertion)
216
+ scenario.with(1, 2) {:return_value}
217
+ @object.foobar?(1, 2).should == :return_value
218
+ end
219
+ end
220
+ end
221
+ end