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 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