mynyml-rack-respond_to 0.9 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
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