rr 0.2.5 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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.
|