mcmire-rr 1.0.5.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (155) hide show
  1. data/CHANGES +269 -0
  2. data/Gemfile +16 -0
  3. data/Gemfile.lock +47 -0
  4. data/LICENSE +22 -0
  5. data/README.rdoc +390 -0
  6. data/Rakefile +49 -0
  7. data/VERSION +1 -0
  8. data/lib/rr.rb +101 -0
  9. data/lib/rr/adapters/minitest.rb +31 -0
  10. data/lib/rr/adapters/rr_methods.rb +146 -0
  11. data/lib/rr/adapters/rspec.rb +61 -0
  12. data/lib/rr/adapters/rspec2.rb +22 -0
  13. data/lib/rr/adapters/test_unit.rb +31 -0
  14. data/lib/rr/blank_slate.rb +17 -0
  15. data/lib/rr/class_instance_method_defined.rb +9 -0
  16. data/lib/rr/double.rb +154 -0
  17. data/lib/rr/double_definitions/child_double_definition_create.rb +27 -0
  18. data/lib/rr/double_definitions/double_definition.rb +365 -0
  19. data/lib/rr/double_definitions/double_definition_create.rb +139 -0
  20. data/lib/rr/double_definitions/double_definition_create_blank_slate.rb +26 -0
  21. data/lib/rr/double_definitions/double_injections/any_instance_of.rb +28 -0
  22. data/lib/rr/double_definitions/double_injections/instance.rb +16 -0
  23. data/lib/rr/double_definitions/strategies/double_injection/any_instance_of.rb +30 -0
  24. data/lib/rr/double_definitions/strategies/double_injection/double_injection_strategy.rb +10 -0
  25. data/lib/rr/double_definitions/strategies/double_injection/instance.rb +17 -0
  26. data/lib/rr/double_definitions/strategies/implementation/implementation_strategy.rb +10 -0
  27. data/lib/rr/double_definitions/strategies/implementation/proxy.rb +60 -0
  28. data/lib/rr/double_definitions/strategies/implementation/reimplementation.rb +14 -0
  29. data/lib/rr/double_definitions/strategies/implementation/strongly_typed_reimplementation.rb +15 -0
  30. data/lib/rr/double_definitions/strategies/strategy.rb +43 -0
  31. data/lib/rr/double_definitions/strategies/strategy_methods.rb +53 -0
  32. data/lib/rr/double_definitions/strategies/verification/dont_allow.rb +31 -0
  33. data/lib/rr/double_definitions/strategies/verification/mock.rb +42 -0
  34. data/lib/rr/double_definitions/strategies/verification/stub.rb +43 -0
  35. data/lib/rr/double_definitions/strategies/verification/verification_strategy.rb +10 -0
  36. data/lib/rr/double_matches.rb +42 -0
  37. data/lib/rr/errors/argument_equality_error.rb +6 -0
  38. data/lib/rr/errors/double_definition_error.rb +6 -0
  39. data/lib/rr/errors/double_not_found_error.rb +6 -0
  40. data/lib/rr/errors/double_order_error.rb +6 -0
  41. data/lib/rr/errors/rr_error.rb +20 -0
  42. data/lib/rr/errors/spy_verification_errors/double_injection_not_found_error.rb +8 -0
  43. data/lib/rr/errors/spy_verification_errors/invocation_count_error.rb +8 -0
  44. data/lib/rr/errors/spy_verification_errors/spy_verification_error.rb +8 -0
  45. data/lib/rr/errors/subject_does_not_implement_method_error.rb +6 -0
  46. data/lib/rr/errors/subject_has_different_arity_error.rb +6 -0
  47. data/lib/rr/errors/times_called_error.rb +6 -0
  48. data/lib/rr/expectations/any_argument_expectation.rb +21 -0
  49. data/lib/rr/expectations/argument_equality_expectation.rb +41 -0
  50. data/lib/rr/expectations/times_called_expectation.rb +57 -0
  51. data/lib/rr/hash_with_object_id_key.rb +46 -0
  52. data/lib/rr/injections/double_injection.rb +220 -0
  53. data/lib/rr/injections/injection.rb +33 -0
  54. data/lib/rr/injections/method_missing_injection.rb +73 -0
  55. data/lib/rr/injections/singleton_method_added_injection.rb +72 -0
  56. data/lib/rr/method_dispatches/base_method_dispatch.rb +84 -0
  57. data/lib/rr/method_dispatches/method_dispatch.rb +59 -0
  58. data/lib/rr/method_dispatches/method_missing_dispatch.rb +61 -0
  59. data/lib/rr/proc_from_block.rb +7 -0
  60. data/lib/rr/recorded_calls.rb +103 -0
  61. data/lib/rr/space.rb +119 -0
  62. data/lib/rr/spy_verification.rb +48 -0
  63. data/lib/rr/spy_verification_proxy.rb +13 -0
  64. data/lib/rr/times_called_matchers/any_times_matcher.rb +18 -0
  65. data/lib/rr/times_called_matchers/at_least_matcher.rb +15 -0
  66. data/lib/rr/times_called_matchers/at_most_matcher.rb +23 -0
  67. data/lib/rr/times_called_matchers/integer_matcher.rb +19 -0
  68. data/lib/rr/times_called_matchers/never_matcher.rb +23 -0
  69. data/lib/rr/times_called_matchers/non_terminal.rb +27 -0
  70. data/lib/rr/times_called_matchers/proc_matcher.rb +11 -0
  71. data/lib/rr/times_called_matchers/range_matcher.rb +21 -0
  72. data/lib/rr/times_called_matchers/terminal.rb +20 -0
  73. data/lib/rr/times_called_matchers/times_called_matcher.rb +44 -0
  74. data/lib/rr/wildcard_matchers.rb +158 -0
  75. data/lib/rr/wildcard_matchers/anything.rb +18 -0
  76. data/lib/rr/wildcard_matchers/boolean.rb +23 -0
  77. data/lib/rr/wildcard_matchers/duck_type.rb +32 -0
  78. data/lib/rr/wildcard_matchers/hash_including.rb +29 -0
  79. data/lib/rr/wildcard_matchers/is_a.rb +25 -0
  80. data/lib/rr/wildcard_matchers/numeric.rb +13 -0
  81. data/lib/rr/wildcard_matchers/range.rb +7 -0
  82. data/lib/rr/wildcard_matchers/regexp.rb +7 -0
  83. data/lib/rr/wildcard_matchers/satisfy.rb +26 -0
  84. data/spec/api/any_instance_of/all_instances_of_spec.rb +12 -0
  85. data/spec/api/any_instance_of/any_instance_of_spec.rb +47 -0
  86. data/spec/api/any_instance_of/instance_of_spec.rb +12 -0
  87. data/spec/api/dont_allow/dont_allow_after_stub_spec.rb +14 -0
  88. data/spec/api/mock/mock_spec.rb +193 -0
  89. data/spec/api/proxy/proxy_spec.rb +86 -0
  90. data/spec/api/spy/spy_spec.rb +49 -0
  91. data/spec/api/strong/strong_spec.rb +87 -0
  92. data/spec/api/stub/stub_spec.rb +152 -0
  93. data/spec/core_spec_suite.rb +18 -0
  94. data/spec/environment_fixture_setup.rb +7 -0
  95. data/spec/minitest_spec_suite.rb +21 -0
  96. data/spec/proc_from_block_spec.rb +14 -0
  97. data/spec/rr/adapters/rr_methods_argument_matcher_spec.rb +67 -0
  98. data/spec/rr/adapters/rr_methods_creator_spec.rb +137 -0
  99. data/spec/rr/adapters/rr_methods_space_spec.rb +98 -0
  100. data/spec/rr/adapters/rr_methods_spec_helper.rb +7 -0
  101. data/spec/rr/adapters/rr_methods_times_matcher_spec.rb +13 -0
  102. data/spec/rr/double_definitions/child_double_definition_creator_spec.rb +112 -0
  103. data/spec/rr/double_definitions/double_definition_create_blank_slate_spec.rb +91 -0
  104. data/spec/rr/double_definitions/double_definition_create_spec.rb +443 -0
  105. data/spec/rr/double_injection/double_injection_spec.rb +546 -0
  106. data/spec/rr/double_injection/double_injection_verify_spec.rb +29 -0
  107. data/spec/rr/errors/rr_error_spec.rb +67 -0
  108. data/spec/rr/expectations/any_argument_expectation_spec.rb +47 -0
  109. data/spec/rr/expectations/anything_argument_equality_expectation_spec.rb +14 -0
  110. data/spec/rr/expectations/argument_equality_expectation_spec.rb +135 -0
  111. data/spec/rr/expectations/boolean_argument_equality_expectation_spec.rb +34 -0
  112. data/spec/rr/expectations/hash_including_argument_equality_expectation_spec.rb +82 -0
  113. data/spec/rr/expectations/hash_including_spec.rb +17 -0
  114. data/spec/rr/expectations/satisfy_argument_equality_expectation_spec.rb +59 -0
  115. data/spec/rr/expectations/satisfy_spec.rb +14 -0
  116. data/spec/rr/expectations/times_called_expectation/times_called_expectation_any_times_spec.rb +22 -0
  117. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_least_spec.rb +37 -0
  118. data/spec/rr/expectations/times_called_expectation/times_called_expectation_at_most_spec.rb +43 -0
  119. data/spec/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +11 -0
  120. data/spec/rr/expectations/times_called_expectation/times_called_expectation_integer_spec.rb +58 -0
  121. data/spec/rr/expectations/times_called_expectation/times_called_expectation_proc_spec.rb +35 -0
  122. data/spec/rr/expectations/times_called_expectation/times_called_expectation_range_spec.rb +39 -0
  123. data/spec/rr/minitest/minitest_integration_test.rb +59 -0
  124. data/spec/rr/minitest/test_helper.rb +7 -0
  125. data/spec/rr/rspec/invocation_matcher_spec.rb +279 -0
  126. data/spec/rr/rspec/rspec_adapter_spec.rb +63 -0
  127. data/spec/rr/rspec/rspec_backtrace_tweaking_spec.rb +21 -0
  128. data/spec/rr/rspec/rspec_backtrace_tweaking_spec_fixture.rb +11 -0
  129. data/spec/rr/rspec/rspec_usage_spec.rb +86 -0
  130. data/spec/rr/space/hash_with_object_id_key_spec.rb +88 -0
  131. data/spec/rr/space/space_spec.rb +596 -0
  132. data/spec/rr/test_unit/test_helper.rb +7 -0
  133. data/spec/rr/test_unit/test_unit_backtrace_test.rb +36 -0
  134. data/spec/rr/test_unit/test_unit_integration_test.rb +59 -0
  135. data/spec/rr/times_called_matchers/any_times_matcher_spec.rb +47 -0
  136. data/spec/rr/times_called_matchers/at_least_matcher_spec.rb +55 -0
  137. data/spec/rr/times_called_matchers/at_most_matcher_spec.rb +70 -0
  138. data/spec/rr/times_called_matchers/integer_matcher_spec.rb +70 -0
  139. data/spec/rr/times_called_matchers/proc_matcher_spec.rb +55 -0
  140. data/spec/rr/times_called_matchers/range_matcher_spec.rb +76 -0
  141. data/spec/rr/times_called_matchers/times_called_matcher_spec.rb +118 -0
  142. data/spec/rr/wildcard_matchers/anything_spec.rb +24 -0
  143. data/spec/rr/wildcard_matchers/boolean_spec.rb +36 -0
  144. data/spec/rr/wildcard_matchers/duck_type_spec.rb +52 -0
  145. data/spec/rr/wildcard_matchers/is_a_spec.rb +32 -0
  146. data/spec/rr/wildcard_matchers/numeric_spec.rb +32 -0
  147. data/spec/rr/wildcard_matchers/range_spec.rb +35 -0
  148. data/spec/rr/wildcard_matchers/regexp_spec.rb +43 -0
  149. data/spec/rr_spec.rb +28 -0
  150. data/spec/rspec_spec_suite.rb +16 -0
  151. data/spec/spec_helper.rb +40 -0
  152. data/spec/spec_suite.rb +50 -0
  153. data/spec/spy_verification_spec.rb +129 -0
  154. data/spec/test_unit_spec_suite.rb +20 -0
  155. metadata +220 -0
@@ -0,0 +1,98 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ module Adapters
5
+ describe RRMethods do
6
+ attr_reader :space, :subject_1, :subject_2, :method_name
7
+ it_should_behave_like "Swapped Space"
8
+ it_should_behave_like "RR::Adapters::RRMethods"
9
+ before do
10
+ @subject_1 = Object.new
11
+ @subject_2 = Object.new
12
+ @method_name = :foobar
13
+ end
14
+
15
+ describe "#verify" do
16
+ it "aliases #rr_verify" do
17
+ RRMethods.instance_method("verify").should == RRMethods.instance_method("rr_verify")
18
+ end
19
+ end
20
+
21
+ describe "#rr_verify" do
22
+ it "verifies and deletes the double_injections" do
23
+ double_1 = ::RR::Injections::DoubleInjection.find_or_create_by_subject(subject_1, method_name)
24
+ double_1_verify_calls = 0
25
+ double_1_reset_calls = 0
26
+ (
27
+ class << double_1;
28
+ self;
29
+ end).class_eval do
30
+ define_method(:verify) do ||
31
+ double_1_verify_calls += 1
32
+ end
33
+ define_method(:reset) do ||
34
+ double_1_reset_calls += 1
35
+ end
36
+ end
37
+ double_2 = ::RR::Injections::DoubleInjection.find_or_create_by_subject(subject_2, method_name)
38
+ double_2_verify_calls = 0
39
+ double_2_reset_calls = 0
40
+ ( class << double_2; self; end).class_eval do
41
+ define_method(:verify) do ||
42
+ double_2_verify_calls += 1
43
+ end
44
+ define_method(:reset) do ||
45
+ double_2_reset_calls += 1
46
+ end
47
+ end
48
+
49
+ rr_verify
50
+ double_1_verify_calls.should == 1
51
+ double_2_verify_calls.should == 1
52
+ double_1_reset_calls.should == 1
53
+ double_1_reset_calls.should == 1
54
+ end
55
+ end
56
+
57
+ describe "#reset" do
58
+ it "aliases #rr_reset" do
59
+ RRMethods.instance_method("reset").should == RRMethods.instance_method("rr_reset")
60
+ end
61
+ end
62
+
63
+ describe "#rr_reset" do
64
+ it "removes the ordered doubles" do
65
+ mock(subject_1).foobar1.ordered
66
+ mock(subject_2).foobar2.ordered
67
+
68
+ ::RR::Injections::DoubleInjection.instances.should_not be_empty
69
+
70
+ rr_reset
71
+ ::RR::Injections::DoubleInjection.instances
72
+ ::RR::Injections::DoubleInjection.instances.should be_empty
73
+ end
74
+
75
+ it "resets all double_injections" do
76
+ double_1 = ::RR::Injections::DoubleInjection.find_or_create_by_subject(subject_1, method_name)
77
+ double_1_reset_calls = 0
78
+ ( class << double_1; self; end).class_eval do
79
+ define_method(:reset) do ||
80
+ double_1_reset_calls += 1
81
+ end
82
+ end
83
+ double_2 = ::RR::Injections::DoubleInjection.find_or_create_by_subject(subject_2, method_name)
84
+ double_2_reset_calls = 0
85
+ ( class << double_2; self; end).class_eval do
86
+ define_method(:reset) do ||
87
+ double_2_reset_calls += 1
88
+ end
89
+ end
90
+
91
+ rr_reset
92
+ double_1_reset_calls.should == 1
93
+ double_2_reset_calls.should == 1
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,7 @@
1
+ # require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ shared_examples_for "RR::Adapters::RRMethods" do
4
+ before do
5
+ extend RR::Adapters::RRMethods
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ describe RR::Adapters::RRMethods, "#any_times" do
4
+ it_should_behave_like "RR::Adapters::RRMethods"
5
+
6
+ it "returns an AnyTimesMatcher" do
7
+ any_times.should == RR::TimesCalledMatchers::AnyTimesMatcher.new
8
+ end
9
+
10
+ it "rr_any_times returns an AnyTimesMatcher" do
11
+ rr_any_times.should == RR::TimesCalledMatchers::AnyTimesMatcher.new
12
+ end
13
+ end
@@ -0,0 +1,112 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ module DoubleDefinitions
5
+ describe ChildDoubleDefinitionCreate do
6
+ attr_reader :parent_subject, :parent_double_definition_create, :parent_double_definition, :child_double_definition_create
7
+ it_should_behave_like "Swapped Space"
8
+ before(:each) do
9
+ @parent_subject = Object.new
10
+ @parent_double_definition_create = DoubleDefinitionCreate.new
11
+ @parent_double_definition = DoubleDefinition.new(parent_double_definition_create)
12
+ @child_double_definition_create = ChildDoubleDefinitionCreate.new(parent_double_definition)
13
+ end
14
+
15
+ describe "#root_subject" do
16
+ it "returns the #parent_double_definition.root_subject" do
17
+ child_subject = Object.new
18
+ parent_double_definition_create.stub(parent_subject)
19
+ child_double_definition_create.stub(child_subject)
20
+ child_double_definition_create.root_subject.should == parent_subject
21
+ end
22
+ end
23
+
24
+ describe "Strategies::Verification definitions" do
25
+ describe "methods without !" do
26
+ attr_reader :child_subject
27
+ before do
28
+ @child_subject = Object.new
29
+ end
30
+
31
+ describe "#mock" do
32
+ context "when passed a subject" do
33
+ it "sets #parent_double_definition.implementation to a Proc returning the passed-in subject" do
34
+ parent_double_definition.implementation.should be_nil
35
+ child_double_definition_create.mock(child_subject)
36
+ parent_double_definition.implementation.call.should == child_subject
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "#stub" do
42
+ context "when passed a subject" do
43
+ it "sets #parent_double_definition.implementation to a Proc returning the passed-in subject" do
44
+ parent_double_definition.implementation.should be_nil
45
+ child_double_definition_create.stub(child_subject)
46
+ parent_double_definition.implementation.call.should == child_subject
47
+ end
48
+ end
49
+ end
50
+
51
+ describe "#dont_allow" do
52
+ context "when passed a subject" do
53
+ it "sets #parent_double_definition.implementation to a Proc returning the passed-in subject" do
54
+ parent_double_definition.implementation.should be_nil
55
+ child_double_definition_create.dont_allow(child_subject)
56
+ parent_double_definition.implementation.call.should == child_subject
57
+ end
58
+ end
59
+ end
60
+ end
61
+
62
+ describe "methods with !" do
63
+ describe "#mock!" do
64
+ it "sets #parent_double_definition.implementation to a Proc returning the #subject" do
65
+ parent_double_definition.implementation.should be_nil
66
+ child_subject = child_double_definition_create.mock!.__double_definition_create__.subject
67
+ parent_double_definition.implementation.call.should == child_subject
68
+ end
69
+ end
70
+
71
+ describe "#stub!" do
72
+ it "sets #parent_double_definition.implementation to a Proc returning the #subject" do
73
+ parent_double_definition.implementation.should be_nil
74
+ child_subject = child_double_definition_create.stub!.__double_definition_create__.subject
75
+ parent_double_definition.implementation.call.should == child_subject
76
+ end
77
+ end
78
+
79
+ describe "#dont_allow!" do
80
+ it "sets #parent_double_definition.implementation to a Proc returning the #subject" do
81
+ parent_double_definition.implementation.should be_nil
82
+ child_subject = child_double_definition_create.dont_allow!.__double_definition_create__.subject
83
+ parent_double_definition.implementation.call.should == child_subject
84
+ end
85
+ end
86
+ end
87
+ end
88
+
89
+ describe "Strategies::DoubleInjection definitions" do
90
+ describe "methods without !" do
91
+ describe "#instance_of" do
92
+ it "raises a NoMethodError" do
93
+ lambda do
94
+ child_double_definition_create.instance_of
95
+ end.should raise_error(NoMethodError)
96
+ end
97
+ end
98
+ end
99
+
100
+ describe "methods with !" do
101
+ describe "#instance_of!" do
102
+ it "raises a NoMethodError" do
103
+ lambda do
104
+ child_double_definition_create.instance_of!
105
+ end.should raise_error(NoMethodError)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,91 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ module DoubleDefinitions
5
+ describe DoubleDefinitionCreateBlankSlate do
6
+ attr_reader :subject, :double_definition_create, :blank_slate
7
+ it_should_behave_like "Swapped Space"
8
+
9
+ before(:each) do
10
+ @subject = Object.new
11
+ @double_definition_create = DoubleDefinitionCreate.new
12
+ double_definition_create.mock(subject)
13
+ end
14
+
15
+ describe ".new" do
16
+ it "does not undefine object_id" do
17
+ blank_slate = DoubleDefinitionCreateBlankSlate.new(double_definition_create)
18
+ blank_slate.object_id.class.should == Fixnum
19
+ end
20
+
21
+ context "without block" do
22
+ before do
23
+ @blank_slate = DoubleDefinitionCreateBlankSlate.new(double_definition_create)
24
+ end
25
+
26
+ it "clears out all methods from proxy" do
27
+ stub(subject).i_should_be_a_double.should be_instance_of(DoubleDefinition)
28
+ end
29
+ end
30
+
31
+ context "when passed a block" do
32
+ context "when the block has an arity of 1" do
33
+ attr_reader :passed_in_argument
34
+ before do
35
+ passed_in_argument = nil
36
+ stub(subject) do |b|
37
+ passed_in_argument = b
38
+ b.foobar(1, 2) {:one_two}
39
+ b.foobar(1) {:one}
40
+ b.foobar.with_any_args {:default}
41
+ b.baz() {:baz_result}
42
+ end
43
+ @passed_in_argument = passed_in_argument
44
+ end
45
+
46
+ it "creates double_injections" do
47
+ subject.foobar(1, 2).should == :one_two
48
+ subject.foobar(1).should == :one
49
+ subject.foobar(:something).should == :default
50
+ subject.baz.should == :baz_result
51
+ end
52
+
53
+ it "passes the self into the block" do
54
+ passed_in_argument.__double_definition_create__.should be_instance_of(
55
+ ::RR::DoubleDefinitions::DoubleDefinitionCreate
56
+ )
57
+ end
58
+ end
59
+
60
+ context "when the block has an arity of 0" do
61
+ attr_reader :self_value
62
+ before do
63
+ self_value = nil
64
+ stub(subject) do ||
65
+ self_value = self
66
+ foobar(1, 2) {:one_two}
67
+ foobar(1) {:one}
68
+ foobar.with_any_args {:default}
69
+ baz() {:baz_result}
70
+ end
71
+ @self_value = self_value
72
+ end
73
+
74
+ it "creates double_injections" do
75
+ subject.foobar(1, 2).should == :one_two
76
+ subject.foobar(1).should == :one
77
+ subject.foobar(:something).should == :default
78
+ subject.baz.should == :baz_result
79
+ end
80
+
81
+ it "evaluates the block with the context of self" do
82
+ self_value.__double_definition_create__.should be_instance_of(
83
+ ::RR::DoubleDefinitions::DoubleDefinitionCreate
84
+ )
85
+ end
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,443 @@
1
+ require File.expand_path("#{File.dirname(__FILE__)}/../../spec_helper")
2
+
3
+ module RR
4
+ module DoubleDefinitions
5
+ describe DoubleDefinitionCreate do
6
+ attr_reader :double_definition_create, :subject, :strategy_method_name
7
+ it_should_behave_like "Swapped Space"
8
+ before(:each) do
9
+ @subject = Object.new
10
+ @double_definition_create = DoubleDefinitionCreate.new
11
+ end
12
+
13
+ describe "#root_subject" do
14
+ it "returns #subject" do
15
+ double_definition_create.stub(subject).foobar
16
+ double_definition_create.root_subject.should == subject
17
+ end
18
+ end
19
+
20
+ describe "StrategySetupMethods" do
21
+ describe "normal strategy definitions" do
22
+ def call_strategy(*args, &block)
23
+ double_definition_create.__send__(strategy_method_name, *args, &block)
24
+ end
25
+
26
+ describe "#mock" do
27
+ before do
28
+ @strategy_method_name = :mock
29
+ end
30
+
31
+ context "when passing no args" do
32
+ it "returns self" do
33
+ call_strategy.should === double_definition_create
34
+ end
35
+ end
36
+
37
+ context "when passed a subject and a method_name argument" do
38
+ it "creates a mock Double for method" do
39
+ double_definition = double_definition_create.mock(subject, :foobar).returns {:baz}
40
+ double_definition.times_matcher.should == RR::TimesCalledMatchers::IntegerMatcher.new(1)
41
+ double_definition.argument_expectation.class.should == RR::Expectations::ArgumentEqualityExpectation
42
+ double_definition.argument_expectation.expected_arguments.should == []
43
+ subject.foobar.should == :baz
44
+ end
45
+ end
46
+ end
47
+
48
+ describe "#stub" do
49
+ before do
50
+ @strategy_method_name = :stub
51
+ end
52
+
53
+ context "when passing no args" do
54
+ it "returns self" do
55
+ call_strategy.should === double_definition_create
56
+ end
57
+ end
58
+
59
+ context "when passed subject and a method_name argument" do
60
+ it "creates a stub Double for method when passed a method_name argument" do
61
+ double_definition = double_definition_create.stub(subject, :foobar).returns {:baz}
62
+ double_definition.times_matcher.should == RR::TimesCalledMatchers::AnyTimesMatcher.new
63
+ double_definition.argument_expectation.class.should == RR::Expectations::AnyArgumentExpectation
64
+ subject.foobar.should == :baz
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#dont_allow" do
70
+ before do
71
+ @strategy_method_name = :dont_allow
72
+ end
73
+
74
+ context "when passing no args" do
75
+ it "returns self" do
76
+ call_strategy.should === double_definition_create
77
+ end
78
+ end
79
+
80
+ context "when passed a subject and a method_name argument_expectation" do
81
+ it "creates a mock Double for method" do
82
+ double_definition = double_definition_create.dont_allow(subject, :foobar)
83
+ double_definition.times_matcher.should == RR::TimesCalledMatchers::NeverMatcher.new
84
+ double_definition.argument_expectation.class.should == RR::Expectations::AnyArgumentExpectation
85
+
86
+ lambda do
87
+ subject.foobar
88
+ end.should raise_error(RR::Errors::TimesCalledError)
89
+ RR.reset
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ describe "! strategy definitions" do
96
+ attr_reader :strategy_method_name
97
+ def call_strategy(*args, &definition_eval_block)
98
+ double_definition_create.__send__(strategy_method_name, *args, &definition_eval_block)
99
+ end
100
+
101
+ describe "#mock!" do
102
+ before do
103
+ @strategy_method_name = :mock!
104
+ end
105
+
106
+ context "when passed a method_name argument" do
107
+ it "sets #verification_strategy to Mock" do
108
+ double_definition_create.mock!(:foobar)
109
+ double_definition_create.verification_strategy.class.should == Strategies::Verification::Mock
110
+ lambda {RR.verify}.should raise_error(::RR::Errors::TimesCalledError)
111
+ end
112
+ end
113
+ end
114
+
115
+ describe "#stub!" do
116
+ before do
117
+ @strategy_method_name = :stub!
118
+ end
119
+
120
+ context "when passed a method_name argument" do
121
+ it "sets #verification_strategy to Stub" do
122
+ double_definition_create.stub!(:foobar)
123
+ double_definition_create.verification_strategy.class.should == Strategies::Verification::Stub
124
+ end
125
+ end
126
+ end
127
+
128
+ describe "#dont_allow!" do
129
+ before do
130
+ @strategy_method_name = :dont_allow!
131
+ end
132
+
133
+ context "when passed a method_name argument" do
134
+ it "sets #verification_strategy to DontAllow" do
135
+ double_definition_create.dont_allow!(:foobar)
136
+ double_definition_create.verification_strategy.class.should == Strategies::Verification::DontAllow
137
+ end
138
+ end
139
+ end
140
+ end
141
+
142
+ describe "#stub.proxy" do
143
+ before do
144
+ class << subject
145
+ def foobar(*args)
146
+ :original_foobar
147
+ end
148
+ end
149
+ end
150
+
151
+ context "when passed a method_name argument" do
152
+ it "creates a proxy Double for method" do
153
+ double_definition = double_definition_create.stub.proxy(subject, :foobar).after_call {:baz}
154
+ double_definition.times_matcher.should == RR::TimesCalledMatchers::AnyTimesMatcher.new
155
+ double_definition.argument_expectation.class.should == RR::Expectations::AnyArgumentExpectation
156
+ subject.foobar.should == :baz
157
+ end
158
+ end
159
+ end
160
+
161
+ describe "#instance_of" do
162
+ context "when not passed a class" do
163
+ it "raises an ArgumentError" do
164
+ lambda do
165
+ double_definition_create.instance_of(Object.new).foobar
166
+ end.should raise_error(ArgumentError, "instance_of only accepts class objects")
167
+ end
168
+ end
169
+
170
+ context "when passed a method_name argument" do
171
+ it "creates a proxy Double for method" do
172
+ klass = Class.new
173
+ double_definition = double_definition_create.stub.instance_of(klass, :foobar).returns {:baz}
174
+ double_definition.times_matcher.should == RR::TimesCalledMatchers::AnyTimesMatcher.new
175
+ double_definition.argument_expectation.class.should == RR::Expectations::AnyArgumentExpectation
176
+ klass.new.foobar.should == :baz
177
+ end
178
+ end
179
+ end
180
+
181
+ describe "#instance_of.mock" do
182
+ before do
183
+ @klass = Class.new
184
+ end
185
+
186
+ # context "when passed no arguments" do
187
+ # it "returns a DoubleDefinitiondouble_definition_create" do
188
+ # instance_of.instance_of.should be_instance_of(DoubleDefinitionCreate)
189
+ # end
190
+ # end
191
+
192
+ context "when passed a method_name argument" do
193
+ it "creates a instance_of Double for method" do
194
+ double_definition = instance_of.mock(@klass, :foobar)
195
+ double_definition.with(1, 2) {:baz}
196
+ double_definition.times_matcher.should == RR::TimesCalledMatchers::IntegerMatcher.new(1)
197
+ double_definition.argument_expectation.class.should == RR::Expectations::ArgumentEqualityExpectation
198
+ double_definition.argument_expectation.expected_arguments.should == [1, 2]
199
+
200
+ @klass.new.foobar(1, 2).should == :baz
201
+ end
202
+ end
203
+ end
204
+ end
205
+
206
+ describe "StrategyExecutionMethods" do
207
+ describe "#create" do
208
+ context "when #verification_strategy is a Mock" do
209
+ context "when #implementation_strategy is a Reimplementation" do
210
+ before do
211
+ double_definition_create.mock(subject)
212
+ end
213
+
214
+ it "sets expectation on the #subject that it will be sent the method_name once with the passed-in arguments" do
215
+ mock(subject).foobar(1, 2)
216
+ subject.foobar(1, 2)
217
+ lambda {subject.foobar(1, 2)}.should raise_error(RR::Errors::TimesCalledError)
218
+ lambda {RR.verify}.should raise_error(RR::Errors::TimesCalledError)
219
+ end
220
+
221
+ describe "#subject.method_name being called" do
222
+ it "returns the return value of the Double#returns block" do
223
+ double_definition_create.call(:foobar, 1, 2) {:baz}
224
+ subject.foobar(1, 2).should == :baz
225
+ end
226
+ end
227
+ end
228
+
229
+ context "when #implementation_strategy is a Proxy" do
230
+ before do
231
+ double_definition_create.mock
232
+ double_definition_create.proxy(subject)
233
+ end
234
+
235
+ it "sets expectation on the #subject that it will be sent the method_name once with the passed-in arguments" do
236
+ def subject.foobar(*args)
237
+ :baz
238
+ end
239
+ mock(subject).foobar(1, 2)
240
+
241
+ subject.foobar(1, 2)
242
+ lambda {subject.foobar(1, 2)}.should raise_error(RR::Errors::TimesCalledError)
243
+ lambda {RR.verify}.should raise_error(RR::Errors::TimesCalledError)
244
+ end
245
+
246
+ describe "#subject.method_name being called" do
247
+ it "calls the original method" do
248
+ original_method_called = false
249
+ (class << subject; self; end).class_eval do
250
+ define_method(:foobar) do |*args|
251
+ original_method_called = true
252
+ end
253
+ end
254
+ double_definition_create.call(:foobar, 1, 2)
255
+ subject.foobar(1, 2)
256
+ original_method_called.should be_true
257
+ end
258
+
259
+ context "when not passed a block" do
260
+ it "returns the value of the original method" do
261
+ def subject.foobar(*args)
262
+ :baz;
263
+ end
264
+ double_definition_create.call(:foobar, 1, 2)
265
+ subject.foobar(1, 2).should == :baz
266
+ end
267
+ end
268
+
269
+ context "when passed a block" do
270
+ attr_reader :real_value
271
+ before do
272
+ @real_value = real_value = Object.new
273
+ (class << subject; self; end).class_eval do
274
+ define_method(:foobar) {|arg1, arg2| real_value}
275
+ end
276
+ end
277
+
278
+ it "calls the block with the return value of the original method" do
279
+ double_definition_create.call(:foobar, 1, 2) do |value|
280
+ mock(value).a_method {99}
281
+ value
282
+ end
283
+ subject.foobar(1, 2)
284
+ real_value.a_method.should == 99
285
+ end
286
+
287
+ it "returns the return value of the block" do
288
+ double_definition_create.call(:foobar, 1, 2) do |value|
289
+ :something_else
290
+ end
291
+ subject.foobar(1, 2).should == :something_else
292
+ end
293
+ end
294
+ end
295
+ end
296
+ end
297
+
298
+ context "when #verification_strategy is a Stub" do
299
+ context "when #implementation_strategy is a Reimplementation" do
300
+ before do
301
+ double_definition_create.stub(subject)
302
+ end
303
+
304
+ context "when not passed a block" do
305
+ it "returns nil" do
306
+ double_definition_create.call(:foobar)
307
+ subject.foobar.should be_nil
308
+ end
309
+ end
310
+
311
+ context "when passed a block" do
312
+ describe "#subject.method_name being called" do
313
+ it "returns the return value of the block" do
314
+ double_definition_create.call(:foobar) {:baz}
315
+ subject.foobar.should == :baz
316
+ end
317
+ end
318
+ end
319
+
320
+ context "when not passed args" do
321
+ describe "#subject.method_name being called with any arguments" do
322
+ it "invokes the implementation of the Stub" do
323
+ double_definition_create.call(:foobar) {:baz}
324
+ subject.foobar(1, 2).should == :baz
325
+ subject.foobar().should == :baz
326
+ subject.foobar([]).should == :baz
327
+ end
328
+ end
329
+ end
330
+
331
+ context "when passed args" do
332
+ describe "#subject.method_name being called with the passed-in arguments" do
333
+ it "invokes the implementation of the Stub" do
334
+ double_definition_create.call(:foobar, 1, 2) {:baz}
335
+ subject.foobar(1, 2).should == :baz
336
+ end
337
+ end
338
+
339
+ describe "#subject.method_name being called with different arguments" do
340
+ it "raises a DoubleNotFoundError" do
341
+ double_definition_create.call(:foobar, 1, 2) {:baz}
342
+ lambda do
343
+ subject.foobar
344
+ end.should raise_error(RR::Errors::DoubleNotFoundError)
345
+ end
346
+ end
347
+ end
348
+ end
349
+
350
+ context "when #implementation_strategy is a Proxy" do
351
+ before do
352
+ def subject.foobar(*args)
353
+ :original_return_value
354
+ end
355
+ double_definition_create.stub
356
+ double_definition_create.proxy(subject)
357
+ end
358
+
359
+ context "when not passed a block" do
360
+ describe "#subject.method_name being called" do
361
+ it "invokes the original implementanion" do
362
+ double_definition_create.call(:foobar)
363
+ subject.foobar.should == :original_return_value
364
+ end
365
+ end
366
+ end
367
+
368
+ context "when passed a block" do
369
+ describe "#subject.method_name being called" do
370
+ it "invokes the original implementanion and invokes the block with the return value of the original implementanion" do
371
+ passed_in_value = nil
372
+ double_definition_create.call(:foobar) do |original_return_value|
373
+ passed_in_value = original_return_value
374
+ end
375
+ subject.foobar
376
+ passed_in_value.should == :original_return_value
377
+ end
378
+
379
+ it "returns the return value of the block" do
380
+ double_definition_create.call(:foobar) do |original_return_value|
381
+ :new_return_value
382
+ end
383
+ subject.foobar.should == :new_return_value
384
+ end
385
+ end
386
+ end
387
+
388
+ context "when passed args" do
389
+ describe "#subject.method_name being called with the passed-in arguments" do
390
+ it "invokes the implementation of the Stub" do
391
+ double_definition_create.call(:foobar, 1, 2) {:baz}
392
+ subject.foobar(1, 2).should == :baz
393
+ end
394
+ end
395
+
396
+ describe "#subject.method_name being called with different arguments" do
397
+ it "raises a DoubleNotFoundError" do
398
+ double_definition_create.call(:foobar, 1, 2) {:baz}
399
+ lambda do
400
+ subject.foobar
401
+ end.should raise_error(RR::Errors::DoubleNotFoundError)
402
+ end
403
+ end
404
+ end
405
+ end
406
+ end
407
+
408
+ context "when #verification_strategy is a DontAllow" do
409
+ before do
410
+ double_definition_create.dont_allow(subject)
411
+ end
412
+
413
+ context "when not passed args" do
414
+ describe "#subject.method_name being called with any arguments" do
415
+ it "raises a TimesCalledError" do
416
+ double_definition_create.call(:foobar)
417
+ lambda {subject.foobar}.should raise_error(RR::Errors::TimesCalledError)
418
+ lambda {subject.foobar(1, 2)}.should raise_error(RR::Errors::TimesCalledError)
419
+ end
420
+ end
421
+ end
422
+
423
+ context "when passed args" do
424
+ describe "#subject.method_name being called with the passed-in arguments" do
425
+ it "raises a TimesCalledError" do
426
+ double_definition_create.call(:foobar, 1, 2)
427
+ lambda {subject.foobar(1, 2)}.should raise_error(RR::Errors::TimesCalledError)
428
+ end
429
+ end
430
+
431
+ describe "#subject.method_name being called with different arguments" do
432
+ it "raises a DoubleNotFoundError" do
433
+ double_definition_create.call(:foobar, 1, 2)
434
+ lambda {subject.foobar()}.should raise_error(RR::Errors::DoubleNotFoundError)
435
+ end
436
+ end
437
+ end
438
+ end
439
+ end
440
+ end
441
+ end
442
+ end
443
+ end