mynyml-rack-respond_to 0.9.6 → 0.9.7

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -11,6 +11,7 @@ preference (see http://github.com/mynyml/rack-accept-media-types).
11
11
 
12
12
  * Based on familiar API (Rails)
13
13
  * Cascades down priority list of accepted media types
14
+ * Handles wildcard media types
14
15
  * Simple to use
15
16
  * Simple code (~50 LOCs)
16
17
  * Flexible (standalone use)
data/Rakefile CHANGED
@@ -22,7 +22,7 @@ end
22
22
 
23
23
  spec = Gem::Specification.new do |s|
24
24
  s.name = 'rack-respond_to'
25
- s.version = '0.9.6'
25
+ s.version = '0.9.7'
26
26
  s.summary = "Rack middleware port of Rails's respond_to feature"
27
27
  s.description = "Rack middleware port of Rails's respond_to feature"
28
28
  s.author = "Martin Aumont"
@@ -60,7 +60,7 @@ end
60
60
  desc "Generate rdoc documentation."
61
61
  Rake::RDocTask.new("rdoc") { |rdoc|
62
62
  rdoc.rdoc_dir = 'doc/rdoc'
63
- rdoc.title = "Simple Router - Document"
63
+ rdoc.title = "Rack::RespondTo"
64
64
  rdoc.options << '--line-numbers' << '--inline-source'
65
65
  rdoc.options << '--charset' << 'utf-8'
66
66
  rdoc.rdoc_files.include('README')
data/TODO CHANGED
@@ -1,27 +0,0 @@
1
- o handle wildcard content-types
2
- e.g. */* matches first format block
3
-
4
- Rack::RespondTo.mime_type = '*/*'
5
-
6
- body = respond_to do |format|
7
- format.html { 'html' }
8
- format.xml { 'xml' }
9
- end
10
- body #=> 'html'
11
-
12
- body = respond_to do |format|
13
- format.xml { 'xml' }
14
- format.html { 'html' }
15
- end
16
- body #=> 'xml'
17
-
18
- x cascade down accept types priority instead of only responding to prefered
19
- type. e.g:
20
-
21
- env['HTTP_ACCEPT'] #=> 'text/plain,text/html;q=0.9,application/xml;q=0.8'
22
-
23
- body = respond_to do |format|
24
- format.html { 'html' }
25
- format.xml { 'xml' }
26
- end
27
- body #=> 'html'
@@ -97,6 +97,12 @@ module Rack
97
97
  # cascade down the RespondTo.media_types list until it finds a match.
98
98
  # Returns nil if there is no match.
99
99
  #
100
+ # Wildcard media types (*/*, text/*, etc.) will trigger the first
101
+ # matching format definition, so order matters if you expect the Accept
102
+ # header to contain any (a nil Accept header, for instance, will be
103
+ # turned into '*/*' as per rfc2616-sec14.1). Simply define the 'default'
104
+ # handler first (usually html), and it will work like a charm.
105
+ #
100
106
  # ===== Examples
101
107
  #
102
108
  # RespondTo.media_types = ['text/html', 'application/xml']
@@ -123,19 +129,64 @@ module Rack
123
129
  # end
124
130
  # #=> nil
125
131
  #
132
+ # RespondTo.media_types = ['*/*']
133
+ #
134
+ # respond_to do |format|
135
+ # format.html { 'html' }
136
+ # format.xml { 'xml' }
137
+ # end
138
+ # #=> 'html'
139
+ #
140
+ # RespondTo.media_types = ['*/*']
141
+ #
142
+ # respond_to do |format|
143
+ # format.xml { 'xml' }
144
+ # format.html { 'html' }
145
+ # end
146
+ # #=> 'xml'
147
+ #
148
+ # RespondTo.media_types = ['text/*']
149
+ #
150
+ # respond_to do |format|
151
+ # format.xml { 'xml' } # application/xml (skip)
152
+ # format.html { 'html' } # text/html (match)
153
+ # format.txt { 'txt' }
154
+ # end
155
+ # #=> 'html'
156
+ #
126
157
  def respond_to
127
158
  format = Format.new
128
159
  yield format
129
- type = RespondTo.media_types.detect {|type| format[type] }
160
+ type, handler = Helpers.match(RespondTo.media_types, format)
130
161
  RespondTo.selected_media_type = type
131
- handler = format[type]
132
162
  handler.nil? ? nil : handler.call
133
163
  end
134
164
  end
135
165
 
136
- class Format < Hash #:nodoc:
166
+ # Helper methods, kept in a seperate namespace to avoid pollution.
167
+ module Helpers #:nodoc:
168
+ extend self
169
+
170
+ # TODO refactor
171
+ def match(media_types, format)
172
+ selected = []
173
+ accepted_types = media_types.map {|type| type.gsub(/\*/,'.*') }
174
+ accepted_types.each do |at|
175
+ format.each do |ht, handler|
176
+ (selected = [ht, handler]) and break if ht.match(at)
177
+ end
178
+ break unless selected.empty?
179
+ end
180
+ selected
181
+ end
182
+ end
183
+
184
+ # NOTE
185
+ # Array instead of hash because order matters (wildcard type matches first
186
+ # handler)
187
+ class Format < Array #:nodoc:
137
188
  def method_missing(format, *args, &handler)
138
- self[RespondTo::MediaType(format.to_s)] = handler
189
+ self << [RespondTo::MediaType(format.to_s), handler]
139
190
  end
140
191
  end
141
192
  end
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-respond_to
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Aumont
@@ -126,4 +126,45 @@ class TestRespondTo < Test::Unit::TestCase
126
126
  assert_equal 'txt', body
127
127
  assert_equal 'text/plain', Rack::RespondTo.selected_media_type
128
128
  end
129
+
130
+ ## wildcard media types
131
+
132
+ test "wildcard type matches first handler" do
133
+ Rack::RespondTo.media_types = %w( */* )
134
+
135
+ body = App.respond_to do |format|
136
+ format.xml { 'xml' }
137
+ format.txt { 'txt' }
138
+ end
139
+ assert_equal 'xml', body
140
+
141
+ body = App.respond_to do |format|
142
+ format.txt { 'txt' }
143
+ format.xml { 'xml' }
144
+ end
145
+ assert_equal 'txt', body
146
+ end
147
+
148
+ test "wildcard subtype matches first handler for type" do
149
+ Rack::RespondTo.media_types = %w( text/* )
150
+
151
+ body = App.respond_to do |format|
152
+ format.xml { 'xml' }
153
+ format.txt { 'txt' }
154
+ format.htm { 'htm' }
155
+ end
156
+ assert_equal 'txt', body
157
+
158
+ body = App.respond_to do |format|
159
+ format.xml { 'xml' }
160
+ format.htm { 'htm' }
161
+ format.txt { 'txt' }
162
+ end
163
+ assert_equal 'htm', body
164
+
165
+ body = App.respond_to do |format|
166
+ format.xml { 'xml' }
167
+ end
168
+ assert_equal nil, body
169
+ end
129
170
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mynyml-rack-respond_to
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.6
4
+ version: 0.9.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Aumont