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,98 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "multi_route plugin" do
|
4
|
+
before do
|
5
|
+
app(:bare) do
|
6
|
+
plugin :multi_route
|
7
|
+
|
8
|
+
route(:get) do |r|
|
9
|
+
r.is "" do
|
10
|
+
"get"
|
11
|
+
end
|
12
|
+
|
13
|
+
r.is "a" do
|
14
|
+
"geta"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
route(:post) do |r|
|
19
|
+
r.is "" do
|
20
|
+
"post"
|
21
|
+
end
|
22
|
+
|
23
|
+
r.is "a" do
|
24
|
+
"posta"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
route do |r|
|
29
|
+
r.get do
|
30
|
+
route(:get)
|
31
|
+
|
32
|
+
r.is "b" do
|
33
|
+
"getb"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
r.post do
|
37
|
+
route(:post)
|
38
|
+
|
39
|
+
r.is "b" do
|
40
|
+
"postb"
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "adds named routing support" do
|
48
|
+
body.should == 'get'
|
49
|
+
body('REQUEST_METHOD'=>'POST').should == 'post'
|
50
|
+
body('/a').should == 'geta'
|
51
|
+
body('/a', 'REQUEST_METHOD'=>'POST').should == 'posta'
|
52
|
+
body('/b').should == 'getb'
|
53
|
+
body('/b', 'REQUEST_METHOD'=>'POST').should == 'postb'
|
54
|
+
status('/c').should == 404
|
55
|
+
status('/c', 'REQUEST_METHOD'=>'POST').should == 404
|
56
|
+
end
|
57
|
+
|
58
|
+
it "handles loading the plugin multiple times correctly" do
|
59
|
+
app.plugin :multi_route
|
60
|
+
body.should == 'get'
|
61
|
+
body('REQUEST_METHOD'=>'POST').should == 'post'
|
62
|
+
body('/a').should == 'geta'
|
63
|
+
body('/a', 'REQUEST_METHOD'=>'POST').should == 'posta'
|
64
|
+
body('/b').should == 'getb'
|
65
|
+
body('/b', 'REQUEST_METHOD'=>'POST').should == 'postb'
|
66
|
+
status('/c').should == 404
|
67
|
+
status('/c', 'REQUEST_METHOD'=>'POST').should == 404
|
68
|
+
end
|
69
|
+
|
70
|
+
it "handles subclassing correctly" do
|
71
|
+
@app = Class.new(@app)
|
72
|
+
@app.route do |r|
|
73
|
+
r.get do
|
74
|
+
route(:post)
|
75
|
+
|
76
|
+
r.is "b" do
|
77
|
+
"1b"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
r.post do
|
81
|
+
route(:get)
|
82
|
+
|
83
|
+
r.is "b" do
|
84
|
+
"2b"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
body.should == 'post'
|
90
|
+
body('REQUEST_METHOD'=>'POST').should == 'get'
|
91
|
+
body('/a').should == 'posta'
|
92
|
+
body('/a', 'REQUEST_METHOD'=>'POST').should == 'geta'
|
93
|
+
body('/b').should == '1b'
|
94
|
+
body('/b', 'REQUEST_METHOD'=>'POST').should == '2b'
|
95
|
+
status('/c').should == 404
|
96
|
+
status('/c', 'REQUEST_METHOD'=>'POST').should == 404
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "not_found plugin" do
|
4
|
+
it "executes on no arguments" do
|
5
|
+
app(:bare) do
|
6
|
+
plugin :not_found
|
7
|
+
|
8
|
+
not_found do
|
9
|
+
"not found"
|
10
|
+
end
|
11
|
+
|
12
|
+
route do |r|
|
13
|
+
r.on "a" do
|
14
|
+
"found"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
body.should == 'not found'
|
20
|
+
status.should == 404
|
21
|
+
body("/a").should == 'found'
|
22
|
+
status("/a").should == 200
|
23
|
+
end
|
24
|
+
|
25
|
+
it "allows overriding status inside not_found" do
|
26
|
+
app(:bare) do
|
27
|
+
plugin :not_found
|
28
|
+
|
29
|
+
not_found do
|
30
|
+
response.status = 403
|
31
|
+
"not found"
|
32
|
+
end
|
33
|
+
|
34
|
+
route do |r|
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
status.should == 403
|
39
|
+
end
|
40
|
+
|
41
|
+
it "does not modify behavior if not_found is not called" do
|
42
|
+
app(:not_found) do |r|
|
43
|
+
r.on "a" do
|
44
|
+
"found"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
body.should == ''
|
49
|
+
body("/a").should == 'found'
|
50
|
+
end
|
51
|
+
|
52
|
+
it "can set not_found via the plugin block" do
|
53
|
+
app(:bare) do
|
54
|
+
plugin :not_found do
|
55
|
+
"not found"
|
56
|
+
end
|
57
|
+
|
58
|
+
route do |r|
|
59
|
+
r.on "a" do
|
60
|
+
"found"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
body.should == 'not found'
|
66
|
+
body("/a").should == 'found'
|
67
|
+
end
|
68
|
+
|
69
|
+
it "does not modify behavior if body is not an array" do
|
70
|
+
app(:bare) do
|
71
|
+
plugin :not_found do
|
72
|
+
"not found"
|
73
|
+
end
|
74
|
+
|
75
|
+
o = Object.new
|
76
|
+
def o.join() '' end
|
77
|
+
route do |r|
|
78
|
+
r.halt [404, {}, o]
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
body.should == ''
|
83
|
+
end
|
84
|
+
|
85
|
+
it "does not modify behavior if body is not an empty array" do
|
86
|
+
app(:bare) do
|
87
|
+
plugin :not_found do
|
88
|
+
"not found"
|
89
|
+
end
|
90
|
+
|
91
|
+
route do |r|
|
92
|
+
response.status = 404
|
93
|
+
response.write 'a'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
body.should == 'a'
|
98
|
+
end
|
99
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "pass plugin" do
|
4
|
+
it "executes on no arguments" do
|
5
|
+
app(:pass) do |r|
|
6
|
+
r.on :id do |id|
|
7
|
+
r.pass if id == 'foo'
|
8
|
+
id
|
9
|
+
end
|
10
|
+
|
11
|
+
r.on ":x/:y" do |x, y|
|
12
|
+
x + y
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
body("/a").should == 'a'
|
17
|
+
body("/a/b").should == 'a'
|
18
|
+
body("/foo/a").should == 'fooa'
|
19
|
+
body("/foo/a/b").should == 'fooa'
|
20
|
+
status("/foo").should == 404
|
21
|
+
status.should == 404
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'tilt'
|
5
|
+
rescue LoadError
|
6
|
+
warn "tilt not installed, skipping render plugin test"
|
7
|
+
else
|
8
|
+
describe "render plugin" do
|
9
|
+
before do
|
10
|
+
app(:bare) do
|
11
|
+
plugin :render
|
12
|
+
render_opts[:views] = "./spec/views"
|
13
|
+
|
14
|
+
route do |r|
|
15
|
+
r.on "home" do
|
16
|
+
view("home", :locals=>{:name => "Agent Smith", :title => "Home"}, :layout_opts=>{:locals=>{:title=>"Home"}})
|
17
|
+
end
|
18
|
+
|
19
|
+
r.on "about" do
|
20
|
+
render("about", :locals=>{:title => "About Roda"})
|
21
|
+
end
|
22
|
+
|
23
|
+
r.on "inline" do
|
24
|
+
view(:inline=>"Hello <%= name %>", :locals=>{:name => "Agent Smith"}, :layout=>nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
r.on "path" do
|
28
|
+
render(:path=>"./spec/views/about.erb", :locals=>{:title => "Path"}, :layout_opts=>{:locals=>{:title=>"Home"}})
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "default actions" do
|
35
|
+
body("/about").strip.should == "<h1>About Roda</h1>"
|
36
|
+
body("/home").strip.should == "<title>Roda: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
|
37
|
+
body("/inline").strip.should == "Hello Agent Smith"
|
38
|
+
body("/path").strip.should == "<h1>Path</h1>"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "with str as engine" do
|
42
|
+
app.render_opts[:engine] = "str"
|
43
|
+
body("/about").strip.should == "<h1>About Roda</h1>"
|
44
|
+
body("/home").strip.should == "<title>Roda: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
|
45
|
+
body("/inline").strip.should == "Hello <%= name %>"
|
46
|
+
end
|
47
|
+
|
48
|
+
it "with str as ext" do
|
49
|
+
app.render_opts[:ext] = "str"
|
50
|
+
body("/about").strip.should == "<h1>About Roda</h1>"
|
51
|
+
body("/home").strip.should == "<title>Roda: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
|
52
|
+
body("/inline").strip.should == "Hello Agent Smith"
|
53
|
+
end
|
54
|
+
|
55
|
+
it "custom default layout support" do
|
56
|
+
app.render_opts[:layout] = "layout-alternative"
|
57
|
+
body("/home").strip.should == "<title>Alternative Layout: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
describe "render plugin" do
|
62
|
+
it "simple layout support" do
|
63
|
+
app(:bare) do
|
64
|
+
plugin :render
|
65
|
+
|
66
|
+
route do |r|
|
67
|
+
render(:path=>"spec/views/layout-yield.erb") do
|
68
|
+
render(:path=>"spec/views/content-yield.erb")
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
body.gsub(/\n+/, "\n").should == "Header\nThis is the actual content.\nFooter\n"
|
74
|
+
end
|
75
|
+
|
76
|
+
it "views without default layouts" do
|
77
|
+
app(:bare) do
|
78
|
+
plugin :render, :views=>"./spec/views", :layout=>false
|
79
|
+
|
80
|
+
route do |r|
|
81
|
+
view("home", :locals=>{:name=>"Agent Smith", :title=>"Home"})
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
body.strip.should == "<h1>Home</h1>\n<p>Hello Agent Smith</p>"
|
86
|
+
end
|
87
|
+
|
88
|
+
it "layout overrides" do
|
89
|
+
app(:bare) do
|
90
|
+
plugin :render, :views=>"./spec/views"
|
91
|
+
|
92
|
+
route do |r|
|
93
|
+
view("home", :locals=>{:name=>"Agent Smith", :title=>"Home" }, :layout=>"layout-alternative", :layout_opts=>{:locals=>{:title=>"Home"}})
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
body.strip.should == "<title>Alternative Layout: Home</title>\n<h1>Home</h1>\n<p>Hello Agent Smith</p>"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "inline layouts and inline views" do
|
101
|
+
app(:render) do
|
102
|
+
view({:inline=>'bar'}, :layout=>{:inline=>'Foo: <%= yield %>'})
|
103
|
+
end
|
104
|
+
|
105
|
+
body.strip.should == "Foo: bar"
|
106
|
+
end
|
107
|
+
|
108
|
+
it "inline renders with opts" do
|
109
|
+
app(:render) do
|
110
|
+
render({:inline=>'<%= bar %>'}, {:engine=>'str'})
|
111
|
+
end
|
112
|
+
|
113
|
+
body.strip.should == '<%= bar %>'
|
114
|
+
end
|
115
|
+
|
116
|
+
it "render_opts inheritance" do
|
117
|
+
c = Class.new(Roda)
|
118
|
+
c.plugin :render
|
119
|
+
sc = Class.new(c)
|
120
|
+
|
121
|
+
c.render_opts.should_not equal(sc.render_opts)
|
122
|
+
c.render_opts[:layout_opts].should_not equal(sc.render_opts[:layout_opts])
|
123
|
+
c.render_opts[:opts].should_not equal(sc.render_opts[:opts])
|
124
|
+
c.render_opts[:cache].should_not equal(sc.render_opts[:cache])
|
125
|
+
end
|
126
|
+
|
127
|
+
it "render plugin call should not override options" do
|
128
|
+
c = Class.new(Roda)
|
129
|
+
c.plugin :render, :layout=>:foo
|
130
|
+
c.plugin :render
|
131
|
+
c.render_opts[:layout].should == :foo
|
132
|
+
end
|
133
|
+
|
134
|
+
it "with caching disabled" do
|
135
|
+
app(:bare) do
|
136
|
+
plugin :render, :views=>"./spec/views", :cache=>false
|
137
|
+
|
138
|
+
route do |r|
|
139
|
+
view(:inline=>"Hello <%= name %>: <%= render_opts[:cache] %>", :locals=>{:name => "Agent Smith"}, :layout=>nil)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
body("/inline").strip.should == "Hello Agent Smith: false"
|
144
|
+
|
145
|
+
Class.new(app).render_opts[:cache].should == false
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "streaming plugin" do
|
4
|
+
it "adds stream method for streaming responses" do
|
5
|
+
app(:streaming) do |r|
|
6
|
+
stream do |out|
|
7
|
+
%w'a b c'.each{|v| out << v}
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
s, h, b = req
|
12
|
+
s.should == 200
|
13
|
+
h.should == {'Content-Type'=>'text/html'}
|
14
|
+
b.to_a.should == %w'a b c'
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should handle errors when streaming, and run callbacks" do
|
18
|
+
a = []
|
19
|
+
app(:streaming) do |r|
|
20
|
+
stream(:callback=>proc{a << 'e'}) do |out|
|
21
|
+
%w'a b'.each{|v| out << v}
|
22
|
+
raise Roda::RodaError, 'foo'
|
23
|
+
out << 'c'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
s, h, b = req
|
28
|
+
s.should == 200
|
29
|
+
h.should == {'Content-Type'=>'text/html'}
|
30
|
+
b.callback{a << 'd'}
|
31
|
+
proc{b.each{|v| a << v}}.should raise_error(Roda::RodaError)
|
32
|
+
a.should == %w'a b e d'
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should handle :loop option to loop" do
|
36
|
+
a = []
|
37
|
+
app(:streaming) do |r|
|
38
|
+
b = %w'a b c'
|
39
|
+
stream(:loop=>true, :callback=>proc{a << 'e'}) do |out|
|
40
|
+
out << b.shift
|
41
|
+
raise Roda::RodaError, 'foo' if b.length == 1
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
s, h, b = req
|
46
|
+
s.should == 200
|
47
|
+
h.should == {'Content-Type'=>'text/html'}
|
48
|
+
b.callback{a << 'd'}
|
49
|
+
proc{b.each{|v| a << v}}.should raise_error(Roda::RodaError)
|
50
|
+
a.should == %w'a b e d'
|
51
|
+
end
|
52
|
+
end
|
data/spec/plugin_spec.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "plugins" do
|
4
|
+
it "should be able to override class, instance, response, and request methods, and execute configure method" do
|
5
|
+
c = Module.new do
|
6
|
+
self::ClassMethods = Module.new do
|
7
|
+
def fix(str)
|
8
|
+
opts[:prefix] + str.strip
|
9
|
+
end
|
10
|
+
end
|
11
|
+
self::InstanceMethods = Module.new do
|
12
|
+
def fix(str)
|
13
|
+
super("a" + str)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
self::RequestMethods = Module.new do
|
17
|
+
def hello(&block)
|
18
|
+
on 'hello', &block
|
19
|
+
end
|
20
|
+
end
|
21
|
+
self::ResponseMethods = Module.new do
|
22
|
+
def foobar
|
23
|
+
"Default "
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.load_dependencies(mod, prefix)
|
28
|
+
mod.send(:include, Module.new do
|
29
|
+
def fix(str)
|
30
|
+
self.class.fix(str)
|
31
|
+
end
|
32
|
+
end)
|
33
|
+
end
|
34
|
+
|
35
|
+
def self.configure(mod, prefix)
|
36
|
+
mod.opts[:prefix] = prefix
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
app(:bare) do
|
41
|
+
plugin c, "Foo "
|
42
|
+
|
43
|
+
route do |r|
|
44
|
+
r.hello do
|
45
|
+
fix(response.foobar)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
body('/hello').should == 'Foo aDefault'
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should support registering plugins and loading them by symbol" do
|
54
|
+
Roda::RodaPlugins.register_plugin(:foo, Module.new{module self::InstanceMethods; def a; '1' end end})
|
55
|
+
app(:foo) do
|
56
|
+
a
|
57
|
+
end
|
58
|
+
|
59
|
+
body.should == '1'
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "redirects" do
|
4
|
+
it "should be immediately processed" do
|
5
|
+
app do |r|
|
6
|
+
r.on "about" do
|
7
|
+
r.redirect "/hello", 301
|
8
|
+
"Foo"
|
9
|
+
end
|
10
|
+
r.on do
|
11
|
+
r.redirect "/hello"
|
12
|
+
"Foo"
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
status.should == 302
|
17
|
+
header('Location').should == '/hello'
|
18
|
+
body.should == ''
|
19
|
+
|
20
|
+
status("/about").should == 301
|
21
|
+
header('Location', "/about").should == '/hello'
|
22
|
+
body("/about").should == ''
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "request.full_path_info" do
|
4
|
+
it "should return the script name and path_info as a string" do
|
5
|
+
app do |r|
|
6
|
+
r.on "foo" do
|
7
|
+
"#{r.full_path_info}:#{r.script_name}:#{r.path_info}"
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
body("/foo/bar").should == "/foo/bar:/foo:/bar"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "request.halt" do
|
16
|
+
it "should return rack response as argument given it as argument" do
|
17
|
+
app do |r|
|
18
|
+
r.halt [200, {}, ['foo']]
|
19
|
+
end
|
20
|
+
|
21
|
+
body.should == "foo"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "request.scope" do
|
26
|
+
it "should return roda instance" do
|
27
|
+
app(:bare) do
|
28
|
+
attr_accessor :b
|
29
|
+
|
30
|
+
route do |r|
|
31
|
+
self.b = 'a'
|
32
|
+
request.scope.b
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
body.should == "a"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "request.inspect" do
|
41
|
+
it "should return information about request" do
|
42
|
+
app(:bare) do
|
43
|
+
def self.inspect
|
44
|
+
'Foo'
|
45
|
+
end
|
46
|
+
|
47
|
+
route do |r|
|
48
|
+
request.inspect
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
body('/a/b').should == "#<Foo::RodaRequest GET /a/b>"
|
53
|
+
body('REQUEST_METHOD'=>'POST').should == "#<Foo::RodaRequest POST />"
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(__FILE__))
|
2
|
+
|
3
|
+
describe "cookie handling" do
|
4
|
+
it "should set cookies on response" do
|
5
|
+
app do |r|
|
6
|
+
response.set_cookie("foo", "bar")
|
7
|
+
response.set_cookie("bar", "baz")
|
8
|
+
"Hello"
|
9
|
+
end
|
10
|
+
|
11
|
+
header('Set-Cookie').should == "foo=bar\nbar=baz"
|
12
|
+
body.should == 'Hello'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should delete cookies on response" do
|
16
|
+
app do |r|
|
17
|
+
response.set_cookie("foo", "bar")
|
18
|
+
response.delete_cookie("foo")
|
19
|
+
"Hello"
|
20
|
+
end
|
21
|
+
|
22
|
+
header('Set-Cookie').should =~ /foo=; (max-age=0; )?expires=Thu, 01[ -]Jan[ -]1970 00:00:00 (-0000|GMT)/
|
23
|
+
body.should == 'Hello'
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "response #[] and #[]=" do
|
28
|
+
it "should get/set headers" do
|
29
|
+
app do |r|
|
30
|
+
response['foo'] = 'bar'
|
31
|
+
response['foo'] + response.headers['foo']
|
32
|
+
end
|
33
|
+
|
34
|
+
header('foo').should == "bar"
|
35
|
+
body.should == 'barbar'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "response #write" do
|
40
|
+
it "should add to body" do
|
41
|
+
app do |r|
|
42
|
+
response.write 'a'
|
43
|
+
response.write 'b'
|
44
|
+
end
|
45
|
+
|
46
|
+
body.should == 'ab'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe "response #finish" do
|
51
|
+
it "should set status to 404 if body has not been written to" do
|
52
|
+
app do |r|
|
53
|
+
s, h, b = response.finish
|
54
|
+
"#{s}#{h['Content-Type']}#{b.length}"
|
55
|
+
end
|
56
|
+
|
57
|
+
body.should == '404text/html0'
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should set status to 200 if body has been written to" do
|
61
|
+
app do |r|
|
62
|
+
response.write 'a'
|
63
|
+
s, h, b = response.finish
|
64
|
+
response.write "#{s}#{h['Content-Type']}#{b.length}"
|
65
|
+
end
|
66
|
+
|
67
|
+
body.should == 'a200text/html1'
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should not overwrite existing status" do
|
71
|
+
app do |r|
|
72
|
+
response.status = 500
|
73
|
+
s, h, b = response.finish
|
74
|
+
"#{s}#{h['Content-Type']}#{b.length}"
|
75
|
+
end
|
76
|
+
|
77
|
+
body.should == '500text/html0'
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe "response #redirect" do
|
82
|
+
it "should set location and status" do
|
83
|
+
app do |r|
|
84
|
+
r.on 'a' do
|
85
|
+
response.redirect '/foo', 303
|
86
|
+
end
|
87
|
+
r.on do
|
88
|
+
response.redirect '/bar'
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
status('/a').should == 303
|
93
|
+
status.should == 302
|
94
|
+
header('Location', '/a').should == '/foo'
|
95
|
+
header('Location').should == '/bar'
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "response #empty?" do
|
100
|
+
it "should return whether the body is empty" do
|
101
|
+
app do |r|
|
102
|
+
r.on 'a' do
|
103
|
+
response['foo'] = response.empty?.to_s
|
104
|
+
end
|
105
|
+
r.on do
|
106
|
+
response.write 'a'
|
107
|
+
response['foo'] = response.empty?.to_s
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
header('foo', '/a').should == 'true'
|
112
|
+
header('foo').should == 'false'
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
describe "response #inspect" do
|
117
|
+
it "should return information about response" do
|
118
|
+
app(:bare) do
|
119
|
+
def self.inspect
|
120
|
+
'Foo'
|
121
|
+
end
|
122
|
+
|
123
|
+
route do |r|
|
124
|
+
response.status = 200
|
125
|
+
response.inspect
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
body.should == '#<Foo::RodaResponse 200 {"Content-Type"=>"text/html"} []>'
|
130
|
+
end
|
131
|
+
end
|