browser 2.7.0 → 2.7.1

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.
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
  - - ">="