sinatra-contrib 1.3.2 → 1.4.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/README.md +9 -8
- data/lib/sinatra/capture.rb +87 -5
- data/lib/sinatra/config_file.rb +19 -3
- data/lib/sinatra/content_for.rb +2 -2
- data/lib/sinatra/contrib/setup.rb +2 -2
- data/lib/sinatra/cookies.rb +4 -4
- data/lib/sinatra/decompile.rb +13 -5
- data/lib/sinatra/extension.rb +5 -5
- data/lib/sinatra/json.rb +26 -30
- data/lib/sinatra/link_header.rb +2 -2
- data/lib/sinatra/multi_route.rb +6 -0
- data/lib/sinatra/namespace.rb +9 -6
- data/lib/sinatra/reloader.rb +7 -7
- data/lib/sinatra/respond_with.rb +18 -14
- data/lib/sinatra/streaming.rb +6 -6
- data/lib/sinatra/test_helpers.rb +1 -1
- data/sinatra-contrib.gemspec +5 -22
- data/spec/capture_spec.rb +14 -1
- data/spec/config_file/key_value.yml.erb +6 -0
- data/spec/config_file_spec.rb +10 -0
- data/spec/content_for_spec.rb +3 -3
- data/spec/cookies_spec.rb +26 -6
- data/spec/json_spec.rb +5 -3
- data/spec/multi_route_spec.rb +28 -13
- data/spec/namespace_spec.rb +294 -283
- data/spec/respond_with_spec.rb +10 -0
- data/spec/spec_helper.rb +1 -0
- metadata +8 -25
- data/spec/content_for/footer.erb +0 -3
- data/spec/content_for/footer.erubis +0 -3
- data/spec/content_for/footer.haml +0 -2
- data/spec/content_for/footer.slim +0 -2
data/spec/namespace_spec.rb
CHANGED
@@ -18,258 +18,269 @@ describe Sinatra::Namespace do
|
|
18
18
|
|
19
19
|
verbs.each do |verb|
|
20
20
|
describe "HTTP #{verb.to_s.upcase}" do
|
21
|
-
describe 'pattern generation' do
|
22
|
-
it "should add routes including prefix to the base app" do
|
23
|
-
namespace("/foo") { send(verb, "/bar") { "baz" }}
|
24
|
-
send(verb, "/foo/bar").should be_ok
|
25
|
-
body.should == "baz" unless verb == :head
|
26
|
-
send(verb, "/foo/baz").should_not be_ok
|
27
|
-
end
|
28
21
|
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
22
|
+
it 'prefixes the path with the namespace' do
|
23
|
+
namespace('/foo') { send(verb, '/bar') { 'baz' }}
|
24
|
+
send(verb, '/foo/bar').should be_ok
|
25
|
+
body.should == 'baz' unless verb == :head
|
26
|
+
send(verb, '/foo/baz').should_not be_ok
|
27
|
+
end
|
34
28
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
29
|
+
context 'when namespace is a string' do
|
30
|
+
it 'accepts routes with no path' do
|
31
|
+
namespace('/foo') { send(verb) { 'bar' } }
|
32
|
+
send(verb, '/foo').should be_ok
|
33
|
+
body.should == 'bar' unless verb == :head
|
40
34
|
end
|
41
35
|
|
42
|
-
it
|
43
|
-
namespace(
|
44
|
-
send(verb,
|
45
|
-
body.should ==
|
46
|
-
send(verb,
|
36
|
+
it 'accepts the path as a named parameter' do
|
37
|
+
namespace('/foo') { send(verb, '/:bar') { params[:bar] }}
|
38
|
+
send(verb, '/foo/bar').should be_ok
|
39
|
+
body.should == 'bar' unless verb == :head
|
40
|
+
send(verb, '/foo/baz').should be_ok
|
41
|
+
body.should == 'baz' unless verb == :head
|
47
42
|
end
|
48
43
|
|
49
|
-
it
|
50
|
-
namespace(
|
51
|
-
send(verb,
|
52
|
-
body.should ==
|
53
|
-
send(verb,
|
54
|
-
send(verb, "/fox/bar").should be_ok
|
55
|
-
body.should == "fox" unless verb == :head
|
44
|
+
it 'accepts the path as a regular expression' do
|
45
|
+
namespace('/foo') { send(verb, /\/\d\d/) { 'bar' }}
|
46
|
+
send(verb, '/foo/12').should be_ok
|
47
|
+
body.should == 'bar' unless verb == :head
|
48
|
+
send(verb, '/foo/123').should_not be_ok
|
56
49
|
end
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
send(verb,
|
63
|
-
body.should ==
|
50
|
+
end
|
51
|
+
|
52
|
+
context 'when namespace is a named parameter' do
|
53
|
+
it 'accepts routes with no path' do
|
54
|
+
namespace('/:foo') { send(verb) { 'bar' } }
|
55
|
+
send(verb, '/foo').should be_ok
|
56
|
+
body.should == 'bar' unless verb == :head
|
64
57
|
end
|
65
58
|
|
66
|
-
it
|
67
|
-
namespace(
|
59
|
+
it 'sets the parameter correctly' do
|
60
|
+
namespace('/:foo') { send(verb, '/bar') { params[:foo] }}
|
68
61
|
send(verb, '/foo/bar').should be_ok
|
69
|
-
body.should ==
|
62
|
+
body.should == 'foo' unless verb == :head
|
63
|
+
send(verb, '/fox/bar').should be_ok
|
64
|
+
body.should == 'fox' unless verb == :head
|
65
|
+
send(verb, '/foo/baz').should_not be_ok
|
70
66
|
end
|
71
67
|
|
72
|
-
it
|
73
|
-
namespace(
|
74
|
-
send(verb,
|
75
|
-
body.should ==
|
76
|
-
send(verb,
|
77
|
-
|
78
|
-
body.should == "fox" unless verb == :head
|
68
|
+
it 'accepts the path as a named parameter' do
|
69
|
+
namespace('/:foo') { send(verb, '/:bar') { params[:bar] }}
|
70
|
+
send(verb, '/foo/bar').should be_ok
|
71
|
+
body.should == 'bar' unless verb == :head
|
72
|
+
send(verb, '/foo/baz').should be_ok
|
73
|
+
body.should == 'baz' unless verb == :head
|
79
74
|
end
|
80
75
|
|
81
|
-
it
|
82
|
-
namespace(
|
83
|
-
send(verb,
|
84
|
-
body.should ==
|
85
|
-
send(verb,
|
86
|
-
body.should ==
|
76
|
+
it 'accepts the path as regular expression' do
|
77
|
+
namespace('/:foo') { send(verb, %r{/bar}) { params[:foo] }}
|
78
|
+
send(verb, '/foo/bar').should be_ok
|
79
|
+
body.should == 'foo' unless verb == :head
|
80
|
+
send(verb, '/fox/bar').should be_ok
|
81
|
+
body.should == 'fox' unless verb == :head
|
82
|
+
send(verb, '/foo/baz').should_not be_ok
|
87
83
|
end
|
84
|
+
end
|
88
85
|
|
89
|
-
|
86
|
+
context 'when namespace is a regular expression' do
|
87
|
+
it 'accepts routes with no path' do
|
90
88
|
namespace(%r{/foo}) { send(verb) { 'bar' } }
|
91
89
|
send(verb, '/foo').should be_ok
|
92
|
-
body.should == 'bar' unless verb == :head
|
90
|
+
body.should == 'bar' unless verb == :head
|
93
91
|
end
|
94
|
-
end
|
95
92
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.com')
|
103
|
-
last_response.should be_ok
|
104
|
-
body.should == 'yes' unless verb == :head
|
105
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.org')
|
106
|
-
last_response.should be_ok
|
107
|
-
body.should == 'no' unless verb == :head
|
93
|
+
it 'accepts the path as a named parameter' do
|
94
|
+
namespace(%r{/foo}) { send(verb, '/:bar') { params[:bar] }}
|
95
|
+
send(verb, '/foo/bar').should be_ok
|
96
|
+
body.should == 'bar' unless verb == :head
|
97
|
+
send(verb, '/foo/baz').should be_ok
|
98
|
+
body.should == 'baz' unless verb == :head
|
108
99
|
end
|
109
100
|
|
110
|
-
it '
|
111
|
-
namespace '
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com')
|
116
|
-
last_response.should be_ok
|
117
|
-
body.should == 'yes' unless verb == :head
|
118
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org')
|
119
|
-
last_response.should be_ok
|
120
|
-
body.should == 'no' unless verb == :head
|
101
|
+
it 'accepts the path as a regular expression' do
|
102
|
+
namespace(/\/\d\d/) { send(verb, /\/\d\d/) { 'foo' }}
|
103
|
+
send(verb, '/23/12').should be_ok
|
104
|
+
body.should == 'foo' unless verb == :head
|
105
|
+
send(verb, '/123/12').should_not be_ok
|
121
106
|
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context 'when namespace is a splat' do
|
110
|
+
it 'accepts the path as a splat' do
|
111
|
+
namespace('/*') { send(verb, '/*') { params[:splat].join ' - ' }}
|
112
|
+
send(verb, '/foo/bar').should be_ok
|
113
|
+
body.should == 'foo - bar' unless verb == :head
|
114
|
+
end
|
115
|
+
end
|
122
116
|
|
123
|
-
|
117
|
+
describe 'before-filters' do
|
118
|
+
specify 'are triggered' do
|
124
119
|
ran = false
|
125
|
-
namespace
|
126
|
-
|
127
|
-
send(verb) { "ok" }
|
128
|
-
end
|
129
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org')
|
130
|
-
ran.should be_false
|
131
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com')
|
120
|
+
namespace('/foo') { before { ran = true }}
|
121
|
+
send(verb, '/foo')
|
132
122
|
ran.should be_true
|
133
123
|
end
|
134
124
|
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org').should_not be_ok
|
125
|
+
specify 'are not triggered for a different namespace' do
|
126
|
+
ran = false
|
127
|
+
namespace('/foo') { before { ran = true }}
|
128
|
+
send(verb, '/fox')
|
129
|
+
ran.should be_false
|
141
130
|
end
|
131
|
+
end
|
142
132
|
|
143
|
-
|
133
|
+
describe 'after-filters' do
|
134
|
+
specify 'are triggered' do
|
144
135
|
ran = false
|
145
|
-
namespace
|
146
|
-
|
147
|
-
send(verb) { "ok" }
|
148
|
-
end
|
149
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
150
|
-
ran.should be_false
|
151
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
152
|
-
ran.should be_false
|
153
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
136
|
+
namespace('/foo') { after { ran = true }}
|
137
|
+
send(verb, '/foo')
|
154
138
|
ran.should be_true
|
155
139
|
end
|
156
140
|
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html').should_not be_ok
|
163
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain').should_not be_ok
|
141
|
+
specify 'are not triggered for a different namespace' do
|
142
|
+
ran = false
|
143
|
+
namespace('/foo') { after { ran = true }}
|
144
|
+
send(verb, '/fox')
|
145
|
+
ran.should be_false
|
164
146
|
end
|
147
|
+
end
|
165
148
|
|
166
|
-
|
167
|
-
|
168
|
-
|
149
|
+
describe 'conditions' do
|
150
|
+
context 'when the namespace has no prefix' do
|
151
|
+
specify 'are accepted in the namespace' do
|
152
|
+
mock_app do
|
153
|
+
namespace(:host_name => 'example.com') { send(verb) { 'yes' }}
|
154
|
+
send(verb, '/') { 'no' }
|
155
|
+
end
|
156
|
+
send(verb, '/', {}, 'HTTP_HOST' => 'example.com')
|
157
|
+
last_response.should be_ok
|
158
|
+
body.should == 'yes' unless verb == :head
|
159
|
+
send(verb, '/', {}, 'HTTP_HOST' => 'example.org')
|
160
|
+
last_response.should be_ok
|
161
|
+
body.should == 'no' unless verb == :head
|
169
162
|
end
|
170
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.com').should be_ok
|
171
|
-
send(verb, '/', {}, 'HTTP_HOST' => 'example.org').should_not be_ok
|
172
|
-
end
|
173
163
|
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
send(verb, '
|
164
|
+
specify 'are accepted in the route definition' do
|
165
|
+
namespace :host_name => 'example.com' do
|
166
|
+
send(verb, '/foo', :provides => :txt) { 'ok' }
|
167
|
+
end
|
168
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain').should be_ok
|
169
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html').should_not be_ok
|
170
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain').should_not be_ok
|
179
171
|
end
|
180
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
181
|
-
ran.should be_false
|
182
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
183
|
-
ran.should be_false
|
184
|
-
send(verb, '/bar', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
185
|
-
ran.should be_false
|
186
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
187
|
-
ran.should be_true
|
188
|
-
end
|
189
172
|
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
173
|
+
specify 'are accepted in the before-filter' do
|
174
|
+
ran = false
|
175
|
+
namespace :provides => :txt do
|
176
|
+
before('/foo', :host_name => 'example.com') { ran = true }
|
177
|
+
send(verb, '/*') { 'ok' }
|
178
|
+
end
|
179
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
180
|
+
ran.should be_false
|
181
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
182
|
+
ran.should be_false
|
183
|
+
send(verb, '/bar', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
184
|
+
ran.should be_false
|
185
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
186
|
+
ran.should be_true
|
195
187
|
end
|
196
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
197
|
-
ran.should be_false
|
198
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
199
|
-
ran.should be_false
|
200
|
-
send(verb, '/bar', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
201
|
-
ran.should be_false
|
202
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
203
|
-
ran.should be_true
|
204
|
-
end
|
205
188
|
|
206
|
-
|
207
|
-
|
208
|
-
|
189
|
+
specify 'are accepted in the after-filter' do
|
190
|
+
ran = false
|
191
|
+
namespace :provides => :txt do
|
192
|
+
after('/foo', :host_name => 'example.com') { ran = true }
|
193
|
+
send(verb, '/*') { 'ok' }
|
194
|
+
end
|
195
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
196
|
+
ran.should be_false
|
197
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
198
|
+
ran.should be_false
|
199
|
+
send(verb, '/bar', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
200
|
+
ran.should be_false
|
201
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
202
|
+
ran.should be_true
|
209
203
|
end
|
210
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain').should be_ok
|
211
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html').should_not be_ok
|
212
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain').should_not be_ok
|
213
204
|
end
|
214
205
|
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
206
|
+
context 'when the namespace is a string' do
|
207
|
+
specify 'are accepted in the namespace' do
|
208
|
+
namespace '/foo', :host_name => 'example.com' do
|
209
|
+
send(verb) { 'ok' }
|
210
|
+
end
|
211
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com').should be_ok
|
212
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org').should_not be_ok
|
220
213
|
end
|
221
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
222
|
-
ran.should be_false
|
223
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
224
|
-
ran.should be_false
|
225
|
-
send(verb, '/far', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
226
|
-
ran.should be_false
|
227
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
228
|
-
ran.should be_true
|
229
|
-
end
|
230
214
|
|
231
|
-
|
232
|
-
|
233
|
-
|
215
|
+
specify 'are accepted in the before-filter' do
|
216
|
+
namespace '/foo' do
|
217
|
+
before(:host_name => 'example.com') { @yes = 'yes' }
|
218
|
+
send(verb) { @yes || 'no' }
|
219
|
+
end
|
220
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com')
|
221
|
+
last_response.should be_ok
|
222
|
+
body.should == 'yes' unless verb == :head
|
223
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org')
|
224
|
+
last_response.should be_ok
|
225
|
+
body.should == 'no' unless verb == :head
|
234
226
|
end
|
235
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain').should be_ok
|
236
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html').should_not be_ok
|
237
|
-
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain').should_not be_ok
|
238
|
-
end
|
239
|
-
end
|
240
|
-
|
241
|
-
describe 'filters' do
|
242
|
-
it 'should trigger before filters for namespaces' do
|
243
|
-
ran = false
|
244
|
-
namespace('/foo') { before { ran = true }}
|
245
|
-
send(verb, '/foo')
|
246
|
-
ran.should be_true
|
247
|
-
end
|
248
227
|
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
228
|
+
specify 'are accepted in the after-filter' do
|
229
|
+
ran = false
|
230
|
+
namespace '/foo' do
|
231
|
+
before(:host_name => 'example.com') { ran = true }
|
232
|
+
send(verb) { 'ok' }
|
233
|
+
end
|
234
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org')
|
235
|
+
ran.should be_false
|
236
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com')
|
237
|
+
ran.should be_true
|
238
|
+
end
|
255
239
|
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
240
|
+
specify 'are accepted in the route definition' do
|
241
|
+
namespace '/foo' do
|
242
|
+
send(verb, :host_name => 'example.com') { 'ok' }
|
243
|
+
end
|
244
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com').should be_ok
|
245
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org').should_not be_ok
|
246
|
+
end
|
262
247
|
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
248
|
+
context 'when the namespace has a condition' do
|
249
|
+
specify 'are accepted in the before-filter' do
|
250
|
+
ran = false
|
251
|
+
namespace '/', :provides => :txt do
|
252
|
+
before(:host_name => 'example.com') { ran = true }
|
253
|
+
send(verb) { 'ok' }
|
254
|
+
end
|
255
|
+
send(verb, '/', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
256
|
+
ran.should be_false
|
257
|
+
send(verb, '/', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
258
|
+
ran.should be_false
|
259
|
+
send(verb, '/', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
260
|
+
ran.should be_true
|
261
|
+
end
|
262
|
+
|
263
|
+
specify 'are accepted in the filters' do
|
264
|
+
ran = false
|
265
|
+
namespace '/f', :provides => :txt do
|
266
|
+
before('oo', :host_name => 'example.com') { ran = true }
|
267
|
+
send(verb, '/*') { 'ok' }
|
268
|
+
end
|
269
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.org', 'HTTP_ACCEPT' => 'text/plain')
|
270
|
+
ran.should be_false
|
271
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/html')
|
272
|
+
ran.should be_false
|
273
|
+
send(verb, '/far', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
274
|
+
ran.should be_false
|
275
|
+
send(verb, '/foo', {}, 'HTTP_HOST' => 'example.com', 'HTTP_ACCEPT' => 'text/plain')
|
276
|
+
ran.should be_true
|
277
|
+
end
|
278
|
+
end
|
268
279
|
end
|
269
280
|
end
|
270
281
|
|
271
282
|
describe 'helpers' do
|
272
|
-
it
|
283
|
+
it 'are defined using the helpers method' do
|
273
284
|
namespace '/foo' do
|
274
285
|
helpers do
|
275
286
|
def magic
|
@@ -286,7 +297,7 @@ describe Sinatra::Namespace do
|
|
286
297
|
body.should == '42' unless verb == :head
|
287
298
|
end
|
288
299
|
|
289
|
-
it
|
300
|
+
it 'can be defined as normal methods' do
|
290
301
|
namespace '/foo' do
|
291
302
|
def magic
|
292
303
|
42
|
@@ -301,7 +312,7 @@ describe Sinatra::Namespace do
|
|
301
312
|
body.should == '42' unless verb == :head
|
302
313
|
end
|
303
314
|
|
304
|
-
it
|
315
|
+
it 'can be defined using module mixins' do
|
305
316
|
mixin = Module.new do
|
306
317
|
def magic
|
307
318
|
42
|
@@ -319,7 +330,7 @@ describe Sinatra::Namespace do
|
|
319
330
|
body.should == '42' unless verb == :head
|
320
331
|
end
|
321
332
|
|
322
|
-
|
333
|
+
specify 'are unavailable outside the namespace where they are defined' do
|
323
334
|
mock_app do
|
324
335
|
namespace '/foo' do
|
325
336
|
def magic
|
@@ -339,7 +350,7 @@ describe Sinatra::Namespace do
|
|
339
350
|
proc { send verb, '/' }.should raise_error(NameError)
|
340
351
|
end
|
341
352
|
|
342
|
-
|
353
|
+
specify 'are unavailable outside the namespace that they are mixed into' do
|
343
354
|
mixin = Module.new do
|
344
355
|
def magic
|
345
356
|
42
|
@@ -362,7 +373,7 @@ describe Sinatra::Namespace do
|
|
362
373
|
proc { send verb, '/' }.should raise_error(NameError)
|
363
374
|
end
|
364
375
|
|
365
|
-
|
376
|
+
specify 'are available to nested namespaces' do
|
366
377
|
mock_app do
|
367
378
|
helpers do
|
368
379
|
def magic
|
@@ -381,7 +392,7 @@ describe Sinatra::Namespace do
|
|
381
392
|
body.should == '42' unless verb == :head
|
382
393
|
end
|
383
394
|
|
384
|
-
|
395
|
+
specify 'can call super from nested definitions' do
|
385
396
|
mock_app do
|
386
397
|
helpers do
|
387
398
|
def magic
|
@@ -436,7 +447,7 @@ describe Sinatra::Namespace do
|
|
436
447
|
body.should == '42' unless verb == :head
|
437
448
|
end
|
438
449
|
|
439
|
-
|
450
|
+
specify 'does not provide access to nested helper methods' do
|
440
451
|
namespace '/foo' do
|
441
452
|
namespace '/bar' do
|
442
453
|
def magic
|
@@ -456,15 +467,15 @@ describe Sinatra::Namespace do
|
|
456
467
|
proc { send verb, '/foo' }.should raise_error(NameError)
|
457
468
|
end
|
458
469
|
|
459
|
-
it '
|
470
|
+
it 'accepts a nested namespace as a named parameter' do
|
460
471
|
namespace('/:a') { namespace('/:b') { send(verb) { params[:a] }}}
|
461
472
|
send(verb, '/foo/bar').should be_ok
|
462
473
|
body.should == 'foo' unless verb == :head
|
463
474
|
end
|
464
475
|
end
|
465
476
|
|
466
|
-
describe 'error
|
467
|
-
it
|
477
|
+
describe 'error handling' do
|
478
|
+
it 'can be customized using the not_found block' do
|
468
479
|
namespace('/de') do
|
469
480
|
not_found { 'nicht gefunden' }
|
470
481
|
end
|
@@ -476,7 +487,7 @@ describe Sinatra::Namespace do
|
|
476
487
|
last_response.body.should == 'nicht gefunden' unless verb == :head
|
477
488
|
end
|
478
489
|
|
479
|
-
it
|
490
|
+
it 'can be customized for specific error codes' do
|
480
491
|
namespace('/de') do
|
481
492
|
error(404) { 'nicht gefunden' }
|
482
493
|
end
|
@@ -488,15 +499,15 @@ describe Sinatra::Namespace do
|
|
488
499
|
last_response.body.should == 'nicht gefunden' unless verb == :head
|
489
500
|
end
|
490
501
|
|
491
|
-
it
|
492
|
-
mock_app
|
502
|
+
it 'falls back to the handler defined in the base app' do
|
503
|
+
mock_app do
|
493
504
|
error(404) { 'not found...' }
|
494
505
|
namespace('/en') do
|
495
506
|
end
|
496
507
|
namespace('/de') do
|
497
508
|
error(404) { 'nicht gefunden' }
|
498
509
|
end
|
499
|
-
|
510
|
+
end
|
500
511
|
send(verb, '/foo').status.should == 404
|
501
512
|
last_response.body.should == 'not found...' unless verb == :head
|
502
513
|
get('/en/foo').status.should == 404
|
@@ -505,25 +516,33 @@ describe Sinatra::Namespace do
|
|
505
516
|
last_response.body.should == 'nicht gefunden' unless verb == :head
|
506
517
|
end
|
507
518
|
|
508
|
-
it
|
509
|
-
mock_app
|
519
|
+
it 'can be customized for specific Exception classes' do
|
520
|
+
mock_app do
|
510
521
|
class AError < StandardError; end
|
511
522
|
class BError < AError; end
|
512
|
-
|
513
|
-
error(AError)
|
523
|
+
|
524
|
+
error(AError) do
|
525
|
+
body('auth failed')
|
526
|
+
401
|
527
|
+
end
|
528
|
+
|
514
529
|
namespace('/en') do
|
515
530
|
get '/foo' do
|
516
531
|
raise BError
|
517
532
|
end
|
518
533
|
end
|
534
|
+
|
519
535
|
namespace('/de') do
|
520
|
-
error(AError)
|
536
|
+
error(AError) do
|
537
|
+
body('methode nicht erlaubt')
|
538
|
+
406
|
539
|
+
end
|
521
540
|
|
522
541
|
get '/foo' do
|
523
542
|
raise BError
|
524
543
|
end
|
525
544
|
end
|
526
|
-
|
545
|
+
end
|
527
546
|
get('/en/foo').status.should == 401
|
528
547
|
last_response.body.should == 'auth failed' unless verb == :head
|
529
548
|
get('/de/foo').status.should == 406
|
@@ -531,91 +550,83 @@ describe Sinatra::Namespace do
|
|
531
550
|
end
|
532
551
|
end
|
533
552
|
|
534
|
-
|
535
|
-
|
536
|
-
|
537
|
-
|
538
|
-
|
539
|
-
|
540
|
-
|
553
|
+
unless verb == :head
|
554
|
+
describe 'templates' do
|
555
|
+
specify 'default to the base app\'s template' do
|
556
|
+
mock_app do
|
557
|
+
template(:foo) { 'hi' }
|
558
|
+
send(verb, '/') { erb :foo }
|
559
|
+
namespace '/foo' do
|
560
|
+
send(verb) { erb :foo }
|
561
|
+
end
|
541
562
|
end
|
542
|
-
end
|
543
563
|
|
544
|
-
|
545
|
-
send(verb, '/').body.should ==
|
546
|
-
send(verb, '/foo').body.should == "hi"
|
564
|
+
send(verb, '/').body.should == 'hi'
|
565
|
+
send(verb, '/foo').body.should == 'hi'
|
547
566
|
end
|
548
|
-
end
|
549
567
|
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
555
|
-
|
556
|
-
|
568
|
+
specify 'can be nested' do
|
569
|
+
mock_app do
|
570
|
+
template(:foo) { 'hi' }
|
571
|
+
send(verb, '/') { erb :foo }
|
572
|
+
namespace '/foo' do
|
573
|
+
template(:foo) { 'ho' }
|
574
|
+
send(verb) { erb :foo }
|
575
|
+
end
|
557
576
|
end
|
558
|
-
end
|
559
577
|
|
560
|
-
|
561
|
-
send(verb, '/').body.should ==
|
562
|
-
send(verb, '/foo').body.should == "ho"
|
578
|
+
send(verb, '/').body.should == 'hi'
|
579
|
+
send(verb, '/foo').body.should == 'ho'
|
563
580
|
end
|
564
|
-
end
|
565
581
|
|
566
|
-
|
567
|
-
|
568
|
-
|
569
|
-
|
570
|
-
|
571
|
-
|
572
|
-
|
573
|
-
|
582
|
+
specify 'can use a custom views directory' do
|
583
|
+
mock_app do
|
584
|
+
set :views, File.expand_path('../namespace', __FILE__)
|
585
|
+
send(verb, '/') { erb :foo }
|
586
|
+
namespace('/foo') do
|
587
|
+
set :views, File.expand_path('../namespace/nested', __FILE__)
|
588
|
+
send(verb) { erb :foo }
|
589
|
+
end
|
574
590
|
end
|
575
|
-
end
|
576
591
|
|
577
|
-
|
578
|
-
send(verb, '/').body.should == "
|
579
|
-
send(verb, '/foo').body.should == "Hi World!"
|
592
|
+
send(verb, '/').body.should == "hi\n"
|
593
|
+
send(verb, '/foo').body.should == "ho\n"
|
580
594
|
end
|
581
|
-
end
|
582
595
|
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
587
|
-
|
588
|
-
|
589
|
-
|
590
|
-
|
596
|
+
specify 'default to the base app\'s layout' do
|
597
|
+
mock_app do
|
598
|
+
layout { 'he said: <%= yield %>' }
|
599
|
+
template(:foo) { 'hi' }
|
600
|
+
send(verb, '/') { erb :foo }
|
601
|
+
namespace '/foo' do
|
602
|
+
template(:foo) { 'ho' }
|
603
|
+
send(verb) { erb :foo }
|
604
|
+
end
|
591
605
|
end
|
592
|
-
end
|
593
606
|
|
594
|
-
|
595
|
-
send(verb, '/').body.should ==
|
596
|
-
send(verb, '/foo').body.should == "he said: ho"
|
607
|
+
send(verb, '/').body.should == 'he said: hi'
|
608
|
+
send(verb, '/foo').body.should == 'he said: ho'
|
597
609
|
end
|
598
|
-
end
|
599
610
|
|
600
|
-
|
601
|
-
|
602
|
-
|
603
|
-
|
604
|
-
|
605
|
-
|
606
|
-
|
611
|
+
specify 'can define nested layouts' do
|
612
|
+
mock_app do
|
613
|
+
layout { 'Hello <%= yield %>!' }
|
614
|
+
template(:foo) { 'World' }
|
615
|
+
send(verb, '/') { erb :foo }
|
616
|
+
namespace '/foo' do
|
617
|
+
layout { 'Hi <%= yield %>!' }
|
618
|
+
send(verb) { erb :foo }
|
619
|
+
end
|
607
620
|
end
|
608
|
-
end
|
609
621
|
|
610
|
-
|
611
|
-
send(verb, '/').body.should ==
|
612
|
-
send(verb, '/foo').body.should == "ho\n"
|
622
|
+
send(verb, '/').body.should == 'Hello World!'
|
623
|
+
send(verb, '/foo').body.should == 'Hi World!'
|
613
624
|
end
|
614
625
|
end
|
615
626
|
end
|
616
627
|
|
617
628
|
describe 'extensions' do
|
618
|
-
|
629
|
+
specify 'provide read access to settings' do
|
619
630
|
value = nil
|
620
631
|
mock_app do
|
621
632
|
set :foo, 42
|
@@ -626,9 +637,9 @@ describe Sinatra::Namespace do
|
|
626
637
|
value.should == 42
|
627
638
|
end
|
628
639
|
|
629
|
-
|
640
|
+
specify 'can be registered within a namespace' do
|
630
641
|
a = b = nil
|
631
|
-
extension = Module.new { define_method(:views) {
|
642
|
+
extension = Module.new { define_method(:views) { 'CUSTOM!!!' } }
|
632
643
|
mock_app do
|
633
644
|
namespace '/' do
|
634
645
|
register extension
|
@@ -640,7 +651,7 @@ describe Sinatra::Namespace do
|
|
640
651
|
b.should_not == 'CUSTOM!!!'
|
641
652
|
end
|
642
653
|
|
643
|
-
|
654
|
+
specify 'trigger the route_added hook' do
|
644
655
|
route = nil
|
645
656
|
extension = Module.new
|
646
657
|
extension.singleton_class.class_eval do
|
@@ -656,7 +667,7 @@ describe Sinatra::Namespace do
|
|
656
667
|
route[1].should == '/foo'
|
657
668
|
end
|
658
669
|
|
659
|
-
|
670
|
+
specify 'prevent app-global settings from being changed' do
|
660
671
|
proc { namespace('/') { set :foo, :bar }}.should raise_error
|
661
672
|
end
|
662
673
|
end
|