adamwiggins-sinatra 0.8.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (78) hide show
  1. data/AUTHORS +40 -0
  2. data/CHANGES +167 -0
  3. data/LICENSE +22 -0
  4. data/README.rdoc +529 -0
  5. data/Rakefile +180 -0
  6. data/compat/app_test.rb +300 -0
  7. data/compat/application_test.rb +334 -0
  8. data/compat/builder_test.rb +101 -0
  9. data/compat/custom_error_test.rb +62 -0
  10. data/compat/erb_test.rb +136 -0
  11. data/compat/events_test.rb +75 -0
  12. data/compat/filter_test.rb +30 -0
  13. data/compat/haml_test.rb +233 -0
  14. data/compat/helper.rb +21 -0
  15. data/compat/mapped_error_test.rb +72 -0
  16. data/compat/pipeline_test.rb +71 -0
  17. data/compat/public/foo.xml +1 -0
  18. data/compat/sass_test.rb +57 -0
  19. data/compat/sessions_test.rb +39 -0
  20. data/compat/streaming_test.rb +121 -0
  21. data/compat/sym_params_test.rb +19 -0
  22. data/compat/template_test.rb +30 -0
  23. data/compat/use_in_file_templates_test.rb +47 -0
  24. data/compat/views/foo.builder +1 -0
  25. data/compat/views/foo.erb +1 -0
  26. data/compat/views/foo.haml +1 -0
  27. data/compat/views/foo.sass +2 -0
  28. data/compat/views/foo_layout.erb +2 -0
  29. data/compat/views/foo_layout.haml +2 -0
  30. data/compat/views/layout_test/foo.builder +1 -0
  31. data/compat/views/layout_test/foo.erb +1 -0
  32. data/compat/views/layout_test/foo.haml +1 -0
  33. data/compat/views/layout_test/foo.sass +2 -0
  34. data/compat/views/layout_test/layout.builder +3 -0
  35. data/compat/views/layout_test/layout.erb +1 -0
  36. data/compat/views/layout_test/layout.haml +1 -0
  37. data/compat/views/layout_test/layout.sass +2 -0
  38. data/compat/views/no_layout/no_layout.builder +1 -0
  39. data/compat/views/no_layout/no_layout.haml +1 -0
  40. data/lib/sinatra/base.rb +818 -0
  41. data/lib/sinatra/compat.rb +239 -0
  42. data/lib/sinatra/images/404.png +0 -0
  43. data/lib/sinatra/images/500.png +0 -0
  44. data/lib/sinatra/main.rb +48 -0
  45. data/lib/sinatra/test/rspec.rb +2 -0
  46. data/lib/sinatra/test/spec.rb +2 -0
  47. data/lib/sinatra/test/unit.rb +11 -0
  48. data/lib/sinatra/test.rb +112 -0
  49. data/lib/sinatra.rb +3 -0
  50. data/sinatra.gemspec +107 -0
  51. data/test/base_test.rb +72 -0
  52. data/test/builder_test.rb +68 -0
  53. data/test/data/reload_app_file.rb +3 -0
  54. data/test/erb_test.rb +55 -0
  55. data/test/filter_test.rb +39 -0
  56. data/test/haml_test.rb +72 -0
  57. data/test/helpers_test.rb +368 -0
  58. data/test/mapped_error_test.rb +164 -0
  59. data/test/middleware_test.rb +63 -0
  60. data/test/options_test.rb +103 -0
  61. data/test/reload_test.rb +65 -0
  62. data/test/request_test.rb +11 -0
  63. data/test/result_test.rb +92 -0
  64. data/test/routing_test.rb +338 -0
  65. data/test/sass_test.rb +40 -0
  66. data/test/sinatra_test.rb +15 -0
  67. data/test/static_test.rb +60 -0
  68. data/test/templates_test.rb +92 -0
  69. data/test/views/hello.builder +1 -0
  70. data/test/views/hello.erb +1 -0
  71. data/test/views/hello.haml +1 -0
  72. data/test/views/hello.sass +2 -0
  73. data/test/views/hello.test +1 -0
  74. data/test/views/layout2.builder +3 -0
  75. data/test/views/layout2.erb +2 -0
  76. data/test/views/layout2.haml +2 -0
  77. data/test/views/layout2.test +1 -0
  78. metadata +159 -0
@@ -0,0 +1,63 @@
1
+ require 'test/spec'
2
+ require 'sinatra/base'
3
+ require 'sinatra/test'
4
+
5
+ describe "Middleware" do
6
+ include Sinatra::Test
7
+
8
+ before do
9
+ @app = mock_app(Sinatra::Default) {
10
+ get '/*' do
11
+ response.headers['X-Tests'] = env['test.ran'].join(', ')
12
+ env['PATH_INFO']
13
+ end
14
+ }
15
+ end
16
+
17
+ class MockMiddleware < Struct.new(:app)
18
+ def call(env)
19
+ (env['test.ran'] ||= []) << self.class.to_s
20
+ app.call(env)
21
+ end
22
+ end
23
+
24
+ class UpcaseMiddleware < MockMiddleware
25
+ def call(env)
26
+ env['PATH_INFO'] = env['PATH_INFO'].upcase
27
+ super
28
+ end
29
+ end
30
+
31
+ it "is added with Sinatra::Application.use" do
32
+ @app.use UpcaseMiddleware
33
+ get '/hello-world'
34
+ response.should.be.ok
35
+ body.should.equal '/HELLO-WORLD'
36
+ end
37
+
38
+ class DowncaseMiddleware < MockMiddleware
39
+ def call(env)
40
+ env['PATH_INFO'] = env['PATH_INFO'].downcase
41
+ super
42
+ end
43
+ end
44
+
45
+ specify "runs in the order defined" do
46
+ @app.use UpcaseMiddleware
47
+ @app.use DowncaseMiddleware
48
+ get '/Foo'
49
+ body.should.equal "/foo"
50
+ response['X-Tests'].should.equal "UpcaseMiddleware, DowncaseMiddleware"
51
+ end
52
+
53
+ specify "resets the prebuilt pipeline when new middleware is added" do
54
+ @app.use UpcaseMiddleware
55
+ get '/Foo'
56
+ body.should.equal "/FOO"
57
+ @app.use DowncaseMiddleware
58
+ get '/Foo'
59
+ body.should.equal '/foo'
60
+ response['X-Tests'].should.equal "UpcaseMiddleware, DowncaseMiddleware"
61
+ end
62
+
63
+ end
@@ -0,0 +1,103 @@
1
+ require 'test/spec'
2
+ require 'sinatra/base'
3
+ require 'sinatra/test'
4
+
5
+ describe 'Options' do
6
+ include Sinatra::Test
7
+
8
+ before do
9
+ @app = Class.new(Sinatra::Base)
10
+ end
11
+
12
+ it 'sets options to literal values' do
13
+ @app.set(:foo, 'bar')
14
+ @app.should.respond_to? :foo
15
+ @app.foo.should.equal 'bar'
16
+ end
17
+
18
+ it 'sets options to Procs' do
19
+ @app.set(:foo, Proc.new { 'baz' })
20
+ @app.should.respond_to? :foo
21
+ @app.foo.should.equal 'baz'
22
+ end
23
+
24
+ it "sets multiple options with a Hash" do
25
+ @app.set :foo => 1234,
26
+ :bar => 'Hello World',
27
+ :baz => Proc.new { 'bizzle' }
28
+ @app.foo.should.equal 1234
29
+ @app.bar.should.equal 'Hello World'
30
+ @app.baz.should.equal 'bizzle'
31
+ end
32
+
33
+ it 'inherits option methods when subclassed' do
34
+ @app.set :foo, 'bar'
35
+ @app.set :biz, Proc.new { 'baz' }
36
+
37
+ sub = Class.new(@app)
38
+ sub.should.respond_to :foo
39
+ sub.foo.should.equal 'bar'
40
+ sub.should.respond_to :biz
41
+ sub.biz.should.equal 'baz'
42
+ end
43
+
44
+ it 'overrides options in subclass' do
45
+ @app.set :foo, 'bar'
46
+ @app.set :biz, Proc.new { 'baz' }
47
+ sub = Class.new(@app)
48
+ sub.set :foo, 'bling'
49
+ sub.foo.should.equal 'bling'
50
+ @app.foo.should.equal 'bar'
51
+ end
52
+
53
+ it 'creates setter methods when first defined' do
54
+ @app.set :foo, 'bar'
55
+ @app.should.respond_to 'foo='
56
+ @app.foo = 'biz'
57
+ @app.foo.should.equal 'biz'
58
+ end
59
+
60
+ it 'creates predicate methods when first defined' do
61
+ @app.set :foo, 'hello world'
62
+ @app.should.respond_to :foo?
63
+ @app.foo?.should.be true
64
+ @app.set :foo, nil
65
+ @app.foo?.should.be false
66
+ end
67
+
68
+ it 'uses existing setter methods if detected' do
69
+ class << @app
70
+ def foo
71
+ @foo
72
+ end
73
+ def foo=(value)
74
+ @foo = 'oops'
75
+ end
76
+ end
77
+
78
+ @app.set :foo, 'bam'
79
+ @app.foo.should.equal 'oops'
80
+ end
81
+
82
+ it "sets multiple options to true with #enable" do
83
+ @app.enable :sessions, :foo, :bar
84
+ @app.sessions.should.be true
85
+ @app.foo.should.be true
86
+ @app.bar.should.be true
87
+ end
88
+
89
+ it "sets multiple options to false with #disable" do
90
+ @app.disable :sessions, :foo, :bar
91
+ @app.sessions.should.be false
92
+ @app.foo.should.be false
93
+ @app.bar.should.be false
94
+ end
95
+
96
+ it 'enables MethodOverride middleware when :methodoverride is enabled' do
97
+ @app.set :methodoverride, true
98
+ @app.put('/') { 'okay' }
99
+ post '/', {'_method'=>'PUT'}, {}
100
+ status.should.equal 200
101
+ body.should.equal 'okay'
102
+ end
103
+ end
@@ -0,0 +1,65 @@
1
+ require 'test/spec'
2
+ require 'sinatra/base'
3
+ require 'sinatra/test'
4
+
5
+ $reload_count = 0
6
+ $reload_app = nil
7
+
8
+ describe "Reloading" do
9
+ include Sinatra::Test
10
+
11
+ before {
12
+ @app = mock_app(Sinatra::Default)
13
+ $reload_app = @app
14
+ }
15
+
16
+ after {
17
+ $reload_app = nil
18
+ }
19
+
20
+ it 'is enabled by default when in development and the app_file is set' do
21
+ @app.set :app_file, __FILE__
22
+ @app.set :environment, :development
23
+ @app.reload.should.be true
24
+ @app.reload?.should.be true
25
+ end
26
+
27
+ it 'is disabled by default when running in non-development environment' do
28
+ @app.set :app_file, __FILE__
29
+ @app.set :environment, :test
30
+ @app.reload.should.not.be true
31
+ @app.reload?.should.be false
32
+ end
33
+
34
+ it 'is disabled by default when no app_file is available' do
35
+ @app.set :app_file, nil
36
+ @app.set :environment, :development
37
+ @app.reload.should.not.be true
38
+ @app.reload?.should.be false
39
+ end
40
+
41
+ it 'can be turned off explicitly' do
42
+ @app.set :app_file, __FILE__
43
+ @app.set :environment, :development
44
+ @app.reload.should.be true
45
+ @app.set :reload, false
46
+ @app.reload.should.be false
47
+ @app.reload?.should.be false
48
+ end
49
+
50
+ it 'reloads the app_file each time a request is made' do
51
+ @app.set :app_file, File.dirname(__FILE__) + '/data/reload_app_file.rb'
52
+ @app.set :reload, true
53
+ @app.get('/') { 'Hello World' }
54
+
55
+ get '/'
56
+ status.should.equal 200
57
+ body.should.equal 'Hello from reload file'
58
+ $reload_count.should.equal 1
59
+
60
+ get '/'
61
+ status.should.equal 200
62
+ body.should.equal 'Hello from reload file'
63
+ $reload_count.should.equal 2
64
+ end
65
+ end
@@ -0,0 +1,11 @@
1
+ require 'test/spec'
2
+ require 'sinatra/base'
3
+ require 'sinatra/test'
4
+
5
+ describe 'Sinatra::Request' do
6
+ it 'responds to #user_agent' do
7
+ request = Sinatra::Request.new({'HTTP_USER_AGENT' => 'Test'})
8
+ request.should.respond_to :user_agent
9
+ request.user_agent.should.equal 'Test'
10
+ end
11
+ end
@@ -0,0 +1,92 @@
1
+ require 'test/spec'
2
+ require 'sinatra/base'
3
+ require 'sinatra/test'
4
+
5
+ describe 'Result Handling' do
6
+ include Sinatra::Test
7
+
8
+ it "sets response.body when result is a String" do
9
+ mock_app {
10
+ get '/' do
11
+ 'Hello World'
12
+ end
13
+ }
14
+
15
+ get '/'
16
+ should.be.ok
17
+ body.should.equal 'Hello World'
18
+ end
19
+
20
+ it "sets response.body when result is an Array of Strings" do
21
+ mock_app {
22
+ get '/' do
23
+ ['Hello', 'World']
24
+ end
25
+ }
26
+
27
+ get '/'
28
+ should.be.ok
29
+ body.should.equal 'HelloWorld'
30
+ end
31
+
32
+ it "sets response.body when result responds to #each" do
33
+ mock_app {
34
+ get '/' do
35
+ res = lambda { 'Hello World' }
36
+ def res.each ; yield call ; end
37
+ res
38
+ end
39
+ }
40
+
41
+ get '/'
42
+ should.be.ok
43
+ body.should.equal 'Hello World'
44
+ end
45
+
46
+ it "sets response.body to [] when result is nil" do
47
+ mock_app {
48
+ get '/' do
49
+ nil
50
+ end
51
+ }
52
+
53
+ get '/'
54
+ should.be.ok
55
+ body.should.equal ''
56
+ end
57
+
58
+ it "sets status, headers, and body when result is a Rack response tuple" do
59
+ mock_app {
60
+ get '/' do
61
+ [205, {'Content-Type' => 'foo/bar'}, 'Hello World']
62
+ end
63
+ }
64
+
65
+ get '/'
66
+ status.should.equal 205
67
+ response['Content-Type'].should.equal 'foo/bar'
68
+ body.should.equal 'Hello World'
69
+ end
70
+
71
+ it "sets status and body when result is a two-tuple" do
72
+ mock_app {
73
+ get '/' do
74
+ [409, 'formula of']
75
+ end
76
+ }
77
+
78
+ get '/'
79
+ status.should.equal 409
80
+ body.should.equal 'formula of'
81
+ end
82
+
83
+ it "sets status when result is a Fixnum status code" do
84
+ mock_app {
85
+ get('/') { 205 }
86
+ }
87
+
88
+ get '/'
89
+ status.should.equal 205
90
+ body.should.be.empty
91
+ end
92
+ end
@@ -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 ADDED
@@ -0,0 +1,40 @@
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 '/'
14
+ end
15
+
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
21
+
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
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"
32
+ end
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
40
+ end