pakada-dispatch 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.yardopts +1 -0
- data/Gemfile +4 -1
- data/README.md +4 -1
- data/lib/pakada/dispatch.rb +10 -29
- data/lib/pakada/dispatch/controller.rb +32 -142
- data/lib/pakada/dispatch/module.rb +27 -56
- data/lib/pakada/dispatch/version.rb +1 -1
- data/pakada-dispatch.gemspec +5 -5
- data/spec/controller_spec.rb +101 -316
- data/spec/controllers/foo.rb +1 -0
- data/spec/dispatch_spec.rb +44 -60
- data/spec/module_spec.rb +61 -258
- data/spec/spec_helper.rb +11 -10
- metadata +62 -76
- data/lib/pakada/dispatch/util.rb +0 -12
- data/spec/util_spec.rb +0 -21
@@ -0,0 +1 @@
|
|
1
|
+
action(:bar) {}
|
data/spec/dispatch_spec.rb
CHANGED
@@ -1,78 +1,62 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Pakada::Dispatch do
|
4
|
-
|
4
|
+
let(:dispatch) { Pakada::Dispatch.new }
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "#initialize" do
|
11
|
-
it "initializes the router" do
|
12
|
-
subject.router.should respond_to :add_route
|
13
|
-
subject.router.should respond_to :call
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
describe "#boot" do
|
18
|
-
before :each do
|
19
|
-
[:apply_patches, :load_module_controllers].each {|m| subject.stub m }
|
20
|
-
end
|
6
|
+
context "#initialize" do
|
7
|
+
let(:router) { stub "router" }
|
21
8
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
it "calls #load_module_controllers" do
|
28
|
-
subject.should_receive :load_module_controllers
|
29
|
-
subject.boot
|
30
|
-
end
|
31
|
-
|
32
|
-
it "calls #set_app" do
|
33
|
-
subject.should_receive :set_app
|
34
|
-
subject.boot
|
35
|
-
end
|
9
|
+
before {
|
10
|
+
HttpRouter.stub :new => router
|
11
|
+
}
|
36
12
|
|
37
|
-
it "
|
38
|
-
|
39
|
-
subject.boot
|
13
|
+
it "sets the router" do
|
14
|
+
dispatch.router.should equal(router)
|
40
15
|
end
|
41
16
|
end
|
42
17
|
|
43
|
-
|
44
|
-
it "
|
45
|
-
Pakada.instance.
|
46
|
-
|
47
|
-
|
48
|
-
Pakada[:foo].should respond_to(:load_controllers)
|
18
|
+
context "#hooks" do
|
19
|
+
it "replaces Pakada#request with router#call" do
|
20
|
+
Pakada.instance.should_receive(:instead_of).with(
|
21
|
+
:request, dispatch.router.method(:call))
|
22
|
+
dispatch.hooks
|
49
23
|
end
|
50
24
|
end
|
51
25
|
|
52
|
-
|
53
|
-
|
54
|
-
|
26
|
+
context "#boot" do
|
27
|
+
let(:module1) {
|
28
|
+
Class.new { @pakada_name = :module1; include Pakada::Module }.new
|
29
|
+
}
|
30
|
+
let(:module2) {
|
31
|
+
Class.new { @pakada_name = :module2; include Pakada::Module }.new
|
32
|
+
}
|
33
|
+
|
34
|
+
before {
|
35
|
+
Pakada.instance.stub :modules => {
|
36
|
+
:dispatch => dispatch,
|
37
|
+
:module1 => module1,
|
38
|
+
:module2 => module2
|
39
|
+
}
|
40
|
+
module1.stub :routes
|
41
|
+
}
|
42
|
+
|
43
|
+
it "includes Module into each Pakada module" do
|
44
|
+
mod = Pakada.safety(Pakada::Dispatch::Module)
|
55
45
|
|
56
|
-
|
57
|
-
|
46
|
+
dispatch.boot
|
47
|
+
module1.singleton_class.included_modules.should include(mod)
|
48
|
+
module2.singleton_class.included_modules.should include(mod)
|
58
49
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
req, resp = stub("request"), stub("response")
|
66
|
-
subject.should_receive(:request).with(req).and_return resp
|
67
|
-
|
68
|
-
Pakada.app.call(req).should == resp
|
50
|
+
|
51
|
+
it "loads each module's controllers" do
|
52
|
+
module1.should_receive :load_controllers
|
53
|
+
module2.should_receive :load_controllers
|
54
|
+
dispatch.boot
|
69
55
|
end
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
subject.router.should_receive :rehash
|
75
|
-
subject.freeze_router
|
56
|
+
|
57
|
+
it "tries to call #routes on each module" do
|
58
|
+
module1.should_receive :routes
|
59
|
+
dispatch.boot
|
76
60
|
end
|
77
61
|
end
|
78
62
|
end
|
data/spec/module_spec.rb
CHANGED
@@ -1,282 +1,85 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Pakada::Dispatch::Module do
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
Class.new do
|
16
|
-
@module_name, @path = :foo, "/mymodule"
|
17
|
-
include Pakada::Module
|
18
|
-
include Pakada::Dispatch::Module
|
19
|
-
end.new
|
20
|
-
end
|
21
|
-
|
22
|
-
it "iterates over the module's controllers/ directory and builds a controller for each file" do
|
23
|
-
subject.load_controllers
|
24
|
-
subject.controllers[:foo].should have(1).actions
|
25
|
-
end
|
4
|
+
let(:mod) {
|
5
|
+
Class.new {
|
6
|
+
@pakada_name, @path = :foo, "/path/to"
|
7
|
+
include Pakada::Module
|
8
|
+
include Pakada::Dispatch::Module
|
9
|
+
}.new
|
10
|
+
}
|
11
|
+
|
12
|
+
context "#controller_path" do
|
13
|
+
let(:path) { mod.controller_path }
|
26
14
|
|
27
|
-
it "
|
28
|
-
|
29
|
-
subject.load_controllers
|
30
|
-
subject.should have(0).controllers
|
15
|
+
it "sets the path to the controller directory" do
|
16
|
+
path.should == Pathname.new("/path/to/controllers")
|
31
17
|
end
|
32
18
|
|
33
|
-
|
34
|
-
|
35
|
-
FakeFS::FileSystem.clear
|
36
|
-
|
37
|
-
Pakada::Module.descendants.delete :foo
|
19
|
+
it "does memoization" do
|
20
|
+
mod.controller_path.should equal(path)
|
38
21
|
end
|
39
22
|
end
|
40
23
|
|
41
|
-
|
42
|
-
|
43
|
-
it "creates an anonymous route" do
|
44
|
-
Pakada.boot
|
45
|
-
|
46
|
-
Pakada[:dispatch].router.should_receive(:add_route) do |*args|
|
47
|
-
args[0].should respond_to(:call)
|
48
|
-
args[1][:path_info].should be_a(Regexp)
|
49
|
-
args[2].should == {
|
50
|
-
:module => :dispatch,
|
51
|
-
:controller => :foo,
|
52
|
-
:action => :bar
|
53
|
-
}
|
54
|
-
args[3].should be_nil
|
55
|
-
end
|
56
|
-
Pakada[:dispatch].route "/pattern" => "foo#bar"
|
57
|
-
end
|
58
|
-
end
|
24
|
+
context "#controller(name)" do
|
25
|
+
let(:controller) { stub "controller" }
|
59
26
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
subject { Pakada[:dispatch] }
|
64
|
-
|
65
|
-
it "contains a route-pattern => target-action pair" do
|
66
|
-
subject.router.should_receive(:add_route) do |*args|
|
67
|
-
args[0].should respond_to(:call)
|
68
|
-
args[1][:path_info].should == %r{^/pattern$}
|
69
|
-
args[2].should == {
|
70
|
-
:module => :foo,
|
71
|
-
:controller => :bar,
|
72
|
-
:action => :baz
|
73
|
-
}
|
74
|
-
args[3].should == :myroute
|
75
|
-
end
|
76
|
-
subject.route :myroute, "/pattern" => "foo::bar#baz"
|
77
|
-
end
|
78
|
-
|
79
|
-
it "can contain default values for parameters" do
|
80
|
-
subject.router.should_receive(:add_route) do |*args|
|
81
|
-
args[0].should respond_to(:call)
|
82
|
-
args[1][:path_info].should == %r{^/pattern$}
|
83
|
-
args[2].should == {
|
84
|
-
:module => :dispatch,
|
85
|
-
:controller => :foo,
|
86
|
-
:action => :bar,
|
87
|
-
:key => :value
|
88
|
-
}
|
89
|
-
args[3].should == :myroute
|
90
|
-
end
|
91
|
-
subject.route :myroute, "/pattern" => "#bar", :key => :value, :controller => :foo
|
92
|
-
end
|
93
|
-
|
94
|
-
it "whose contained default values won't override the target-action" do
|
95
|
-
subject.router.should_receive(:add_route) do |*args|
|
96
|
-
args[0].should respond_to(:call)
|
97
|
-
args[1][:path_info].should be_a(Regexp)
|
98
|
-
args[2].should == {
|
99
|
-
:module => :dispatch,
|
100
|
-
:controller => :foo,
|
101
|
-
:action => :bar
|
102
|
-
}
|
103
|
-
args[3].should == :myroute
|
104
|
-
end
|
105
|
-
subject.route :myroute, "/pattern" => "foo#bar", :action => :baz
|
106
|
-
end
|
27
|
+
it "returns the named controller class if it exists" do
|
28
|
+
mod.controllers[:foo] = controller
|
29
|
+
mod.controller(:foo).should equal(controller)
|
107
30
|
end
|
108
31
|
end
|
109
32
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
it "can contain optional parts" do
|
130
|
-
subject.router.should_receive(:add_route) do |*args|
|
131
|
-
args[1][:path_info].should == %r{^(/(?<key>[a-z0-9\-_]+))?/(?<key2>[a-z0-9\-_]+)$}
|
132
|
-
end
|
133
|
-
subject.route :myroute, "(/:key)/:key2" => ""
|
33
|
+
context "#controller(name) { ... }" do
|
34
|
+
let(:block) { proc {} }
|
35
|
+
let(:controller) { stub "controller" }
|
36
|
+
let(:dispatch) { Pakada::Dispatch.new }
|
37
|
+
|
38
|
+
before {
|
39
|
+
Pakada.instance.modules[:dispatch] = dispatch
|
40
|
+
}
|
41
|
+
|
42
|
+
it "creates a controller class from the given block" do
|
43
|
+
Pakada.safety(Pakada::Dispatch::Controller)
|
44
|
+
.should_receive(:create) {|&blk|
|
45
|
+
blk.should equal(block)
|
46
|
+
controller
|
47
|
+
}
|
48
|
+
|
49
|
+
mod.controller :bar, &block
|
50
|
+
mod.controllers[:bar].should equal(controller)
|
134
51
|
end
|
135
52
|
end
|
136
53
|
|
137
|
-
|
138
|
-
before {
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
it "uses the current module's name as default :module parameter" do
|
143
|
-
subject.router.should_receive :add_route do |*args|
|
144
|
-
args[2].should == {
|
145
|
-
:module => :dispatch
|
146
|
-
}
|
147
|
-
end
|
148
|
-
subject.route "/" => ""
|
149
|
-
end
|
150
|
-
|
151
|
-
it "can consist of a controller and an action" do
|
152
|
-
subject.router.should_receive :add_route do |*args|
|
153
|
-
args[2].should == {
|
154
|
-
:module => :dispatch,
|
155
|
-
:controller => :foo,
|
156
|
-
:action => :bar
|
157
|
-
}
|
158
|
-
end
|
159
|
-
subject.route "/" => "foo#bar"
|
160
|
-
end
|
54
|
+
context "#load_controllers" do
|
55
|
+
before {
|
56
|
+
path = Pathname.new(__FILE__).parent.join("controllers")
|
57
|
+
mod.stub :controller_path => Pathname.new(path)
|
58
|
+
}
|
161
59
|
|
162
|
-
it "
|
163
|
-
|
164
|
-
|
165
|
-
:module => :dispatch,
|
166
|
-
:action => :bar
|
167
|
-
}
|
168
|
-
end
|
169
|
-
subject.route "/" => "#bar"
|
170
|
-
end
|
171
|
-
|
172
|
-
it "can consist of a controller" do
|
173
|
-
subject.router.should_receive :add_route do |*args|
|
174
|
-
args[2].should == {
|
175
|
-
:module => :dispatch,
|
176
|
-
:controller => :foo
|
177
|
-
}
|
178
|
-
end
|
179
|
-
subject.route "/" => "foo"
|
180
|
-
end
|
181
|
-
|
182
|
-
it "can consist of a module" do
|
183
|
-
subject.router.should_receive :add_route do |*args|
|
184
|
-
args[2].should == {
|
185
|
-
:module => :mymodule,
|
186
|
-
}
|
187
|
-
end
|
188
|
-
subject.route "/" => "mymodule::"
|
189
|
-
end
|
190
|
-
|
191
|
-
it "can consist of a module and a controller" do
|
192
|
-
subject.router.should_receive :add_route do |*args|
|
193
|
-
args[2].should == {
|
194
|
-
:module => :mymodule,
|
195
|
-
:controller => :foo
|
196
|
-
}
|
197
|
-
end
|
198
|
-
subject.route "/" => "mymodule::foo"
|
199
|
-
end
|
200
|
-
|
201
|
-
it "can consist of a module and an action" do
|
202
|
-
subject.router.should_receive :add_route do |*args|
|
203
|
-
args[2].should == {
|
204
|
-
:module => :mymodule,
|
205
|
-
:action => :bar
|
206
|
-
}
|
207
|
-
end
|
208
|
-
subject.route "/" => "mymodule::#bar"
|
60
|
+
it "creates a controller class from each file in controller path" do
|
61
|
+
mod.load_controllers
|
62
|
+
mod.controller(:foo).action(:bar).should respond_to(:call)
|
209
63
|
end
|
210
64
|
end
|
211
65
|
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
end
|
228
|
-
subject.route route_name, route => ""
|
229
|
-
end
|
230
|
-
|
231
|
-
before { Pakada.boot }
|
232
|
-
|
233
|
-
subject { Pakada[:dispatch] }
|
234
|
-
|
235
|
-
it "splits splat parameters" do
|
236
|
-
stub_action "/*something", :something => "/some///thing/123" do |env|
|
237
|
-
env["pakada.dispatch.params"][:something].should == ["some", "thing", "123"]
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
it "makes sure the module, controller and action params are symbols" do
|
242
|
-
stub_action "/", {
|
243
|
-
:module => subject.module_name.to_s,
|
244
|
-
:controller => "bar",
|
245
|
-
:action => "baz"
|
246
|
-
} do |env|
|
247
|
-
[:module, :controller, :action].each do |k|
|
248
|
-
env["pakada.dispatch.params"][k].should be_kind_of(Symbol)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
it "calls the respective action" do
|
254
|
-
called = false
|
255
|
-
stub_action("/") {|env| called = true }
|
256
|
-
|
257
|
-
called.should be_true
|
258
|
-
end
|
259
|
-
|
260
|
-
it "returns an X-Cascade: pass response if the module or controller doesn't exist" do
|
261
|
-
subject.router.should_receive :add_route do |app, *nothing|
|
262
|
-
env = {"rack.routing_args" => {
|
263
|
-
:module => :dispatch,
|
264
|
-
:controller => :bar,
|
265
|
-
:action => :foofoofoo
|
266
|
-
}}
|
267
|
-
app.call(env).should == [404, {"X-Cascade" => "pass"}, []]
|
268
|
-
end
|
269
|
-
subject.route "/" => ""
|
270
|
-
end
|
271
|
-
|
272
|
-
it "puts the matched route's name into the environment if it has a name" do
|
273
|
-
stub_action "/with_name", {}, :myroute do |env|
|
274
|
-
env["pakada.dispatch.route"].should == :myroute
|
275
|
-
end
|
66
|
+
context "#route(name, pattern) {|env| ... }" do
|
67
|
+
let(:dispatch) { Pakada::Dispatch.new }
|
68
|
+
let(:route) { stub "route" }
|
69
|
+
let(:pattern) { stub "pattern" }
|
70
|
+
let(:name) { stub "name" }
|
71
|
+
let(:block) { proc {} }
|
72
|
+
|
73
|
+
before {
|
74
|
+
Pakada.instance.modules[:dispatch] = dispatch
|
75
|
+
}
|
76
|
+
|
77
|
+
it "adds the specified route to the router" do
|
78
|
+
dispatch.router.should_receive(:add).with(pattern) { route }
|
79
|
+
route.should_receive(:name).with(name) { route }
|
80
|
+
route.should_receive(:to) {|&blk| block.should equal(blk) }
|
276
81
|
|
277
|
-
|
278
|
-
env["pakada.dispatch.route"].should be_nil
|
279
|
-
end
|
82
|
+
mod.route name, pattern, &block
|
280
83
|
end
|
281
84
|
end
|
282
85
|
end
|