http_accept_language 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 64deaf476a87d9192739905f051cd546124d358e
4
+ data.tar.gz: 5afdaecd6f46c4df2240ae700c0bd66bc131eba1
5
+ SHA512:
6
+ metadata.gz: 077e921e1398f9925a8498c6bf0c77f54b65c8d7cf6082e77613da8f7599c07d732ef3610f965a276a6529c586e659542ba2c16dd28b04d8d42a9abd5df4fcc8
7
+ data.tar.gz: 99a4e05c30bc9102686dc890ac5acd63af862eeecfe679e96514aecdbdc6d7380a328c384eba2f8ecb00c32803cbba62d511e384b1b3b4df70f9629815790a48
data/.travis.yml ADDED
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ cache: bundler
3
+ sudo: false
4
+ rvm:
5
+ - 1.9.3
6
+ - 2.0.0
7
+ - 2.1
8
+ - 2.2
9
+ script: bundle exec rspec spec
data/README.md CHANGED
@@ -1,9 +1,9 @@
1
- # HttpAcceptLanguage
1
+ # HttpAcceptLanguage [![Build Status](https://travis-ci.org/iain/http_accept_language.svg?branch=master)](https://travis-ci.org/iain/http_accept_language)
2
2
 
3
3
  A gem which helps you detect the users preferred language, as sent by the "Accept-Language" HTTP header.
4
4
 
5
- The algorithm is based on [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html), with one exception:
6
- when a user requests "en-US" and "en" is an available language, "en" is deemed compatible with "en-US".
5
+ The algorithm is based on [RFC 2616](http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html), with one exception:
6
+ when a user requests "en-US" and "en" is an available language, "en" is deemed compatible with "en-US".
7
7
  The RFC specifies that the requested language must either exactly match the available language or must exactly match a prefix of the available language. This means that when the user requests "en" and "en-US" is available, "en-US" would be compatible, but not the other way around. This is usually not what you're looking for.
8
8
 
9
9
  Since version 2.0, this gem is Rack middleware.
@@ -43,6 +43,22 @@ class SomeController < ApplicationController
43
43
  end
44
44
  ```
45
45
 
46
+ If you want to enable this behavior by default in your controllers, you can just include the provided concern:
47
+
48
+ ```ruby
49
+ class ApplicationController < ActionController::Base
50
+ include HttpAcceptLanguage::AutoLocale
51
+
52
+ #...
53
+ end
54
+ ```
55
+
56
+ Then set available locales in `config/application.rb`:
57
+
58
+ ```ruby
59
+ config.i18n.available_locales = %w(en nl de fr)
60
+ ```
61
+
46
62
  To use the middleware in any Rack application, simply add the middleware:
47
63
 
48
64
  ``` ruby
@@ -1,3 +1,4 @@
1
+ require 'http_accept_language/auto_locale'
1
2
  require 'http_accept_language/parser'
2
3
  require 'http_accept_language/middleware'
3
4
  require 'http_accept_language/railtie' if defined?(Rails::Railtie)
@@ -0,0 +1,17 @@
1
+ require 'active_support/concern'
2
+
3
+ module HttpAcceptLanguage
4
+ module AutoLocale
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ before_filter :set_locale
9
+ end
10
+
11
+ private
12
+
13
+ def set_locale
14
+ I18n.locale = http_accept_language.compatible_language_from(I18n.available_locales) || I18n.default_locale
15
+ end
16
+ end
17
+ end
@@ -6,6 +6,7 @@ module HttpAcceptLanguage
6
6
 
7
7
  def call(env)
8
8
  env["http_accept_language.parser"] = Parser.new(env["HTTP_ACCEPT_LANGUAGE"])
9
+
9
10
  def env.http_accept_language
10
11
  self["http_accept_language.parser"]
11
12
  end
@@ -1,7 +1,5 @@
1
1
  module HttpAcceptLanguage
2
-
3
2
  class Parser
4
-
5
3
  attr_accessor :header
6
4
 
7
5
  def initialize(header)
@@ -17,20 +15,26 @@ module HttpAcceptLanguage
17
15
  # # => [ 'nl-NL', 'nl-BE', 'nl', 'en-US', 'en' ]
18
16
  #
19
17
  def user_preferred_languages
20
- @user_preferred_languages ||= header.gsub(/\s+/, '').split(/,/).collect do |l|
21
- l += ';q=1.0' unless l =~ /;q=\d+\.\d+$/
22
- l.split(';q=')
23
- end.sort do |x,y|
24
- raise "Not correctly formatted" unless x.first =~ /^[a-z\-0-9]+$/i
25
- y.last.to_f <=> x.last.to_f
26
- end.collect do |l|
27
- l.first.downcase.gsub(/-[a-z0-9]+$/i) { |x| x.upcase }
18
+ @user_preferred_languages ||= begin
19
+ header.to_s.gsub(/\s+/, '').split(',').map do |language|
20
+ locale, quality = language.split(';q=')
21
+ raise ArgumentError, 'Not correctly formatted' unless locale =~ /^[a-z\-0-9]+|\*$/i
22
+
23
+ locale = locale.downcase.gsub(/-[a-z0-9]+$/i, &:upcase) # Uppercase territory
24
+ locale = nil if locale == '*' # Ignore wildcards
25
+
26
+ quality = quality ? quality.to_f : 1.0
27
+
28
+ [locale, quality]
29
+ end.sort do |(_, left), (_, right)|
30
+ right <=> left
31
+ end.map(&:first).compact
32
+ rescue ArgumentError # Just rescue anything if the browser messed up badly.
33
+ []
28
34
  end
29
- rescue # Just rescue anything if the browser messed up badly.
30
- []
31
35
  end
32
36
 
33
- # Sets the user languages preference, overiding the browser
37
+ # Sets the user languages preference, overriding the browser
34
38
  #
35
39
  def user_preferred_languages=(languages)
36
40
  @user_preferred_languages = languages
@@ -44,7 +48,7 @@ module HttpAcceptLanguage
44
48
  # # => 'nl'
45
49
  #
46
50
  def preferred_language_from(array)
47
- (user_preferred_languages & array.collect { |i| i.to_s }).first
51
+ (user_preferred_languages & array.map(&:to_s)).first
48
52
  end
49
53
 
50
54
  # Returns the first of the user_preferred_languages that is compatible
@@ -55,10 +59,13 @@ module HttpAcceptLanguage
55
59
  # request.compatible_language_from I18n.available_locales
56
60
  #
57
61
  def compatible_language_from(available_languages)
58
- user_preferred_languages.map do |x| #en-US
59
- available_languages.find do |y| # en
60
- y = y.to_s
61
- x == y || x.split('-', 2).first == y.split('-', 2).first
62
+ user_preferred_languages.map do |preferred| #en-US
63
+ preferred = preferred.downcase
64
+ preferred_language = preferred.split('-', 2).first
65
+
66
+ available_languages.find do |available| # en
67
+ available = available.to_s.downcase
68
+ preferred == available || preferred_language == available.split('-', 2).first
62
69
  end
63
70
  end.compact.first
64
71
  end
@@ -70,12 +77,8 @@ module HttpAcceptLanguage
70
77
  # [ja_JP-x1, en-US-x4, en_UK-x5, fr-FR-x3] => [ja-JP, en-US, en-UK, fr-FR]
71
78
  #
72
79
  def sanitize_available_locales(available_languages)
73
- available_languages.map do |avail|
74
- split_locale = avail.split(/[_-]/)
75
-
76
- split_locale.map do |e|
77
- e unless e.match(/x|[0-9*]/)
78
- end.compact.join("-")
80
+ available_languages.map do |available|
81
+ available.to_s.split(/[_-]/).reject { |part| part.start_with?("x") }.join("-")
79
82
  end
80
83
  end
81
84
 
@@ -90,15 +93,16 @@ module HttpAcceptLanguage
90
93
  #
91
94
  def language_region_compatible_from(available_languages)
92
95
  available_languages = sanitize_available_locales(available_languages)
93
- user_preferred_languages.map do |x| #en-US
94
- lang_group = available_languages.select do |y| # en
95
- y = y.to_s
96
- x.split('-', 2).first == y.split('-', 2).first
96
+ user_preferred_languages.map do |preferred| #en-US
97
+ preferred = preferred.downcase
98
+ preferred_language = preferred.split('-', 2).first
99
+
100
+ lang_group = available_languages.select do |available| # en
101
+ preferred_language == available.downcase.split('-', 2).first
97
102
  end
98
- lang_group.find{|l| l == x} || lang_group.first #en-US, en-UK
103
+
104
+ lang_group.find { |lang| lang.downcase == preferred } || lang_group.first #en-US, en-UK
99
105
  end.compact.first
100
106
  end
101
-
102
107
  end
103
-
104
108
  end
@@ -2,7 +2,7 @@ module HttpAcceptLanguage
2
2
  class Railtie < ::Rails::Railtie
3
3
  initializer "http_accept_language.add_middleware" do |app|
4
4
  app.middleware.use Middleware
5
-
5
+
6
6
  ActiveSupport.on_load :action_controller do
7
7
  include EasyAccess
8
8
  end
@@ -11,7 +11,7 @@ module HttpAcceptLanguage
11
11
 
12
12
  module EasyAccess
13
13
  def http_accept_language
14
- @http_accept_language ||= request.env["http_accept_language.parser"] || Parser.new("")
14
+ @http_accept_language ||= request.env["http_accept_language.parser"] || Parser.new(request.env["HTTP_ACCEPT_LANGUAGE"])
15
15
  end
16
16
  end
17
17
  end
@@ -1,3 +1,3 @@
1
1
  module HttpAcceptLanguage
2
- VERSION = '2.0.0'
2
+ VERSION = '2.1.0'
3
3
  end
@@ -0,0 +1,67 @@
1
+ require 'i18n'
2
+ require 'http_accept_language/auto_locale'
3
+ require 'http_accept_language/parser'
4
+ require 'http_accept_language/middleware'
5
+
6
+ describe HttpAcceptLanguage::AutoLocale do
7
+ let(:controller_class) do
8
+ Class.new do
9
+ def initialize(header = nil)
10
+ super()
11
+ @header = header
12
+ end
13
+
14
+ def self.before_filter(dummy)
15
+ # dummy method
16
+ end
17
+
18
+ def http_accept_language
19
+ @http_accept_language ||= HttpAcceptLanguage::Parser.new(@header)
20
+ end
21
+
22
+ include HttpAcceptLanguage::AutoLocale
23
+ end
24
+ end
25
+
26
+ let(:controller) { controller_class.new("ja,en-us;q=0.7,en;q=0.3") }
27
+
28
+ context "available languages includes accept_languages" do
29
+ before do
30
+ I18n.available_locales = [:en, :ja]
31
+ end
32
+
33
+ it "take a suitable locale" do
34
+ controller.send(:set_locale)
35
+
36
+ expect(I18n.locale).to eq(:ja)
37
+ end
38
+ end
39
+
40
+ context "available languages do not include accept_languages" do
41
+ before do
42
+ I18n.available_locales = [:es]
43
+ I18n.default_locale = :es
44
+ end
45
+
46
+ it "set the locale to default" do
47
+ no_accept_language_controller.send(:set_locale)
48
+
49
+ expect(I18n.locale).to eq(:es)
50
+ end
51
+ end
52
+
53
+ let(:no_accept_language_controller) { controller_class.new() }
54
+
55
+ context "default locale is ja" do
56
+ before do
57
+ I18n.available_locales = [:en, :ja]
58
+ I18n.default_locale = :ja
59
+ end
60
+
61
+ it "set the locale to default" do
62
+ no_accept_language_controller.send(:set_locale)
63
+
64
+ expect(I18n.locale).to eq(:ja)
65
+ end
66
+ end
67
+ end
@@ -33,20 +33,20 @@ describe "Rack integration" do
33
33
  app = lambda { |env| env }
34
34
  middleware = HttpAcceptLanguage::Middleware.new(app)
35
35
  middleware.call(env)
36
- env.http_accept_language.user_preferred_languages.should eq %w{en}
36
+ expect(env.http_accept_language.user_preferred_languages).to eq %w{en}
37
37
  env["HTTP_ACCEPT_LANGUAGE"] = "de"
38
38
  middleware.call(env)
39
- env.http_accept_language.user_preferred_languages.should eq %w{de}
39
+ expect(env.http_accept_language.user_preferred_languages).to eq %w{de}
40
40
  end
41
41
 
42
42
  it "decodes the HTTP_ACCEPT_LANGUAGE header" do
43
43
  request_with_header 'en-us,en-gb;q=0.8,en;q=0.6,es-419'
44
- r['user_preferred_languages'].should eq %w{en-US es-419 en-GB en}
44
+ expect(r['user_preferred_languages']).to eq %w{en-US es-419 en-GB en}
45
45
  end
46
46
 
47
47
  it "finds the first available language" do
48
48
  request_with_header 'en-us,en-gb;q=0.8,en;q=0.6,es-419', :preferred => %w(en en-GB)
49
- r['preferred_language_from'].should eq 'en-GB'
49
+ expect(r['preferred_language_from']).to eq 'en-GB'
50
50
  end
51
51
 
52
52
  def request_with_header(header, params = {})
data/spec/parser_spec.rb CHANGED
@@ -8,49 +8,58 @@ describe HttpAcceptLanguage::Parser do
8
8
 
9
9
  it "should return empty array" do
10
10
  parser.header = nil
11
- parser.user_preferred_languages.should eq []
11
+ expect(parser.user_preferred_languages).to eq []
12
12
  end
13
13
 
14
14
  it "should properly split" do
15
- parser.user_preferred_languages.should eq %w{en-US es-419 en-GB en}
15
+ expect(parser.user_preferred_languages).to eq %w{en-US es-419 en-GB en}
16
16
  end
17
17
 
18
18
  it "should ignore jambled header" do
19
19
  parser.header = 'odkhjf89fioma098jq .,.,'
20
- parser.user_preferred_languages.should eq []
20
+ expect(parser.user_preferred_languages).to eq []
21
21
  end
22
22
 
23
23
  it "should properly respect whitespace" do
24
24
  parser.header = 'en-us, en-gb; q=0.8,en;q = 0.6,es-419'
25
- parser.user_preferred_languages.should eq %w{en-US es-419 en-GB en}
25
+ expect(parser.user_preferred_languages).to eq %w{en-US es-419 en-GB en}
26
26
  end
27
27
 
28
28
  it "should find first available language" do
29
- parser.preferred_language_from(%w{en en-GB}).should eq "en-GB"
29
+ expect(parser.preferred_language_from(%w{en en-GB})).to eq "en-GB"
30
30
  end
31
31
 
32
32
  it "should find first compatible language" do
33
- parser.compatible_language_from(%w{en-hk}).should eq "en-hk"
34
- parser.compatible_language_from(%w{en}).should eq "en"
33
+ expect(parser.compatible_language_from(%w{en-hk})).to eq "en-hk"
34
+ expect(parser.compatible_language_from(%w{en})).to eq "en"
35
35
  end
36
36
 
37
37
  it "should find first compatible from user preferred" do
38
38
  parser.header = 'en-us,de-de'
39
- parser.compatible_language_from(%w{de en}).should eq 'en'
39
+ expect(parser.compatible_language_from(%w{de en})).to eq 'en'
40
40
  end
41
41
 
42
42
  it "should accept symbols as available languages" do
43
43
  parser.header = 'en-us'
44
- parser.compatible_language_from([:"en-HK"]).should eq :"en-HK"
44
+ expect(parser.compatible_language_from([:"en-HK"])).to eq :"en-HK"
45
+ end
46
+
47
+ it "should accept and ignore wildcards" do
48
+ parser.header = 'en-US,en,*'
49
+ expect(parser.compatible_language_from([:"en-US"])).to eq :"en-US"
45
50
  end
46
51
 
47
52
  it "should sanitize available language names" do
48
- parser.sanitize_available_locales(%w{en_UK-x3 en-US-x1 ja_JP-x2 pt-BR-x5}).should eq ["en-UK", "en-US", "ja-JP", "pt-BR"]
53
+ expect(parser.sanitize_available_locales(%w{en_UK-x3 en-US-x1 ja_JP-x2 pt-BR-x5 es-419-x4})).to eq ["en-UK", "en-US", "ja-JP", "pt-BR", "es-419"]
54
+ end
55
+
56
+ it "should accept available language names as symbols and return them as strings" do
57
+ expect(parser.sanitize_available_locales([:en, :"en-US", :ca, :"ca-ES"])).to eq ["en", "en-US", "ca", "ca-ES"]
49
58
  end
50
59
 
51
60
  it "should find most compatible language from user preferred" do
52
61
  parser.header = 'ja,en-gb,en-us,fr-fr'
53
- parser.language_region_compatible_from(%w{en-UK en-US ja-JP}).should eq "ja-JP"
62
+ expect(parser.language_region_compatible_from(%w{en-UK en-US ja-JP})).to eq "ja-JP"
54
63
  end
55
64
 
56
65
  end
metadata CHANGED
@@ -1,93 +1,113 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: http_accept_language
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
5
- prerelease:
4
+ version: 2.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - iain
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2013-09-06 00:00:00.000000000 Z
11
+ date: 2016-10-27 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: rake
16
- requirement: &70157591116080 !ruby/object:Gem::Requirement
17
- none: false
15
+ requirement: !ruby/object:Gem::Requirement
18
16
  requirements:
19
- - - ! '>='
17
+ - - ">="
20
18
  - !ruby/object:Gem::Version
21
19
  version: '0'
22
20
  type: :development
23
21
  prerelease: false
24
- version_requirements: *70157591116080
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
25
27
  - !ruby/object:Gem::Dependency
26
28
  name: rspec
27
- requirement: &70157591115660 !ruby/object:Gem::Requirement
28
- none: false
29
+ requirement: !ruby/object:Gem::Requirement
29
30
  requirements:
30
- - - ! '>='
31
+ - - ">="
31
32
  - !ruby/object:Gem::Version
32
33
  version: '0'
33
34
  type: :development
34
35
  prerelease: false
35
- version_requirements: *70157591115660
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
36
41
  - !ruby/object:Gem::Dependency
37
42
  name: rack-test
38
- requirement: &70157591115240 !ruby/object:Gem::Requirement
39
- none: false
43
+ requirement: !ruby/object:Gem::Requirement
40
44
  requirements:
41
- - - ! '>='
45
+ - - ">="
42
46
  - !ruby/object:Gem::Version
43
47
  version: '0'
44
48
  type: :development
45
49
  prerelease: false
46
- version_requirements: *70157591115240
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
47
55
  - !ruby/object:Gem::Dependency
48
56
  name: guard-rspec
49
- requirement: &70157591114820 !ruby/object:Gem::Requirement
50
- none: false
57
+ requirement: !ruby/object:Gem::Requirement
51
58
  requirements:
52
- - - ! '>='
59
+ - - ">="
53
60
  - !ruby/object:Gem::Version
54
61
  version: '0'
55
62
  type: :development
56
63
  prerelease: false
57
- version_requirements: *70157591114820
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
58
69
  - !ruby/object:Gem::Dependency
59
70
  name: rails
60
- requirement: &70157591114320 !ruby/object:Gem::Requirement
61
- none: false
71
+ requirement: !ruby/object:Gem::Requirement
62
72
  requirements:
63
- - - ! '>='
73
+ - - ">="
64
74
  - !ruby/object:Gem::Version
65
75
  version: 3.2.6
66
76
  type: :development
67
77
  prerelease: false
68
- version_requirements: *70157591114320
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: 3.2.6
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: cucumber
71
- requirement: &70157591113900 !ruby/object:Gem::Requirement
72
- none: false
85
+ requirement: !ruby/object:Gem::Requirement
73
86
  requirements:
74
- - - ! '>='
87
+ - - ">="
75
88
  - !ruby/object:Gem::Version
76
89
  version: '0'
77
90
  type: :development
78
91
  prerelease: false
79
- version_requirements: *70157591113900
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
80
97
  - !ruby/object:Gem::Dependency
81
98
  name: aruba
82
- requirement: &70157578096080 !ruby/object:Gem::Requirement
83
- none: false
99
+ requirement: !ruby/object:Gem::Requirement
84
100
  requirements:
85
- - - ! '>='
101
+ - - ">="
86
102
  - !ruby/object:Gem::Version
87
103
  version: '0'
88
104
  type: :development
89
105
  prerelease: false
90
- version_requirements: *70157578096080
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
91
111
  description: Find out which locale the user preferes by reading the languages they
92
112
  specified in their browser
93
113
  email:
@@ -96,8 +116,9 @@ executables: []
96
116
  extensions: []
97
117
  extra_rdoc_files: []
98
118
  files:
99
- - .gitignore
100
- - .rspec
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".travis.yml"
101
122
  - Gemfile
102
123
  - Guardfile
103
124
  - README.md
@@ -108,41 +129,43 @@ files:
108
129
  - features/support/rails_driver.rb
109
130
  - http_accept_language.gemspec
110
131
  - lib/http_accept_language.rb
132
+ - lib/http_accept_language/auto_locale.rb
111
133
  - lib/http_accept_language/middleware.rb
112
134
  - lib/http_accept_language/parser.rb
113
135
  - lib/http_accept_language/railtie.rb
114
136
  - lib/http_accept_language/version.rb
137
+ - spec/auto_locale_spec.rb
115
138
  - spec/middleware_spec.rb
116
139
  - spec/parser_spec.rb
117
140
  homepage: https://github.com/iain/http_accept_language
118
141
  licenses:
119
142
  - MIT
143
+ metadata: {}
120
144
  post_install_message:
121
145
  rdoc_options: []
122
146
  require_paths:
123
147
  - lib
124
148
  required_ruby_version: !ruby/object:Gem::Requirement
125
- none: false
126
149
  requirements:
127
- - - ! '>='
150
+ - - ">="
128
151
  - !ruby/object:Gem::Version
129
152
  version: '0'
130
153
  required_rubygems_version: !ruby/object:Gem::Requirement
131
- none: false
132
154
  requirements:
133
- - - ! '>='
155
+ - - ">="
134
156
  - !ruby/object:Gem::Version
135
157
  version: '0'
136
158
  requirements: []
137
159
  rubyforge_project: http_accept_language
138
- rubygems_version: 1.8.6
160
+ rubygems_version: 2.5.1
139
161
  signing_key:
140
- specification_version: 3
162
+ specification_version: 4
141
163
  summary: Find out which locale the user preferes by reading the languages they specified
142
164
  in their browser
143
165
  test_files:
144
166
  - features/rails_integration.feature
145
167
  - features/steps/rails.rb
146
168
  - features/support/rails_driver.rb
169
+ - spec/auto_locale_spec.rb
147
170
  - spec/middleware_spec.rb
148
171
  - spec/parser_spec.rb