rtomayko-sinatra 0.3.3 → 0.8.9
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/AUTHORS +40 -0
- data/CHANGES +167 -0
- data/README.rdoc +104 -98
- data/Rakefile +27 -9
- data/{test → compat}/app_test.rb +11 -10
- data/{test → compat}/application_test.rb +10 -5
- data/compat/builder_test.rb +101 -0
- data/{test → compat}/custom_error_test.rb +0 -0
- data/compat/erb_test.rb +136 -0
- data/{test → compat}/events_test.rb +12 -2
- data/compat/filter_test.rb +30 -0
- data/compat/haml_test.rb +233 -0
- data/compat/helper.rb +21 -0
- data/compat/mapped_error_test.rb +72 -0
- data/{test → compat}/pipeline_test.rb +9 -4
- data/{test → compat}/public/foo.xml +0 -0
- data/compat/sass_test.rb +57 -0
- data/{test → compat}/sessions_test.rb +0 -0
- data/{test → compat}/streaming_test.rb +4 -1
- data/{test → compat}/sym_params_test.rb +0 -0
- data/{test → compat}/template_test.rb +0 -0
- data/{test → compat}/use_in_file_templates_test.rb +0 -0
- data/{test → compat}/views/foo.builder +0 -0
- data/{test → compat}/views/foo.erb +0 -0
- data/{test → compat}/views/foo.haml +0 -0
- data/{test → compat}/views/foo.sass +0 -0
- data/{test → compat}/views/foo_layout.erb +0 -0
- data/{test → compat}/views/foo_layout.haml +0 -0
- data/{test → compat}/views/layout_test/foo.builder +0 -0
- data/{test → compat}/views/layout_test/foo.erb +0 -0
- data/{test → compat}/views/layout_test/foo.haml +0 -0
- data/{test → compat}/views/layout_test/foo.sass +0 -0
- data/{test → compat}/views/layout_test/layout.builder +0 -0
- data/{test → compat}/views/layout_test/layout.erb +0 -0
- data/{test → compat}/views/layout_test/layout.haml +0 -0
- data/{test → compat}/views/layout_test/layout.sass +0 -0
- data/{test → compat}/views/no_layout/no_layout.builder +0 -0
- data/{test → compat}/views/no_layout/no_layout.haml +0 -0
- data/lib/sinatra/base.rb +818 -0
- data/lib/sinatra/compat.rb +239 -0
- data/{images → lib/sinatra/images}/404.png +0 -0
- data/{images → lib/sinatra/images}/500.png +0 -0
- data/lib/sinatra/main.rb +48 -0
- data/lib/sinatra/test/rspec.rb +1 -9
- data/lib/sinatra/test/spec.rb +1 -9
- data/lib/sinatra/test/unit.rb +3 -5
- data/lib/sinatra/test.rb +112 -0
- data/lib/sinatra.rb +3 -1486
- data/sinatra.gemspec +66 -36
- data/test/base_test.rb +72 -0
- data/test/builder_test.rb +56 -89
- data/test/data/reload_app_file.rb +3 -0
- data/test/erb_test.rb +44 -125
- data/test/filter_test.rb +29 -20
- data/test/haml_test.rb +57 -218
- data/test/helpers_test.rb +368 -0
- data/test/mapped_error_test.rb +141 -49
- data/test/middleware_test.rb +63 -0
- data/test/options_test.rb +103 -0
- data/test/reload_test.rb +65 -0
- data/test/request_test.rb +11 -0
- data/test/result_test.rb +92 -0
- data/test/routing_test.rb +338 -0
- data/test/sass_test.rb +33 -50
- data/test/sinatra_test.rb +15 -0
- data/test/static_test.rb +60 -0
- data/test/templates_test.rb +92 -0
- data/test/views/hello.builder +1 -0
- data/test/views/hello.erb +1 -0
- data/test/views/hello.haml +1 -0
- data/test/views/hello.sass +2 -0
- data/test/views/hello.test +1 -0
- data/test/views/layout2.builder +3 -0
- data/test/views/layout2.erb +2 -0
- data/test/views/layout2.haml +2 -0
- data/test/views/layout2.test +1 -0
- metadata +78 -48
- data/ChangeLog +0 -96
- data/lib/sinatra/test/methods.rb +0 -76
- data/test/event_context_test.rb +0 -15
- data/test/helper.rb +0 -9
@@ -0,0 +1,338 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'sinatra/test'
|
4
|
+
|
5
|
+
describe "Routing" do
|
6
|
+
include Sinatra::Test
|
7
|
+
|
8
|
+
%w[get put post delete head].each do |verb|
|
9
|
+
it "defines #{verb.upcase} request handlers with #{verb}" do
|
10
|
+
mock_app {
|
11
|
+
send verb, '/hello' do
|
12
|
+
'Hello World'
|
13
|
+
end
|
14
|
+
}
|
15
|
+
|
16
|
+
request = Rack::MockRequest.new(@app)
|
17
|
+
response = request.request(verb.upcase, '/hello', {})
|
18
|
+
response.should.be.ok
|
19
|
+
response.body.should.equal 'Hello World'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "404s when no route satisfies the request" do
|
24
|
+
mock_app {
|
25
|
+
get('/foo') { }
|
26
|
+
}
|
27
|
+
get '/bar'
|
28
|
+
status.should.equal 404
|
29
|
+
end
|
30
|
+
|
31
|
+
it "exposes params with indifferent hash" do
|
32
|
+
mock_app {
|
33
|
+
get '/:foo' do
|
34
|
+
params['foo'].should.equal 'bar'
|
35
|
+
params[:foo].should.equal 'bar'
|
36
|
+
'well, alright'
|
37
|
+
end
|
38
|
+
}
|
39
|
+
get '/bar'
|
40
|
+
body.should.equal 'well, alright'
|
41
|
+
end
|
42
|
+
|
43
|
+
it "merges named params and query string params in params" do
|
44
|
+
mock_app {
|
45
|
+
get '/:foo' do
|
46
|
+
params['foo'].should.equal 'bar'
|
47
|
+
params['baz'].should.equal 'biz'
|
48
|
+
end
|
49
|
+
}
|
50
|
+
get '/bar?baz=biz'
|
51
|
+
should.be.ok
|
52
|
+
end
|
53
|
+
|
54
|
+
it "supports named params like /hello/:person" do
|
55
|
+
mock_app {
|
56
|
+
get '/hello/:person' do
|
57
|
+
"Hello #{params['person']}"
|
58
|
+
end
|
59
|
+
}
|
60
|
+
get '/hello/Frank'
|
61
|
+
body.should.equal 'Hello Frank'
|
62
|
+
end
|
63
|
+
|
64
|
+
it "supports optional named params like /?:foo?/?:bar?" do
|
65
|
+
mock_app {
|
66
|
+
get '/?:foo?/?:bar?' do
|
67
|
+
"foo=#{params[:foo]};bar=#{params[:bar]}"
|
68
|
+
end
|
69
|
+
}
|
70
|
+
|
71
|
+
get '/hello/world'
|
72
|
+
should.be.ok
|
73
|
+
body.should.equal "foo=hello;bar=world"
|
74
|
+
|
75
|
+
get '/hello'
|
76
|
+
should.be.ok
|
77
|
+
body.should.equal "foo=hello;bar="
|
78
|
+
|
79
|
+
get '/'
|
80
|
+
should.be.ok
|
81
|
+
body.should.equal "foo=;bar="
|
82
|
+
end
|
83
|
+
|
84
|
+
it "supports single splat params like /*" do
|
85
|
+
mock_app {
|
86
|
+
get '/*' do
|
87
|
+
params['splat'].should.be.kind_of Array
|
88
|
+
params['splat'].join "\n"
|
89
|
+
end
|
90
|
+
}
|
91
|
+
|
92
|
+
get '/foo'
|
93
|
+
body.should.equal "foo"
|
94
|
+
|
95
|
+
get '/foo/bar/baz'
|
96
|
+
body.should.equal "foo/bar/baz"
|
97
|
+
end
|
98
|
+
|
99
|
+
it "supports mixing multiple splat params like /*/foo/*/*" do
|
100
|
+
mock_app {
|
101
|
+
get '/*/foo/*/*' do
|
102
|
+
params['splat'].should.be.kind_of Array
|
103
|
+
params['splat'].join "\n"
|
104
|
+
end
|
105
|
+
}
|
106
|
+
|
107
|
+
get '/bar/foo/bling/baz/boom'
|
108
|
+
body.should.equal "bar\nbling\nbaz/boom"
|
109
|
+
|
110
|
+
get '/bar/foo/baz'
|
111
|
+
should.be.not_found
|
112
|
+
end
|
113
|
+
|
114
|
+
it "supports mixing named and splat params like /:foo/*" do
|
115
|
+
mock_app {
|
116
|
+
get '/:foo/*' do
|
117
|
+
params['foo'].should.equal 'foo'
|
118
|
+
params['splat'].should.equal ['bar/baz']
|
119
|
+
end
|
120
|
+
}
|
121
|
+
|
122
|
+
get '/foo/bar/baz'
|
123
|
+
should.be.ok
|
124
|
+
end
|
125
|
+
|
126
|
+
it "supports paths that include spaces" do
|
127
|
+
mock_app {
|
128
|
+
get '/path with spaces' do
|
129
|
+
'looks good'
|
130
|
+
end
|
131
|
+
}
|
132
|
+
|
133
|
+
get '/path%20with%20spaces'
|
134
|
+
should.be.ok
|
135
|
+
body.should.equal 'looks good'
|
136
|
+
end
|
137
|
+
|
138
|
+
it "URL decodes named parameters and splats" do
|
139
|
+
mock_app {
|
140
|
+
get '/:foo/*' do
|
141
|
+
params['foo'].should.equal 'hello world'
|
142
|
+
params['splat'].should.equal ['how are you']
|
143
|
+
nil
|
144
|
+
end
|
145
|
+
}
|
146
|
+
|
147
|
+
get '/hello%20world/how%20are%20you'
|
148
|
+
should.be.ok
|
149
|
+
end
|
150
|
+
|
151
|
+
it 'supports regular expressions' do
|
152
|
+
mock_app {
|
153
|
+
get(/^\/foo...\/bar$/) do
|
154
|
+
'Hello World'
|
155
|
+
end
|
156
|
+
}
|
157
|
+
|
158
|
+
get '/foooom/bar'
|
159
|
+
should.be.ok
|
160
|
+
body.should.equal 'Hello World'
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'makes regular expression captures available in params[:captures]' do
|
164
|
+
mock_app {
|
165
|
+
get(/^\/fo(.*)\/ba(.*)/) do
|
166
|
+
params[:captures].should.equal ['orooomma', 'f']
|
167
|
+
'right on'
|
168
|
+
end
|
169
|
+
}
|
170
|
+
|
171
|
+
get '/foorooomma/baf'
|
172
|
+
should.be.ok
|
173
|
+
body.should.equal 'right on'
|
174
|
+
end
|
175
|
+
|
176
|
+
it "returns response immediately on halt" do
|
177
|
+
mock_app {
|
178
|
+
get '/' do
|
179
|
+
halt 'Hello World'
|
180
|
+
'Boo-hoo World'
|
181
|
+
end
|
182
|
+
}
|
183
|
+
|
184
|
+
get '/'
|
185
|
+
should.be.ok
|
186
|
+
body.should.equal 'Hello World'
|
187
|
+
end
|
188
|
+
|
189
|
+
it "transitions to the next matching route on pass" do
|
190
|
+
mock_app {
|
191
|
+
get '/:foo' do
|
192
|
+
pass
|
193
|
+
'Hello Foo'
|
194
|
+
end
|
195
|
+
|
196
|
+
get '/*' do
|
197
|
+
params.should.not.include 'foo'
|
198
|
+
'Hello World'
|
199
|
+
end
|
200
|
+
}
|
201
|
+
|
202
|
+
get '/bar'
|
203
|
+
should.be.ok
|
204
|
+
body.should.equal 'Hello World'
|
205
|
+
end
|
206
|
+
|
207
|
+
it "transitions to 404 when passed and no subsequent route matches" do
|
208
|
+
mock_app {
|
209
|
+
get '/:foo' do
|
210
|
+
pass
|
211
|
+
'Hello Foo'
|
212
|
+
end
|
213
|
+
}
|
214
|
+
|
215
|
+
get '/bar'
|
216
|
+
should.be.not_found
|
217
|
+
end
|
218
|
+
|
219
|
+
it "passes when matching condition returns false" do
|
220
|
+
mock_app {
|
221
|
+
condition { params[:foo] == 'bar' }
|
222
|
+
get '/:foo' do
|
223
|
+
'Hello World'
|
224
|
+
end
|
225
|
+
}
|
226
|
+
|
227
|
+
get '/bar'
|
228
|
+
should.be.ok
|
229
|
+
body.should.equal 'Hello World'
|
230
|
+
|
231
|
+
get '/foo'
|
232
|
+
should.be.not_found
|
233
|
+
end
|
234
|
+
|
235
|
+
it "does not pass when matching condition returns nil" do
|
236
|
+
mock_app {
|
237
|
+
condition { nil }
|
238
|
+
get '/:foo' do
|
239
|
+
'Hello World'
|
240
|
+
end
|
241
|
+
}
|
242
|
+
|
243
|
+
get '/bar'
|
244
|
+
should.be.ok
|
245
|
+
body.should.equal 'Hello World'
|
246
|
+
end
|
247
|
+
|
248
|
+
it "passes to next route when condition calls pass explicitly" do
|
249
|
+
mock_app {
|
250
|
+
condition { pass unless params[:foo] == 'bar' }
|
251
|
+
get '/:foo' do
|
252
|
+
'Hello World'
|
253
|
+
end
|
254
|
+
}
|
255
|
+
|
256
|
+
get '/bar'
|
257
|
+
should.be.ok
|
258
|
+
body.should.equal 'Hello World'
|
259
|
+
|
260
|
+
get '/foo'
|
261
|
+
should.be.not_found
|
262
|
+
end
|
263
|
+
|
264
|
+
it "passes to the next route when host_name does not match" do
|
265
|
+
mock_app {
|
266
|
+
host_name 'example.com'
|
267
|
+
get '/foo' do
|
268
|
+
'Hello World'
|
269
|
+
end
|
270
|
+
}
|
271
|
+
get '/foo'
|
272
|
+
should.be.not_found
|
273
|
+
|
274
|
+
get '/foo', :env => { 'HTTP_HOST' => 'example.com' }
|
275
|
+
status.should.equal 200
|
276
|
+
body.should.equal 'Hello World'
|
277
|
+
end
|
278
|
+
|
279
|
+
it "passes to the next route when user_agent does not match" do
|
280
|
+
mock_app {
|
281
|
+
user_agent(/Foo/)
|
282
|
+
get '/foo' do
|
283
|
+
'Hello World'
|
284
|
+
end
|
285
|
+
}
|
286
|
+
get '/foo'
|
287
|
+
should.be.not_found
|
288
|
+
|
289
|
+
get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
|
290
|
+
status.should.equal 200
|
291
|
+
body.should.equal 'Hello World'
|
292
|
+
end
|
293
|
+
|
294
|
+
it "makes captures in user agent pattern available in params[:agent]" do
|
295
|
+
mock_app {
|
296
|
+
user_agent(/Foo (.*)/)
|
297
|
+
get '/foo' do
|
298
|
+
'Hello ' + params[:agent].first
|
299
|
+
end
|
300
|
+
}
|
301
|
+
get '/foo', :env => { 'HTTP_USER_AGENT' => 'Foo Bar' }
|
302
|
+
status.should.equal 200
|
303
|
+
body.should.equal 'Hello Bar'
|
304
|
+
end
|
305
|
+
|
306
|
+
it "filters by accept header" do
|
307
|
+
mock_app {
|
308
|
+
get '/', :provides => :xml do
|
309
|
+
request.env['HTTP_ACCEPT']
|
310
|
+
end
|
311
|
+
}
|
312
|
+
|
313
|
+
get '/', :env => { :accept => 'application/xml' }
|
314
|
+
should.be.ok
|
315
|
+
body.should.equal 'application/xml'
|
316
|
+
response.headers['Content-Type'].should.equal 'application/xml'
|
317
|
+
|
318
|
+
get '/', :env => { :accept => 'text/html' }
|
319
|
+
should.not.be.ok
|
320
|
+
end
|
321
|
+
|
322
|
+
it "allows multiple mime types for accept header" do
|
323
|
+
types = ['image/jpeg', 'image/pjpeg']
|
324
|
+
|
325
|
+
mock_app {
|
326
|
+
get '/', :provides => types do
|
327
|
+
request.env['HTTP_ACCEPT']
|
328
|
+
end
|
329
|
+
}
|
330
|
+
|
331
|
+
types.each do |type|
|
332
|
+
get '/', :env => { :accept => type }
|
333
|
+
should.be.ok
|
334
|
+
body.should.equal type
|
335
|
+
response.headers['Content-Type'].should.equal type
|
336
|
+
end
|
337
|
+
end
|
338
|
+
end
|
data/test/sass_test.rb
CHANGED
@@ -1,57 +1,40 @@
|
|
1
|
-
require
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
1
|
+
require 'test/spec'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'sinatra/test'
|
4
|
+
|
5
|
+
describe "Sass Templates" do
|
6
|
+
include Sinatra::Test
|
7
|
+
|
8
|
+
def sass_app(&block)
|
9
|
+
mock_app {
|
10
|
+
set :views, File.dirname(__FILE__) + '/views'
|
11
|
+
get '/', &block
|
12
|
+
}
|
13
|
+
get '/'
|
7
14
|
end
|
8
15
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
specify "are read from files if Symbols" do
|
16
|
-
|
17
|
-
get '/from_file' do
|
18
|
-
sass :foo, :views_directory => File.dirname(__FILE__) + "/views"
|
19
|
-
end
|
20
|
-
|
21
|
-
get_it '/from_file'
|
22
|
-
should.be.ok
|
23
|
-
body.should.equal "#sass {\n background_color: #FFF; }\n"
|
24
|
-
|
25
|
-
end
|
26
|
-
|
27
|
-
specify "raise an error if template not found" do
|
28
|
-
get '/' do
|
29
|
-
sass :not_found
|
30
|
-
end
|
31
|
-
|
32
|
-
lambda { get_it '/' }.should.raise(Errno::ENOENT)
|
33
|
-
end
|
34
|
-
|
35
|
-
specify "ignore default layout file with .sass extension" do
|
36
|
-
get '/' do
|
37
|
-
sass :foo, :views_directory => File.dirname(__FILE__) + "/views/layout_test"
|
38
|
-
end
|
39
|
-
|
40
|
-
get_it '/'
|
41
|
-
should.be.ok
|
42
|
-
body.should.equal "#sass {\n background_color: #FFF; }\n"
|
43
|
-
end
|
44
|
-
|
45
|
-
specify "ignore explicitly specified layout file" do
|
46
|
-
get '/' do
|
47
|
-
sass :foo, :layout => :layout, :views_directory => File.dirname(__FILE__) + "/views/layout_test"
|
48
|
-
end
|
16
|
+
it 'renders inline Sass strings' do
|
17
|
+
sass_app { sass "#sass\n :background-color #FFF\n" }
|
18
|
+
should.be.ok
|
19
|
+
body.should.equal "#sass {\n background-color: #FFF; }\n"
|
20
|
+
end
|
49
21
|
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
22
|
+
it 'renders .sass files in views path' do
|
23
|
+
sass_app { sass :hello }
|
24
|
+
should.be.ok
|
25
|
+
body.should.equal "#sass {\n background-color: #FFF; }\n"
|
26
|
+
end
|
54
27
|
|
28
|
+
it 'ignores the layout option' do
|
29
|
+
sass_app { sass :hello, :layout => :layout2 }
|
30
|
+
should.be.ok
|
31
|
+
body.should.equal "#sass {\n background-color: #FFF; }\n"
|
55
32
|
end
|
56
33
|
|
34
|
+
it "raises error if template not found" do
|
35
|
+
mock_app {
|
36
|
+
get('/') { sass :no_such_template }
|
37
|
+
}
|
38
|
+
lambda { get('/') }.should.raise(Errno::ENOENT)
|
39
|
+
end
|
57
40
|
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'sinatra/test'
|
4
|
+
|
5
|
+
describe 'Sinatra' do
|
6
|
+
it 'creates a new Sinatra::Base subclass on new' do
|
7
|
+
app =
|
8
|
+
Sinatra.new do
|
9
|
+
get '/' do
|
10
|
+
'Hello World'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
app.superclass.should.be Sinatra::Base
|
14
|
+
end
|
15
|
+
end
|
data/test/static_test.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'sinatra/test'
|
4
|
+
|
5
|
+
describe 'Static' do
|
6
|
+
include Sinatra::Test
|
7
|
+
F = ::File
|
8
|
+
|
9
|
+
before do
|
10
|
+
@app = mock_app {
|
11
|
+
set :static, true
|
12
|
+
set :public, F.dirname(__FILE__)
|
13
|
+
}
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'serves GET requests for files in the public directory' do
|
17
|
+
get "/#{F.basename(__FILE__)}"
|
18
|
+
should.be.ok
|
19
|
+
body.should.equal File.read(__FILE__)
|
20
|
+
response['Content-Length'].should.equal File.size(__FILE__).to_s
|
21
|
+
response.headers.should.include 'Last-Modified'
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'serves HEAD requests for files in the public directory' do
|
25
|
+
head "/#{F.basename(__FILE__)}"
|
26
|
+
should.be.ok
|
27
|
+
body.should.be.empty
|
28
|
+
response['Content-Length'].should.equal File.size(__FILE__).to_s
|
29
|
+
response.headers.should.include 'Last-Modified'
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'serves files in preference to custom routes' do
|
33
|
+
@app.get("/#{F.basename(__FILE__)}") { 'Hello World' }
|
34
|
+
get "/#{F.basename(__FILE__)}"
|
35
|
+
should.be.ok
|
36
|
+
body.should.not.equal 'Hello World'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'does not serve directories' do
|
40
|
+
get "/"
|
41
|
+
should.be.not_found
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'passes to the next handler when the static option is disabled' do
|
45
|
+
@app.set :static, false
|
46
|
+
get "/#{F.basename(__FILE__)}"
|
47
|
+
should.be.not_found
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'passes to the next handler when the public option is nil' do
|
51
|
+
@app.set :public, nil
|
52
|
+
get "/#{F.basename(__FILE__)}"
|
53
|
+
should.be.not_found
|
54
|
+
end
|
55
|
+
|
56
|
+
it '404s when a file is not found' do
|
57
|
+
get "/foobarbaz.txt"
|
58
|
+
should.be.not_found
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'test/spec'
|
2
|
+
require 'sinatra/base'
|
3
|
+
require 'sinatra/test'
|
4
|
+
|
5
|
+
describe 'Templating' do
|
6
|
+
include Sinatra::Test
|
7
|
+
|
8
|
+
def render_app(&block)
|
9
|
+
mock_app {
|
10
|
+
def render_test(template, data, options, &block)
|
11
|
+
inner = block ? block.call : ''
|
12
|
+
data + inner
|
13
|
+
end
|
14
|
+
set :views, File.dirname(__FILE__) + '/views'
|
15
|
+
get '/', &block
|
16
|
+
template(:layout3) { "Layout 3!\n" }
|
17
|
+
}
|
18
|
+
get '/'
|
19
|
+
end
|
20
|
+
|
21
|
+
def with_default_layout
|
22
|
+
layout = File.dirname(__FILE__) + '/views/layout.test'
|
23
|
+
File.open(layout, 'wb') { |io| io.write "Layout!\n" }
|
24
|
+
yield
|
25
|
+
ensure
|
26
|
+
File.unlink(layout) rescue nil
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'renders String templates directly' do
|
30
|
+
render_app { render :test, 'Hello World' }
|
31
|
+
should.be.ok
|
32
|
+
body.should.equal 'Hello World'
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'renders Proc templates using the call result' do
|
36
|
+
render_app { render :test, Proc.new {'Hello World'} }
|
37
|
+
should.be.ok
|
38
|
+
body.should.equal 'Hello World'
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'looks up Symbol templates in views directory' do
|
42
|
+
render_app { render :test, :hello }
|
43
|
+
should.be.ok
|
44
|
+
body.should.equal "Hello World!\n"
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'uses the default layout template if not explicitly overridden' do
|
48
|
+
with_default_layout do
|
49
|
+
render_app { render :test, :hello }
|
50
|
+
should.be.ok
|
51
|
+
body.should.equal "Layout!\nHello World!\n"
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'uses the default layout template if not really overriden' do
|
56
|
+
with_default_layout do
|
57
|
+
render_app { render :test, :hello, :layout => true }
|
58
|
+
should.be.ok
|
59
|
+
body.should.equal "Layout!\nHello World!\n"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'uses the layout template specified' do
|
64
|
+
render_app { render :test, :hello, :layout => :layout2 }
|
65
|
+
should.be.ok
|
66
|
+
body.should.equal "Layout 2!\nHello World!\n"
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'uses layout templates defined with the #template method' do
|
70
|
+
render_app { render :test, :hello, :layout => :layout3 }
|
71
|
+
should.be.ok
|
72
|
+
body.should.equal "Layout 3!\nHello World!\n"
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'loads templates from source file with use_in_file_templates!' do
|
76
|
+
mock_app {
|
77
|
+
use_in_file_templates!
|
78
|
+
}
|
79
|
+
@app.templates[:foo].should.equal "this is foo\n\n"
|
80
|
+
@app.templates[:layout].should.equal "X\n= yield\nX\n"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
__END__
|
85
|
+
|
86
|
+
@@ foo
|
87
|
+
this is foo
|
88
|
+
|
89
|
+
@@ layout
|
90
|
+
X
|
91
|
+
= yield
|
92
|
+
X
|
@@ -0,0 +1 @@
|
|
1
|
+
xml.exclaim "You're my boy, #{@name}!"
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello <%= 'World' %>
|
@@ -0,0 +1 @@
|
|
1
|
+
%h1 Hello From Haml
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello World!
|
@@ -0,0 +1 @@
|
|
1
|
+
Layout 2!
|