cehoffman-sinatra-respond_to 0.3.4 → 0.3.5

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
- :patch: 4
2
+ :patch: 5
3
3
  :major: 0
4
4
  :minor: 3
@@ -1,6 +1,6 @@
1
1
  require 'sinatra/base'
2
2
 
3
- # Simple note, accept header parsing was looked at but deamed
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' unless app.respond_to?(:default_charset)
29
- app.set :default_content, :html unless app.respond_to?(:default_content)
30
- app.set :assume_xhr_is_js, true unless app.respond_to?(:assume_xhr_is_js)
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 as <tt>format</tt>
41
+ # and the format will automatically be available in <tt>format</tt>
42
42
  app.before do
43
- unless options.static? && options.public? && ["GET", "HEAD"].include?(request.request_method) && static_file?(request.path_info)
44
- request.path_info.gsub! %r{\.([^\./]+)$}, ''
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
- # For the oh so common case of actually wanting Javascript from an XmlHttpRequest
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
- # Replace all routes that have an ending extension with one that doesn't
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
- app.routes[verb][1][0] = Regexp.new(app.routes[verb][1][0].source.gsub(/\\\.[^\.\/]+\$$/, '$'))
56
+ dev.routes[verb][1][0] = Regexp.new(dev.routes[verb][1][0].source.gsub(/\\\.[^\.\/]+\$$/, '$'))
67
57
  end
68
58
 
69
- app.error UnhandledFormat do
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
- app.error MissingTemplate do
84
+ dev.error MissingTemplate do
95
85
  content_type :html, :charset => 'utf-8'
96
- response.status = 500 # If I can find out how to reference the error code from the exception, I would
86
+ response.status = request.env['sinatra.error'].code
97
87
 
98
- engine = request.env['sinatra.error'].message[/\.([^\.]+)$/, 1]
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[/([^\/]+)$/, 1]
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 if 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
- new_mime_type = media_type(val.to_sym)
168
- fail "Unknown media type #{val}\nTry registering the extension with a mime type" if new_mime_type.nil?
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
- request.env['sinatra.respond_to.format'] = val.to_sym
171
- old_mime_type, params = response['Content-Type'].split(';', 2)
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
- request.env['sinatra.respond_to.format']
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
- return false if path[0, public_dir.length] != public_dir
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'].gsub!(/charset=[^ ;,]+/, (val == '' && '') || "charset=#{val}")
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=([^ ;,]+)/, 1]
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, &block)
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
- options = args.pop if args.last.is_a?(::Hash)
203
- self[type] = block
192
+ self[type] = handler
204
193
  end
205
194
 
206
195
  yield wants
207
196
 
208
- handler = wants[format]
209
- raise UnhandledFormat if handler.nil?
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
@@ -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{#{Rack::Mime.mime_type(".js")}}
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{#{Rack::Mime.mime_type(".js")}}
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{#{Rack::Mime.mime_type('.xml')}}
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{#{Rack::Mime.mime_type(".#{TestApp.default_content}")}}
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{#{Rack::Mime.mime_type(".css")}}
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{#{Rack::Mime.mime_type(".css")}}
162
+ last_response['Content-Type'].should =~ %r{charset=#{TestApp.default_charset}}
159
163
  end
160
164
  end
161
165
 
162
- describe "error pages in development:" do
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 500 status when looking for a missing template" do
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 == 500
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
- it "should return 500 status when looking for a missing template in production" do
171
- TestApp.set :environment, :production
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(Rack::Request.new({}))
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(Rack::Mime.mime_type(".xml"))
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
@@ -9,7 +9,7 @@ require File.join(File.dirname(__FILE__), 'app', 'test_app')
9
9
 
10
10
  Spec::Runner.configure do |config|
11
11
  def app
12
- @app = Rack::Builder.new do
12
+ @app ||= Rack::Builder.new do
13
13
  run TestApp
14
14
  end
15
15
  end
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
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-13 00:00:00 -07:00
12
+ date: 2009-05-14 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency