mynyml-rack-respond_to 0.9.6 → 0.9.7

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