darkhelmet-sinatra 0.9.0.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (85) hide show
  1. data/AUTHORS +41 -0
  2. data/CHANGES +243 -0
  3. data/LICENSE +22 -0
  4. data/README.rdoc +535 -0
  5. data/Rakefile +136 -0
  6. data/compat/app_test.rb +301 -0
  7. data/compat/application_test.rb +334 -0
  8. data/compat/builder_test.rb +101 -0
  9. data/compat/compat_test.rb +12 -0
  10. data/compat/custom_error_test.rb +62 -0
  11. data/compat/erb_test.rb +136 -0
  12. data/compat/events_test.rb +78 -0
  13. data/compat/filter_test.rb +30 -0
  14. data/compat/haml_test.rb +233 -0
  15. data/compat/helper.rb +30 -0
  16. data/compat/mapped_error_test.rb +72 -0
  17. data/compat/pipeline_test.rb +71 -0
  18. data/compat/public/foo.xml +1 -0
  19. data/compat/sass_test.rb +57 -0
  20. data/compat/sessions_test.rb +39 -0
  21. data/compat/streaming_test.rb +133 -0
  22. data/compat/sym_params_test.rb +19 -0
  23. data/compat/template_test.rb +30 -0
  24. data/compat/use_in_file_templates_test.rb +47 -0
  25. data/compat/views/foo.builder +1 -0
  26. data/compat/views/foo.erb +1 -0
  27. data/compat/views/foo.haml +1 -0
  28. data/compat/views/foo.sass +2 -0
  29. data/compat/views/foo_layout.erb +2 -0
  30. data/compat/views/foo_layout.haml +2 -0
  31. data/compat/views/layout_test/foo.builder +1 -0
  32. data/compat/views/layout_test/foo.erb +1 -0
  33. data/compat/views/layout_test/foo.haml +1 -0
  34. data/compat/views/layout_test/foo.sass +2 -0
  35. data/compat/views/layout_test/layout.builder +3 -0
  36. data/compat/views/layout_test/layout.erb +1 -0
  37. data/compat/views/layout_test/layout.haml +1 -0
  38. data/compat/views/layout_test/layout.sass +2 -0
  39. data/compat/views/no_layout/no_layout.builder +1 -0
  40. data/compat/views/no_layout/no_layout.haml +1 -0
  41. data/lib/sinatra/base.rb +1007 -0
  42. data/lib/sinatra/compat.rb +252 -0
  43. data/lib/sinatra/images/404.png +0 -0
  44. data/lib/sinatra/images/500.png +0 -0
  45. data/lib/sinatra/main.rb +47 -0
  46. data/lib/sinatra/test/bacon.rb +19 -0
  47. data/lib/sinatra/test/rspec.rb +13 -0
  48. data/lib/sinatra/test/spec.rb +11 -0
  49. data/lib/sinatra/test/unit.rb +13 -0
  50. data/lib/sinatra/test.rb +121 -0
  51. data/lib/sinatra.rb +8 -0
  52. data/sinatra.gemspec +116 -0
  53. data/test/base_test.rb +112 -0
  54. data/test/builder_test.rb +64 -0
  55. data/test/data/reload_app_file.rb +3 -0
  56. data/test/erb_test.rb +81 -0
  57. data/test/extensions_test.rb +63 -0
  58. data/test/filter_test.rb +99 -0
  59. data/test/haml_test.rb +68 -0
  60. data/test/helper.rb +85 -0
  61. data/test/helpers_test.rb +467 -0
  62. data/test/mapped_error_test.rb +160 -0
  63. data/test/middleware_test.rb +60 -0
  64. data/test/options_test.rb +374 -0
  65. data/test/reload_test.rb +68 -0
  66. data/test/request_test.rb +18 -0
  67. data/test/response_test.rb +42 -0
  68. data/test/result_test.rb +98 -0
  69. data/test/routing_test.rb +712 -0
  70. data/test/sass_test.rb +36 -0
  71. data/test/server_test.rb +41 -0
  72. data/test/sinatra_test.rb +13 -0
  73. data/test/static_test.rb +65 -0
  74. data/test/templates_test.rb +88 -0
  75. data/test/test_test.rb +109 -0
  76. data/test/views/hello.builder +1 -0
  77. data/test/views/hello.erb +1 -0
  78. data/test/views/hello.haml +1 -0
  79. data/test/views/hello.sass +2 -0
  80. data/test/views/hello.test +1 -0
  81. data/test/views/layout2.builder +3 -0
  82. data/test/views/layout2.erb +2 -0
  83. data/test/views/layout2.haml +2 -0
  84. data/test/views/layout2.test +1 -0
  85. metadata +184 -0
data/Rakefile ADDED
@@ -0,0 +1,136 @@
1
+ require 'rake/clean'
2
+ require 'rake/testtask'
3
+ require 'fileutils'
4
+
5
+ task :default => [:test]
6
+ task :spec => :test
7
+
8
+ # SPECS ===============================================================
9
+
10
+ Rake::TestTask.new(:test) do |t|
11
+ t.test_files = FileList['test/*_test.rb']
12
+ t.ruby_opts = ['-rubygems'] if defined? Gem
13
+ end
14
+
15
+ desc 'Run compatibility specs (requires test/spec)'
16
+ task :compat do |t|
17
+ pattern = ENV['TEST'] || '.*'
18
+ sh "specrb --testcase '#{pattern}' -Ilib:test compat/*_test.rb"
19
+ end
20
+
21
+ # PACKAGING ============================================================
22
+
23
+ # Load the gemspec using the same limitations as github
24
+ def spec
25
+ @spec ||=
26
+ begin
27
+ require 'rubygems/specification'
28
+ data = File.read('sinatra.gemspec')
29
+ spec = nil
30
+ Thread.new { spec = eval("$SAFE = 3\n#{data}") }.join
31
+ spec
32
+ end
33
+ end
34
+
35
+ def package(ext='')
36
+ "dist/sinatra-#{spec.version}" + ext
37
+ end
38
+
39
+ desc 'Build packages'
40
+ task :package => %w[.gem .tar.gz].map {|e| package(e)}
41
+
42
+ desc 'Build and install as local gem'
43
+ task :install => package('.gem') do
44
+ sh "gem install #{package('.gem')}"
45
+ end
46
+
47
+ directory 'dist/'
48
+ CLOBBER.include('dist')
49
+
50
+ file package('.gem') => %w[dist/ sinatra.gemspec] + spec.files do |f|
51
+ sh "gem build sinatra.gemspec"
52
+ mv File.basename(f.name), f.name
53
+ end
54
+
55
+ file package('.tar.gz') => %w[dist/] + spec.files do |f|
56
+ sh <<-SH
57
+ git archive \
58
+ --prefix=sinatra-#{source_version}/ \
59
+ --format=tar \
60
+ HEAD | gzip > #{f.name}
61
+ SH
62
+ end
63
+
64
+ # Rubyforge Release / Publish Tasks ==================================
65
+
66
+ desc 'Publish gem and tarball to rubyforge'
67
+ task 'publish:gem' => [package('.gem'), package('.tar.gz')] do |t|
68
+ sh <<-end
69
+ rubyforge add_release sinatra sinatra #{spec.version} #{package('.gem')} &&
70
+ rubyforge add_file sinatra sinatra #{spec.version} #{package('.tar.gz')}
71
+ end
72
+ end
73
+
74
+ # Website ============================================================
75
+ # Building docs requires HAML and the hanna gem:
76
+ # gem install mislav-hanna --source=http://gems.github.com
77
+
78
+ task 'doc' => ['doc:api']
79
+
80
+ desc 'Generate Hanna RDoc under doc/api'
81
+ task 'doc:api' => ['doc/api/index.html']
82
+
83
+ file 'doc/api/index.html' => FileList['lib/**/*.rb','README.rdoc'] do |f|
84
+ rb_files = f.prerequisites
85
+ sh((<<-end).gsub(/\s+/, ' '))
86
+ hanna --charset utf8 \
87
+ --fmt html \
88
+ --inline-source \
89
+ --line-numbers \
90
+ --main README.rdoc \
91
+ --op doc/api \
92
+ --title 'Sinatra API Documentation' \
93
+ #{rb_files.join(' ')}
94
+ end
95
+ end
96
+ CLEAN.include 'doc/api'
97
+
98
+ def rdoc_to_html(file_name)
99
+ require 'rdoc/markup/to_html'
100
+ rdoc = RDoc::Markup::ToHtml.new
101
+ rdoc.convert(File.read(file_name))
102
+ end
103
+
104
+ # Gemspec Helpers ====================================================
105
+
106
+ def source_version
107
+ line = File.read('lib/sinatra/base.rb')[/^\s*VERSION = .*/]
108
+ line.match(/.*VERSION = '(.*)'/)[1]
109
+ end
110
+
111
+ project_files =
112
+ FileList[
113
+ '{lib,test,compat,images}/**',
114
+ 'Rakefile', 'CHANGES', 'README.rdoc'
115
+ ]
116
+ file 'sinatra.gemspec' => project_files do |f|
117
+ # read spec file and split out manifest section
118
+ spec = File.read(f.name)
119
+ head, manifest, tail = spec.split(" # = MANIFEST =\n")
120
+ # replace version and date
121
+ head.sub!(/\.version = '.*'/, ".version = '#{source_version}'")
122
+ head.sub!(/\.date = '.*'/, ".date = '#{Date.today.to_s}'")
123
+ # determine file list from git ls-files
124
+ files = `git ls-files`.
125
+ split("\n").
126
+ sort.
127
+ reject{ |file| file =~ /^\./ }.
128
+ reject { |file| file =~ /^doc/ }.
129
+ map{ |file| " #{file}" }.
130
+ join("\n")
131
+ # piece file back together and write...
132
+ manifest = " s.files = %w[\n#{files}\n ]\n"
133
+ spec = [head,manifest,tail].join(" # = MANIFEST =\n")
134
+ File.open(f.name, 'w') { |io| io.write(spec) }
135
+ puts "updated #{f.name}"
136
+ end
@@ -0,0 +1,301 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ context "Sinatra" do
4
+
5
+ setup do
6
+ Sinatra.application = nil
7
+ end
8
+
9
+ specify "should put all DSL methods on (main)" do
10
+ object = Object.new
11
+ methods = %w[get put post head delete configure template helpers set]
12
+ methods.each do |method|
13
+ object.private_methods.map { |m| m.to_sym }.should.include(method.to_sym)
14
+ end
15
+ end
16
+
17
+ specify "should handle result of nil" do
18
+ get '/' do
19
+ nil
20
+ end
21
+
22
+ get_it '/'
23
+ should.be.ok
24
+ body.should == ''
25
+ end
26
+
27
+ specify "handles events" do
28
+ get '/:name' do
29
+ 'Hello ' + params["name"]
30
+ end
31
+
32
+ get_it '/Blake'
33
+
34
+ should.be.ok
35
+ body.should.equal 'Hello Blake'
36
+ end
37
+
38
+
39
+ specify "handles splats" do
40
+ get '/hi/*' do
41
+ params["splat"].kind_of?(Array).should.equal true
42
+ params["splat"].first
43
+ end
44
+
45
+ get_it '/hi/Blake'
46
+
47
+ should.be.ok
48
+ body.should.equal 'Blake'
49
+ end
50
+
51
+ specify "handles multiple splats" do
52
+ get '/say/*/to/*' do
53
+ params["splat"].join(' ')
54
+ end
55
+
56
+ get_it '/say/hello/to/world'
57
+
58
+ should.be.ok
59
+ body.should.equal 'hello world'
60
+ end
61
+
62
+ specify "allow empty splats" do
63
+ get '/say/*/to*/*' do
64
+ params["splat"].join(' ')
65
+ end
66
+
67
+ get_it '/say/hello/to/world'
68
+
69
+ should.be.ok
70
+ body.should.equal 'hello world' # second splat is empty
71
+
72
+ get_it '/say/hello/tomy/world'
73
+
74
+ should.be.ok
75
+ body.should.equal 'hello my world'
76
+ end
77
+
78
+ specify "gives access to underlying response header Hash" do
79
+ get '/' do
80
+ header['X-Test'] = 'Is this thing on?'
81
+ headers 'X-Test2' => 'Foo', 'X-Test3' => 'Bar'
82
+ ''
83
+ end
84
+
85
+ get_it '/'
86
+ should.be.ok
87
+ headers.should.include 'X-Test'
88
+ headers['X-Test'].should.equal 'Is this thing on?'
89
+ headers.should.include 'X-Test3'
90
+ headers['X-Test3'].should.equal 'Bar'
91
+ end
92
+
93
+ specify "follows redirects" do
94
+ get '/' do
95
+ redirect '/blake'
96
+ end
97
+
98
+ get '/blake' do
99
+ 'Mizerany'
100
+ end
101
+
102
+ get_it '/'
103
+ should.be.redirection
104
+ body.should.equal ''
105
+
106
+ follow!
107
+ should.be.ok
108
+ body.should.equal 'Mizerany'
109
+ end
110
+
111
+ specify "renders a body with a redirect" do
112
+ helpers do
113
+ def foo ; 'blah' ; end
114
+ end
115
+ get "/" do
116
+ redirect 'foo', :foo
117
+ end
118
+ get_it '/'
119
+ should.be.redirection
120
+ headers['Location'].should.equal 'foo'
121
+ body.should.equal 'blah'
122
+ end
123
+
124
+ specify "redirects permanently with 301 status code" do
125
+ get "/" do
126
+ redirect 'foo', 301
127
+ end
128
+ get_it '/'
129
+ should.be.redirection
130
+ headers['Location'].should.equal 'foo'
131
+ status.should.equal 301
132
+ body.should.be.empty
133
+ end
134
+
135
+ specify "stop sets content and ends event" do
136
+ get '/set_body' do
137
+ stop 'Hello!'
138
+ stop 'World!'
139
+ fail 'stop should have halted'
140
+ end
141
+
142
+ get_it '/set_body'
143
+
144
+ should.be.ok
145
+ body.should.equal 'Hello!'
146
+
147
+ end
148
+
149
+ # Deprecated. WTF was going on here? What's the 1 in [:foo, 1] do?
150
+ xspecify "should set status then call helper with a var" do
151
+ helpers do
152
+ def foo
153
+ 'bah!'
154
+ end
155
+ end
156
+
157
+ get '/set_body' do
158
+ stop [404, [:foo, 1]]
159
+ end
160
+
161
+ get_it '/set_body'
162
+
163
+ should.be.not_found
164
+ body.should.equal 'bah!'
165
+
166
+ end
167
+
168
+ specify "should easily set response Content-Type" do
169
+ get '/foo.html' do
170
+ content_type 'text/html', :charset => 'utf-8'
171
+ "<h1>Hello, World</h1>"
172
+ end
173
+
174
+ get_it '/foo.html'
175
+ should.be.ok
176
+ headers['Content-Type'].should.equal 'text/html;charset=utf-8'
177
+ body.should.equal '<h1>Hello, World</h1>'
178
+
179
+ get '/foo_test.xml' do
180
+ content_type :xml
181
+ "<feed></feed>"
182
+ end
183
+
184
+ get_it '/foo_test.xml'
185
+ should.be.ok
186
+ headers['Content-Type'].should.equal 'application/xml'
187
+ body.should.equal '<feed></feed>'
188
+ end
189
+
190
+ specify "supports conditional GETs with last_modified" do
191
+ modified_at = Time.now
192
+ get '/maybe' do
193
+ last_modified modified_at
194
+ 'response body, maybe'
195
+ end
196
+
197
+ get_it '/maybe'
198
+ should.be.ok
199
+ body.should.equal 'response body, maybe'
200
+
201
+ get_it '/maybe', :env => { 'HTTP_IF_MODIFIED_SINCE' => modified_at.httpdate }
202
+ status.should.equal 304
203
+ body.should.equal ''
204
+ end
205
+
206
+ specify "supports conditional GETs with entity_tag" do
207
+ get '/strong' do
208
+ entity_tag 'FOO'
209
+ 'foo response'
210
+ end
211
+
212
+ get_it '/strong'
213
+ should.be.ok
214
+ body.should.equal 'foo response'
215
+
216
+ get_it '/strong', {},
217
+ 'HTTP_IF_NONE_MATCH' => '"BAR"'
218
+ should.be.ok
219
+ body.should.equal 'foo response'
220
+
221
+ get_it '/strong', {},
222
+ 'HTTP_IF_NONE_MATCH' => '"FOO"'
223
+ status.should.equal 304
224
+ body.should.equal ''
225
+
226
+ get_it '/strong', {},
227
+ 'HTTP_IF_NONE_MATCH' => '"BAR", *'
228
+ status.should.equal 304
229
+ body.should.equal ''
230
+ end
231
+
232
+ specify "delegates HEAD requests to GET handlers" do
233
+ get '/invisible' do
234
+ "I am invisible to the world"
235
+ end
236
+
237
+ head_it '/invisible'
238
+ should.be.ok
239
+ body.should.not.equal "I am invisible to the world"
240
+ body.should.equal ''
241
+ end
242
+
243
+
244
+ specify "supports PUT" do
245
+ put '/' do
246
+ 'puted'
247
+ end
248
+ put_it '/'
249
+ assert_equal 'puted', body
250
+ end
251
+
252
+ specify "rewrites POSTs with _method param to PUT" do
253
+ put '/' do
254
+ 'puted'
255
+ end
256
+ post_it '/', :_method => 'PUT'
257
+ assert_equal 'puted', body
258
+ end
259
+
260
+ specify "rewrites POSTs with lowercase _method param to PUT" do
261
+ put '/' do
262
+ 'puted'
263
+ end
264
+ post_it '/', :_method => 'put'
265
+ body.should.equal 'puted'
266
+ end
267
+
268
+ specify "does not rewrite GETs with _method param to PUT" do
269
+ get '/' do
270
+ 'getted'
271
+ end
272
+ get_it '/', :_method => 'put'
273
+ should.be.ok
274
+ body.should.equal 'getted'
275
+ end
276
+
277
+ specify "ignores _method query string parameter on non-POST requests" do
278
+ post '/' do
279
+ 'posted'
280
+ end
281
+ put '/' do
282
+ 'booo'
283
+ end
284
+ post_it "/?_method=PUT"
285
+ should.be.ok
286
+ body.should.equal 'posted'
287
+ end
288
+
289
+ specify "does not read body if content type is not url encoded" do
290
+ post '/foo.xml' do
291
+ request.env['CONTENT_TYPE'].should.be == 'application/xml'
292
+ request.content_type.should.be == 'application/xml'
293
+ request.body.read
294
+ end
295
+
296
+ post_it '/foo.xml', '<foo></foo>', :content_type => 'application/xml'
297
+ @response.should.be.ok
298
+ @response.body.should.be == '<foo></foo>'
299
+ end
300
+
301
+ end
@@ -0,0 +1,334 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ require 'uri'
4
+
5
+ class TesterWithEach
6
+ def each
7
+ yield 'foo'
8
+ yield 'bar'
9
+ yield 'baz'
10
+ end
11
+ end
12
+
13
+ context "Looking up a request" do
14
+
15
+ setup do
16
+ Sinatra.application = nil
17
+ end
18
+
19
+ # Deprecated. The lookup method is no longer used.
20
+ xspecify "returns what's at the end" do
21
+ block = Proc.new { 'Hello' }
22
+ get '/', &block
23
+
24
+ result = Sinatra.application.lookup(
25
+ Rack::Request.new(
26
+ 'REQUEST_METHOD' => 'GET',
27
+ 'PATH_INFO' => '/'
28
+ )
29
+ )
30
+
31
+ result.should.not.be.nil
32
+ result.block.should.be block
33
+ end
34
+
35
+ # Deprecated. The lookup method is no longer used.
36
+ xspecify "takes params in path" do
37
+ block = Proc.new { 'Hello' }
38
+ get '/:foo', &block
39
+
40
+ result = Sinatra.application.lookup(
41
+ Rack::Request.new(
42
+ 'REQUEST_METHOD' => 'GET',
43
+ 'PATH_INFO' => '/bar'
44
+ )
45
+ )
46
+
47
+ result.should.not.be.nil
48
+ result.block.should.be block
49
+ result.params.should.equal "foo" => 'bar'
50
+ end
51
+
52
+ end
53
+
54
+ context "An app returns" do
55
+
56
+ setup do
57
+ Sinatra.application = nil
58
+ end
59
+
60
+ specify "404 if no events found" do
61
+ request = Rack::MockRequest.new(@app)
62
+ get_it '/'
63
+ should.be.not_found
64
+ body.should.equal '<h1>Not Found</h1>'
65
+ end
66
+
67
+ specify "200 if success" do
68
+ get '/' do
69
+ 'Hello World'
70
+ end
71
+ get_it '/'
72
+ should.be.ok
73
+ body.should.equal 'Hello World'
74
+ end
75
+
76
+ specify "an objects result from each if it has it" do
77
+
78
+ get '/' do
79
+ TesterWithEach.new
80
+ end
81
+
82
+ get_it '/'
83
+ should.be.ok
84
+ body.should.equal 'foobarbaz'
85
+
86
+ end
87
+
88
+ # Deprecated. The body method no longer halts.
89
+ xspecify "the body set if set before the last" do
90
+
91
+ get '/' do
92
+ body 'Blake'
93
+ 'Mizerany'
94
+ end
95
+
96
+ get_it '/'
97
+ should.be.ok
98
+ body.should.equal 'Blake'
99
+
100
+ end
101
+
102
+ specify "404 if NotFound is raised" do
103
+
104
+ get '/' do
105
+ raise Sinatra::NotFound
106
+ end
107
+
108
+ get_it '/'
109
+ should.be.not_found
110
+
111
+ end
112
+
113
+ end
114
+
115
+ context "Application#configure blocks" do
116
+
117
+ setup do
118
+ Sinatra.application = nil
119
+ end
120
+
121
+ specify "run when no environment specified" do
122
+ ref = false
123
+ configure { ref = true }
124
+ ref.should.equal true
125
+ end
126
+
127
+ specify "run when matching environment specified" do
128
+ ref = false
129
+ configure(:test) { ref = true }
130
+ ref.should.equal true
131
+ end
132
+
133
+ specify "do not run when no matching environment specified" do
134
+ configure(:foo) { flunk "block should not have been executed" }
135
+ configure(:development, :production, :foo) { flunk "block should not have been executed" }
136
+ end
137
+
138
+ specify "accept multiple environments" do
139
+ ref = false
140
+ configure(:foo, :test, :bar) { ref = true }
141
+ ref.should.equal true
142
+ end
143
+
144
+ end
145
+
146
+ context "Default Application Configuration" do
147
+
148
+ # Sinatra::ServerError is no longer used
149
+ xspecify "includes 404 and 500 error handlers" do
150
+ Sinatra.application.errors.should.include(Sinatra::ServerError)
151
+ Sinatra.application.errors[Sinatra::ServerError].should.not.be.nil
152
+ Sinatra.application.errors.should.include(Sinatra::NotFound)
153
+ Sinatra.application.errors[Sinatra::NotFound].should.not.be.nil
154
+ end
155
+
156
+ # Deprecated. No such thing as a Static event anymore.
157
+ xspecify "includes Static event" do
158
+ assert Sinatra.application.events[:get].any? { |e| Sinatra::Static === e }
159
+ end
160
+
161
+ end
162
+
163
+ context "Events in an app" do
164
+
165
+ setup do
166
+ Sinatra.application = nil
167
+ end
168
+
169
+ specify "evaluate in a clean context" do
170
+ helpers do
171
+ def foo
172
+ 'foo'
173
+ end
174
+ end
175
+
176
+ get '/foo' do
177
+ foo
178
+ end
179
+
180
+ get_it '/foo'
181
+ should.be.ok
182
+ body.should.equal 'foo'
183
+ end
184
+
185
+ specify "get access to request, response, and params" do
186
+ get '/:foo' do
187
+ params["foo"] + params["bar"]
188
+ end
189
+
190
+ get_it '/foo?bar=baz'
191
+ should.be.ok
192
+ body.should.equal 'foobaz'
193
+ end
194
+
195
+ specify "can filters by agent" do
196
+
197
+ get '/', :agent => /Windows/ do
198
+ request.env['HTTP_USER_AGENT']
199
+ end
200
+
201
+ get_it '/', :env => { :agent => 'Windows' }
202
+ should.be.ok
203
+ body.should.equal 'Windows'
204
+
205
+ get_it '/', :env => { :agent => 'Mac' }
206
+ should.not.be.ok
207
+
208
+ end
209
+
210
+ specify "can use regex to get parts of user-agent" do
211
+
212
+ get '/', :agent => /Windows (NT)/ do
213
+ params[:agent].first
214
+ end
215
+
216
+ get_it '/', :env => { :agent => 'Windows NT' }
217
+
218
+ body.should.equal 'NT'
219
+
220
+ end
221
+
222
+ specify "can deal with spaces in paths" do
223
+
224
+ path = '/path with spaces'
225
+
226
+ get path do
227
+ "Look ma, a path with spaces!"
228
+ end
229
+
230
+ get_it URI.encode(path)
231
+
232
+ body.should.equal "Look ma, a path with spaces!"
233
+ end
234
+
235
+ specify "route based on host" do
236
+
237
+ get '/' do
238
+ 'asdf'
239
+ end
240
+
241
+ get_it '/'
242
+ assert ok?
243
+ assert_equal('asdf', body)
244
+
245
+ get '/foo', :host => 'foo.sinatrarb.com' do
246
+ 'in foo!'
247
+ end
248
+
249
+ get '/foo', :host => 'bar.sinatrarb.com' do
250
+ 'in bar!'
251
+ end
252
+
253
+ get_it '/foo', {}, 'HTTP_HOST' => 'foo.sinatrarb.com'
254
+ assert ok?
255
+ assert_equal 'in foo!', body
256
+
257
+ get_it '/foo', {}, 'HTTP_HOST' => 'bar.sinatrarb.com'
258
+ assert ok?
259
+ assert_equal 'in bar!', body
260
+
261
+ get_it '/foo'
262
+ assert not_found?
263
+
264
+ end
265
+
266
+ end
267
+
268
+
269
+ context "Options in an app" do
270
+
271
+ setup do
272
+ Sinatra.application = nil
273
+ @app = Sinatra::application
274
+ end
275
+
276
+ specify "can be set singly on app" do
277
+ @app.set :foo, 1234
278
+ @app.options.foo.should.equal 1234
279
+ end
280
+
281
+ specify "can be set singly from top-level" do
282
+ set_option :foo, 1234
283
+ @app.options.foo.should.equal 1234
284
+ end
285
+
286
+ specify "can be set multiply on app" do
287
+ @app.options.foo.should.be.nil
288
+ @app.set :foo => 1234,
289
+ :bar => 'hello, world'
290
+ @app.options.foo.should.equal 1234
291
+ @app.options.bar.should.equal 'hello, world'
292
+ end
293
+
294
+ specify "can be set multiply from top-level" do
295
+ @app.options.foo.should.be.nil
296
+ set_options :foo => 1234,
297
+ :bar => 'hello, world'
298
+ @app.options.foo.should.equal 1234
299
+ @app.options.bar.should.equal 'hello, world'
300
+ end
301
+
302
+ specify "can be enabled on app" do
303
+ @app.options.foo.should.be.nil
304
+ @app.enable :sessions, :foo, :bar
305
+ @app.options.sessions.should.equal true
306
+ @app.options.foo.should.equal true
307
+ @app.options.bar.should.equal true
308
+ end
309
+
310
+ specify "can be enabled from top-level" do
311
+ @app.options.foo.should.be.nil
312
+ enable :sessions, :foo, :bar
313
+ @app.options.sessions.should.equal true
314
+ @app.options.foo.should.equal true
315
+ @app.options.bar.should.equal true
316
+ end
317
+
318
+ specify "can be disabled on app" do
319
+ @app.options.foo.should.be.nil
320
+ @app.disable :sessions, :foo, :bar
321
+ @app.options.sessions.should.equal false
322
+ @app.options.foo.should.equal false
323
+ @app.options.bar.should.equal false
324
+ end
325
+
326
+ specify "can be enabled from top-level" do
327
+ @app.options.foo.should.be.nil
328
+ disable :sessions, :foo, :bar
329
+ @app.options.sessions.should.equal false
330
+ @app.options.foo.should.equal false
331
+ @app.options.bar.should.equal false
332
+ end
333
+
334
+ end