browser 2.7.0 → 2.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -113
  3. data/.travis.yml +9 -3
  4. data/CHANGELOG.md +6 -0
  5. data/browser.gemspec +8 -6
  6. data/lib/browser/accept_language.rb +5 -7
  7. data/lib/browser/action_controller.rb +1 -3
  8. data/lib/browser/alipay.rb +1 -1
  9. data/lib/browser/base.rb +1 -1
  10. data/lib/browser/blackberry.rb +2 -2
  11. data/lib/browser/bot.rb +4 -6
  12. data/lib/browser/chrome.rb +4 -4
  13. data/lib/browser/detect_version.rb +3 -5
  14. data/lib/browser/device.rb +5 -7
  15. data/lib/browser/device/surface.rb +1 -3
  16. data/lib/browser/edge.rb +2 -2
  17. data/lib/browser/electron.rb +1 -1
  18. data/lib/browser/facebook.rb +2 -2
  19. data/lib/browser/firefox.rb +1 -1
  20. data/lib/browser/generic.rb +3 -5
  21. data/lib/browser/instagram.rb +1 -1
  22. data/lib/browser/internet_explorer.rb +8 -9
  23. data/lib/browser/meta/generic_browser.rb +1 -3
  24. data/lib/browser/micro_messenger.rb +1 -1
  25. data/lib/browser/middleware.rb +1 -1
  26. data/lib/browser/nokia.rb +1 -1
  27. data/lib/browser/opera.rb +2 -2
  28. data/lib/browser/otter.rb +1 -1
  29. data/lib/browser/phantom_js.rb +1 -1
  30. data/lib/browser/platform/adobe_air.rb +1 -1
  31. data/lib/browser/platform/blackberry.rb +1 -1
  32. data/lib/browser/platform/ios.rb +2 -1
  33. data/lib/browser/qq.rb +4 -4
  34. data/lib/browser/rails.rb +1 -3
  35. data/lib/browser/safari.rb +3 -3
  36. data/lib/browser/snapchat.rb +1 -1
  37. data/lib/browser/sputnik.rb +2 -2
  38. data/lib/browser/uc_browser.rb +1 -1
  39. data/lib/browser/version.rb +1 -1
  40. data/lib/browser/weibo.rb +1 -1
  41. data/lib/browser/yandex.rb +1 -1
  42. data/test/sample_app.rb +1 -3
  43. data/test/ua.yml +3 -0
  44. data/test/unit/ios_test.rb +7 -0
  45. data/test/unit/snapchat_test.rb +20 -0
  46. metadata +26 -12
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0e06930aa3adaf7fcb64ba7835316a1e621ca68d48b9e7cb628613737e3f2b3c
4
- data.tar.gz: 63af8472b567a45c2cc9bf7fcab64522772313fa701c155d536de81ae5e4bc06
3
+ metadata.gz: 17e665a446ca2a9578cae49ad272bbbc596c29bf8518643cbcec39f2654e4bc4
4
+ data.tar.gz: 0dd132f6f496e0221417a5b474878823eed6b7e4eac51764f383cd2825cb1969
5
5
  SHA512:
6
- metadata.gz: f09b0e90fa5df86138f39f549dab4128ae459066a60eeb22e80ec87edf72b7d228c83115dff7f6e6498c8f98f72660ff2c262341ecd1201eb368c52e5be38134
7
- data.tar.gz: ddecdb109e863eac0418faaab17b2dbe581fd1d244ab85d3bdbeb6b416b9c20204ef1c39d400c2ac5340cde9960280fc41367e889eee2ef912b819f394ff206c
6
+ metadata.gz: 2902444a66316eb79ccb9fd409d58d21ac764b6f22a86bb9a2af74791f3bd8c86301a7c7b8829fe17f14a24c0827b3584d0c0a7813f85c9a4022a179ea67db7a
7
+ data.tar.gz: 1282a961f637a98449d6425272abcd3f005c003908ce37e0954052b3b5fd8bc6bf3d5d75e3104e6d3705823e3abe60f9eb9fca7046bf94f1c16f625cc6a09b07
@@ -1,6 +1,9 @@
1
1
  ---
2
+ inherit_gem:
3
+ rubocop-fnando: .rubocop.yml
2
4
 
3
5
  AllCops:
6
+ TargetRubyVersion: 2.5
4
7
  Exclude:
5
8
  - bin/**/*
6
9
  - gemfiles/**/*
@@ -10,129 +13,17 @@ AllCops:
10
13
  - "*.gemspec"
11
14
  - config.ru
12
15
 
13
- Layout/DotPosition:
14
- EnforcedStyle: leading
15
-
16
- Layout/RescueEnsureAlignment:
17
- Enabled: false
18
-
19
- Layout/SpaceBeforeBlockBraces:
20
- EnforcedStyle: space
21
-
22
- Layout/SpaceInsideBlockBraces:
23
- EnforcedStyle: space
24
- SpaceBeforeBlockParameters: false
25
-
26
- Layout/SpaceInsideHashLiteralBraces:
27
- Enabled: false
28
-
29
- Metrics/AbcSize:
30
- Enabled: false
31
-
32
16
  Metrics/ClassLength:
33
17
  Enabled: false
34
18
 
35
- Metrics/CyclomaticComplexity:
36
- Enabled: false
37
-
38
19
  Metrics/LineLength:
39
20
  Max: 80
40
21
 
41
22
  Metrics/MethodLength:
42
23
  Enabled: false
43
24
 
44
- Metrics/ParameterLists:
45
- Enabled: false
46
-
47
- Naming/FileName:
48
- Enabled: false
49
-
50
- Naming/PredicateName:
51
- NamePrefixBlacklist:
52
- - is_
53
-
54
- Naming/UncommunicativeMethodParamName:
55
- Enabled: false
56
-
57
25
  Style/Alias:
58
26
  EnforcedStyle: prefer_alias_method
59
27
 
60
- Style/BlockDelimiters:
61
- Enabled: false
62
-
63
- Style/ClassCheck:
64
- EnforcedStyle: kind_of?
65
-
66
- Style/CollectionMethods:
67
- PreferredMethods:
68
- collect: map
69
- collect!: map!
70
- inject: reduce
71
- detect: find
72
- find_all: select
73
-
74
- Style/Documentation:
75
- Enabled: false
76
-
77
- Style/DoubleNegation:
78
- Enabled: false
79
-
80
- Style/Encoding:
81
- Enabled: false
82
-
83
- Style/FrozenStringLiteralComment:
84
- EnforcedStyle: always
85
-
86
- Style/IfUnlessModifier:
87
- Enabled: false
88
-
89
- Style/ModuleFunction:
90
- Enabled: false
91
-
92
- Style/OneLineConditional:
93
- Enabled: false
94
-
95
- Style/PercentLiteralDelimiters:
96
- PreferredDelimiters:
97
- "%": "[]"
98
- "%i": "[]"
99
- "%q": "[]"
100
- "%Q": "[]"
101
- "%r": "[]"
102
- "%s": "[]"
103
- "%w": "[]"
104
- "%W": "[]"
105
- "%x": "[]"
106
-
107
- Style/PerlBackrefs:
108
- Enabled: false
109
-
110
- Style/Proc:
111
- Enabled: false
112
-
113
- Style/RegexpLiteral:
114
- Enabled: false
115
-
116
- Style/SafeNavigation:
117
- Enabled: false
118
-
119
- Style/SingleLineBlockParams:
120
- Enabled: false
121
-
122
- Style/StringLiterals:
123
- EnforcedStyle: double_quotes
124
- SupportedStyles:
125
- - single_quotes
126
- - double_quotes
127
-
128
- Style/TrailingCommaInArrayLiteral:
129
- Enabled: false
130
-
131
- Style/TrailingCommaInHashLiteral:
132
- Enabled: false
133
-
134
- Style/VariableInterpolation:
135
- Enabled: false
136
-
137
- Style/WhileUntilModifier:
28
+ Lint/RedundantCopDisableDirective:
138
29
  Enabled: false
@@ -3,8 +3,8 @@ language: ruby
3
3
  sudo: false
4
4
  cache: bundler
5
5
  rvm:
6
- - "2.6.0"
7
- - "2.5.0"
6
+ - 2.6.0
7
+ - 2.5.0
8
8
  gemfile:
9
9
  - Gemfile
10
10
  - gemfiles/rails5.gemfile
@@ -12,6 +12,12 @@ gemfile:
12
12
  script: bundle exec rake
13
13
  notifications:
14
14
  email: false
15
+ before_script:
16
+ - curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
17
+ - chmod +x ./cc-test-reporter
18
+ - "./cc-test-reporter before-build"
19
+ after_script:
20
+ - "./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT"
15
21
  env:
16
22
  global:
17
- secure: egPPk/jMVzOoZGkk8jcf1f1N++oI4p4hqtk53T2kpHChxpmR8sP/oFlAhebvqMhM8svbQx+lWTvdxPDj9GBQGsC4ekqubV6S0MNJQS4/F41PSEU+DFUzNU1PHiDO+/0AbIheTj15UIt8IC4NVaM236HuSdMDWOjVI3ydBsgJ/GY=
23
+ secure: LrxynbbiJMX5vy/UVPfQsnT21oUpqpuHbUM9YOy0+ZYfDCjprvM/UGxFgjM+unRzyPI0mrNyU65ohpj8R1//tvdFW+xYau6QmFgSTU6OAQrckW/n+jqwQZV37a38wEGV0QvA6A0HW9pTrJfatUBmpaAeHAxcaBMk51tEgX/8poA=
@@ -2,6 +2,12 @@
2
2
 
3
3
  ## Unreleased
4
4
 
5
+ - Handle Snapchat user agents that have a space or an empty string instead of a slash before the version.
6
+ - Fix iOS 10+ version detection.
7
+ - Add fallback versions for instagram and snapchat to avoid NoMethodErrors on unexpected user agents.
8
+
9
+ ## 2.7.0
10
+
5
11
  - Add more Slack bots.
6
12
  - Handle instagram user agents that have a slash instead of a space.
7
13
  - Add `Browser::Bot.why?(ua)` to help debugging why a user agent is considered bot.
@@ -1,7 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require "./lib/browser/version"
2
4
 
3
5
  Gem::Specification.new do |s|
4
- s.required_ruby_version = ">= 2.0"
5
6
  s.name = "browser"
6
7
  s.version = Browser::VERSION
7
8
  s.platform = Gem::Platform::RUBY
@@ -20,13 +21,14 @@ Gem::Specification.new do |s|
20
21
  s.require_paths = ["lib"]
21
22
 
22
23
  s.add_development_dependency "bundler", ">= 0"
23
- s.add_development_dependency "rake"
24
- s.add_development_dependency "rails"
25
- s.add_development_dependency "rack-test"
26
24
  s.add_development_dependency "minitest"
25
+ s.add_development_dependency "minitest-autotest"
27
26
  s.add_development_dependency "minitest-utils"
28
27
  s.add_development_dependency "pry-meta"
29
- s.add_development_dependency "minitest-autotest"
30
- s.add_development_dependency "simplecov"
28
+ s.add_development_dependency "rack-test"
29
+ s.add_development_dependency "rails"
30
+ s.add_development_dependency "rake"
31
31
  s.add_development_dependency "rubocop"
32
+ s.add_development_dependency "rubocop-fnando"
33
+ s.add_development_dependency "simplecov"
32
34
  end
@@ -34,28 +34,26 @@ module Browser
34
34
  def code
35
35
  @code ||= begin
36
36
  code = part[/\A([^-;]+)/, 1]
37
- code.downcase if code
37
+ code&.downcase
38
38
  end
39
39
  end
40
40
 
41
41
  def region
42
42
  @region ||= begin
43
43
  region = part[/\A(?:.*?)-([^;-]+)/, 1]
44
- region.upcase if region
44
+ region&.upcase
45
45
  end
46
46
  end
47
47
 
48
48
  def quality
49
49
  @quality ||= begin
50
50
  Float(quality_value || 1.0)
51
- rescue ArgumentError
52
- 0.1
51
+ rescue ArgumentError
52
+ 0.1
53
53
  end
54
54
  end
55
55
 
56
- private
57
-
58
- def quality_value
56
+ private def quality_value
59
57
  qvalue = part[/;q=([\d.]+)/, 1]
60
58
  qvalue = qvalue =~ /\A0\.0?\z/ ? "0.0" : qvalue
61
59
  qvalue = qvalue.gsub(/\.+/, ".") if qvalue
@@ -10,9 +10,7 @@ module Browser
10
10
  helper_method(:browser) if respond_to?(:helper_method)
11
11
  end
12
12
 
13
- private
14
-
15
- def browser
13
+ private def browser
16
14
  @browser ||= Browser.new(
17
15
  request.headers["User-Agent"],
18
16
  accept_language: request.headers["Accept-Language"]
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[(?:AlipayClient)/([\d.]+)]i, 1] || "0.0"
14
+ ua[%r{(?:AlipayClient)/([\d.]+)}i, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -193,7 +193,7 @@ module Browser
193
193
  end
194
194
 
195
195
  def webkit_full_version
196
- ua[%r[AppleWebKit/([\d.]+)], 1] || "0.0"
196
+ ua[%r{AppleWebKit/([\d.]+)}, 1] || "0.0"
197
197
  end
198
198
 
199
199
  def known?
@@ -11,8 +11,8 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[BlackBerry[\da-z]+/([\d.]+)], 1] ||
15
- ua[%r[Version/([\d.]+)], 1] ||
14
+ ua[%r{BlackBerry[\da-z]+/([\d.]+)}, 1] ||
15
+ ua[%r{Version/([\d.]+)}, 1] ||
16
16
  "0.0"
17
17
  end
18
18
 
@@ -50,21 +50,19 @@ module Browser
50
50
  self.class.bots.find {|key, _| downcased_ua.include?(key) }.last
51
51
  end
52
52
 
53
- private
54
-
55
- def bot_with_empty_ua?
53
+ private def bot_with_empty_ua?
56
54
  self.class.detect_empty_ua? && ua.strip == ""
57
55
  end
58
56
 
59
- def bot_exception?
57
+ private def bot_exception?
60
58
  self.class.bot_exceptions.any? {|key| downcased_ua.include?(key) }
61
59
  end
62
60
 
63
- def detect_bot?
61
+ private def detect_bot?
64
62
  self.class.bots.any? {|key, _| downcased_ua.include?(key) }
65
63
  end
66
64
 
67
- def downcased_ua
65
+ private def downcased_ua
68
66
  @downcased_ua ||= ua.downcase
69
67
  end
70
68
  end
@@ -12,10 +12,10 @@ module Browser
12
12
 
13
13
  def full_version
14
14
  # Each regex on its own line to enforce precedence.
15
- ua[%r[Chrome/([\d.]+)], 1] ||
16
- ua[%r[CriOS/([\d.]+)], 1] ||
17
- ua[%r[Safari/([\d.]+)], 1] ||
18
- ua[%r[AppleWebKit/([\d.]+)], 1] ||
15
+ ua[%r{Chrome/([\d.]+)}, 1] ||
16
+ ua[%r{CriOS/([\d.]+)}, 1] ||
17
+ ua[%r{Safari/([\d.]+)}, 1] ||
18
+ ua[%r{AppleWebKit/([\d.]+)}, 1] ||
19
19
  "0.0"
20
20
  end
21
21
 
@@ -2,9 +2,7 @@
2
2
 
3
3
  module Browser
4
4
  module DetectVersion
5
- private
6
-
7
- def detect_version?(actual_version, expected_version)
5
+ private def detect_version?(actual_version, expected_version)
8
6
  return true unless expected_version
9
7
  return false if expected_version && !actual_version
10
8
 
@@ -17,8 +15,8 @@ module Browser
17
15
  false
18
16
  end
19
17
 
20
- def parse_version(version)
21
- version.kind_of?(Numeric) ? version.to_s : version
18
+ private def parse_version(version)
19
+ version.is_a?(Numeric) ? version.to_s : version
22
20
  end
23
21
  end
24
22
  end
@@ -191,19 +191,17 @@ module Browser
191
191
  xbox? || playstation? || nintendo?
192
192
  end
193
193
 
194
- private
195
-
196
194
  # Regex taken from http://detectmobilebrowsers.com
197
195
  # rubocop:disable Metrics/LineLength
198
- def detect_mobile?
196
+ private def detect_mobile?
199
197
  psp? ||
200
- /zunewp7/i.match(ua) ||
201
- /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.match(ua) ||
202
- /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.match(ua[0..3])
198
+ /zunewp7/i.match(ua) ||
199
+ %r{(android|bb\d+|meego).+mobile|avantgo|bada/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino}i.match(ua) ||
200
+ %r{1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-}i.match(ua[0..3])
203
201
  end
204
202
  # rubocop:enable Metrics/LineLength
205
203
 
206
- def platform
204
+ private def platform
207
205
  @platform ||= Platform.new(ua)
208
206
  end
209
207
  end
@@ -15,9 +15,7 @@ module Browser
15
15
  platform.windows_rt? && ua =~ /Touch/
16
16
  end
17
17
 
18
- private
19
-
20
- def platform
18
+ private def platform
21
19
  @platform ||= Platform.new(ua)
22
20
  end
23
21
  end
@@ -11,11 +11,11 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[(?:Edge|Edg)/([\d.]+)], 1] || super
14
+ ua[%r{(?:Edge|Edg)/([\d.]+)}, 1] || super
15
15
  end
16
16
 
17
17
  def match?
18
- ua =~ %r[((?:Edge|Edg)/[\d.]+|Trident/8)]
18
+ ua =~ %r{((?:Edge|Edg)/[\d.]+|Trident/8)}
19
19
  end
20
20
 
21
21
  def chrome_based?
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[Electron/([\d.]+)], 1] ||
14
+ ua[%r{Electron/([\d.]+)}, 1] ||
15
15
  "0.0"
16
16
  end
17
17
 
@@ -11,8 +11,8 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[FBAV/([\d.]+)], 1] ||
15
- ua[%r[AppleWebKit/([\d.]+)], 0] ||
14
+ ua[%r{FBAV/([\d.]+)}, 1] ||
15
+ ua[%r{AppleWebKit/([\d.]+)}, 0] ||
16
16
  "0.0"
17
17
  end
18
18
 
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[(?:Firefox|FxiOS)/([\d.]+)], 1] || "0.0"
14
+ ua[%r{(?:Firefox|FxiOS)/([\d.]+)}, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -16,8 +16,8 @@ module Browser
16
16
  end
17
17
 
18
18
  def full_version
19
- ua[%r[(?:QuickTime)/([\d.]+)], 1] ||
20
- ua[%r[CoreMedia v([\d.]+)], 1] ||
19
+ ua[%r{(?:QuickTime)/([\d.]+)}, 1] ||
20
+ ua[/CoreMedia v([\d.]+)/, 1] ||
21
21
  "0.0"
22
22
  end
23
23
 
@@ -25,9 +25,7 @@ module Browser
25
25
  true
26
26
  end
27
27
 
28
- private
29
-
30
- def infer_name
28
+ private def infer_name
31
29
  (NAMES.find {|key, _| ua.include?(key) } || []).last
32
30
  end
33
31
  end
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[Instagram[ /]([\d.]+)], 1]
14
+ ua[%r{Instagram[ /]([\d.]+)}, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -24,7 +24,8 @@ module Browser
24
24
  end
25
25
 
26
26
  def msie_full_version
27
- (ua.match(%r{MSIE ([\d.]+)|Trident/.*?; rv:([\d.]+)}) && ($1 || $2)) ||
27
+ (ua.match(%r{MSIE ([\d.]+)|Trident/.*?; rv:([\d.]+)}) &&
28
+ (Regexp.last_match(1) || Regexp.last_match(2))) ||
28
29
  "0.0"
29
30
  end
30
31
 
@@ -41,23 +42,21 @@ module Browser
41
42
  trident_version && msie_version.to_i < (trident_version.to_i + 4)
42
43
  end
43
44
 
44
- private
45
-
46
- def ie_version
45
+ private def ie_version
47
46
  TRIDENT_MAPPING[trident_version] || msie_version
48
47
  end
49
48
 
50
49
  # Return the trident version.
51
- def trident_version
52
- ua.match(%r[Trident/([0-9.]+)]) && $1
50
+ private def trident_version
51
+ ua.match(%r{Trident/([0-9.]+)}) && Regexp.last_match(1)
53
52
  end
54
53
 
55
- def msie?
54
+ private def msie?
56
55
  ua =~ /MSIE/ && ua !~ /Opera/
57
56
  end
58
57
 
59
- def modern_ie?
60
- ua =~ %r[Trident/.*?; rv:(.*?)]
58
+ private def modern_ie?
59
+ ua =~ %r{Trident/.*?; rv:(.*?)}
61
60
  end
62
61
  end
63
62
  end
@@ -7,9 +7,7 @@ module Browser
7
7
  "#{browser.id} #{browser.id}#{browser.version}" if generic?
8
8
  end
9
9
 
10
- private
11
-
12
- def generic?
10
+ private def generic?
13
11
  !browser.safari? && !browser.chrome?
14
12
  end
15
13
  end
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[(?:MicroMessenger)/([\d.]+)]i, 1] || "0.0"
14
+ ua[%r{(?:MicroMessenger)/([\d.]+)}i, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -10,7 +10,7 @@ module Browser
10
10
  /\.(css|png|jpe?g|gif|js|svg|ico|flv|mov|m4v|ogg|swf)\z/i.freeze
11
11
 
12
12
  # Detect the ACCEPT header. IE8 send */*.
13
- ACCEPT_REGEX = %r[(text/html|\*/\*)].freeze
13
+ ACCEPT_REGEX = %r{(text/html|\*/\*)}.freeze
14
14
 
15
15
  def initialize(app, &block)
16
16
  raise ArgumentError, "Browser::Middleware requires a block" unless block
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[S40OviBrowser/([\d.]+)], 1] || "0.0"
14
+ ua[%r{S40OviBrowser/([\d.]+)}, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -11,11 +11,11 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[OPR/([\d.]+)], 1] || ua[%r[Version/([\d.]+)], 1] || "0.0"
14
+ ua[%r{OPR/([\d.]+)}, 1] || ua[%r{Version/([\d.]+)}, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
18
- ua =~ /(Opera|OPR\/)/
18
+ ua =~ %r{(Opera|OPR/)}
19
19
  end
20
20
  end
21
21
  end
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[Otter/([\d.]+)], 1] || "0.0"
14
+ ua[%r{Otter/([\d.]+)}, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[PhantomJS/([\d.]+)], 1] || "0.0"
14
+ ua[%r{PhantomJS/([\d.]+)}, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -8,7 +8,7 @@ module Browser
8
8
  end
9
9
 
10
10
  def version
11
- ua[%r[AdobeAIR/([\d.]+)], 1]
11
+ ua[%r{AdobeAIR/([\d.]+)}, 1]
12
12
  end
13
13
 
14
14
  def name
@@ -16,7 +16,7 @@ module Browser
16
16
  end
17
17
 
18
18
  def version
19
- ua[%r[(?:Version|BlackBerry[\da-z]+)/([\d.]+)], 1]
19
+ ua[%r{(?:Version|BlackBerry[\da-z]+)/([\d.]+)}, 1]
20
20
  end
21
21
  end
22
22
  end
@@ -4,7 +4,8 @@ module Browser
4
4
  class Platform
5
5
  class IOS < Base
6
6
  MATCHER = /(iPhone|iPad|iPod)/.freeze
7
- VERSION_MATCHER = /OS ((?<major>\d)_(?<minor>\d)_?(?<patch>\d)?)/.freeze
7
+ VERSION_MATCHER =
8
+ /OS ((?<major>\d+)_(?<minor>\d+)_?(?<patch>\d+)?)/.freeze
8
9
 
9
10
  def version
10
11
  matches = VERSION_MATCHER.match(ua)
@@ -11,10 +11,10 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[(?:Mobile MQQBrowser)/([\d.]+)]i, 1] ||
15
- ua[%r[(?:QQBrowserLite)/([\d.]+)]i, 1] ||
16
- ua[%r[(?:QQBrowser)/([\d.]+)]i, 1] ||
17
- ua[%r[(?:QQ)/([\d.]+)]i, 1] ||
14
+ ua[%r{(?:Mobile MQQBrowser)/([\d.]+)}i, 1] ||
15
+ ua[%r{(?:QQBrowserLite)/([\d.]+)}i, 1] ||
16
+ ua[%r{(?:QQBrowser)/([\d.]+)}i, 1] ||
17
+ ua[%r{(?:QQ)/([\d.]+)}i, 1] ||
18
18
  "0.0"
19
19
  end
20
20
 
@@ -12,9 +12,7 @@ module Browser
12
12
  ActiveSupport.on_load(:action_controller) do
13
13
  ::ActionController::Base.include(Browser::ActionController)
14
14
 
15
- if defined?(::ActionController::Metal)
16
- ::ActionController::Metal.include(Browser::ActionController)
17
- end
15
+ ::ActionController::Metal.include(Browser::ActionController) if defined?(::ActionController::Metal) # rubocop:disable Metrics/LineLength
18
16
 
19
17
  Browser::Middleware::Context.include(
20
18
  Browser::Middleware::Context::Additions
@@ -11,9 +11,9 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[Version/([\d.]+)], 1] ||
15
- ua[%r[Safari/([\d.]+)], 1] ||
16
- ua[%r[AppleWebKit/([\d.]+)], 1] ||
14
+ ua[%r{Version/([\d.]+)}, 1] ||
15
+ ua[%r{Safari/([\d.]+)}, 1] ||
16
+ ua[%r{AppleWebKit/([\d.]+)}, 1] ||
17
17
  "0.0"
18
18
  end
19
19
 
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[Snapchat/([\d.]+)], 1]
14
+ ua[%r{Snapchat( ?|/)([\d.]+)}, 2] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -12,8 +12,8 @@ module Browser
12
12
 
13
13
  def full_version
14
14
  # Each regex on its own line to enforce precedence.
15
- ua[%r[SputnikBrowser/([\d.]+)], 1] ||
16
- ua[%r[Chrome/([\d.]+)], 1] ||
15
+ ua[%r{SputnikBrowser/([\d.]+)}, 1] ||
16
+ ua[%r{Chrome/([\d.]+)}, 1] ||
17
17
  "0.0"
18
18
  end
19
19
 
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[UCBrowser/([\d.]+)], 1] || "0.0"
14
+ ua[%r{UCBrowser/([\d.]+)}, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Browser
4
- VERSION = "2.7.0"
4
+ VERSION = "2.7.1"
5
5
  end
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[(?:__weibo__)([\d.]+)]i, 1] || "0.0"
14
+ ua[/(?:__weibo__)([\d.]+)/i, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -11,7 +11,7 @@ module Browser
11
11
  end
12
12
 
13
13
  def full_version
14
- ua[%r[YaBrowser/([\d.]+)], 1] || "0.0"
14
+ ua[%r{YaBrowser/([\d.]+)}, 1] || "0.0"
15
15
  end
16
16
 
17
17
  def match?
@@ -25,9 +25,7 @@ class SampleApp < Rails::Application
25
25
  config.active_support.deprecation = :log
26
26
 
27
27
  # Introduced by Rails 6.
28
- if config.respond_to?(:hosts)
29
- config.hosts << "example.org"
30
- end
28
+ config.hosts << "example.org" if config.respond_to?(:hosts)
31
29
 
32
30
  routes.append do
33
31
  default_headers = {"Content-Type" => "text/html"}
@@ -66,6 +66,7 @@ IOS8: "Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4
66
66
  IOS8_1_2: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B440 Safari/600.1.4'
67
67
  IOS8_3: 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12F70 Safari/600.1.4'
68
68
  IOS9: "Mozilla/5.0 (iPad; CPU OS 9_0 like Mac OS X) AppleWebKit/601.1.17 (KHTML, like Gecko) Version/8.0 Mobile/13A175 Safari/600.1.4"
69
+ IOS12: "Mozilla/5.0 (iPhone; CPU iPhone OS 12_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/12.0 Mobile/15E148 Safari/604.1"
69
70
  IOS_WEBVIEW: Mozilla/5.0 (iPhone; CPU iPhone OS 8_4 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12H141
70
71
  IPAD: "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B367 Safari/531.21.10"
71
72
  IPHONE: "Mozilla/5.0 (iPhone; U; CPU iPhone OS 3_0 like Mac OS X; en-us) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/1A542a Safari/419.3"
@@ -120,6 +121,8 @@ SAMSUNG: "Mozilla/5.0 (Linux; U; Android 4.0.4; en-us; SAMSUNG-SGH-I497 Build/IM
120
121
  SAMSUNG_CHROME: "Mozilla/5.0 (Linux; Android 4.4.2; en-gb; SAMSUNG GT-I9195/I9195XXUCNEA Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/1.5 Chrome/28.0.1500.94 Mobile Safari/537.36"
121
122
  SMART_TV: "Mozilla/5.0 (SmartHub; SMART-TV; U; Linux/SmartTV) AppleWebKit/531.2+ (KHTML, like Gecko) WebBrowser/1.0 SmartTV Safari/531.2+"
122
123
  SNAPCHAT: Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Snapchat/10.69.5.72 (iPhone10,3; iOS 13.2.2; gzip)
124
+ SNAPCHAT_SPACE_VERSION: "Mozilla/5.0 (Linux; Android 9; SM-N960U Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36Snapchat 10.70.0.0 (SM-N960U; Android 9#N960USQS3CSJ2#28; gzip)"
125
+ SNAPCHAT_EMPTY_STRING_VERSION: "Mozilla/5.0 (Linux; Android 9; SM-N960U Build/PPR1.180610.011; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.96 Mobile Safari/537.36Snapchat10.70.0.0 (SM-N960U; Android 9#N960USQS3CSJ2#28; gzip)"
123
126
  SPUTNIK: "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/64.0.3282.140 SputnikBrowser/4.1.2801.0 Safari/537.36"
124
127
  SURFACE: "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch)"
125
128
  SYMBIAN: "Nokia5250/10.0.011 (SymbianOS/9.4; U; Series60/5.0 Mozilla/5.0; Profile/MIDP-2.1 Configuration/CLDC-1.1 ) AppleWebKit/525 (KHTML, like Gecko) Safari/525 3gpp-gba"
@@ -105,6 +105,13 @@ class IosTest < Minitest::Test
105
105
  refute browser.platform.mac?
106
106
  end
107
107
 
108
+ test "detects ios12" do
109
+ browser = Browser.new(Browser["IOS12"])
110
+ assert browser.platform.ios?
111
+ assert browser.platform.ios?(12)
112
+ refute browser.platform.mac?
113
+ end
114
+
108
115
  test "don't detect as two different versions" do
109
116
  browser = Browser.new(Browser["IOS8"])
110
117
  assert browser.platform.ios?(8)
@@ -13,6 +13,26 @@ class SnapchatTest < Minitest::Test
13
13
  assert_equal "10", browser.version
14
14
  end
15
15
 
16
+ test "detects snapchat for badly formatted user agent" do
17
+ browser = Browser.new(Browser["SNAPCHAT_EMPTY_STRING_VERSION"])
18
+
19
+ assert_equal "Snapchat", browser.name
20
+ assert browser.snapchat?
21
+ assert :snapchat, browser.id
22
+ assert_equal "10.70.0.0", browser.full_version
23
+ assert_equal "10", browser.version
24
+ end
25
+
26
+ test "detects alternate snapchat user agent" do
27
+ browser = Browser.new(Browser["SNAPCHAT_SPACE_VERSION"])
28
+
29
+ assert_equal "Snapchat", browser.name
30
+ assert browser.snapchat?
31
+ assert :snapchat, browser.id
32
+ assert_equal "10.70.0.0", browser.full_version
33
+ assert_equal "10", browser.version
34
+ end
35
+
16
36
  test "detects version by range" do
17
37
  browser = Browser.new(Browser["SNAPCHAT"])
18
38
  assert browser.snapchat?(%w[>=10])
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browser
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nando Vieira
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-11-16 00:00:00.000000000 Z
11
+ date: 2019-11-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -25,7 +25,7 @@ dependencies:
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: rake
28
+ name: minitest
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - ">="
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: rails
42
+ name: minitest-autotest
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: rack-test
56
+ name: minitest-utils
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: minitest
70
+ name: pry-meta
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: minitest-utils
84
+ name: rack-test
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -95,7 +95,7 @@ dependencies:
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  - !ruby/object:Gem::Dependency
98
- name: pry-meta
98
+ name: rails
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
101
  - - ">="
@@ -109,7 +109,7 @@ dependencies:
109
109
  - !ruby/object:Gem::Version
110
110
  version: '0'
111
111
  - !ruby/object:Gem::Dependency
112
- name: minitest-autotest
112
+ name: rake
113
113
  requirement: !ruby/object:Gem::Requirement
114
114
  requirements:
115
115
  - - ">="
@@ -123,7 +123,7 @@ dependencies:
123
123
  - !ruby/object:Gem::Version
124
124
  version: '0'
125
125
  - !ruby/object:Gem::Dependency
126
- name: simplecov
126
+ name: rubocop
127
127
  requirement: !ruby/object:Gem::Requirement
128
128
  requirements:
129
129
  - - ">="
@@ -137,7 +137,21 @@ dependencies:
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
139
  - !ruby/object:Gem::Dependency
140
- name: rubocop
140
+ name: rubocop-fnando
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ - !ruby/object:Gem::Dependency
154
+ name: simplecov
141
155
  requirement: !ruby/object:Gem::Requirement
142
156
  requirements:
143
157
  - - ">="
@@ -317,7 +331,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
317
331
  requirements:
318
332
  - - ">="
319
333
  - !ruby/object:Gem::Version
320
- version: '2.0'
334
+ version: '0'
321
335
  required_rubygems_version: !ruby/object:Gem::Requirement
322
336
  requirements:
323
337
  - - ">="