mynyml-rack-respond_to 0.9 → 0.9.4

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
@@ -1,13 +1,13 @@
1
- SUMMARY
1
+ ===== Summary
2
2
 
3
3
  Rack convenience middleware that allows triggering different actions based on
4
- requested format. Standalone version of the equivalent Rails functionality.
4
+ requested mime type. Standalone version of the equivalent Rails functionality.
5
5
 
6
- INSTALLATION
6
+ ===== Installation
7
7
 
8
8
  sudo gem install mynyml-rack-respond_to --source=http://gems.github.com/
9
9
 
10
- USAGE
10
+ ===== Example
11
11
 
12
12
  require 'rubygems'
13
13
  require 'rack'
@@ -17,32 +17,37 @@ USAGE
17
17
  include Rack::RespondTo
18
18
 
19
19
  def call(env)
20
- # simply pass in the env if another middleware already added
21
- # the format to env['request.format']
22
- #Rack::RespondTo.env = env
20
+ # Pass in the env, and RespondTo will retrieve the requested mime type
21
+ # from the HTTP_ACCEPT header
22
+ Rack::RespondTo.env = env
23
23
 
24
- # otherwise, you can assign it directly
25
- Rack::RespondTo.format = 'html'
24
+ # Alternatively, to use standalone you can also assign the mime type
25
+ # directly (this will take precedence over the env)
26
+ #Rack::RespondTo.mime_type = 'text/html'
26
27
 
27
28
  body = respond_to do |format|
28
29
  format.html { '<em>html</em>' }
29
30
  format.xml { '<body>xml</body>' }
30
31
  end
31
32
 
32
- content_type = Rack::RespondTo.mime_type
33
- [200, {'Content-Type' => content_type}, [body]]
33
+ [200, {'Content-Type' => Rack::RespondTo.mime_type}, [body]]
34
34
  end
35
35
  end
36
36
 
37
37
  run App.new
38
38
 
39
- TIP
39
+ ===== Tips
40
40
 
41
- To fully extract the requested format, use:
41
+ Use together with Rack::AbstractFormat to respond to routes based on url
42
+ extensions. For example, if you want <tt>example.com/foo.xml</tt> to trigger
43
+ the <tt>format.xml</tt> block (Rack::AbstractFormat moves the extension into
44
+ HTTP_ACCEPT).
42
45
 
43
- Rack::AcceptFormat (sudo gem install rack-rack-contrib --source=http://gems.github.com/)
44
- Rack::AbstractFormat (sudo gem install mynyml-rack-abstract-format --source=http://gems.github.com/)
45
-
46
- These will allow using only <tt>Rack::RespondTo.env = env</tt> to set up ResondTo.
46
+ sudo gem install mynyml-rack-abstract-format --source=http://gems.github.com/
47
47
 
48
48
  See examples/recommended_use.ru for a complete example.
49
+
50
+ ===== Links
51
+
52
+ source:: http://github.com/mynyml/rack-respond_to
53
+ rdocs:: http://docs.github.com/mynyml/rack-respond_to
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'
25
+ s.version = '0.9.4'
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"
data/TODO ADDED
@@ -0,0 +1,2 @@
1
+ o handle wildcard content-types?
2
+ - */*;q=0.8
@@ -1,14 +1,20 @@
1
1
  # install required dependencies:
2
2
  #
3
- # $sudo gem install rack-rack-contrib --source=http://gems.github.com/
4
3
  # $sudo gem install mynyml-rack-abstract-format --source=http://gems.github.com/
5
4
  #
6
5
  # and run me with:
7
6
  # $rackup examples/recommended_use.ru -p 8080
8
7
  #
8
+ # and request:
9
+ # localhost:8080/foo.html
10
+ # localhost:8080/foo.xml
11
+ #
12
+ require 'pathname'
13
+ root = Pathname(__FILE__).dirname.parent.expand_path
14
+ $:.unshift(root + 'lib')
15
+
9
16
  require 'rubygems'
10
17
  require 'rack'
11
- require 'rack/contrib' # for Rack::AcceptFormat
12
18
  require 'rack/abstract_format'
13
19
  require 'rack/respond_to'
14
20
 
@@ -27,12 +33,10 @@ class App
27
33
  end
28
34
  end
29
35
 
30
- content_type = Rack::RespondTo.mime_type
31
- [200, {'Content-Type' => content_type}, [body]]
36
+ [200, {'Content-Type' => Rack::RespondTo.mime_type}, [body]]
32
37
  end
33
38
  end
34
39
 
35
- use Rack::AcceptFormat
36
40
  use Rack::AbstractFormat
37
41
  run App.new
38
42
 
@@ -3,7 +3,7 @@
3
3
  #
4
4
  require 'pathname'
5
5
  root = Pathname(__FILE__).dirname.parent.expand_path
6
- $:.unshift(root.join('lib'))
6
+ $:.unshift(root + 'lib')
7
7
 
8
8
  require 'rubygems'
9
9
  require 'rack'
@@ -13,12 +13,7 @@ class App
13
13
  include Rack::RespondTo
14
14
 
15
15
  def call(env)
16
- # simply pass in the env if another middleware already added
17
- # the format to env['request.format']
18
- #Rack::RespondTo.env = env
19
-
20
- # otherwise, you can assign it directly
21
- Rack::RespondTo.format = 'html'
16
+ Rack::RespondTo.mime_type = 'application/xml'
22
17
 
23
18
  body = case env['PATH_INFO']
24
19
  when '/'
@@ -28,8 +23,7 @@ class App
28
23
  end
29
24
  end
30
25
 
31
- content_type = Rack::RespondTo.mime_type
32
- [200, {'Content-Type' => content_type}, [body]]
26
+ [200, {'Content-Type' => Rack::RespondTo.mime_type}, [body]]
33
27
  end
34
28
  end
35
29
 
@@ -3,22 +3,29 @@ module Rack
3
3
  # Based on Rails's API, and sinatra-respond_to (http://github.com/cehoffman/sinatra-respond_to)
4
4
  #
5
5
  # See examples/ directory for code examples.
6
+ #
6
7
  module RespondTo
7
8
  class << self
8
- # Assign the environment directly if it contains the format in
9
- # env['request.format']. This is useful in conjunction with other
10
- # middlewares that store the format in the env key.
9
+ # Assign the environment directly to fetch the mime type from
10
+ # env['HTTP_ACCEPT'] ('Accept:' request header).
11
+ #
12
+ # ===== Example
13
+ #
14
+ # def call(env)
15
+ # Rack::RespondTo.env = env
16
+ # end
17
+ #
11
18
  attr_accessor :env
12
19
 
13
- # If used completely standalone, you can assign the request format directly.
20
+ # If used completely standalone, you can assign the request mime_type directly.
14
21
  #
15
- # RespondTo.format = 'xml'
16
- attr_writer :format
17
-
18
- # Requested format
19
- def format
20
- (@format || self.env['request.format']).to_s.strip.downcase.sub(/^\./,'')
21
- end
22
+ # ===== Example
23
+ #
24
+ # RespondTo.mime_type = 'application/xml'
25
+ #
26
+ attr_accessor :mime_type
27
+ alias :media_type= :mime_type=
28
+ alias :media_type :mime_type
22
29
 
23
30
  def included(base) #:nodoc:
24
31
  base.extend(ClassMethods)
@@ -37,11 +44,30 @@ module Rack
37
44
  # ===== Example
38
45
  #
39
46
  # [200, {'Content-Type' => Rack::RespondTo.mime_type}, [body]]
47
+ #
40
48
  def mime_type(format = nil)
41
- format ||= self.format
42
- ext = format.sub(/^\./,'').insert(0,'.')
43
- Rack::Mime.mime_type(ext)
49
+ @mime_type || accept
50
+ end
51
+
52
+ # Cast format to mime type
53
+ #
54
+ # ===== Example
55
+ #
56
+ # RespondTo::MimeType('html') #=> 'text/html'
57
+ #
58
+ def MimeType(format)
59
+ Rack::Mime.mime_type(format.sub(/^\./,'').insert(0,'.'))
44
60
  end
61
+
62
+ private
63
+ # The mime type retained from the HTTP_ACCEPT header's list
64
+ #
65
+ # ===== Returns
66
+ # String:: first mime type from header's list or nil if none
67
+ #
68
+ def accept
69
+ self.env['HTTP_ACCEPT'].split(',').first.split(';').first if env && env['HTTP_ACCEPT'] && !env['HTTP_ACCEPT'].empty?
70
+ end
45
71
  end
46
72
 
47
73
  module InstanceMethods
@@ -53,11 +79,11 @@ module Rack
53
79
 
54
80
  module ClassMethods
55
81
  # Allows defining different actions and returns the one which corresponds
56
- # to the current RespondTo.format.
82
+ # to the current RespondTo.mime_type.
57
83
  #
58
84
  # ===== Example
59
85
  #
60
- # RespondTo.format = 'html'
86
+ # RespondTo.mime_type = 'text/html'
61
87
  #
62
88
  # respond_to do |format|
63
89
  # format.html { '<em>html</em>' }
@@ -75,7 +101,7 @@ module Rack
75
101
 
76
102
  class Format < Hash #:nodoc:
77
103
  def method_missing(format, *args, &handler)
78
- self[RespondTo.mime_type(format.to_s)] = handler
104
+ self[RespondTo::MimeType(format.to_s)] = handler
79
105
  end
80
106
  end
81
107
  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"
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Aumont
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-22 00:00:00 -04:00
12
+ date: 2009-06-03 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -29,6 +29,7 @@ files:
29
29
  - examples
30
30
  - examples/simple_app.ru
31
31
  - examples/recommended_use.ru
32
+ - TODO
32
33
  - lib
33
34
  - lib/rack
34
35
  - lib/rack/respond_to.rb
data/test/test_helper.rb CHANGED
@@ -4,6 +4,8 @@ require 'rubygems'
4
4
  require 'rack'
5
5
  begin
6
6
  require 'ruby-debug'
7
+ require 'phocus/test_unit'
8
+ require 'pending'
7
9
  rescue LoadError, RuntimeError
8
10
  end
9
11
 
@@ -7,17 +7,24 @@ end
7
7
  class TestRespondTo < Test::Unit::TestCase
8
8
 
9
9
  def setup
10
- Rack::RespondTo.format = nil
10
+ Rack::RespondTo.mime_type = nil
11
11
  end
12
12
 
13
13
  ## api
14
14
 
15
- test "format accessor" do
16
- Rack::RespondTo.format = 'xml'
15
+ test "env accessor" do
16
+ env = {'HTTP_ACCEPT' => 'text/html,application/xml'}
17
+ Rack::RespondTo.env = env
18
+ assert_equal env, Rack::RespondTo.env
17
19
  end
18
20
 
19
- test "env accessor" do
20
- Rack::RespondTo.env = {}
21
+ test "mime type accessor" do
22
+ Rack::RespondTo.mime_type = 'application/xml'
23
+ assert_equal 'application/xml', Rack::RespondTo.mime_type
24
+
25
+ # alias
26
+ Rack::RespondTo.media_type = 'application/xml'
27
+ assert_equal 'application/xml', Rack::RespondTo.media_type
21
28
  end
22
29
 
23
30
  test "mixin injects respond_to class method" do
@@ -28,59 +35,84 @@ class TestRespondTo < Test::Unit::TestCase
28
35
  assert App.new.respond_to?(:respond_to)
29
36
  end
30
37
 
31
- ## format
38
+ ## mime type
39
+
40
+ test "mime type is extracted from header (first in list)" do
41
+ Rack::RespondTo.env = {'HTTP_ACCEPT' => 'text/html,application/xml'}
42
+ assert_equal 'text/html', Rack::RespondTo.mime_type
32
43
 
33
- test "format is extracted from env" do
34
- Rack::RespondTo.env = {'request.format' => 'xml'}
35
- assert_equal 'xml', Rack::RespondTo.format
44
+ Rack::RespondTo.env = {'HTTP_ACCEPT' => 'application/xml,text/html'}
45
+ assert_equal 'application/xml', Rack::RespondTo.mime_type
36
46
  end
37
47
 
38
- test "explicitly specified format takes precedence of env's" do
39
- Rack::RespondTo.env = {'request.format' => 'xml'}
40
- Rack::RespondTo.format = 'html'
41
- assert_equal 'html', Rack::RespondTo.format
48
+ test "mime type with empty header" do
49
+ assert_nothing_raised do
50
+ Rack::RespondTo.env = {'HTTP_ACCEPT' => ''}
51
+ Rack::RespondTo.mime_type = nil
52
+ assert_equal nil, Rack::RespondTo.mime_type
53
+ end
42
54
  end
43
55
 
44
- test "format is normalized" do
45
- Rack::RespondTo.format = '.html'
46
- assert_equal 'html', Rack::RespondTo.format
56
+ test "mime type with nil header" do
57
+ assert_nothing_raised do
58
+ Rack::RespondTo.env = {}
59
+ Rack::RespondTo.mime_type = nil
60
+ assert_equal nil, Rack::RespondTo.mime_type
61
+ end
62
+ end
47
63
 
48
- Rack::RespondTo.format = :html
49
- assert_equal 'html', Rack::RespondTo.format
64
+ test "mime type without source" do
65
+ assert_nothing_raised do
66
+ Rack::RespondTo.env = nil
67
+ Rack::RespondTo.mime_type = nil
68
+ assert_equal nil, Rack::RespondTo.mime_type
69
+ end
70
+ end
50
71
 
51
- Rack::RespondTo.format = ' html '
52
- assert_equal 'html', Rack::RespondTo.format
72
+ test "mime type ignores content-type arguments" do
73
+ Rack::RespondTo.env = {'HTTP_ACCEPT' => 'application/xml;q=0.9,text/html'}
74
+ assert_equal 'application/xml', Rack::RespondTo.mime_type
75
+ end
53
76
 
54
- Rack::RespondTo.format = 'HTML'
55
- assert_equal 'html', Rack::RespondTo.format
77
+ test "explicitly specified mime type takes precedence over env's" do
78
+ Rack::RespondTo.env = {'HTTP_ACCEPT' => 'text/html'}
79
+ Rack::RespondTo.mime_type = 'text/plain'
80
+ assert_equal 'text/plain', Rack::RespondTo.mime_type
56
81
  end
57
82
 
58
83
  ## respond_to
59
84
 
60
85
  test "respond_to returns block for requested format" do
61
- Rack::RespondTo.format = 'xml'
62
- response = App.respond_to do |format|
86
+ Rack::RespondTo.mime_type = 'application/xml'
87
+ body = App.respond_to do |format|
63
88
  format.xml { 'xml' }
64
89
  format.txt { 'txt' }
65
90
  end
66
- assert_equal 'xml', response
91
+ assert_equal 'xml', body
67
92
  end
68
93
 
69
- test "respond_to returns nil when no format matches" do
70
- Rack::RespondTo.format = 'html'
71
- response = App.respond_to do |format|
94
+ test "respond_to with no matching format" do
95
+ Rack::RespondTo.mime_type = 'text/html'
96
+ body = App.respond_to do |format|
72
97
  format.xml { 'xml' }
73
98
  format.txt { 'txt' }
74
99
  end
75
- assert_equal nil, response
100
+ assert_equal nil, body
76
101
  end
77
102
 
78
103
  test "respond_to handles synonymous formats" do
79
- Rack::RespondTo.format = 'htm' # htm should trigger both htm and html
80
- response = App.respond_to do |format|
81
- format.html { 'html' }
104
+ Rack::RespondTo.mime_type = 'text/html'
105
+
106
+ body = App.respond_to do |format|
107
+ format.htm { 'htm' } # htm/html
108
+ format.xml { 'xml' }
109
+ end
110
+ assert_equal 'htm', body
111
+
112
+ body = App.respond_to do |format|
113
+ format.html { 'html' } # htm/html
82
114
  format.json { 'json' }
83
115
  end
84
- assert_equal 'html', response
116
+ assert_equal 'html', body
85
117
  end
86
118
  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"
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Martin Aumont
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-05-21 21:00:00 -07:00
12
+ date: 2009-06-02 21:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -29,6 +29,7 @@ files:
29
29
  - examples
30
30
  - examples/simple_app.ru
31
31
  - examples/recommended_use.ru
32
+ - TODO
32
33
  - lib
33
34
  - lib/rack
34
35
  - lib/rack/respond_to.rb