adamwiggins-sinatra 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.
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