roda-cj 0.9.1
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.
- checksums.yaml +7 -0
- data/CHANGELOG +13 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +715 -0
- data/Rakefile +124 -0
- data/lib/roda/plugins/all_verbs.rb +48 -0
- data/lib/roda/plugins/default_headers.rb +50 -0
- data/lib/roda/plugins/error_handler.rb +69 -0
- data/lib/roda/plugins/flash.rb +108 -0
- data/lib/roda/plugins/h.rb +24 -0
- data/lib/roda/plugins/halt.rb +79 -0
- data/lib/roda/plugins/header_matchers.rb +57 -0
- data/lib/roda/plugins/hooks.rb +106 -0
- data/lib/roda/plugins/indifferent_params.rb +47 -0
- data/lib/roda/plugins/middleware.rb +88 -0
- data/lib/roda/plugins/multi_route.rb +77 -0
- data/lib/roda/plugins/not_found.rb +62 -0
- data/lib/roda/plugins/pass.rb +34 -0
- data/lib/roda/plugins/render.rb +217 -0
- data/lib/roda/plugins/streaming.rb +165 -0
- data/lib/roda/version.rb +3 -0
- data/lib/roda.rb +610 -0
- data/spec/composition_spec.rb +19 -0
- data/spec/env_spec.rb +11 -0
- data/spec/integration_spec.rb +63 -0
- data/spec/matchers_spec.rb +683 -0
- data/spec/module_spec.rb +29 -0
- data/spec/opts_spec.rb +42 -0
- data/spec/plugin/all_verbs_spec.rb +29 -0
- data/spec/plugin/default_headers_spec.rb +63 -0
- data/spec/plugin/error_handler_spec.rb +67 -0
- data/spec/plugin/flash_spec.rb +123 -0
- data/spec/plugin/h_spec.rb +13 -0
- data/spec/plugin/halt_spec.rb +62 -0
- data/spec/plugin/header_matchers_spec.rb +61 -0
- data/spec/plugin/hooks_spec.rb +97 -0
- data/spec/plugin/indifferent_params_spec.rb +13 -0
- data/spec/plugin/middleware_spec.rb +52 -0
- data/spec/plugin/multi_route_spec.rb +98 -0
- data/spec/plugin/not_found_spec.rb +99 -0
- data/spec/plugin/pass_spec.rb +23 -0
- data/spec/plugin/render_spec.rb +148 -0
- data/spec/plugin/streaming_spec.rb +52 -0
- data/spec/plugin_spec.rb +61 -0
- data/spec/redirect_spec.rb +24 -0
- data/spec/request_spec.rb +55 -0
- data/spec/response_spec.rb +131 -0
- data/spec/session_spec.rb +35 -0
- data/spec/spec_helper.rb +89 -0
- data/spec/version_spec.rb +8 -0
- metadata +136 -0
@@ -0,0 +1,683 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "capturing" do
|
4
|
+
it "doesn't yield the verb" do
|
5
|
+
app do |r|
|
6
|
+
r.get do |*args|
|
7
|
+
args.size.to_s
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
body.should == '0'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "doesn't yield the path" do
|
15
|
+
app do |r|
|
16
|
+
r.get "home" do |*args|
|
17
|
+
args.size.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
body('/home').should == '0'
|
22
|
+
end
|
23
|
+
|
24
|
+
it "yields the segment" do
|
25
|
+
app do |r|
|
26
|
+
r.get "user", :id do |id|
|
27
|
+
id
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
body("/user/johndoe").should == 'johndoe'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "yields a number" do
|
35
|
+
app do |r|
|
36
|
+
r.get "user", :id do |id|
|
37
|
+
id
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
body("/user/101").should == '101'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "yields a segment per nested block" do
|
45
|
+
app do |r|
|
46
|
+
r.on :one do |one|
|
47
|
+
r.on :two do |two|
|
48
|
+
r.on :three do |three|
|
49
|
+
one + two + three
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
body("/one/two/three").should == "onetwothree"
|
56
|
+
end
|
57
|
+
|
58
|
+
it "regex captures in regex format" do
|
59
|
+
app do |r|
|
60
|
+
r.get %r{posts/(\d+)-(.*)} do |id, slug|
|
61
|
+
id + slug
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
body("/posts/123-postal-service").should == "123postal-service"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe "r.is" do
|
70
|
+
it "ensures the patch is matched fully" do
|
71
|
+
app do |r|
|
72
|
+
r.is "" do
|
73
|
+
"+1"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
body.should == '+1'
|
78
|
+
status('//').should == 404
|
79
|
+
end
|
80
|
+
|
81
|
+
it "handles no arguments" do
|
82
|
+
app do |r|
|
83
|
+
r.on "" do
|
84
|
+
r.is do
|
85
|
+
"+1"
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
body.should == '+1'
|
91
|
+
status('//').should == 404
|
92
|
+
end
|
93
|
+
|
94
|
+
it "matches strings" do
|
95
|
+
app do |r|
|
96
|
+
r.is "123" do
|
97
|
+
"+1"
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
body("/123").should == '+1'
|
102
|
+
status("/123/").should == 404
|
103
|
+
end
|
104
|
+
|
105
|
+
it "matches regexps" do
|
106
|
+
app do |r|
|
107
|
+
r.is /(\w+)/ do |id|
|
108
|
+
id
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
body("/123").should == '123'
|
113
|
+
status("/123/").should == 404
|
114
|
+
end
|
115
|
+
|
116
|
+
it "matches segments" do
|
117
|
+
app do |r|
|
118
|
+
r.is :id do |id|
|
119
|
+
id
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
body("/123").should == '123'
|
124
|
+
status("/123/").should == 404
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "matchers" do
|
129
|
+
it "should handle string with embedded param" do
|
130
|
+
app do |r|
|
131
|
+
r.on "posts/:id" do |id|
|
132
|
+
id
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
body('/posts/123').should == '123'
|
137
|
+
status('/post/123').should == 404
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should handle multiple params in single string" do
|
141
|
+
app do |r|
|
142
|
+
r.on "u/:uid/posts/:id" do |uid, id|
|
143
|
+
uid + id
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
body("/u/jdoe/posts/123").should == 'jdoe123'
|
148
|
+
status("/u/jdoe/pots/123").should == 404
|
149
|
+
end
|
150
|
+
|
151
|
+
it "should escape regexp metacharaters in string" do
|
152
|
+
app do |r|
|
153
|
+
r.on "u/:uid/posts?/:id" do |uid, id|
|
154
|
+
uid + id
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
body("/u/jdoe/posts?/123").should == 'jdoe123'
|
159
|
+
status("/u/jdoe/post/123").should == 404
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should handle colons by themselves" do
|
163
|
+
app do |r|
|
164
|
+
r.on "u/:/:uid/posts/::id" do |uid, id|
|
165
|
+
uid + id
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
body("/u/:/jdoe/posts/:123").should == 'jdoe123'
|
170
|
+
status("/u/a/jdoe/post/b123").should == 404
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should handle regexes and nesting" do
|
174
|
+
app do |r|
|
175
|
+
r.on(/u\/(\w+)/) do |uid|
|
176
|
+
r.on(/posts\/(\d+)/) do |id|
|
177
|
+
uid + id
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
body("/u/jdoe/posts/123").should == 'jdoe123'
|
183
|
+
status("/u/jdoe/pots/123").should == 404
|
184
|
+
end
|
185
|
+
|
186
|
+
it "should handle regex nesting colon param style" do
|
187
|
+
app do |r|
|
188
|
+
r.on(/u:(\w+)/) do |uid|
|
189
|
+
r.on(/posts:(\d+)/) do |id|
|
190
|
+
uid + id
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
body("/u:jdoe/posts:123").should == 'jdoe123'
|
196
|
+
status("/u:jdoe/poss:123").should == 404
|
197
|
+
end
|
198
|
+
|
199
|
+
it "symbol matching" do
|
200
|
+
app do |r|
|
201
|
+
r.on "user", :id do |uid|
|
202
|
+
r.on "posts", :pid do |id|
|
203
|
+
uid + id
|
204
|
+
end
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
body("/user/jdoe/posts/123").should == 'jdoe123'
|
209
|
+
status("/user/jdoe/pots/123").should == 404
|
210
|
+
end
|
211
|
+
|
212
|
+
it "paths and numbers" do
|
213
|
+
app do |r|
|
214
|
+
r.on "about" do
|
215
|
+
r.on :one, :two do |one, two|
|
216
|
+
one + two
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
body("/about/1/2").should == '12'
|
222
|
+
status("/about/1").should == 404
|
223
|
+
end
|
224
|
+
|
225
|
+
it "paths and decimals" do
|
226
|
+
app do |r|
|
227
|
+
r.on "about" do
|
228
|
+
r.on(/(\d+)/) do |one|
|
229
|
+
one
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
|
234
|
+
body("/about/1").should == '1'
|
235
|
+
status("/about/1.2").should == 404
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should allow arrays to match any value" do
|
239
|
+
app do |r|
|
240
|
+
r.on [/(\d+)/, /\d+(bar)?/] do |id|
|
241
|
+
id
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
body('/123').should == '123'
|
246
|
+
body('/123bar').should == 'bar'
|
247
|
+
status('/123bard').should == 404
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should have array capture match string if match" do
|
251
|
+
app do |r|
|
252
|
+
r.on %w'p q' do |id|
|
253
|
+
id
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
body('/p').should == 'p'
|
258
|
+
body('/q').should == 'q'
|
259
|
+
status('/r').should == 404
|
260
|
+
end
|
261
|
+
end
|
262
|
+
|
263
|
+
describe "r.on" do
|
264
|
+
it "executes on no arguments" do
|
265
|
+
app do |r|
|
266
|
+
r.on do
|
267
|
+
"+1"
|
268
|
+
end
|
269
|
+
end
|
270
|
+
|
271
|
+
body.should == '+1'
|
272
|
+
end
|
273
|
+
|
274
|
+
it "executes on true" do
|
275
|
+
app do |r|
|
276
|
+
r.on true do
|
277
|
+
"+1"
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
body.should == '+1'
|
282
|
+
end
|
283
|
+
|
284
|
+
it "executes on non-false" do
|
285
|
+
app do |r|
|
286
|
+
r.on "123" do
|
287
|
+
"+1"
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
body("/123").should == '+1'
|
292
|
+
end
|
293
|
+
|
294
|
+
it "ensures SCRIPT_NAME and PATH_INFO are reverted" do
|
295
|
+
app do |r|
|
296
|
+
r.on lambda { r.env["SCRIPT_NAME"] = "/hello"; false } do
|
297
|
+
"Unreachable"
|
298
|
+
end
|
299
|
+
|
300
|
+
r.on do
|
301
|
+
r.env["SCRIPT_NAME"] + ':' + r.env["PATH_INFO"]
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
body("/hello").should == ':/hello'
|
306
|
+
end
|
307
|
+
|
308
|
+
it "doesn't mutate SCRIPT_NAME or PATH_INFO after request is returned" do
|
309
|
+
app do |r|
|
310
|
+
r.on 'login', 'foo' do
|
311
|
+
"Unreachable"
|
312
|
+
end
|
313
|
+
|
314
|
+
r.on do
|
315
|
+
r.env["SCRIPT_NAME"] + ':' + r.env["PATH_INFO"]
|
316
|
+
end
|
317
|
+
end
|
318
|
+
|
319
|
+
pi, sn = '/login', ''
|
320
|
+
env = {"REQUEST_METHOD" => "GET", "PATH_INFO" => pi, "SCRIPT_NAME" => sn}
|
321
|
+
app.call(env)[2].join.should == ":/login"
|
322
|
+
env["PATH_INFO"].should equal(pi)
|
323
|
+
env["SCRIPT_NAME"].should equal(sn)
|
324
|
+
end
|
325
|
+
|
326
|
+
it "skips consecutive matches" do
|
327
|
+
app do |r|
|
328
|
+
r.on do
|
329
|
+
"foo"
|
330
|
+
end
|
331
|
+
|
332
|
+
r.on do
|
333
|
+
"bar"
|
334
|
+
end
|
335
|
+
end
|
336
|
+
|
337
|
+
body.should == "foo"
|
338
|
+
end
|
339
|
+
|
340
|
+
it "finds first match available" do
|
341
|
+
app do |r|
|
342
|
+
r.on false do
|
343
|
+
"foo"
|
344
|
+
end
|
345
|
+
|
346
|
+
r.on do
|
347
|
+
"bar"
|
348
|
+
end
|
349
|
+
end
|
350
|
+
|
351
|
+
body.should == "bar"
|
352
|
+
end
|
353
|
+
|
354
|
+
it "reverts a half-met matcher" do
|
355
|
+
app do |r|
|
356
|
+
r.on "post", false do
|
357
|
+
"Should be unmet"
|
358
|
+
end
|
359
|
+
|
360
|
+
r.on do
|
361
|
+
r.env["SCRIPT_NAME"] + ':' + r.env["PATH_INFO"]
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
body("/hello").should == ':/hello'
|
366
|
+
end
|
367
|
+
|
368
|
+
it "doesn't write to body if body already written to" do
|
369
|
+
app do |r|
|
370
|
+
r.on do
|
371
|
+
response.write "a"
|
372
|
+
"b"
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
376
|
+
body.should == 'a'
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
describe "param! matcher" do
|
381
|
+
it "should yield a param only if given and not empty" do
|
382
|
+
app do |r|
|
383
|
+
r.get "signup", :param! => "email" do |email|
|
384
|
+
email
|
385
|
+
end
|
386
|
+
|
387
|
+
r.on do
|
388
|
+
"No email"
|
389
|
+
end
|
390
|
+
end
|
391
|
+
|
392
|
+
io = StringIO.new
|
393
|
+
body("/signup", "rack.input" => io, "QUERY_STRING" => "email=john@doe.com").should == 'john@doe.com'
|
394
|
+
body("/signup", "rack.input" => io, "QUERY_STRING" => "").should == 'No email'
|
395
|
+
body("/signup", "rack.input" => io, "QUERY_STRING" => "email=").should == 'No email'
|
396
|
+
end
|
397
|
+
end
|
398
|
+
|
399
|
+
describe "param matcher" do
|
400
|
+
it "should yield a param only if given" do
|
401
|
+
app do |r|
|
402
|
+
r.get "signup", :param=>"email" do |email|
|
403
|
+
email
|
404
|
+
end
|
405
|
+
|
406
|
+
r.on do
|
407
|
+
"No email"
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
io = StringIO.new
|
412
|
+
body("/signup", "rack.input" => io, "QUERY_STRING" => "email=john@doe.com").should == 'john@doe.com'
|
413
|
+
body("/signup", "rack.input" => io, "QUERY_STRING" => "").should == 'No email'
|
414
|
+
body("/signup", "rack.input" => io, "QUERY_STRING" => "email=").should == ''
|
415
|
+
end
|
416
|
+
end
|
417
|
+
|
418
|
+
describe "path matchers" do
|
419
|
+
it "one level path" do
|
420
|
+
app do |r|
|
421
|
+
r.on "about" do
|
422
|
+
"About"
|
423
|
+
end
|
424
|
+
end
|
425
|
+
|
426
|
+
body('/about').should == "About"
|
427
|
+
status("/abot").should == 404
|
428
|
+
end
|
429
|
+
|
430
|
+
it "two level nested paths" do
|
431
|
+
app do |r|
|
432
|
+
r.on "about" do
|
433
|
+
r.on "1" do
|
434
|
+
"+1"
|
435
|
+
end
|
436
|
+
|
437
|
+
r.on "2" do
|
438
|
+
"+2"
|
439
|
+
end
|
440
|
+
end
|
441
|
+
end
|
442
|
+
|
443
|
+
body('/about/1').should == "+1"
|
444
|
+
body('/about/2').should == "+2"
|
445
|
+
status('/about/3').should == 404
|
446
|
+
end
|
447
|
+
|
448
|
+
it "two level inlined paths" do
|
449
|
+
app do |r|
|
450
|
+
r.on "a/b" do
|
451
|
+
"ab"
|
452
|
+
end
|
453
|
+
end
|
454
|
+
|
455
|
+
body('/a/b').should == "ab"
|
456
|
+
status('/a/d').should == 404
|
457
|
+
end
|
458
|
+
|
459
|
+
it "a path with some regex captures" do
|
460
|
+
app do |r|
|
461
|
+
r.on /user(\d+)/ do |uid|
|
462
|
+
uid
|
463
|
+
end
|
464
|
+
end
|
465
|
+
|
466
|
+
body('/user123').should == "123"
|
467
|
+
status('/useradf').should == 404
|
468
|
+
end
|
469
|
+
|
470
|
+
it "matching the root with a string" do
|
471
|
+
app do |r|
|
472
|
+
r.is "" do
|
473
|
+
"Home"
|
474
|
+
end
|
475
|
+
end
|
476
|
+
|
477
|
+
body.should == 'Home'
|
478
|
+
status("//").should == 404
|
479
|
+
status("/foo").should == 404
|
480
|
+
end
|
481
|
+
|
482
|
+
it "matching the root with the root method" do
|
483
|
+
app do |r|
|
484
|
+
r.root do
|
485
|
+
"Home"
|
486
|
+
end
|
487
|
+
end
|
488
|
+
|
489
|
+
body.should == 'Home'
|
490
|
+
status("//").should == 404
|
491
|
+
status("/foo").should == 404
|
492
|
+
end
|
493
|
+
|
494
|
+
it "matching the root with the root method and request method symbol" do
|
495
|
+
app do |r|
|
496
|
+
r.root(:get) do
|
497
|
+
"Home"
|
498
|
+
end
|
499
|
+
end
|
500
|
+
|
501
|
+
body.should == 'Home'
|
502
|
+
status("//").should == 404
|
503
|
+
status('REQUEST_METHOD'=>"POST").should == 404
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
describe "root/empty segment matching" do
|
508
|
+
it "matching an empty segment" do
|
509
|
+
app do |r|
|
510
|
+
r.on "" do
|
511
|
+
r.path
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
body.should == '/'
|
516
|
+
status("/foo").should == 404
|
517
|
+
end
|
518
|
+
|
519
|
+
it "nested empty segments" do
|
520
|
+
app do |r|
|
521
|
+
r.on "" do
|
522
|
+
r.on "" do
|
523
|
+
r.on "1" do
|
524
|
+
r.path
|
525
|
+
end
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
body("///1").should == '///1'
|
531
|
+
status("/1").should == 404
|
532
|
+
status("//1").should == 404
|
533
|
+
end
|
534
|
+
|
535
|
+
it "/events/? scenario" do
|
536
|
+
a = app do |r|
|
537
|
+
r.on "" do
|
538
|
+
"Hooray"
|
539
|
+
end
|
540
|
+
|
541
|
+
r.is do
|
542
|
+
"Foo"
|
543
|
+
end
|
544
|
+
end
|
545
|
+
|
546
|
+
app(:new) do |r|
|
547
|
+
r.on "events" do
|
548
|
+
r.run a
|
549
|
+
end
|
550
|
+
end
|
551
|
+
|
552
|
+
body("/events").should == 'Foo'
|
553
|
+
body("/events/").should == 'Hooray'
|
554
|
+
status("/events/foo").should == 404
|
555
|
+
end
|
556
|
+
end
|
557
|
+
|
558
|
+
describe "segment handling" do
|
559
|
+
before do
|
560
|
+
app do |r|
|
561
|
+
r.on "post" do
|
562
|
+
r.on :id do |id|
|
563
|
+
id
|
564
|
+
end
|
565
|
+
end
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
it "matches numeric ids" do
|
570
|
+
body('/post/1').should == '1'
|
571
|
+
end
|
572
|
+
|
573
|
+
it "matches decimal numbers" do
|
574
|
+
body('/post/1.1').should == '1.1'
|
575
|
+
end
|
576
|
+
|
577
|
+
it "matches slugs" do
|
578
|
+
body('/post/my-blog-post-about-cuba').should == 'my-blog-post-about-cuba'
|
579
|
+
end
|
580
|
+
|
581
|
+
it "matches only the first segment available" do
|
582
|
+
body('/post/one/two/three').should == 'one'
|
583
|
+
end
|
584
|
+
end
|
585
|
+
|
586
|
+
describe "request verb methods" do
|
587
|
+
it "executes if verb matches" do
|
588
|
+
app do |r|
|
589
|
+
r.get do
|
590
|
+
"g"
|
591
|
+
end
|
592
|
+
r.post do
|
593
|
+
"p"
|
594
|
+
end
|
595
|
+
end
|
596
|
+
|
597
|
+
body.should == 'g'
|
598
|
+
body('REQUEST_METHOD'=>'POST').should == 'p'
|
599
|
+
end
|
600
|
+
|
601
|
+
it "requires exact match if given arguments" do
|
602
|
+
app do |r|
|
603
|
+
r.get "" do
|
604
|
+
"g"
|
605
|
+
end
|
606
|
+
r.post "" do
|
607
|
+
"p"
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
611
|
+
body.should == 'g'
|
612
|
+
body('REQUEST_METHOD'=>'POST').should == 'p'
|
613
|
+
status("/a").should == 404
|
614
|
+
status("/a", 'REQUEST_METHOD'=>'POST').should == 404
|
615
|
+
end
|
616
|
+
|
617
|
+
it "does not require exact match if given arguments" do
|
618
|
+
app do |r|
|
619
|
+
r.get do
|
620
|
+
r.is "" do
|
621
|
+
"g"
|
622
|
+
end
|
623
|
+
|
624
|
+
"get"
|
625
|
+
end
|
626
|
+
r.post do
|
627
|
+
r.is "" do
|
628
|
+
"p"
|
629
|
+
end
|
630
|
+
|
631
|
+
"post"
|
632
|
+
end
|
633
|
+
end
|
634
|
+
|
635
|
+
body.should == 'g'
|
636
|
+
body('REQUEST_METHOD'=>'POST').should == 'p'
|
637
|
+
body("/a").should == 'get'
|
638
|
+
body("/a", 'REQUEST_METHOD'=>'POST').should == 'post'
|
639
|
+
end
|
640
|
+
end
|
641
|
+
|
642
|
+
describe "extension matcher" do
|
643
|
+
it "should match given file extensions" do
|
644
|
+
app do |r|
|
645
|
+
r.on "styles" do
|
646
|
+
r.on :extension=>"css" do |file|
|
647
|
+
file
|
648
|
+
end
|
649
|
+
end
|
650
|
+
end
|
651
|
+
|
652
|
+
body("/styles/reset.css").should == 'reset'
|
653
|
+
status("/styles/reset.bar").should == 404
|
654
|
+
end
|
655
|
+
end
|
656
|
+
|
657
|
+
describe "method matcher" do
|
658
|
+
it "should match given request types" do
|
659
|
+
app do |r|
|
660
|
+
r.is "", :method=>:get do
|
661
|
+
"foo"
|
662
|
+
end
|
663
|
+
r.is "", :method=>[:patch, :post] do
|
664
|
+
"bar"
|
665
|
+
end
|
666
|
+
end
|
667
|
+
|
668
|
+
body("REQUEST_METHOD"=>"GET").should == 'foo'
|
669
|
+
body("REQUEST_METHOD"=>"PATCH").should == 'bar'
|
670
|
+
body("REQUEST_METHOD"=>"POST").should == 'bar'
|
671
|
+
status("REQUEST_METHOD"=>"DELETE").should == 404
|
672
|
+
end
|
673
|
+
end
|
674
|
+
|
675
|
+
describe "route block that returns string" do
|
676
|
+
it "should be treated as if an on block returned string" do
|
677
|
+
app do |r|
|
678
|
+
"+1"
|
679
|
+
end
|
680
|
+
|
681
|
+
body.should == '+1'
|
682
|
+
end
|
683
|
+
end
|
data/spec/module_spec.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "Roda.request_module and .response_module" do
|
4
|
+
it "should include given module in request or response class" do
|
5
|
+
app(:bare) do
|
6
|
+
request_module(Module.new{def h; halt response.finish end})
|
7
|
+
response_module(Module.new{def finish; [1, {}, []] end})
|
8
|
+
|
9
|
+
route do |r|
|
10
|
+
r.h
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
req.should == [1, {}, []]
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept blocks and turn them into modules" do
|
18
|
+
app(:bare) do
|
19
|
+
request_module{def h; halt response.finish end}
|
20
|
+
response_module{def finish; [1, {}, []] end}
|
21
|
+
|
22
|
+
route do |r|
|
23
|
+
r.h
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
req.should == [1, {}, []]
|
28
|
+
end
|
29
|
+
end
|