pakada-dispatch 0.1.1 → 0.2.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/.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
|