cehoffman-sinatra-respond_to 0.3.4 → 0.3.5
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/VERSION.yml +1 -1
- data/lib/sinatra/respond_to.rb +39 -49
- data/spec/extension_spec.rb +91 -28
- data/spec/spec_helper.rb +1 -1
- metadata +2 -2
data/VERSION.yml
CHANGED
data/lib/sinatra/respond_to.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
require 'sinatra/base'
|
|
2
2
|
|
|
3
|
-
#
|
|
3
|
+
# Accept header parsing was looked at but deemed
|
|
4
4
|
# too much of an irregularity to deal with. Problems with the header
|
|
5
5
|
# differences from IE, Firefox, Safari, and every other UA causes
|
|
6
6
|
# problems with the expected output. The general expected behavior
|
|
@@ -25,9 +25,9 @@ module Sinatra
|
|
|
25
25
|
def self.registered(app)
|
|
26
26
|
app.helpers RespondTo::Helpers
|
|
27
27
|
|
|
28
|
-
app.set :default_charset, 'utf-8'
|
|
29
|
-
app.set :default_content, :html
|
|
30
|
-
app.set :assume_xhr_is_js, true
|
|
28
|
+
app.set :default_charset, 'utf-8'
|
|
29
|
+
app.set :default_content, :html
|
|
30
|
+
app.set :assume_xhr_is_js, true
|
|
31
31
|
|
|
32
32
|
# We remove the trailing extension so routes
|
|
33
33
|
# don't have to be of the style
|
|
@@ -38,35 +38,25 @@ module Sinatra
|
|
|
38
38
|
#
|
|
39
39
|
# get '/resource'
|
|
40
40
|
#
|
|
41
|
-
# and the format will automatically be available in
|
|
41
|
+
# and the format will automatically be available in <tt>format</tt>
|
|
42
42
|
app.before do
|
|
43
|
-
unless options.static? && options.public? &&
|
|
44
|
-
request.path_info.
|
|
45
|
-
format $1 || options.default_content
|
|
43
|
+
unless options.static? && options.public? && (request.get? || request.head?) && static_file?(request.path_info)
|
|
44
|
+
request.path_info.sub! %r{\.([^\./]+)$}, ''
|
|
46
45
|
|
|
47
|
-
|
|
48
|
-
format :js if request.xhr? && options.assume_xhr_is_js?
|
|
46
|
+
format request.xhr? && options.assume_xhr_is_js? ? :js : $1 || options.default_content
|
|
49
47
|
|
|
50
48
|
charset options.default_charset if TEXT_MIME_TYPES.include? format
|
|
51
49
|
end
|
|
52
50
|
end
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
# Most generally a fix for the __sinatra__ routes in development
|
|
56
|
-
# app.routes.each_pair do |verb, subroutes|
|
|
57
|
-
# subroutes.each do |subroute|
|
|
58
|
-
# subroute[0] = Regexp.new(subroute[0].source.gsub(/\\\.[^\.\/]+\$$/, '$'))
|
|
59
|
-
# end
|
|
60
|
-
# end
|
|
61
|
-
|
|
62
|
-
app.configure :development do
|
|
52
|
+
app.configure :development do |dev|
|
|
63
53
|
# Very, very, very hackish but only for development at least
|
|
64
54
|
# Modifies the regex matching /__sinatra__/:image.png to not have the extension
|
|
65
55
|
["GET", "HEAD"].each do |verb|
|
|
66
|
-
|
|
56
|
+
dev.routes[verb][1][0] = Regexp.new(dev.routes[verb][1][0].source.gsub(/\\\.[^\.\/]+\$$/, '$'))
|
|
67
57
|
end
|
|
68
58
|
|
|
69
|
-
|
|
59
|
+
dev.error UnhandledFormat do
|
|
70
60
|
content_type :html, :charset => 'utf-8'
|
|
71
61
|
|
|
72
62
|
(<<-HTML).gsub(/^ {10}/, '')
|
|
@@ -91,18 +81,18 @@ module Sinatra
|
|
|
91
81
|
HTML
|
|
92
82
|
end
|
|
93
83
|
|
|
94
|
-
|
|
84
|
+
dev.error MissingTemplate do
|
|
95
85
|
content_type :html, :charset => 'utf-8'
|
|
96
|
-
response.status =
|
|
86
|
+
response.status = request.env['sinatra.error'].code
|
|
97
87
|
|
|
98
|
-
engine = request.env['sinatra.error'].message
|
|
88
|
+
engine = request.env['sinatra.error'].message.split('.').last
|
|
99
89
|
engine = 'haml' unless ['haml', 'builder', 'erb'].include? engine
|
|
100
|
-
|
|
101
|
-
path = request.path_info
|
|
90
|
+
|
|
91
|
+
path = File.basename(request.path_info)
|
|
102
92
|
path = "root" if path.nil? || path.empty?
|
|
103
|
-
|
|
93
|
+
|
|
104
94
|
format = engine == 'builder' ? 'xml' : 'html'
|
|
105
|
-
|
|
95
|
+
|
|
106
96
|
layout = case engine
|
|
107
97
|
when 'haml' then "!!!\n%html\n %body= yield"
|
|
108
98
|
when 'erb' then "<html>\n <body>\n <%= yield %>\n </body>\n</html>"
|
|
@@ -128,7 +118,7 @@ module Sinatra
|
|
|
128
118
|
<img src='/__sinatra__/500.png'>
|
|
129
119
|
<div id="c">
|
|
130
120
|
Try this:<br />
|
|
131
|
-
#{layout
|
|
121
|
+
#{layout}
|
|
132
122
|
<small>#{path}.#{format}.#{engine}</small>
|
|
133
123
|
<pre>Hello World!</pre>
|
|
134
124
|
<small>application.rb</small>
|
|
@@ -153,7 +143,7 @@ module Sinatra
|
|
|
153
143
|
alias_method :render, :render_with_format
|
|
154
144
|
|
|
155
145
|
def lookup_layout_with_format(*args)
|
|
156
|
-
args[1] = "#{args[1]}.#{format}".to_sym if args
|
|
146
|
+
args[1] = "#{args[1]}.#{format}".to_sym if args[1].is_a?(::Symbol)
|
|
157
147
|
lookup_layout_without_format *args
|
|
158
148
|
end
|
|
159
149
|
alias_method :lookup_layout_without_format, :lookup_layout
|
|
@@ -164,53 +154,53 @@ module Sinatra
|
|
|
164
154
|
module Helpers
|
|
165
155
|
def format(val=nil)
|
|
166
156
|
unless val.nil?
|
|
167
|
-
|
|
168
|
-
fail "Unknown media type #{val}\nTry registering the extension with a mime type" if
|
|
157
|
+
mime_type = media_type(val)
|
|
158
|
+
fail "Unknown media type #{val}\nTry registering the extension with a mime type" if mime_type.nil?
|
|
169
159
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
response['Content-Type'] = [new_mime_type, params].join(';')
|
|
160
|
+
@format = val.to_sym
|
|
161
|
+
response['Content-Type'].sub!(/^[^;]+/, mime_type)
|
|
173
162
|
end
|
|
174
163
|
|
|
175
|
-
|
|
164
|
+
@format
|
|
176
165
|
end
|
|
177
166
|
|
|
167
|
+
# This is mostly just a helper so request.path_info isn't changed when
|
|
168
|
+
# serving files from the public directory
|
|
178
169
|
def static_file?(path)
|
|
179
|
-
return false unless path =~ /.*[^\/]$/
|
|
180
170
|
public_dir = File.expand_path(options.public)
|
|
181
171
|
path = File.expand_path(File.join(public_dir, unescape(path)))
|
|
182
|
-
|
|
183
|
-
File.file?(path)
|
|
172
|
+
|
|
173
|
+
path[0, public_dir.length] == public_dir && File.file?(path)
|
|
184
174
|
end
|
|
185
175
|
|
|
186
176
|
def charset(val=nil)
|
|
187
177
|
fail "Content-Type must be set in order to specify a charset" if response['Content-Type'].nil?
|
|
188
178
|
|
|
189
|
-
if response['Content-Type'] =~ /charset=[
|
|
190
|
-
response['Content-Type'].
|
|
179
|
+
if response['Content-Type'] =~ /charset=[^;]+/
|
|
180
|
+
response['Content-Type'].sub!(/charset=[^;]+/, (val == '' && '') || "charset=#{val}")
|
|
191
181
|
else
|
|
192
182
|
response['Content-Type'] += ";charset=#{val}"
|
|
193
183
|
end unless val.nil?
|
|
194
184
|
|
|
195
|
-
response['Content-Type'][/charset=([
|
|
185
|
+
response['Content-Type'][/charset=([^;]+)/, 1]
|
|
196
186
|
end
|
|
197
187
|
|
|
198
188
|
def respond_to(&block)
|
|
199
189
|
wants = {}
|
|
200
|
-
def wants.method_missing(type, *args, &
|
|
190
|
+
def wants.method_missing(type, *args, &handler)
|
|
201
191
|
Sinatra::Base.send(:fail, "Unknown media type for respond_to: #{type}\nTry registering the extension with a mime type") if Sinatra::Base.media_type(type).nil?
|
|
202
|
-
|
|
203
|
-
self[type] = block
|
|
192
|
+
self[type] = handler
|
|
204
193
|
end
|
|
205
194
|
|
|
206
195
|
yield wants
|
|
207
196
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
handler.call
|
|
197
|
+
raise UnhandledFormat if wants[format].nil?
|
|
198
|
+
wants[format].call
|
|
211
199
|
end
|
|
212
200
|
end
|
|
213
201
|
end
|
|
214
202
|
|
|
203
|
+
# Get around before filter problem for classic applications by registering
|
|
204
|
+
# with the context they are run in explicitly instead of Sinatra::Default
|
|
215
205
|
Sinatra::Application.register RespondTo
|
|
216
|
-
end
|
|
206
|
+
end
|
data/spec/extension_spec.rb
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
require File.join(File.dirname(__FILE__), 'spec_helper')
|
|
2
2
|
|
|
3
3
|
describe Sinatra::RespondTo do
|
|
4
|
+
def media_type(sym)
|
|
5
|
+
Sinatra::Base.media_type(sym)
|
|
6
|
+
end
|
|
7
|
+
|
|
4
8
|
describe "options" do
|
|
5
9
|
it "should initialize with :default_charset set to 'utf-8'" do
|
|
6
10
|
TestApp.default_charset.should == 'utf-8'
|
|
@@ -21,7 +25,7 @@ describe Sinatra::RespondTo do
|
|
|
21
25
|
|
|
22
26
|
get '/resource'
|
|
23
27
|
|
|
24
|
-
last_response['Content-Type'].should =~ %r{#{
|
|
28
|
+
last_response['Content-Type'].should =~ %r{#{media_type(:js)}}
|
|
25
29
|
end
|
|
26
30
|
|
|
27
31
|
it "should not set the content type to application/javascript for an XMLHttpRequest when assume_xhr_is_js is false" do
|
|
@@ -29,7 +33,7 @@ describe Sinatra::RespondTo do
|
|
|
29
33
|
header 'HTTP_X_REQUESTED_WITH', 'XMLHttpRequest'
|
|
30
34
|
get '/resource'
|
|
31
35
|
|
|
32
|
-
last_response['Content-Type'].should_not =~ %r{#{
|
|
36
|
+
last_response['Content-Type'].should_not =~ %r{#{media_type(:js)}}
|
|
33
37
|
|
|
34
38
|
# Put back the option, no side effects here
|
|
35
39
|
TestApp.enable :assume_xhr_is_js
|
|
@@ -72,7 +76,7 @@ describe Sinatra::RespondTo do
|
|
|
72
76
|
it "should set the appropriate content-type for route with an extension" do
|
|
73
77
|
get "/resource.xml"
|
|
74
78
|
|
|
75
|
-
last_response['Content-Type'].should =~ %r{#{
|
|
79
|
+
last_response['Content-Type'].should =~ %r{#{media_type(:xml)}}
|
|
76
80
|
end
|
|
77
81
|
|
|
78
82
|
it "should set the character set to the default character set" do
|
|
@@ -137,7 +141,7 @@ describe Sinatra::RespondTo do
|
|
|
137
141
|
it "should set the default content type when no extension" do
|
|
138
142
|
get "/normal-no-respond_to"
|
|
139
143
|
|
|
140
|
-
last_response['Content-Type'].should =~ %r{#{
|
|
144
|
+
last_response['Content-Type'].should =~ %r{#{media_type(TestApp.default_content)}}
|
|
141
145
|
end
|
|
142
146
|
|
|
143
147
|
it "should set the default character when no extension" do
|
|
@@ -149,31 +153,63 @@ describe Sinatra::RespondTo do
|
|
|
149
153
|
it "should set the appropriate content type when given an extension" do
|
|
150
154
|
get "/normal-no-respond_to.css"
|
|
151
155
|
|
|
152
|
-
last_response['Content-Type'].should =~ %r{#{
|
|
156
|
+
last_response['Content-Type'].should =~ %r{#{media_type(:css)}}
|
|
153
157
|
end
|
|
154
158
|
|
|
155
159
|
it "should set the default charset when given an extension" do
|
|
156
160
|
get "/normal-no-respond_to.css"
|
|
157
161
|
|
|
158
|
-
last_response['Content-Type'].should =~ %r{
|
|
162
|
+
last_response['Content-Type'].should =~ %r{charset=#{TestApp.default_charset}}
|
|
159
163
|
end
|
|
160
164
|
end
|
|
161
165
|
|
|
162
|
-
describe "error pages in
|
|
166
|
+
describe "error pages in production" do
|
|
167
|
+
class ProductionErrorApp < Sinatra::Base
|
|
168
|
+
set :environment, :production
|
|
169
|
+
register Sinatra::RespondTo
|
|
170
|
+
get '/missing-template' do
|
|
171
|
+
respond_to do |wants|
|
|
172
|
+
wants.html { haml :missing }
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
before(:each) do
|
|
178
|
+
@app = Rack::Builder.new { run ProductionErrorApp }
|
|
179
|
+
end
|
|
180
|
+
|
|
163
181
|
describe Sinatra::RespondTo::MissingTemplate do
|
|
164
|
-
it "should return
|
|
182
|
+
it "should return 404 status when looking for a missing template in production" do
|
|
165
183
|
get '/missing-template'
|
|
166
184
|
|
|
167
|
-
last_response.status.should ==
|
|
185
|
+
last_response.status.should == 404
|
|
186
|
+
last_response.body.should_not =~ /Sinatra can't find/
|
|
187
|
+
end
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
describe Sinatra::RespondTo::UnhandledFormat do
|
|
191
|
+
it "should return with a 404 when an extension is not supported in production" do
|
|
192
|
+
get '/missing-template.txt'
|
|
193
|
+
|
|
194
|
+
last_response.status.should == 404
|
|
195
|
+
last_response.body.should_not =~ /respond_to/
|
|
168
196
|
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
describe "error pages in development:" do
|
|
201
|
+
|
|
202
|
+
it "should allow access to the /__sinatra__/*.png images" do
|
|
203
|
+
get '/__sinatra__/404.png'
|
|
169
204
|
|
|
170
|
-
|
|
171
|
-
|
|
205
|
+
last_response.should be_ok
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
describe Sinatra::RespondTo::MissingTemplate do
|
|
209
|
+
it "should return 500 status when looking for a missing template" do
|
|
172
210
|
get '/missing-template'
|
|
173
211
|
|
|
174
212
|
last_response.status.should == 500
|
|
175
|
-
|
|
176
|
-
TestApp.set :environment, :development
|
|
177
213
|
end
|
|
178
214
|
|
|
179
215
|
it "should provide a helpful error message for a missing template when in development" do
|
|
@@ -219,15 +255,6 @@ describe Sinatra::RespondTo do
|
|
|
219
255
|
last_response.status.should == 404
|
|
220
256
|
end
|
|
221
257
|
|
|
222
|
-
it "should return with a 404 when an extension is not support in production" do
|
|
223
|
-
TestApp.set :environment, :production
|
|
224
|
-
get '/missing-template.txt'
|
|
225
|
-
|
|
226
|
-
last_response.status.should == 404
|
|
227
|
-
|
|
228
|
-
TestApp.set :environment, :development
|
|
229
|
-
end
|
|
230
|
-
|
|
231
258
|
it "should provide a helpful error message for an unhandled format" do
|
|
232
259
|
get '/missing-template.txt'
|
|
233
260
|
|
|
@@ -276,21 +303,25 @@ describe Sinatra::RespondTo do
|
|
|
276
303
|
|
|
277
304
|
lambda { charset }.should raise_error
|
|
278
305
|
end
|
|
306
|
+
|
|
307
|
+
it "should not modify the Content-Type when given no argument" do
|
|
308
|
+
response['Content-Type'] = "text/html;charset=iso-8859-1"
|
|
309
|
+
|
|
310
|
+
charset
|
|
311
|
+
|
|
312
|
+
response['Content-Type'].should == "text/html;charset=iso-8859-1"
|
|
313
|
+
end
|
|
279
314
|
end
|
|
280
315
|
|
|
281
316
|
describe "format" do
|
|
282
317
|
before(:each) do
|
|
283
|
-
stub!(:request).and_return(
|
|
284
|
-
end
|
|
285
|
-
|
|
286
|
-
def media_type(sym)
|
|
287
|
-
Sinatra::Base.media_type(sym)
|
|
318
|
+
stub!(:request).and_return(Sinatra::Request.new({}))
|
|
288
319
|
end
|
|
289
320
|
|
|
290
321
|
it "should set the correct mime type when given an extension" do
|
|
291
322
|
format :xml
|
|
292
323
|
|
|
293
|
-
response['Content-Type'].split(';').should include(
|
|
324
|
+
response['Content-Type'].split(';').should include(media_type(:xml))
|
|
294
325
|
end
|
|
295
326
|
|
|
296
327
|
it "should fail when set to an unknown extension type" do
|
|
@@ -302,6 +333,14 @@ describe Sinatra::RespondTo do
|
|
|
302
333
|
|
|
303
334
|
format.should == :js
|
|
304
335
|
end
|
|
336
|
+
|
|
337
|
+
it "should not modify the Content-Type when given no argument" do
|
|
338
|
+
response['Content-Type'] = "application/xml;charset=utf-8"
|
|
339
|
+
|
|
340
|
+
format
|
|
341
|
+
|
|
342
|
+
response['Content-Type'].should == "application/xml;charset=utf-8"
|
|
343
|
+
end
|
|
305
344
|
end
|
|
306
345
|
|
|
307
346
|
describe "static_file?" do
|
|
@@ -336,5 +375,29 @@ describe Sinatra::RespondTo do
|
|
|
336
375
|
static_file?(@static_folder).should be_false
|
|
337
376
|
end
|
|
338
377
|
end
|
|
378
|
+
|
|
379
|
+
describe "respond_to" do
|
|
380
|
+
before(:each) do
|
|
381
|
+
stub!(:request).and_return(Sinatra::Request.new({}))
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it "should fail for an unknown extension" do
|
|
385
|
+
lambda do
|
|
386
|
+
respond_to do |wants|
|
|
387
|
+
wants.bogus
|
|
388
|
+
end
|
|
389
|
+
end.should raise_error
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it "should call the block corresponding to the current format" do
|
|
393
|
+
format :html
|
|
394
|
+
|
|
395
|
+
respond_to do |wants|
|
|
396
|
+
wants.js { "Some JS" }
|
|
397
|
+
wants.html { "Some HTML" }
|
|
398
|
+
wants.xml { "Some XML" }
|
|
399
|
+
end.should == "Some HTML"
|
|
400
|
+
end
|
|
401
|
+
end
|
|
339
402
|
end
|
|
340
403
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cehoffman-sinatra-respond_to
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.3.
|
|
4
|
+
version: 0.3.5
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Chris Hoffman
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2009-05-
|
|
12
|
+
date: 2009-05-14 00:00:00 -07:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies:
|
|
15
15
|
- !ruby/object:Gem::Dependency
|