rack-accept 0.2 → 0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = 'rack-accept'
3
- s.version = '0.2'
3
+ s.version = '0.3'
4
4
  s.date = '2010-04-02'
5
5
 
6
6
  s.summary = 'HTTP Accept* for Ruby/Rack'
@@ -19,7 +19,7 @@ Gem::Specification.new do |s|
19
19
  s.test_files = s.files.select {|path| path =~ /^test\/.*_test.rb/ }
20
20
 
21
21
  s.add_dependency('rack', '>= 0.4')
22
- s.add_development_dependency 'rake'
22
+ s.add_development_dependency('rake')
23
23
 
24
24
  s.has_rdoc = true
25
25
  s.rdoc_options = %w< --line-numbers --inline-source --title Rack::Accept --main Rack::Accept >
data/CHANGES CHANGED
@@ -1,3 +1,8 @@
1
+ ## 0.3 / April 3, 2010
2
+
3
+ * Enhanced Rack middleware component to be able to automatically send a 406
4
+ response when the request is not acceptable
5
+
1
6
  ## 0.2 / April 2, 2010
2
7
 
3
8
  * Moved all common header methods into Rack::Accept::Header module
data/README CHANGED
@@ -23,7 +23,7 @@ Using RubyGems:
23
23
  From a local copy:
24
24
 
25
25
  $ git clone git://github.com/mjijackson/rack-accept.git
26
- $ sudo rake install
26
+ $ rake package && sudo rake install
27
27
 
28
28
  Usage
29
29
  -----
@@ -37,7 +37,7 @@ middleware pipeline and access the Rack::Accept::Request object in the
37
37
 
38
38
  use Rack::Accept
39
39
 
40
- app = lambda {|env|
40
+ app = lambda do |env|
41
41
  accept = env['rack-accept.request']
42
42
  response = Rack::Response.new
43
43
 
@@ -50,22 +50,41 @@ middleware pipeline and access the Rack::Accept::Request object in the
50
50
  end
51
51
 
52
52
  response.finish
53
- }
53
+ end
54
54
 
55
55
  run app
56
56
 
57
+ Rack::Accept can also construct automatic 406 responses if you set up the types
58
+ of media, character sets, encoding, or languages your server is able to serve
59
+ ahead of time.
60
+
61
+ require 'rack/accept'
62
+
63
+ use(Rack::Accept) do |accept|
64
+ # We only ever serve content in English or Japanese from this site, so if
65
+ # the user doesn't accept either of these we will respond with a 406.
66
+ #
67
+ # Note: +accept+ is an instance of Rack::Accept::Context.
68
+ accept.languages = %w< en jp >
69
+ end
70
+
71
+ app = ...
72
+
73
+ run app
74
+
75
+ Note: You should probably think about this very carefully before you use
76
+ Rack::Accept in this way. Many user agents are careless about the types of
77
+ Accept headers they send, and depend on apps not being too picky. Instead of
78
+ automatically sending a 406, you should probably only send one when absolutely
79
+ necessary.
80
+
57
81
  Additionally, Rack::Accept may be used outside of a Rack context to provide
58
82
  any Ruby app the ability to construct and interpret Accept headers.
59
83
 
60
84
  require 'rack/accept'
61
85
 
62
86
  mtype = Rack::Accept::MediaType.new
63
- mtype.qvalues = {
64
- 'text/html' => 1,
65
- 'text/*' => 0.8,
66
- '*/*' => 0.5
67
- }
68
-
87
+ mtype.qvalues = { 'text/html' => 1, 'text/*' => 0.8, '*/*' => 0.5 }
69
88
  mtype.to_s # => "Accept: text/html, text/*;q=0.8, */*;q=0.5"
70
89
 
71
90
  cset = Rack::Accept::Charset.new('unicode-1-1, iso-8859-5;q=0.8')
@@ -74,7 +93,8 @@ any Ruby app the ability to construct and interpret Accept headers.
74
93
 
75
94
  The very last line in this example may look like a mistake to someone not
76
95
  familiar with the intricacies of the spec, but it's actually correct. It
77
- just puts emphasis on the convenience of using this library.
96
+ just puts emphasis on the convenience of using this library so you don't
97
+ have to worry about these kinds of details.
78
98
 
79
99
  Four-letter Words
80
100
  -----------------
@@ -13,16 +13,16 @@
13
13
  <div id="header">
14
14
  <h1>rack-accept</h1>
15
15
  <ul>
16
- <li><a href="license.html">License</a></li>
17
16
  <li><a href="api/index.html">API</a></li>
18
17
  <li><a href="http://github.com/mjijackson/rack-accept/issues">Bugs</a></li>
19
18
  <li><a href="http://github.com/mjijackson/rack-accept">Code</a></li>
19
+ <li><a href="usage.html">Usage</a></li>
20
20
  <li><a href="index.html">Home</a></li>
21
21
  </ul>
22
22
  </div>
23
23
  <div id="content"><%= content %></div>
24
24
  <div id="footer">
25
- <p class="rights">Copyright &copy; 2010 <a href="http://mjijackson.com/about" rel="me author">Michael J. I. Jackson</a></p>
25
+ <p><a href="license.html" rel="license">Copyright</a> &copy; 2010 <a href="http://mjijackson.com/about" rel="me author">Michael J. I. Jackson</a></p>
26
26
  </div>
27
27
  </div>
28
28
  </body>
data/doc/assets/style.css CHANGED
@@ -38,7 +38,17 @@ code {
38
38
  }
39
39
  pre {
40
40
  background-color: #FDFDFD;
41
- padding-left: 6px;
41
+ padding: 4px 0 4px 6px;
42
+ line-height: 1.2;
43
+ }
44
+ strong {
45
+ font-weight: bold;
46
+ }
47
+ ::selection {
48
+ background: rgba(200,200,200,0.5);
49
+ }
50
+ ::-moz-selection {
51
+ background: rgba(200,200,200,0.5);
42
52
  }
43
53
  #wrapper {
44
54
  position: relative;
data/doc/index.markdown CHANGED
@@ -21,58 +21,7 @@ Using [RubyGems][rubygems]:
21
21
  From a local copy:
22
22
 
23
23
  $ git clone git://github.com/mjijackson/rack-accept.git
24
- $ sudo rake install
25
-
26
- Usage
27
- -----
28
-
29
- Rack::Accept implements the Rack middleware interface and may be used with any
30
- Rack-based application. Simply insert the Rack::Accept module in your Rack
31
- middleware pipeline and access the [Rack::Accept::Request][req] object in the
32
- "rack-accept.request" environment key, as in the following example:
33
-
34
- require 'rack/accept'
35
-
36
- use Rack::Accept
37
-
38
- app = lambda {|env|
39
- accept = env['rack-accept.request']
40
- response = Rack::Response.new
41
-
42
- if accept.media_type?('text/html')
43
- response['Content-Type'] = 'text/html'
44
- response.write "<p>Hello. You accept text/html!</p>"
45
- else
46
- response['Content-Type'] = 'text/plain'
47
- response.write "Apparently you don't accept text/html. Too bad."
48
- end
49
-
50
- response.finish
51
- }
52
-
53
- run app
54
-
55
- Additionally, Rack::Accept may be used outside of a Rack context to provide
56
- any Ruby app the ability to construct and interpret Accept headers.
57
-
58
- require 'rack/accept'
59
-
60
- mtype = Rack::Accept::MediaType.new
61
- mtype.qvalues = {
62
- 'text/html' => 1,
63
- 'text/*' => 0.8,
64
- '*/*' => 0.5
65
- }
66
-
67
- mtype.to_s # => "Accept: text/html, text/*;q=0.8, */*;q=0.5"
68
-
69
- cset = Rack::Accept::Charset.new('unicode-1-1, iso-8859-5;q=0.8')
70
- cset.best_of(%w< iso-8859-5 unicode-1-1 >) # => "unicode-1-1"
71
- cset.accept?('iso-8859-1') # => true
72
-
73
- The very last line in this example may look like a mistake to someone not
74
- familiar with the intricacies of [the spec][sec14-3], but it's actually
75
- correct. It just puts emphasis on the convenience of using this library.
24
+ $ rake package && sudo rake install
76
25
 
77
26
  [rfc]: http://www.w3.org/Protocols/rfc2616/rfc2616.html
78
27
  [sec14]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html
@@ -83,4 +32,3 @@ correct. It just puts emphasis on the convenience of using this library.
83
32
  [rack]: http://rack.rubyforge.org/
84
33
  [test]: http://github.com/mjijackson/rack-accept/tree/master/test/
85
34
  [rubygems]: http://rubygems.org/
86
- [req]: api/classes/Rack/Accept/Request.html
data/doc/license.markdown CHANGED
@@ -1,3 +1,6 @@
1
+ License
2
+ -------
3
+
1
4
  Copyright 2010 Michael J. I. Jackson
2
5
 
3
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -0,0 +1,74 @@
1
+ Usage
2
+ -----
3
+
4
+ Rack::Accept implements the Rack middleware interface and may be used with any
5
+ Rack-based application. Simply insert the Rack::Accept module in your Rack
6
+ middleware pipeline and access the [Rack::Accept::Request][req] object in the
7
+ "rack-accept.request" environment key, as in the following example:
8
+
9
+ require 'rack/accept'
10
+
11
+ use Rack::Accept
12
+
13
+ app = lambda do |env|
14
+ accept = env['rack-accept.request']
15
+ response = Rack::Response.new
16
+
17
+ if accept.media_type?('text/html')
18
+ response['Content-Type'] = 'text/html'
19
+ response.write "<p>Hello. You accept text/html!</p>"
20
+ else
21
+ response['Content-Type'] = 'text/plain'
22
+ response.write "Apparently you don't accept text/html. Too bad."
23
+ end
24
+
25
+ response.finish
26
+ end
27
+
28
+ run app
29
+
30
+ Rack::Accept can also construct a [406][406] response automatically if you set
31
+ up the types of media, character sets, encoding, or languages your server is
32
+ able to serve ahead of time.
33
+
34
+ require 'rack/accept'
35
+
36
+ use(Rack::Accept) do |accept|
37
+ # We only ever serve content in English or Japanese from this site, so if
38
+ # the user doesn't accept either of these we will respond with a 406.
39
+ #
40
+ # Note: +accept+ is an instance of Rack::Accept::Context.
41
+ accept.languages = %w< en jp >
42
+ end
43
+
44
+ app = ...
45
+
46
+ run app
47
+
48
+ __Note:__ You should probably think about this very carefully before you use
49
+ Rack::Accept in this way. Many user agents are careless about the types of
50
+ Accept headers they send, and depend on apps not being too picky. Instead of
51
+ automatically sending a 406, you should probably only send one when absolutely
52
+ necessary.
53
+
54
+ Additionally, Rack::Accept may be used outside of a Rack context to provide
55
+ any Ruby app the ability to construct and interpret Accept headers.
56
+
57
+ require 'rack/accept'
58
+
59
+ mtype = Rack::Accept::MediaType.new
60
+ mtype.qvalues = { 'text/html' => 1, 'text/*' => 0.8, '*/*' => 0.5 }
61
+ mtype.to_s # => "Accept: text/html, text/*;q=0.8, */*;q=0.5"
62
+
63
+ cset = Rack::Accept::Charset.new('unicode-1-1, iso-8859-5;q=0.8')
64
+ cset.best_of(%w< iso-8859-5 unicode-1-1 >) # => "unicode-1-1"
65
+ cset.accept?('iso-8859-1') # => true
66
+
67
+ The very last line in this example may look like a mistake to someone not
68
+ familiar with the intricacies of [the spec][sec14-3], but it's actually
69
+ correct. It just puts emphasis on the convenience of using this library so you
70
+ don't have to worry about these kinds of details.
71
+
72
+ [req]: api/classes/Rack/Accept/Request.html
73
+ [406]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.7
74
+ [sec14-3]: http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.3
data/lib/rack/accept.rb CHANGED
@@ -3,7 +3,7 @@ require 'rack'
3
3
  module Rack::Accept
4
4
 
5
5
  # The current version of rack-accept.
6
- VERSION = [0, 2]
6
+ VERSION = [0, 3]
7
7
 
8
8
  # Returns the current version of rack-accept as a string.
9
9
  def self.version
@@ -22,5 +22,6 @@ module Rack::Accept
22
22
  autoload :Language, 'rack/accept/language'
23
23
  autoload :MediaType, 'rack/accept/media_type'
24
24
  autoload :Request, 'rack/accept/request'
25
+ autoload :Response, 'rack/accept/response'
25
26
 
26
27
  end
@@ -15,8 +15,7 @@ module Rack::Accept
15
15
  'Accept-Charset'
16
16
  end
17
17
 
18
- # Determines the quality factor (qvalue) of the given +charset+,
19
- # according to the specifications of the original header.
18
+ # Determines the quality factor (qvalue) of the given +charset+.
20
19
  def qvalue(charset)
21
20
  m = matches(charset)
22
21
  if m.empty?
@@ -26,8 +25,8 @@ module Rack::Accept
26
25
  end
27
26
  end
28
27
 
29
- # Returns an array of character sets from the original header that match
30
- # the given +charset+, ordered by precedence.
28
+ # Returns an array of character sets from this header that match the given
29
+ # +charset+, ordered by precedence.
31
30
  def matches(charset)
32
31
  values.select {|v|
33
32
  v == charset || v == '*'
@@ -3,18 +3,67 @@ module Rack::Accept
3
3
  # Implements the Rack middleware interface.
4
4
  class Context
5
5
 
6
+ # This error is raised when the server is not able to provide an acceptable
7
+ # response.
8
+ class AcceptError < StandardError; end
9
+
6
10
  attr_reader :app
7
11
 
8
12
  def initialize(app)
9
13
  @app = app
14
+ @checks = {}
15
+ @check_headers = []
10
16
  yield self if block_given?
11
17
  end
12
18
 
13
19
  # Inserts a new Rack::Accept::Request object into the environment before
14
20
  # handing the request to the app immediately downstream.
15
21
  def call(env)
16
- env['rack-accept.request'] ||= Request.new(env)
22
+ request = env['rack-accept.request'] ||= Request.new(env)
23
+ check!(request) unless @checks.empty?
17
24
  @app.call(env)
25
+ rescue AcceptError
26
+ response = Response.new
27
+ response.not_acceptable!
28
+ response.finish
29
+ end
30
+
31
+ # Defines the types of media this server is able to serve.
32
+ def media_types=(media_types)
33
+ add_check(:media_type, media_types)
34
+ end
35
+
36
+ # Defines the character sets this server is able to serve.
37
+ def charsets=(charsets)
38
+ add_check(:charset, charsets)
39
+ end
40
+
41
+ # Defines the types of encodings this server is able to serve.
42
+ def encodings=(encodings)
43
+ add_check(:encoding, encodings)
44
+ end
45
+
46
+ # Defines the languages this server is able to serve.
47
+ def languages=(languages)
48
+ add_check(:language, languages)
49
+ end
50
+
51
+ private
52
+
53
+ def add_check(header_name, values)
54
+ @checks[header_name] ||= []
55
+ @checks[header_name].concat(values)
56
+ @check_headers << header_name unless @check_headers.include?(header_name)
57
+ end
58
+
59
+ # Raises an AcceptError if this server is not able to serve an acceptable
60
+ # response.
61
+ def check!(request)
62
+ @check_headers.each do |header_name|
63
+ values = @checks[header_name]
64
+ header = request.send(header_name)
65
+ raise AcceptError unless values.any? {|v| header.accept?(v) }
66
+ end
18
67
  end
19
68
 
20
69
  end
@@ -15,8 +15,7 @@ module Rack::Accept
15
15
  'Accept-Encoding'
16
16
  end
17
17
 
18
- # Determines the quality factor (qvalue) of the given +encoding+,
19
- # according to the specifications of the original header.
18
+ # Determines the quality factor (qvalue) of the given +encoding+.
20
19
  def qvalue(encoding)
21
20
  m = matches(encoding)
22
21
  if m.empty?
@@ -26,8 +25,8 @@ module Rack::Accept
26
25
  end
27
26
  end
28
27
 
29
- # Returns an array of encodings from the original header that match
30
- # the given +encoding+, ordered by precedence.
28
+ # Returns an array of encodings from this header that match the given
29
+ # +encoding+, ordered by precedence.
31
30
  def matches(encoding)
32
31
  values.select {|v|
33
32
  v == encoding || v == '*'
@@ -15,8 +15,7 @@ module Rack::Accept
15
15
  'Accept-Language'
16
16
  end
17
17
 
18
- # Determines the quality factor (qvalue) of the given +language+,
19
- # according to the specifications of the original header.
18
+ # Determines the quality factor (qvalue) of the given +language+.
20
19
  def qvalue(language)
21
20
  return 1 if @qvalues.empty?
22
21
  m = matches(language)
@@ -24,8 +23,8 @@ module Rack::Accept
24
23
  @qvalues[m.first]
25
24
  end
26
25
 
27
- # Returns an array of languages from the original header that match
28
- # the given +language+, ordered by precedence.
26
+ # Returns an array of languages from this header that match the given
27
+ # +language+, ordered by precedence.
29
28
  def matches(language)
30
29
  values.select {|v|
31
30
  v == language || v == '*' || (language.match(/^(.+?)-/) && v == $1)
@@ -15,8 +15,7 @@ module Rack::Accept
15
15
  'Accept'
16
16
  end
17
17
 
18
- # Determines the quality factor (qvalue) of the given +media_type+,
19
- # according to the specifications of the original header.
18
+ # Determines the quality factor (qvalue) of the given +media_type+.
20
19
  def qvalue(media_type)
21
20
  return 1 if @qvalues.empty?
22
21
  m = matches(media_type)
@@ -24,8 +23,8 @@ module Rack::Accept
24
23
  @qvalues[m.first]
25
24
  end
26
25
 
27
- # Returns an array of media types from the original header that match
28
- # the given +media_type+, ordered by precedence.
26
+ # Returns an array of media types from this header that match the given
27
+ # +media_type+, ordered by precedence.
29
28
  def matches(media_type)
30
29
  type, subtype, params = parse_media_type(media_type)
31
30
  values.select {|v|
@@ -1,14 +1,11 @@
1
+ require 'rack/request'
2
+
1
3
  module Rack::Accept
2
4
 
3
5
  # A container class for convenience methods when Rack::Accept is used on the
4
- # request level (as Rack middleware, for example). This class manages a
6
+ # request level as Rack middleware. Instances of this class also manage a
5
7
  # lightweight cache of various header instances to speed up execution.
6
- #
7
- # Request currently does not extend Rack::Request because that class
8
- # currently provides some limited functionality when it comes to determining
9
- # the proper encoding to use with a request and I didn't want to confuse
10
- # users.
11
- class Request
8
+ class Request < Rack::Request
12
9
 
13
10
  attr_reader :env
14
11
 
@@ -0,0 +1,21 @@
1
+ require 'rack/response'
2
+
3
+ module Rack::Accept
4
+
5
+ # The base class for responses issued by Rack::Accept.
6
+ class Response < Rack::Response
7
+
8
+ # Marks this response as being unacceptable and clears the response body.
9
+ #
10
+ # Note: The HTTP spec advises servers to respond with an "entity" that
11
+ # describes acceptable parameters, but it fails to go into detail about its
12
+ # implementation. Thus, it is up to the user of this library to create such
13
+ # an entity if one is desired.
14
+ def not_acceptable!
15
+ self.status = 406
16
+ self.body = []
17
+ header['Content-Length'] = '0'
18
+ end
19
+
20
+ end
21
+ end
data/test/charset_test.rb CHANGED
@@ -22,6 +22,9 @@ class CharsetTest < Test::Unit::TestCase
22
22
  c = C.new('iso-8859-1;q=0, *;q=0.5')
23
23
  assert_equal(0.5, c.qvalue('iso-8859-5'))
24
24
  assert_equal(0, c.qvalue('iso-8859-1'))
25
+
26
+ c = C.new('*;q=0')
27
+ assert_equal(0, c.qvalue('iso-8859-1'))
25
28
  end
26
29
 
27
30
  def test_matches
@@ -0,0 +1,59 @@
1
+ require File.dirname(__FILE__) + '/helper'
2
+
3
+ class ContextTest < Test::Unit::TestCase
4
+
5
+ def media_types; Proc.new {|c| c.media_types = %w< text/html > } end
6
+ def charsets; Proc.new {|c| c.charsets = %w< iso-8859-5 > } end
7
+ def encodings; Proc.new {|c| c.encodings = %w< gzip > } end
8
+ def languages; Proc.new {|c| c.languages = %w< en > } end
9
+
10
+ def test_empty
11
+ request
12
+ assert_equal(200, status)
13
+ end
14
+
15
+ def test_media_types
16
+ request('HTTP_ACCEPT' => 'text/html')
17
+ assert_equal(200, status)
18
+
19
+ request('HTTP_ACCEPT' => 'text/html', &media_types)
20
+ assert_equal(200, status)
21
+
22
+ request('HTTP_ACCEPT' => 'text/plain', &media_types)
23
+ assert_equal(406, status)
24
+ end
25
+
26
+ def test_charsets
27
+ request('HTTP_ACCEPT_CHARSET' => 'iso-8859-5')
28
+ assert_equal(200, status)
29
+
30
+ request('HTTP_ACCEPT_CHARSET' => 'iso-8859-5', &charsets)
31
+ assert_equal(200, status)
32
+
33
+ request('HTTP_ACCEPT_CHARSET' => 'unicode-1-1', &charsets)
34
+ assert_equal(406, status)
35
+ end
36
+
37
+ def test_encodings
38
+ request('HTTP_ACCEPT_ENCODING' => 'gzip')
39
+ assert_equal(200, status)
40
+
41
+ request('HTTP_ACCEPT_ENCODING' => 'gzip', &encodings)
42
+ assert_equal(200, status)
43
+
44
+ request('HTTP_ACCEPT_ENCODING' => 'compress', &encodings)
45
+ assert_equal(406, status)
46
+ end
47
+
48
+ def test_languages
49
+ request('HTTP_ACCEPT_LANGUAGE' => 'en')
50
+ assert_equal(200, status)
51
+
52
+ request('HTTP_ACCEPT_LANGUAGE' => 'en', &languages)
53
+ assert_equal(200, status)
54
+
55
+ request('HTTP_ACCEPT_LANGUAGE' => 'jp', &languages)
56
+ assert_equal(406, status)
57
+ end
58
+
59
+ end
data/test/helper.rb CHANGED
@@ -15,3 +15,24 @@ $LOAD_PATH.unshift(libdir) unless $LOAD_PATH.include?(libdir)
15
15
 
16
16
  require 'test/unit'
17
17
  require 'rack/accept'
18
+
19
+ class Test::Unit::TestCase
20
+ attr_reader :context
21
+ attr_reader :response
22
+
23
+ def status
24
+ @response && @response.status
25
+ end
26
+
27
+ def request(env={}, method='GET', uri='/')
28
+ @context = Rack::Accept.new(fake_app)
29
+ yield @context if block_given?
30
+ mock_request = Rack::MockRequest.new(@context)
31
+ @response = mock_request.request(method.to_s.upcase, uri, env)
32
+ @response
33
+ end
34
+
35
+ def fake_app(status=200, headers={}, body=[])
36
+ lambda {|env| Rack::Response.new(body, status, headers).finish }
37
+ end
38
+ end
metadata CHANGED
@@ -4,8 +4,8 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 2
8
- version: "0.2"
7
+ - 3
8
+ version: "0.3"
9
9
  platform: ruby
10
10
  authors:
11
11
  - Michael J. I. Jackson
@@ -58,8 +58,10 @@ files:
58
58
  - lib/rack/accept/language.rb
59
59
  - lib/rack/accept/media_type.rb
60
60
  - lib/rack/accept/request.rb
61
+ - lib/rack/accept/response.rb
61
62
  - lib/rack/accept.rb
62
63
  - test/charset_test.rb
64
+ - test/context_test.rb
63
65
  - test/encoding_test.rb
64
66
  - test/header_test.rb
65
67
  - test/helper.rb
@@ -70,6 +72,7 @@ files:
70
72
  - doc/assets/style.css
71
73
  - doc/index.markdown
72
74
  - doc/license.markdown
75
+ - doc/usage.markdown
73
76
  - CHANGES
74
77
  - .gemspec
75
78
  - Rakefile
@@ -111,6 +114,7 @@ specification_version: 3
111
114
  summary: HTTP Accept* for Ruby/Rack
112
115
  test_files:
113
116
  - test/charset_test.rb
117
+ - test/context_test.rb
114
118
  - test/encoding_test.rb
115
119
  - test/header_test.rb
116
120
  - test/language_test.rb