rr 0.2.5 → 0.3.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.
- data/CHANGES +5 -0
- data/README +20 -9
- data/Rakefile +1 -1
- data/examples/example_suite.rb +1 -1
- data/examples/high_level_example.rb +4 -4
- data/examples/rr/double/double_dispatching_example.rb +41 -41
- data/examples/rr/double/double_verify_example.rb +1 -1
- data/examples/rr/expectations/times_called_expectation/times_called_expectation_helper.rb +2 -2
- data/examples/rr/extensions/instance_methods_creator_example.rb +48 -38
- data/examples/rr/extensions/instance_methods_space_example.rb +8 -8
- data/examples/rr/rspec/rspec_adapter_example.rb +9 -9
- data/examples/rr/rspec/rspec_usage_example.rb +16 -2
- data/examples/rr/scenario_creator_example.rb +400 -0
- data/examples/rr/scenario_example.rb +19 -4
- data/examples/rr/scenario_method_proxy_example.rb +71 -0
- data/examples/rr/space/space_create_example.rb +93 -106
- data/examples/rr/space/space_example.rb +2 -2
- data/examples/rr/space/space_register_example.rb +3 -3
- data/examples/rr/space/space_reset_example.rb +11 -11
- data/examples/rr/space/space_verify_example.rb +12 -12
- data/examples/rr/test_unit/test_unit_integration_test.rb +11 -2
- data/lib/rr.rb +10 -12
- data/lib/rr/errors/scenario_definition_error.rb +6 -0
- data/lib/rr/extensions/instance_methods.rb +84 -84
- data/lib/rr/scenario.rb +18 -3
- data/lib/rr/scenario_creator.rb +233 -0
- data/lib/rr/scenario_method_proxy.rb +19 -0
- data/lib/rr/space.rb +12 -32
- metadata +7 -13
- data/examples/rr/do_not_allow_creator_example.rb +0 -111
- data/examples/rr/mock_creator_example.rb +0 -87
- data/examples/rr/mock_probe_creator_example.rb +0 -120
- data/examples/rr/stub_creator_example.rb +0 -96
- data/examples/rr/stub_probe_creator_example.rb +0 -127
- data/lib/rr/creator.rb +0 -16
- data/lib/rr/do_not_allow_creator.rb +0 -33
- data/lib/rr/mock_creator.rb +0 -26
- data/lib/rr/mock_probe_creator.rb +0 -36
- data/lib/rr/stub_creator.rb +0 -30
- data/lib/rr/stub_probe_creator.rb +0 -42
@@ -17,12 +17,12 @@ describe Space, " class" do
|
|
17
17
|
it "proxies to a singleton instance of Space" do
|
18
18
|
create_double_args = nil
|
19
19
|
(class << @space; self; end).class_eval do
|
20
|
-
define_method :
|
20
|
+
define_method :double do |*args|
|
21
21
|
create_double_args = args
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
-
Space.
|
25
|
+
Space.double(:foo, :bar)
|
26
26
|
create_double_args.should == [:foo, :bar]
|
27
27
|
end
|
28
28
|
end
|
@@ -10,7 +10,7 @@ describe Space, "#register_ordered_scenario" do
|
|
10
10
|
Space.instance = @space
|
11
11
|
@object = Object.new
|
12
12
|
@method_name = :foobar
|
13
|
-
@double = @space.
|
13
|
+
@double = @space.double(@object, @method_name)
|
14
14
|
end
|
15
15
|
|
16
16
|
after(:each) do
|
@@ -18,13 +18,13 @@ describe Space, "#register_ordered_scenario" do
|
|
18
18
|
end
|
19
19
|
|
20
20
|
it "adds the ordered scenario to the ordered_scenarios collection" do
|
21
|
-
scenario1 = @space.
|
21
|
+
scenario1 = @space.scenario(@double)
|
22
22
|
|
23
23
|
@space.ordered_scenarios.should == []
|
24
24
|
@space.register_ordered_scenario scenario1
|
25
25
|
@space.ordered_scenarios.should == [scenario1]
|
26
26
|
|
27
|
-
scenario2 = @space.
|
27
|
+
scenario2 = @space.scenario(@double)
|
28
28
|
@space.register_ordered_scenario scenario2
|
29
29
|
@space.ordered_scenarios.should == [scenario1, scenario2]
|
30
30
|
end
|
@@ -12,11 +12,11 @@ describe Space, "#reset" do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "removes the ordered scenarios" do
|
15
|
-
double1 = @space.
|
16
|
-
double2 = @space.
|
15
|
+
double1 = @space.double(@object1, :foobar1)
|
16
|
+
double2 = @space.double(@object1, :foobar2)
|
17
17
|
|
18
|
-
scenario1 = @space.
|
19
|
-
scenario2 = @space.
|
18
|
+
scenario1 = @space.scenario(double1)
|
19
|
+
scenario2 = @space.scenario(double2)
|
20
20
|
|
21
21
|
scenario1.ordered
|
22
22
|
scenario2.ordered
|
@@ -28,14 +28,14 @@ describe Space, "#reset" do
|
|
28
28
|
end
|
29
29
|
|
30
30
|
it "resets all doubles" do
|
31
|
-
double1 = @space.
|
31
|
+
double1 = @space.double(@object1, @method_name)
|
32
32
|
double1_reset_calls = 0
|
33
33
|
(class << double1; self; end).class_eval do
|
34
34
|
define_method(:reset) do ||
|
35
35
|
double1_reset_calls += 1
|
36
36
|
end
|
37
37
|
end
|
38
|
-
double2 = @space.
|
38
|
+
double2 = @space.double(@object2, @method_name)
|
39
39
|
double2_reset_calls = 0
|
40
40
|
(class << double2; self; end).class_eval do
|
41
41
|
define_method(:reset) do ||
|
@@ -59,7 +59,7 @@ describe Space, "#reset_double" do
|
|
59
59
|
end
|
60
60
|
|
61
61
|
it "resets the doubles" do
|
62
|
-
double = @space.
|
62
|
+
double = @space.double(@object, @method_name)
|
63
63
|
@space.doubles[@object][@method_name].should === double
|
64
64
|
@object.methods.should include("__rr__#{@method_name}")
|
65
65
|
|
@@ -69,8 +69,8 @@ describe Space, "#reset_double" do
|
|
69
69
|
end
|
70
70
|
|
71
71
|
it "removes the object from the doubles map when it has no doubles" do
|
72
|
-
double1 = @space.
|
73
|
-
double2 = @space.
|
72
|
+
double1 = @space.double(@object, :foobar1)
|
73
|
+
double2 = @space.double(@object, :foobar2)
|
74
74
|
|
75
75
|
@space.doubles.include?(@object).should == true
|
76
76
|
@space.doubles[@object][:foobar1].should_not be_nil
|
@@ -97,14 +97,14 @@ describe Space, "#reset_doubles" do
|
|
97
97
|
end
|
98
98
|
|
99
99
|
it "resets the double and removes it from the doubles list" do
|
100
|
-
double1 = @space.
|
100
|
+
double1 = @space.double(@object1, @method_name)
|
101
101
|
double1_reset_calls = 0
|
102
102
|
(class << double1; self; end).class_eval do
|
103
103
|
define_method(:reset) do ||
|
104
104
|
double1_reset_calls += 1
|
105
105
|
end
|
106
106
|
end
|
107
|
-
double2 = @space.
|
107
|
+
double2 = @space.double(@object2, @method_name)
|
108
108
|
double2_reset_calls = 0
|
109
109
|
(class << double2; self; end).class_eval do
|
110
110
|
define_method(:reset) do ||
|
@@ -12,7 +12,7 @@ describe Space, "#verify_doubles" do
|
|
12
12
|
end
|
13
13
|
|
14
14
|
it "verifies and deletes the doubles" do
|
15
|
-
double1 = @space.
|
15
|
+
double1 = @space.double(@object1, @method_name)
|
16
16
|
double1_verify_calls = 0
|
17
17
|
double1_reset_calls = 0
|
18
18
|
(class << double1; self; end).class_eval do
|
@@ -23,7 +23,7 @@ describe Space, "#verify_doubles" do
|
|
23
23
|
double1_reset_calls += 1
|
24
24
|
end
|
25
25
|
end
|
26
|
-
double2 = @space.
|
26
|
+
double2 = @space.double(@object2, @method_name)
|
27
27
|
double2_verify_calls = 0
|
28
28
|
double2_reset_calls = 0
|
29
29
|
(class << double2; self; end).class_eval do
|
@@ -53,7 +53,7 @@ describe Space, "#verify_double" do
|
|
53
53
|
end
|
54
54
|
|
55
55
|
it "verifies and deletes the double" do
|
56
|
-
double = @space.
|
56
|
+
double = @space.double(@object, @method_name)
|
57
57
|
@space.doubles[@object][@method_name].should === double
|
58
58
|
@object.methods.should include("__rr__#{@method_name}")
|
59
59
|
|
@@ -71,7 +71,7 @@ describe Space, "#verify_double" do
|
|
71
71
|
end
|
72
72
|
|
73
73
|
it "deletes the double when verifying the double raises an error" do
|
74
|
-
double = @space.
|
74
|
+
double = @space.double(@object, @method_name)
|
75
75
|
@space.doubles[@object][@method_name].should === double
|
76
76
|
@object.methods.should include("__rr__#{@method_name}")
|
77
77
|
|
@@ -97,11 +97,11 @@ describe Space, "#verify_ordered_scenario", :shared => true do
|
|
97
97
|
@space = Space.new
|
98
98
|
@object = Object.new
|
99
99
|
@method_name = :foobar
|
100
|
-
@double = @space.
|
100
|
+
@double = @space.double(@object, @method_name)
|
101
101
|
end
|
102
102
|
|
103
103
|
it "raises an error when Scenario is NonTerminal" do
|
104
|
-
scenario = @space.
|
104
|
+
scenario = @space.scenario(@double)
|
105
105
|
@space.register_ordered_scenario(scenario)
|
106
106
|
|
107
107
|
scenario.any_number_of_times
|
@@ -120,7 +120,7 @@ describe Space, "#verify_ordered_scenario where the passed in scenario is at the
|
|
120
120
|
it_should_behave_like "RR::Space#verify_ordered_scenario"
|
121
121
|
|
122
122
|
it "keeps the scenario when times called is not verified" do
|
123
|
-
scenario = @space.
|
123
|
+
scenario = @space.scenario(@double)
|
124
124
|
@space.register_ordered_scenario(scenario)
|
125
125
|
|
126
126
|
scenario.twice
|
@@ -131,7 +131,7 @@ describe Space, "#verify_ordered_scenario where the passed in scenario is at the
|
|
131
131
|
end
|
132
132
|
|
133
133
|
it "removes the scenario when times called expectation should no longer be attempted" do
|
134
|
-
scenario = @space.
|
134
|
+
scenario = @space.scenario(@double)
|
135
135
|
@space.register_ordered_scenario(scenario)
|
136
136
|
|
137
137
|
scenario.with(1).once
|
@@ -147,8 +147,8 @@ describe Space, "#verify_ordered_scenario where the passed in scenario is not at
|
|
147
147
|
it_should_behave_like "RR::Space#verify_ordered_scenario"
|
148
148
|
|
149
149
|
it "raises error" do
|
150
|
-
first_scenario =
|
151
|
-
second_scenario =
|
150
|
+
first_scenario = scenario
|
151
|
+
second_scenario = scenario
|
152
152
|
|
153
153
|
proc do
|
154
154
|
@space.verify_ordered_scenario(second_scenario)
|
@@ -160,8 +160,8 @@ describe Space, "#verify_ordered_scenario where the passed in scenario is not at
|
|
160
160
|
)
|
161
161
|
end
|
162
162
|
|
163
|
-
def
|
164
|
-
scenario = @space.
|
163
|
+
def scenario
|
164
|
+
scenario = @space.scenario(@double).once
|
165
165
|
@space.register_ordered_scenario(scenario)
|
166
166
|
scenario
|
167
167
|
end
|
@@ -21,12 +21,21 @@ class TestUnitIntegrationTest < Test::Unit::TestCase
|
|
21
21
|
assert_equal :baz, @subject.foobar("any", "thing")
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
24
|
+
def test_using_a_mock_probe
|
25
25
|
def @subject.foobar
|
26
26
|
:baz
|
27
27
|
end
|
28
28
|
|
29
|
-
probe(@subject).foobar
|
29
|
+
mock.probe(@subject).foobar
|
30
|
+
assert_equal :baz, @subject.foobar
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_using_a_stub_probe
|
34
|
+
def @subject.foobar
|
35
|
+
:baz
|
36
|
+
end
|
37
|
+
|
38
|
+
stub.probe(@subject).foobar
|
30
39
|
assert_equal :baz, @subject.foobar
|
31
40
|
end
|
32
41
|
|
data/lib/rr.rb
CHANGED
@@ -1,23 +1,21 @@
|
|
1
|
+
require "rr/errors/rr_error"
|
2
|
+
require "rr/errors/scenario_definition_error"
|
3
|
+
require "rr/errors/scenario_not_found_error"
|
4
|
+
require "rr/errors/scenario_order_error"
|
5
|
+
require "rr/errors/argument_equality_error"
|
6
|
+
require "rr/errors/times_called_error"
|
7
|
+
|
1
8
|
require "rr/space"
|
2
9
|
require "rr/double"
|
3
10
|
require "rr/hash_with_object_id_key"
|
4
11
|
|
5
|
-
require "rr/
|
6
|
-
|
7
|
-
require "rr/
|
8
|
-
require "rr/mock_probe_creator"
|
9
|
-
require "rr/stub_probe_creator"
|
10
|
-
require "rr/do_not_allow_creator"
|
12
|
+
require "rr/scenario_method_proxy"
|
13
|
+
|
14
|
+
require "rr/scenario_creator"
|
11
15
|
|
12
16
|
require "rr/scenario"
|
13
17
|
require "rr/scenario_matches"
|
14
18
|
|
15
|
-
require "rr/errors/rr_error"
|
16
|
-
require "rr/errors/scenario_not_found_error"
|
17
|
-
require "rr/errors/scenario_order_error"
|
18
|
-
require "rr/errors/argument_equality_error"
|
19
|
-
require "rr/errors/times_called_error"
|
20
|
-
|
21
19
|
require "rr/expectations/argument_equality_expectation"
|
22
20
|
require "rr/expectations/any_argument_expectation"
|
23
21
|
require "rr/expectations/times_called_expectation"
|
@@ -12,57 +12,90 @@ module Extensions
|
|
12
12
|
RR::Space.instance.reset
|
13
13
|
end
|
14
14
|
|
15
|
-
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
15
|
+
# This method sets the Scenario to have a mock strategy. A mock strategy
|
16
|
+
# sets the default state of the Scenario to expect the method call
|
17
|
+
# with arguments exactly one time. The Scenario's expectations can be
|
18
|
+
# changed.
|
19
|
+
#
|
20
|
+
# This method can be chained with probe.
|
21
|
+
# mock.probe(subject).method_name_1
|
22
|
+
# or
|
23
|
+
# probe.mock(subject).method_name_1
|
24
|
+
#
|
25
|
+
# When passed the subject, a ScenarioMethodProxy is returned. Passing
|
26
|
+
# a method with arguments to the proxy will set up expectations that
|
27
|
+
# the a call to the subject's method with the arguments will happen,
|
28
|
+
# and return the prescribed value.
|
29
|
+
# mock(subject).method_name_1 {return_value_1}
|
30
|
+
# mock(subject).method_name_2(arg1, arg2) {return_value_2}
|
31
|
+
#
|
32
|
+
# When passed the subject and the method_name, this method returns
|
21
33
|
# a mock Scenario with the method already set.
|
22
34
|
#
|
35
|
+
# mock(subject, :method_name_1) {return_value_1}
|
36
|
+
# mock(subject, :method_name_2).with(arg1, arg2) {return_value_2}
|
37
|
+
#
|
23
38
|
# mock also takes a block for definitions.
|
24
|
-
# mock(
|
39
|
+
# mock(subject) do
|
25
40
|
# method_name_1 {return_value_1}
|
26
41
|
# method_name_2(arg_1, arg_2) {return_value_2}
|
27
42
|
# end
|
28
|
-
def mock(
|
29
|
-
RR::Space.
|
43
|
+
def mock(subject=ScenarioCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
44
|
+
creator = RR::Space.scenario_creator
|
45
|
+
creator.mock(subject, method_name, &definition)
|
30
46
|
end
|
31
47
|
|
32
|
-
|
33
|
-
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
48
|
+
|
49
|
+
# This method sets the Scenario to have a stub strategy. A stub strategy
|
50
|
+
# sets the default state of the Scenario to expect the method call
|
51
|
+
# with any arguments any number of times. The Scenario's
|
52
|
+
# expectations can be changed.
|
53
|
+
#
|
54
|
+
# This method can be chained with probe.
|
55
|
+
# stub.probe(subject).method_name_1
|
56
|
+
# or
|
57
|
+
# probe.stub(subject).method_name_1
|
58
|
+
#
|
59
|
+
# When passed the subject, a ScenarioMethodProxy is returned. Passing
|
60
|
+
# a method with arguments to the proxy will set up expectations that
|
61
|
+
# the a call to the subject's method with the arguments will happen,
|
62
|
+
# and return the prescribed value.
|
63
|
+
# stub(subject).method_name_1 {return_value_1}
|
64
|
+
# stub(subject).method_name_2(arg_1, arg_2) {return_value_2}
|
65
|
+
#
|
66
|
+
# When passed the subject and the method_name, this method returns
|
38
67
|
# a stub Scenario with the method already set.
|
39
68
|
#
|
69
|
+
# mock(subject, :method_name_1) {return_value_1}
|
70
|
+
# mock(subject, :method_name_2).with(arg1, arg2) {return_value_2}
|
71
|
+
#
|
40
72
|
# stub also takes a block for definitions.
|
41
|
-
# stub(
|
73
|
+
# stub(subject) do
|
42
74
|
# method_name_1 {return_value_1}
|
43
75
|
# method_name_2(arg_1, arg_2) {return_value_2}
|
44
76
|
# end
|
45
|
-
def stub(
|
46
|
-
RR::Space.
|
77
|
+
def stub(subject=ScenarioCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
78
|
+
creator = RR::Space.scenario_creator
|
79
|
+
creator.stub(subject, method_name, &definition)
|
47
80
|
end
|
48
81
|
|
49
|
-
#
|
50
|
-
#
|
82
|
+
# This method add probe capabilities to the Scenario. probe can be called
|
83
|
+
# with mock or stub.
|
51
84
|
#
|
52
|
-
#
|
85
|
+
# mock.probe(controller.template).render(:partial => "my/socks")
|
53
86
|
#
|
54
|
-
#
|
87
|
+
# stub.probe(controller.template).render(:partial => "my/socks") do |html|
|
55
88
|
# html.should include("My socks are wet")
|
56
89
|
# html
|
57
90
|
# end
|
58
91
|
#
|
59
|
-
#
|
92
|
+
# mock.probe(controller.template).render(:partial => "my/socks") do |html|
|
60
93
|
# html.should include("My socks are wet")
|
61
94
|
# "My new return value"
|
62
95
|
# end
|
63
96
|
#
|
64
|
-
#
|
65
|
-
#
|
97
|
+
# mock.probe also takes a block for definitions.
|
98
|
+
# mock.probe(subject) do
|
66
99
|
# render(:partial => "my/socks")
|
67
100
|
#
|
68
101
|
# render(:partial => "my/socks") do |html|
|
@@ -87,71 +120,38 @@ module Extensions
|
|
87
120
|
# passing in a block. The return value of the block will replace
|
88
121
|
# the actual return value.
|
89
122
|
#
|
90
|
-
#
|
123
|
+
# mock.probe(controller.template).render(:partial => "my/socks") do |html|
|
91
124
|
# html.should include("My socks are wet")
|
92
125
|
# "My new return value"
|
93
126
|
# end
|
94
|
-
def
|
95
|
-
RR::Space.
|
127
|
+
def probe(subject=ScenarioCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
128
|
+
creator = RR::Space.scenario_creator
|
129
|
+
creator.probe(subject, method_name, &definition)
|
96
130
|
end
|
97
131
|
|
98
|
-
#
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
103
|
-
#
|
104
|
-
#
|
105
|
-
#
|
106
|
-
#
|
107
|
-
#
|
108
|
-
#
|
109
|
-
#
|
110
|
-
#
|
111
|
-
#
|
112
|
-
#
|
113
|
-
#
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
#
|
118
|
-
# mock_probe(User) do
|
119
|
-
# new {|user| user}
|
120
|
-
#
|
121
|
-
# new do |user|
|
122
|
-
# mock(user).valid? {false}
|
123
|
-
# end
|
124
|
-
#
|
125
|
-
# new do |user|
|
126
|
-
# mock_probe(user).friends {|friends| friends[0..3]}
|
127
|
-
# user
|
128
|
-
# end
|
129
|
-
# end
|
130
|
-
#
|
131
|
-
# Passing a block to the Scenario (after the method name and arguments)
|
132
|
-
# allows you to intercept the return value.
|
133
|
-
# The return value can be modified, validated, and/or overridden by
|
134
|
-
# passing in a block. The return value of the block will replace
|
135
|
-
# the actual return value.
|
136
|
-
#
|
137
|
-
# stub_probe(controller.template).render(:partial => "my/socks") do |html|
|
138
|
-
# html.should include("My socks are wet")
|
139
|
-
# "My new return value"
|
140
|
-
# end
|
141
|
-
def stub_probe(object, method_name=nil, &definition)
|
142
|
-
RR::Space.instance.stub_probe_creator(object, method_name, &definition)
|
143
|
-
end
|
144
|
-
|
145
|
-
# Same as mock_probe
|
146
|
-
alias_method :probe, :mock_probe
|
147
|
-
|
148
|
-
# Sets up a DoNotAllowCreator that generates a Double Scenario that
|
149
|
-
# expects never to be called.
|
150
|
-
# do_not_allow(object).method_name
|
151
|
-
def do_not_allow(subject, method_name=nil, &definition)
|
152
|
-
RR::Space.instance.do_not_allow_creator(subject, method_name, &definition)
|
132
|
+
# This method sets the Scenario to have a do_not_call strategy.
|
133
|
+
# A do_not_call strategy sets the default state of the Scenario
|
134
|
+
# to expect never to be called. The Scenario's expectations can be
|
135
|
+
# changed.
|
136
|
+
#
|
137
|
+
# The following example sets the expectation that subject.method_name
|
138
|
+
# will never be called with arg1 and arg2.
|
139
|
+
#
|
140
|
+
# do_not_allow(subject).method_name(arg1, arg2)
|
141
|
+
#
|
142
|
+
# do_not_call also supports a block sytnax.
|
143
|
+
# do_not_call(subject) do |m|
|
144
|
+
# m.method1 # Do not allow method1 with any arguments
|
145
|
+
# m.method2(arg1, arg2) # Do not allow method2 with arguments arg1 and arg2
|
146
|
+
# m.method3.with_no_args # Do not allow method3 with no arguments
|
147
|
+
# end
|
148
|
+
def do_not_call(subject=ScenarioCreator::NO_SUBJECT_ARG, method_name=nil, &definition)
|
149
|
+
creator = RR::Space.scenario_creator
|
150
|
+
creator.do_not_call(subject, method_name, &definition)
|
153
151
|
end
|
154
|
-
alias_method :
|
152
|
+
alias_method :dont_call, :do_not_call
|
153
|
+
alias_method :do_not_allow, :do_not_call
|
154
|
+
alias_method :dont_allow, :do_not_call
|
155
155
|
|
156
156
|
# Returns a AnyTimesMatcher. This is meant to be passed in as an argument
|
157
157
|
# to Scenario#times.
|