roda 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +70 -0
- data/README.rdoc +261 -302
- data/Rakefile +1 -1
- data/doc/release_notes/1.2.0.txt +406 -0
- data/lib/roda.rb +206 -124
- data/lib/roda/plugins/all_verbs.rb +11 -10
- data/lib/roda/plugins/assets.rb +5 -5
- data/lib/roda/plugins/backtracking_array.rb +12 -5
- data/lib/roda/plugins/caching.rb +10 -8
- data/lib/roda/plugins/class_level_routing.rb +94 -0
- data/lib/roda/plugins/content_for.rb +6 -0
- data/lib/roda/plugins/default_headers.rb +4 -11
- data/lib/roda/plugins/delay_build.rb +42 -0
- data/lib/roda/plugins/delegate.rb +64 -0
- data/lib/roda/plugins/drop_body.rb +33 -0
- data/lib/roda/plugins/empty_root.rb +48 -0
- data/lib/roda/plugins/environments.rb +68 -0
- data/lib/roda/plugins/error_email.rb +1 -2
- data/lib/roda/plugins/error_handler.rb +1 -1
- data/lib/roda/plugins/halt.rb +7 -5
- data/lib/roda/plugins/head.rb +4 -2
- data/lib/roda/plugins/header_matchers.rb +17 -9
- data/lib/roda/plugins/hooks.rb +16 -32
- data/lib/roda/plugins/json.rb +4 -10
- data/lib/roda/plugins/mailer.rb +233 -0
- data/lib/roda/plugins/match_affix.rb +48 -0
- data/lib/roda/plugins/multi_route.rb +9 -11
- data/lib/roda/plugins/multi_run.rb +81 -0
- data/lib/roda/plugins/named_templates.rb +93 -0
- data/lib/roda/plugins/not_allowed.rb +43 -48
- data/lib/roda/plugins/path.rb +63 -2
- data/lib/roda/plugins/render.rb +79 -48
- data/lib/roda/plugins/render_each.rb +6 -0
- data/lib/roda/plugins/sinatra_helpers.rb +523 -0
- data/lib/roda/plugins/slash_path_empty.rb +25 -0
- data/lib/roda/plugins/static_path_info.rb +64 -0
- data/lib/roda/plugins/streaming.rb +1 -1
- data/lib/roda/plugins/view_subdirs.rb +12 -8
- data/lib/roda/version.rb +1 -1
- data/spec/integration_spec.rb +33 -0
- data/spec/plugin/backtracking_array_spec.rb +24 -18
- data/spec/plugin/class_level_routing_spec.rb +138 -0
- data/spec/plugin/delay_build_spec.rb +23 -0
- data/spec/plugin/delegate_spec.rb +20 -0
- data/spec/plugin/drop_body_spec.rb +20 -0
- data/spec/plugin/empty_root_spec.rb +14 -0
- data/spec/plugin/environments_spec.rb +31 -0
- data/spec/plugin/h_spec.rb +1 -3
- data/spec/plugin/header_matchers_spec.rb +14 -0
- data/spec/plugin/hooks_spec.rb +3 -5
- data/spec/plugin/mailer_spec.rb +191 -0
- data/spec/plugin/match_affix_spec.rb +22 -0
- data/spec/plugin/multi_run_spec.rb +31 -0
- data/spec/plugin/named_templates_spec.rb +65 -0
- data/spec/plugin/path_spec.rb +66 -2
- data/spec/plugin/render_spec.rb +46 -1
- data/spec/plugin/sinatra_helpers_spec.rb +534 -0
- data/spec/plugin/slash_path_empty_spec.rb +22 -0
- data/spec/plugin/static_path_info_spec.rb +50 -0
- data/spec/request_spec.rb +23 -0
- data/spec/response_spec.rb +12 -1
- metadata +48 -6
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "empty_root plugin" do
|
4
|
+
it "makes root match on emtpy path" do
|
5
|
+
app(:empty_root) do |r|
|
6
|
+
r.root{"root"}
|
7
|
+
"notroot"
|
8
|
+
end
|
9
|
+
|
10
|
+
body.should == 'root'
|
11
|
+
body("").should == 'root'
|
12
|
+
body("a").should == 'notroot'
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "environments plugin" do
|
4
|
+
before do
|
5
|
+
app
|
6
|
+
app.plugin :environments, :development
|
7
|
+
end
|
8
|
+
|
9
|
+
it "adds environment accessor for getting/setting the environment" do
|
10
|
+
app.environment.should == :development
|
11
|
+
app.environment = :test
|
12
|
+
app.environment.should == :test
|
13
|
+
|
14
|
+
app.plugin :environments, :production
|
15
|
+
app.environment.should == :production
|
16
|
+
end
|
17
|
+
|
18
|
+
it "adds predicates for testing the environment" do
|
19
|
+
app.development?.should == true
|
20
|
+
app.test?.should == false
|
21
|
+
app.production?.should == false
|
22
|
+
end
|
23
|
+
|
24
|
+
it "adds configure method which yields if no arguments are given or an environment matches" do
|
25
|
+
a = []
|
26
|
+
app.configure{a << 1}
|
27
|
+
app.configure(:development){|ap| a << ap}
|
28
|
+
app.configure(:test, :production){a << 2}
|
29
|
+
a.should == [1, app]
|
30
|
+
end
|
31
|
+
end
|
data/spec/plugin/h_spec.rb
CHANGED
@@ -3,9 +3,7 @@ require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
|
3
3
|
describe "h plugin" do
|
4
4
|
it "adds h method for html escaping" do
|
5
5
|
app(:h) do |r|
|
6
|
-
|
7
|
-
h("<form>") + h(:form)
|
8
|
-
end
|
6
|
+
h("<form>") + h(:form)
|
9
7
|
end
|
10
8
|
|
11
9
|
body.should == '<form>form'
|
@@ -59,3 +59,17 @@ describe "host matcher" do
|
|
59
59
|
body("HTTP_HOST" => "example.com").should == '0'
|
60
60
|
end
|
61
61
|
end
|
62
|
+
|
63
|
+
describe "user_agent matcher" do
|
64
|
+
it "should accept pattern and match against user-agent" do
|
65
|
+
app(:header_matchers) do |r|
|
66
|
+
r.on :user_agent=>/(chrome)(\d+)/ do |agent, num|
|
67
|
+
"a-#{agent}-#{num}"
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
body("HTTP_USER_AGENT" => "chrome31").should == "a-chrome-31"
|
72
|
+
status.should == 404
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
data/spec/plugin/hooks_spec.rb
CHANGED
@@ -0,0 +1,191 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'mail'
|
5
|
+
rescue LoadError
|
6
|
+
warn "mail not installed, skipping mail plugin test"
|
7
|
+
else
|
8
|
+
Mail.defaults do
|
9
|
+
delivery_method :test
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "mailer plugin" do
|
13
|
+
def deliveries
|
14
|
+
Mail::TestMailer.deliveries
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
deliveries.clear
|
19
|
+
end
|
20
|
+
|
21
|
+
setup_email = lambda do
|
22
|
+
from "f@example.com"
|
23
|
+
to "t@example.com"
|
24
|
+
subject 's'
|
25
|
+
end
|
26
|
+
|
27
|
+
it "supports sending emails via the routing tree" do
|
28
|
+
app(:mailer) do |r|
|
29
|
+
r.mail do
|
30
|
+
instance_exec(&setup_email)
|
31
|
+
cc "c@example.com"
|
32
|
+
bcc "b@example.com"
|
33
|
+
response['X-Foo'] = 'Bar'
|
34
|
+
"b"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
m = app.mail('/foo')
|
39
|
+
deliveries.should == []
|
40
|
+
m.from.should == ['f@example.com']
|
41
|
+
m.to.should == ['t@example.com']
|
42
|
+
m.cc.should == ['c@example.com']
|
43
|
+
m.bcc.should == ['b@example.com']
|
44
|
+
m.subject.should == 's'
|
45
|
+
m.body.should == 'b'
|
46
|
+
m.header['X-Foo'].to_s.should == 'Bar'
|
47
|
+
|
48
|
+
m.deliver!
|
49
|
+
deliveries.should == [m]
|
50
|
+
|
51
|
+
deliveries.clear
|
52
|
+
m = app.sendmail('/foo')
|
53
|
+
deliveries.should == [m]
|
54
|
+
m.from.should == ['f@example.com']
|
55
|
+
m.to.should == ['t@example.com']
|
56
|
+
m.cc.should == ['c@example.com']
|
57
|
+
m.bcc.should == ['b@example.com']
|
58
|
+
m.subject.should == 's'
|
59
|
+
m.body.should == 'b'
|
60
|
+
m.header['X-Foo'].to_s.should == 'Bar'
|
61
|
+
end
|
62
|
+
|
63
|
+
it "supports arguments to mail/sendmail methods, yielding them to the route blocks" do
|
64
|
+
app(:mailer) do |r|
|
65
|
+
instance_exec(&setup_email)
|
66
|
+
r.mail "foo" do |*args|
|
67
|
+
"foo#{args.inspect}"
|
68
|
+
end
|
69
|
+
r.mail :d do |*args|
|
70
|
+
args.inspect
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
app.mail('/foo', 1, 2).body.should == 'foo[1, 2]'
|
75
|
+
app.sendmail('/bar', 1, 2).body.should == '["bar", 1, 2]'
|
76
|
+
end
|
77
|
+
|
78
|
+
it "supports attachments" do
|
79
|
+
app(:mailer) do |r|
|
80
|
+
r.mail do
|
81
|
+
instance_exec(&setup_email)
|
82
|
+
add_file __FILE__
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
m = app.mail('foo')
|
87
|
+
m.attachments.length.should == 1
|
88
|
+
m.attachments.first.content_type.should =~ /mailer_spec\.rb/
|
89
|
+
m.content_type.should =~ /\Amultipart\/mixed/
|
90
|
+
end
|
91
|
+
|
92
|
+
it "supports regular web requests in same application" do
|
93
|
+
app(:mailer) do |r|
|
94
|
+
r.get "foo", :param=>'bar' do |bar|
|
95
|
+
"foo#{bar}"
|
96
|
+
end
|
97
|
+
r.mail "bar" do
|
98
|
+
instance_exec(&setup_email)
|
99
|
+
"b"
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
body("/foo", 'QUERY_STRING'=>'bar=baz', 'rack.input'=>StringIO.new).should == 'foobaz'
|
104
|
+
app.mail('/bar').body.should == 'b'
|
105
|
+
end
|
106
|
+
|
107
|
+
it "supports multipart email using text_part/html_pat" do
|
108
|
+
app(:mailer) do |r|
|
109
|
+
r.mail do
|
110
|
+
instance_exec(&setup_email)
|
111
|
+
text_part "t"
|
112
|
+
html_part "h"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
m = app.mail('/foo')
|
117
|
+
m.text_part.body.should == 't'
|
118
|
+
m.html_part.body.should == 'h'
|
119
|
+
m.content_type.should =~ /\Amultipart\/alternative/
|
120
|
+
end
|
121
|
+
|
122
|
+
it "supports setting arbitrary email headers for multipart emails" do
|
123
|
+
app(:mailer) do |r|
|
124
|
+
r.mail do
|
125
|
+
instance_exec(&setup_email)
|
126
|
+
text_part "t", "X-Text"=>'T'
|
127
|
+
html_part "h", "X-HTML"=>'H'
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
m = app.mail('/foo')
|
132
|
+
m.text_part.body.should == 't'
|
133
|
+
m.text_part.header['X-Text'].to_s.should == 'T'
|
134
|
+
m.html_part.body.should == 'h'
|
135
|
+
m.html_part.header['X-HTML'].to_s.should == 'H'
|
136
|
+
m.content_type.should =~ /\Amultipart\/alternative/
|
137
|
+
end
|
138
|
+
|
139
|
+
it "raises error if mail object is not returned" do
|
140
|
+
app(:mailer){}
|
141
|
+
proc{app.mail('/')}.should raise_error(Roda::RodaPlugins::Mailer::Error)
|
142
|
+
end
|
143
|
+
|
144
|
+
it "does not raise an error when using an explicitly empty body" do
|
145
|
+
app(:mailer){""}
|
146
|
+
proc{app.mail('/')}.should_not raise_error
|
147
|
+
end
|
148
|
+
|
149
|
+
it "supports setting the default content-type for emails when loading the plugin" do
|
150
|
+
app(:bare) do
|
151
|
+
plugin :mailer, :content_type=>'text/html'
|
152
|
+
route{""}
|
153
|
+
end
|
154
|
+
app.mail('/').content_type.should =~ /\Atext\/html/
|
155
|
+
end
|
156
|
+
|
157
|
+
it "supports loading the plugin multiple times" do
|
158
|
+
app(:bare) do
|
159
|
+
plugin :mailer, :content_type=>'text/html'
|
160
|
+
plugin :mailer
|
161
|
+
route{""}
|
162
|
+
end
|
163
|
+
app.mail('/').content_type.should =~ /\Atext\/html/
|
164
|
+
end
|
165
|
+
|
166
|
+
it "supports manually overridding the default content-type for emails" do
|
167
|
+
app(:bare) do
|
168
|
+
plugin :mailer, :content_type=>'text/html'
|
169
|
+
route do
|
170
|
+
response['Content-Type'] = 'text/foo'
|
171
|
+
""
|
172
|
+
end
|
173
|
+
end
|
174
|
+
app.mail('/').content_type.should =~ /\Atext\/foo/
|
175
|
+
end
|
176
|
+
|
177
|
+
it "supports handle setting the default content type when attachments are used" do
|
178
|
+
app(:bare) do
|
179
|
+
plugin :mailer, :content_type=>'text/html'
|
180
|
+
route do
|
181
|
+
add_file 'spec/assets/css/raw.css'
|
182
|
+
"a"
|
183
|
+
end
|
184
|
+
end
|
185
|
+
m = app.mail('/')
|
186
|
+
m.content_type.should =~ /\Amultipart\/mixed/
|
187
|
+
m.parts.first.content_type.should =~ /\Atext\/css/
|
188
|
+
m.parts.last.content_type.should =~ /\Atext\/html/
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "match_affix plugin" do
|
4
|
+
it "allows changing the match prefix/suffix" do
|
5
|
+
app(:bare) do
|
6
|
+
plugin :match_affix, "", /(\/|\z)/
|
7
|
+
|
8
|
+
route do |r|
|
9
|
+
r.on "/albums" do |b|
|
10
|
+
r.on "b/:id" do |id, s|
|
11
|
+
"b-#{b}-#{id}-#{s.inspect}"
|
12
|
+
end
|
13
|
+
|
14
|
+
"albums-#{b}"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
body("/albums/a/1").should == 'albums-/'
|
20
|
+
body("/albums/b/1").should == 'b-/-1-""'
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "multi_run plugin" do
|
4
|
+
it "adds Roda.run method for setting up prefix delegations to other rack apps" do
|
5
|
+
app(:multi_run) do |r|
|
6
|
+
r.multi_run
|
7
|
+
"c"
|
8
|
+
end
|
9
|
+
|
10
|
+
app.run "a", Class.new(Roda).class_eval{route{"a1"}; app}
|
11
|
+
|
12
|
+
body("/a").should == 'a1'
|
13
|
+
body("/b").should == 'c'
|
14
|
+
body("/b/a").should == 'c'
|
15
|
+
body.should == 'c'
|
16
|
+
|
17
|
+
app.run "b", Class.new(Roda).class_eval{route{"b1"}; app}
|
18
|
+
|
19
|
+
body("/a").should == 'a1'
|
20
|
+
body("/b").should == 'b1'
|
21
|
+
body("/b/a").should == 'b1'
|
22
|
+
body.should == 'c'
|
23
|
+
|
24
|
+
app.run "b/a", Class.new(Roda).class_eval{route{"b2"}; app}
|
25
|
+
|
26
|
+
body("/a").should == 'a1'
|
27
|
+
body("/b").should == 'b1'
|
28
|
+
body("/b/a").should == 'b2'
|
29
|
+
body.should == 'c'
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
describe "named_templates plugin" do
|
4
|
+
it "adds template method method for naming templates, and have render recognize it" do
|
5
|
+
app(:bare) do
|
6
|
+
plugin :named_templates
|
7
|
+
|
8
|
+
template :foo do
|
9
|
+
@b = 2
|
10
|
+
"foo<%= @a %><%= @b %>"
|
11
|
+
end
|
12
|
+
template :layout, :engine=>:str do
|
13
|
+
@c = 3
|
14
|
+
'bar#{@a}#{@c}-#{yield}-baz'
|
15
|
+
end
|
16
|
+
|
17
|
+
route do |r|
|
18
|
+
@a = 1
|
19
|
+
view(:foo)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
body.should == 'bar13-foo12-baz'
|
24
|
+
@app = Class.new(@app)
|
25
|
+
body.should == 'bar13-foo12-baz'
|
26
|
+
end
|
27
|
+
|
28
|
+
it "works with the view_subdirs plugin" do
|
29
|
+
app(:bare) do
|
30
|
+
plugin :render
|
31
|
+
plugin :view_subdirs
|
32
|
+
plugin :named_templates
|
33
|
+
|
34
|
+
template "foo/bar" do
|
35
|
+
@b = 2
|
36
|
+
"foobar<%= @a %><%= @b %>"
|
37
|
+
end
|
38
|
+
template "foo/layout", :engine=>:str do
|
39
|
+
@c = 3
|
40
|
+
'foo#{@a}#{@c}-#{yield}-baz'
|
41
|
+
end
|
42
|
+
template "bar/layout", :engine=>:str do
|
43
|
+
@c = 3
|
44
|
+
'bar#{@a}#{@c}-#{yield}-baz'
|
45
|
+
end
|
46
|
+
|
47
|
+
route do |r|
|
48
|
+
r.is 'foo' do
|
49
|
+
set_view_subdir :foo
|
50
|
+
@a = 1
|
51
|
+
view(:bar)
|
52
|
+
end
|
53
|
+
r.is 'bar' do
|
54
|
+
set_view_subdir :bar
|
55
|
+
@a = 4
|
56
|
+
@b = 2
|
57
|
+
view(:inline=>"barfoo<%= @a %><%= @b %>")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
body('/foo').should == 'foo13-foobar12-baz'
|
63
|
+
body('/bar').should == 'bar43-barfoo42-baz'
|
64
|
+
end
|
65
|
+
end
|
data/spec/plugin/path_spec.rb
CHANGED
@@ -1,6 +1,19 @@
|
|
1
1
|
require File.expand_path("spec_helper", File.dirname(File.dirname(__FILE__)))
|
2
2
|
|
3
3
|
describe "path plugin" do
|
4
|
+
def path_app(*args, &block)
|
5
|
+
app(:bare) do
|
6
|
+
plugin :path
|
7
|
+
path *args, &block
|
8
|
+
route{|r| send(r.path_info)}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def path_block_app(b, *args, &block)
|
13
|
+
path_app(*args, &block)
|
14
|
+
app.route{|r| send(r.path_info, &b)}
|
15
|
+
end
|
16
|
+
|
4
17
|
it "adds path method for defining named paths" do
|
5
18
|
app(:bare) do
|
6
19
|
plugin :path
|
@@ -8,13 +21,16 @@ describe "path plugin" do
|
|
8
21
|
path :bar do |o|
|
9
22
|
"/bar/#{o}"
|
10
23
|
end
|
24
|
+
path :baz do |&block|
|
25
|
+
"/baz/#{block.call}"
|
26
|
+
end
|
11
27
|
|
12
28
|
route do |r|
|
13
|
-
"#{foo_path}#{bar_path('a')}"
|
29
|
+
"#{foo_path}#{bar_path('a')}#{baz_path{'b'}}"
|
14
30
|
end
|
15
31
|
end
|
16
32
|
|
17
|
-
body.should == '/foo/bar/a'
|
33
|
+
body.should == '/foo/bar/a/baz/b'
|
18
34
|
end
|
19
35
|
|
20
36
|
it "raises if both path and block are given" do
|
@@ -26,4 +42,52 @@ describe "path plugin" do
|
|
26
42
|
app.plugin :path
|
27
43
|
proc{app.path(:foo)}.should raise_error(Roda::RodaError)
|
28
44
|
end
|
45
|
+
|
46
|
+
it "raises if two options hashes are given" do
|
47
|
+
app.plugin :path
|
48
|
+
proc{app.path(:foo, {:name=>'a'}, :add_script_name=>true)}.should raise_error(Roda::RodaError)
|
49
|
+
end
|
50
|
+
|
51
|
+
it "supports :name option for naming the method" do
|
52
|
+
path_app(:foo, :name=>'foobar_route'){"/bar/foo"}
|
53
|
+
body("foobar_route").should == "/bar/foo"
|
54
|
+
end
|
55
|
+
|
56
|
+
it "supports :add_script_name option for automatically adding the script name" do
|
57
|
+
path_app(:foo, :add_script_name=>true){"/bar/foo"}
|
58
|
+
body("foo_path", 'SCRIPT_NAME'=>'/baz').should == "/baz/bar/foo"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "supports path method accepting a block when using :add_script_name" do
|
62
|
+
path_block_app(lambda{"c"}, :foo, :add_script_name=>true){|&block| "/bar/foo/#{block.call}"}
|
63
|
+
body("foo_path", 'SCRIPT_NAME'=>'/baz').should == "/baz/bar/foo/c"
|
64
|
+
end
|
65
|
+
|
66
|
+
it "supports :url option for also creating a *_url method" do
|
67
|
+
path_app(:foo, :url=>true){"/bar/foo"}
|
68
|
+
body("foo_path", 'HTTP_HOST'=>'example.org', "rack.url_scheme"=>'http', 'SERVER_PORT'=>80).should == "/bar/foo"
|
69
|
+
body("foo_url", 'HTTP_HOST'=>'example.org', "rack.url_scheme"=>'http', 'SERVER_PORT'=>80).should == "http://example.org/bar/foo"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "supports url method accepting a block when using :url" do
|
73
|
+
path_block_app(lambda{"c"}, :foo, :url=>true){|&block| "/bar/foo/#{block.call}"}
|
74
|
+
body("foo_url", 'HTTP_HOST'=>'example.org', "rack.url_scheme"=>'http', 'SERVER_PORT'=>80).should == "http://example.org/bar/foo/c"
|
75
|
+
end
|
76
|
+
|
77
|
+
it "supports url method name specified in :url option" do
|
78
|
+
path_app(:foo, :url=>:foobar_uri){"/bar/foo"}
|
79
|
+
body("foo_path", 'HTTP_HOST'=>'example.org', "rack.url_scheme"=>'http', 'SERVER_PORT'=>80).should == "/bar/foo"
|
80
|
+
body("foobar_uri", 'HTTP_HOST'=>'example.org', "rack.url_scheme"=>'http', 'SERVER_PORT'=>80).should == "http://example.org/bar/foo"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "supports :url_only option for not creating a path method" do
|
84
|
+
path_app(:foo, :url_only=>true){"/bar/foo"}
|
85
|
+
proc{body("foo_path")}.should raise_error(NoMethodError)
|
86
|
+
body("foo_url", 'HTTP_HOST'=>'example.org', "rack.url_scheme"=>'http', 'SERVER_PORT'=>80).should == "http://example.org/bar/foo"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "handles non-default ports in url methods" do
|
90
|
+
path_app(:foo, :url=>true){"/bar/foo"}
|
91
|
+
body("foo_url", 'HTTP_HOST'=>'example.org', "rack.url_scheme"=>'http', 'SERVER_PORT'=>81).should == "http://example.org:81/bar/foo"
|
92
|
+
end
|
29
93
|
end
|