accept_headers 0.0.8 → 0.0.9

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b55af3993793d079e27b4b85fd02344b7dbc878b
4
- data.tar.gz: 30264067d3cbd349e13169a8592df750c81d06ba
3
+ metadata.gz: 28f7499031d0c1e01152c3d059446928393d03e9
4
+ data.tar.gz: 2b2f7c553ed27941005df86490e53364c6037098
5
5
  SHA512:
6
- metadata.gz: b45c6294fdba63025d7a1fe4d9c860078427d3011b98aa99c8a8b84429fd4454ed18aef2eefdb22d841a32284df4df475449da2787d485b41349b7664b5ca7e1
7
- data.tar.gz: 32cbb89fbe0f5b85824a8f8ae9cac9bfa095a5f02de33625511fe7e8c1b8cd5f55de8e6231787dd062f10cfe55e0b409226e2146f7861454ed07952eb8c4dc3f
6
+ metadata.gz: 3632e3031010af9c2938a49dd71e6461d8ba6d4efb442b04c6146146a2a64a4051a46da92a3e12e1c2ffec1a67cba66b8b1959a65d9d4417e643955f09d8e57d
7
+ data.tar.gz: 7b2c81b0d7614051d15cd760a95b8489efcc5509ac775dcacd45a71a5e1e0d9e5efc47385ab390eae5f3f037e5421798d0935296e4c7ff63035e2e5948de164b
data/.travis.yml CHANGED
@@ -1,16 +1,17 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 2.0.0
4
- - 2.1.5
3
+ - 2.2.6
4
+ - 2.3.3
5
5
  - rbx
6
6
  - ruby-head
7
7
  - jruby-head
8
8
 
9
9
  matrix:
10
10
  allow_failures:
11
+ - rvm: rbx
11
12
  - rvm: ruby-head
12
13
  - rvm: jruby-head
13
14
 
14
15
  addons:
15
16
  code_climate:
16
- repo_token: 50c636c924d1aa253e29c57822931c1a172cd65675ad66396bba39d255373a58
17
+ repo_token: 50c636c924d1aa253e29c57822931c1a172cd65675ad66396bba39d255373a58
data/CHANGELOG.md CHANGED
@@ -1,5 +1,12 @@
1
1
  ## HEAD
2
2
 
3
+ ## 0.0.9 / December 1, 2016
4
+
5
+ * Require ruby 2.2 minimum.
6
+ * Add `#to_s` method for all Negotiators
7
+ * Return no header if parse header is nil
8
+ * First attempt at rack middleware with simple specs.
9
+
3
10
  ## 0.0.8 / November 23, 2014
4
11
 
5
12
  * Change `#negotiate` to return the type instead of a hash. In the case of `MediaType` it'll also populate `extensions` from the matching accept header media type.
data/Gemfile CHANGED
@@ -4,7 +4,6 @@ source "https://rubygems.org"
4
4
  gemspec
5
5
 
6
6
  group :test do
7
- gem "ruby_gntp"
8
7
  gem "minitest-focus"
9
8
  gem "codeclimate-test-reporter", require: false
10
9
  gem "simplecov", require: false
@@ -13,4 +12,5 @@ end
13
12
  group :development, :test do
14
13
  gem "pry"
15
14
  gem "awesome_print"
15
+ gem "rack-test"
16
16
  end
data/README.md CHANGED
@@ -168,11 +168,50 @@ AcceptHeaders::Language.new('en', 'us')
168
168
  languages.accept?('en-gb') # true
169
169
  ```
170
170
 
171
- ## TODO
171
+ ## Rack Middleware
172
172
 
173
- * Write rack middleware
174
- * More edge case tests
175
- * Add rdoc
173
+ Add the middleware:
174
+
175
+ ```ruby
176
+ require 'accept_headers/middleware'
177
+ use AcceptHeaders::Middleware
178
+ run YourApp
179
+ ```
180
+
181
+ Simple way to set the content response headers based on the request accept headers and the supported media types, encodings, and languages provided by the app or route.
182
+
183
+ ```ruby
184
+ class YourApp
185
+ def initialize(app)
186
+ @app = app
187
+ end
188
+
189
+ def call(env)
190
+ # List your arrays of supported media types, encodings, languages. This can be global or per route/controller
191
+ supported_media_types = %w[application/json application/xml text/html text/plain]
192
+ supported_encodings = %w[gzip identify]
193
+ supported_languages = %w[en-US en-GB]
194
+
195
+ # Call the Negotiators and pass in the supported arrays and it'll return the best match
196
+ matched_media_type = env["accept_headers.media_types"].negotiate(supported_media_types)
197
+ matched_encoding = env["accept_headers.encodings"].negotiate(supported_encodings)
198
+ matched_language = env["accept_headers.languages"].negotiate(supported_languages)
199
+
200
+ # Set a default, in this case an empty string, in case of a bad header that cannot be parsed
201
+ # The return value is a MediaType, Encoding, or Language depending on the case:
202
+ # On MediaType, you can call #type ('text'), #subtype ('html'), #media_range ('text/html') to get the stringified parts
203
+ # On Encoding, you can call #encoding to get the string encoding ('gzip')
204
+ # On Language, you can call #primary_tag ('en'), #subtag ('us'), or #language_tag ('en-us')
205
+ headers = {
206
+ 'Content-Type' => matched_media_type ? matched_media_type.media_range : '',
207
+ 'Content-Encoding' => matched_encoding ? matched_encoding.encoding : '',
208
+ 'Content-Language' => matched_language ? matched_language.language_tag : '',
209
+ }
210
+
211
+ [200, headers, ["Hello World!"]]
212
+ end
213
+ end
214
+ ```
176
215
 
177
216
  ## Contributing
178
217
 
data/Rakefile CHANGED
@@ -5,6 +5,6 @@ task default: :test
5
5
 
6
6
  Rake::TestTask.new do |t|
7
7
  t.libs << "spec"
8
- t.test_files = FileList['spec/*_spec.rb']
8
+ t.test_files = FileList['spec/**/*_spec.rb']
9
9
  t.verbose = true
10
10
  end
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.required_ruby_version = '>= 2.0.0'
21
+ spec.required_ruby_version = '>= 2.2.0'
22
22
 
23
23
  spec.add_development_dependency "bundler", "~> 1.7"
24
24
  spec.add_development_dependency "rake", "~> 10.0"
@@ -4,6 +4,7 @@ module AcceptHeaders
4
4
  class Middleware
5
5
  def initialize(app)
6
6
  @app = app
7
+ yield self if block_given?
7
8
  end
8
9
 
9
10
  def call(env)
@@ -34,6 +34,10 @@ module AcceptHeaders
34
34
  negotiate(other) ? true : false
35
35
  end
36
36
 
37
+ def to_s
38
+ list.join(',')
39
+ end
40
+
37
41
  private
38
42
  def no_header
39
43
  raise NotImplementedError.new("#no_header is not implemented")
@@ -44,6 +48,7 @@ module AcceptHeaders
44
48
  end
45
49
 
46
50
  def parse(header, &block)
51
+ return no_header unless header
47
52
  header = header.dup
48
53
  header.sub!(/\A#{self.class::HEADER_PREFIX}\s*/, '')
49
54
  header.strip!
@@ -1,3 +1,3 @@
1
1
  module AcceptHeaders
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -77,6 +77,12 @@ describe AcceptHeaders::Encoding::Negotiator do
77
77
  end
78
78
  end
79
79
 
80
+ describe "#to_s" do
81
+ it "returns a string of each encoding #to_s joined by a comma" do
82
+ subject.new("compress,gzip;q=0.9").to_s.must_equal "compress;q=1,gzip;q=0.9"
83
+ end
84
+ end
85
+
80
86
  describe "negotiate supported encodings" do
81
87
  it "returns a best matching encoding" do
82
88
  n = subject.new('deflate; q=0.5, gzip, compress; q=0.8, identity')
@@ -69,6 +69,12 @@ describe AcceptHeaders::Language::Negotiator do
69
69
  end
70
70
  end
71
71
 
72
+ describe "#to_s" do
73
+ it "returns a string of each language #to_s joined by a comma" do
74
+ subject.new("en-us, en-gb;q=0.9").to_s.must_equal "en-us;q=1,en-gb;q=0.9"
75
+ end
76
+ end
77
+
72
78
  describe "negotiate supported languages" do
73
79
  it "returns a best matching language" do
74
80
  match = language.new('en', 'us')
@@ -106,6 +106,12 @@ describe AcceptHeaders::MediaType::Negotiator do
106
106
  end
107
107
  end
108
108
 
109
+ describe "#to_s" do
110
+ it "returns a string of each media type #to_s joined by a comma" do
111
+ subject.new("text/html;level=1, text/plain;q=0.9").to_s.must_equal "text/html;q=1;level=1,text/plain;q=0.9"
112
+ end
113
+ end
114
+
109
115
  describe "#negotiate" do
110
116
  it "returns a best matching media type" do
111
117
  all_browsers.each do |browser|
@@ -0,0 +1,64 @@
1
+ require_relative "spec_helper"
2
+ require "accept_headers/middleware"
3
+ require "rack/test"
4
+
5
+ describe AcceptHeaders::Middleware do
6
+ subject do
7
+ AcceptHeaders::Middleware
8
+ end
9
+
10
+ def app(
11
+ supported_media_types: ['application/json'],
12
+ supported_encodings: ['identity'],
13
+ supported_languages: ['en-US']
14
+ )
15
+ Rack::Builder.new do
16
+ use AcceptHeaders::Middleware
17
+ run ->(env) do
18
+ matched_media_type = env["accept_headers.media_types"].negotiate(supported_media_types)
19
+ matched_encoding = env["accept_headers.encodings"].negotiate(supported_encodings)
20
+ matched_language = env["accept_headers.languages"].negotiate(supported_languages)
21
+ headers = {
22
+ 'Content-Type' => matched_media_type ? matched_media_type.media_range : '',
23
+ 'Content-Encoding' => matched_encoding ? matched_encoding.encoding : '',
24
+ 'Content-Language' => matched_language ? matched_language.language_tag : '',
25
+ }
26
+
27
+ [ 200, headers, [ '' ] ]
28
+ end
29
+ end
30
+ end
31
+
32
+ def responds_with_content_type(accept, supported_media_types, expected_content_type)
33
+ response = Rack::MockRequest.new(app(supported_media_types: supported_media_types)).get('/', { 'HTTP_ACCEPT' => accept } )
34
+ response.headers['Content-Type'].must_equal expected_content_type
35
+ end
36
+
37
+ def responds_with_encoding(accept_encoding, supported_encodings, expected_encoding)
38
+ response = Rack::MockRequest.new(app(supported_encodings: supported_encodings)).get('/', { 'HTTP_ACCEPT_ENCODING' => accept_encoding } )
39
+ response.headers['Content-Encoding'].must_equal expected_encoding
40
+ end
41
+
42
+ def responds_with_languages(accept_language, supported_languages, expected_language)
43
+ response = Rack::MockRequest.new(app(supported_languages: supported_languages)).get('/', { 'HTTP_ACCEPT_LANGUAGE' => accept_language } )
44
+ response.headers['Content-Language'].must_equal expected_language
45
+ end
46
+
47
+ it "reads the accept header" do
48
+ responds_with_content_type("application/json", ['application/json'], 'application/json')
49
+ responds_with_content_type("application/json;q=0.9,*/*;q0.8", ['application/json'], 'application/json')
50
+ responds_with_content_type("application/json/error", ['application/json'], '')
51
+ end
52
+
53
+ it "reads the accept encoding header" do
54
+ responds_with_encoding("gzip,identity", ['gzip', 'identity'], 'gzip')
55
+ responds_with_encoding("gzip;q=0.8,identity", ['gzip', 'identity'], 'identity')
56
+ responds_with_encoding("gzip error", ['gzip'], '')
57
+ end
58
+
59
+ it "reads the accept language header" do
60
+ responds_with_languages("en-us", ['en-us'], 'en-us')
61
+ responds_with_languages("en-us;q=1,en-gb;q=0.9,en-*;q=0.8", ['en-us'], 'en-us')
62
+ responds_with_languages("en/us", ['en-us'], '')
63
+ end
64
+ end
data/wercker.yml CHANGED
@@ -7,7 +7,7 @@ build:
7
7
  steps:
8
8
  # Uncomment this to force RVM to use a specific Ruby version
9
9
  - rvm-use:
10
- version: 2.1.5
10
+ version: 2.3.1
11
11
 
12
12
  # A step that executes `bundle install` command
13
13
  - bundle-install
@@ -24,4 +24,4 @@ build:
24
24
  # Add more steps here:
25
25
  - script:
26
26
  name: rake
27
- code: bundle exec rake
27
+ code: bundle exec rake
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: accept_headers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jack Chu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-11-23 00:00:00.000000000 Z
11
+ date: 2016-12-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -114,6 +114,7 @@ files:
114
114
  - spec/language_spec.rb
115
115
  - spec/media_type/negotiator_spec.rb
116
116
  - spec/media_type_spec.rb
117
+ - spec/middleware_spec.rb
117
118
  - spec/spec_helper.rb
118
119
  - spec/support/encodings/content-coding.csv
119
120
  - spec/support/media_types/application.csv
@@ -137,7 +138,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
137
138
  requirements:
138
139
  - - ">="
139
140
  - !ruby/object:Gem::Version
140
- version: 2.0.0
141
+ version: 2.2.0
141
142
  required_rubygems_version: !ruby/object:Gem::Requirement
142
143
  requirements:
143
144
  - - ">="
@@ -145,7 +146,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
145
146
  version: '0'
146
147
  requirements: []
147
148
  rubyforge_project:
148
- rubygems_version: 2.2.2
149
+ rubygems_version: 2.5.2
149
150
  signing_key:
150
151
  specification_version: 4
151
152
  summary: A ruby library that does content negotiation and parses and sorts http accept
@@ -157,6 +158,7 @@ test_files:
157
158
  - spec/language_spec.rb
158
159
  - spec/media_type/negotiator_spec.rb
159
160
  - spec/media_type_spec.rb
161
+ - spec/middleware_spec.rb
160
162
  - spec/spec_helper.rb
161
163
  - spec/support/encodings/content-coding.csv
162
164
  - spec/support/media_types/application.csv