device_detector 0.5.1 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5f0bf4f5cd10e7dd06b4825842c96ab9ce0d5236
4
- data.tar.gz: dd414ed24f7701367f5e5cf05b3502a7a9a82461
3
+ metadata.gz: 89802f3d1a2276198bb17c6889848941b692e962
4
+ data.tar.gz: e4ee7d45dd2e0307a5e547f1f77e0e5f4f99e725
5
5
  SHA512:
6
- metadata.gz: 4ffd8b88962d13e6f550cd279001cd9dafb06e40e791a23c85b6dc130155805612c4560db1b5eba45c357cb45d91e0ac9fde920060c29b8a1627af77ae602e5b
7
- data.tar.gz: d16742dca52e42f7deed6714e9f71bcee501c2538423af8d54edb90da52f2a6104bc6291b631c6c1bc6a35ea1be7a8457e326ed31526ae9dac03f6a05eeeea3b
6
+ metadata.gz: 5c52585792a08a2bd4e9ee96439af347898113872f888119e60f0096239fec438d058c6782c89c4ed52e42cc1414d0776219b2b350730888b71ccf19e05cab65
7
+ data.tar.gz: 988d986ea34e7a9fa96efdf3414ea97eba1931d4b74e7db18b794dca732b2787907c8323f91f54d6102b7cb345367961881d812e6137690fd979ae208b3f3f52
data/.travis.yml CHANGED
@@ -5,7 +5,6 @@ rvm:
5
5
  - 2.1.0
6
6
  - 2.2.0
7
7
  - ruby-head
8
- - jruby-head
9
8
  - rbx-2
10
9
  script:
11
- bundle exec rspec
10
+ bundle exec rake test
data/CHANGELOG.md ADDED
@@ -0,0 +1,21 @@
1
+ # Change Log
2
+
3
+ ## [0.7.0]
4
+ - [Issue #8](https://github.com/podigee/device_detector/issues/8) Fixed Mac OS X full version format. Thanks to [aaronchi](https://github.com/aaronchi) for reporting.
5
+
6
+ ## [0.6.0]
7
+
8
+ - [Issue #7](https://github.com/podigee/device_detector/issues/7) Fixed missing name extraction from regexp. Thanks to [janxious](https://github.com/janxious) for reporting.
9
+ - Optimized performance of name and version extraction, by using the built-in memory cache
10
+ - Move specs from RSpec to the more lightweight Minitest
11
+
12
+ ## [0.5.1]
13
+
14
+ - Added the minimum required Ruby version (>= 1.9.3)
15
+
16
+ ## [0.5.0]
17
+
18
+ - Added rake task for automatic generation of supported and detectable clients and devices
19
+ - Updated detection rules
20
+ - Fixed device type detection, when type is specified on top level of a nested regex
21
+
data/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  DeviceDetector is a precise and fast user agent parser and device detector written in Ruby, backed by the largest and most up-to-date user agent database.
6
6
 
7
- DeviceDetector will parse any user agent and detect the browser, operating system, device used (desktop, tablet, mobile, tv, cars, console, etc.), brand and model.
7
+ DeviceDetector will parse any user agent and detect the browser, operating system, device used (desktop, tablet, mobile, tv, cars, console, etc.), brand and model. DeviceDetector detects thousands of user agent strings, even from rare and obscure browsers and devices.
8
8
 
9
9
  The DeviceDetector is optimized for speed of detection, by providing optimized code and in-memory caching.
10
10
 
@@ -62,15 +62,76 @@ client.known? # => will return false if user_agent is unknown
62
62
  ### Memory cache
63
63
 
64
64
  `DeviceDetector` will cache up 5,000 user agent strings to boost parsing performance.
65
- You can tune the amount of keys that will get saved in the cache:
65
+ You can tune the amount of keys that will get saved in the cache. You have to call this code **before** you initialize the Detector.
66
66
 
67
67
  ```ruby
68
- # You have to call this code **before** you initialize the Detector
69
68
  DeviceDetector.configure do |config|
70
- config.max_cache_keys = 20_000 # increment this if you have enough RAM, proceed with care
69
+ config.max_cache_keys = 5_000 # increment this if you have enough RAM, proceed with care
71
70
  end
72
71
  ```
73
72
 
73
+ If you have a Rails application, you can create an initializer, for example `config/initializers/device_detector.rb`.
74
+
75
+ ## Benchmarks
76
+
77
+ We have measured the parsing speed of almost 200,000 non-unique user agent strings and compared the speed of DeviceDetector with the two most popular user agent parsers in the Ruby community, Browser and UserAgent.
78
+
79
+ ### Testing machine specs
80
+
81
+ - MacBook Pro 15", Late 2013
82
+ - 2.6 GHz Intel Core i7
83
+ - 16 GB 1600 MHz DDR3
84
+
85
+ ### Gem versions
86
+
87
+ - DeviceDetector - 0.5.1
88
+ - Browser - 0.8.0
89
+ - UserAgent - 0.13.1
90
+
91
+ ### Code
92
+
93
+ ```ruby
94
+ require 'device_detector'
95
+ require 'browser'
96
+ require 'user_agent'
97
+ require 'benchmark'
98
+
99
+ user_agent_strings = File.read('./tmp/user_agent_strings.txt').split("\n")
100
+
101
+ ## Benchmarks
102
+
103
+ Benchmark.bm(15) do |x|
104
+ x.report('device_detector') {
105
+ user_agent_strings.each { |uas| DeviceDetector.new(uas).name }
106
+ }
107
+ x.report('browser') {
108
+ user_agent_strings.each { |uas| Browser.new(ua: uas).name }
109
+ }
110
+ x.report('useragent') {
111
+ user_agent_strings.each { |uas| UserAgent.parse(uas).browser }
112
+ }
113
+ end
114
+ ```
115
+
116
+ ### Results
117
+
118
+ ```
119
+ user system total real
120
+ device_detector 1.180000 0.010000 1.190000 ( 1.198721)
121
+ browser 2.240000 0.010000 2.250000 ( 2.245493)
122
+ useragent 4.490000 0.020000 4.510000 ( 4.500673)
123
+
124
+ user system total real
125
+ device_detector 1.190000 0.020000 1.210000 ( 1.201447)
126
+ browser 2.250000 0.010000 2.260000 ( 2.261001)
127
+ useragent 4.440000 0.010000 4.450000 ( 4.451693)
128
+
129
+ user system total real
130
+ device_detector 1.210000 0.020000 1.230000 ( 1.228617)
131
+ browser 2.220000 0.010000 2.230000 ( 2.222565)
132
+ useragent 4.450000 0.000000 4.450000 ( 4.452741)
133
+ ```
134
+
74
135
  ## Detectable clients, bots and devices
75
136
 
76
137
  Updated on 2015-03-17
data/Rakefile CHANGED
@@ -1,13 +1,12 @@
1
- require 'bundler/gem_tasks'
1
+ require 'rake'
2
+ require 'rake/testtask'
2
3
 
3
- require 'rspec/core'
4
- require 'rspec/core/rake_task'
5
-
6
- RSpec::Core::RakeTask.new(:spec) do |spec|
7
- spec.pattern = FileList['spec/**/*_spec.rb']
4
+ Rake::TestTask.new do |t|
5
+ t.pattern = 'spec/**/*_spec.rb'
6
+ t.libs.push 'spec'
8
7
  end
9
8
 
10
- task default: :spec
9
+ task default: :test
11
10
 
12
11
  task :detectable_names do
13
12
  require 'device_detector'
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.required_ruby_version = '>= 1.9.3'
22
22
 
23
- spec.add_development_dependency 'rspec' ,'~> 3.1', '>= 3.1.0'
23
+ spec.add_development_dependency 'minitest'
24
+ spec.add_development_dependency 'rake'
24
25
  spec.add_development_dependency 'pry', '~> 0.10'
25
26
  end
@@ -7,6 +7,7 @@ require 'device_detector/version'
7
7
  require 'device_detector/metadata_extractor'
8
8
  require 'device_detector/version_extractor'
9
9
  require 'device_detector/model_extractor'
10
+ require 'device_detector/name_extractor'
10
11
  require 'device_detector/memory_cache'
11
12
  require 'device_detector/parser'
12
13
  require 'device_detector/bot'
@@ -30,8 +30,8 @@ class DeviceDetector
30
30
  ]
31
31
  end
32
32
 
33
- def self.parse_regexes(regexes, device = nil)
34
- regexes.map { |base, nest|
33
+ def parse_regexes(raw_regexes, device = nil)
34
+ raw_regexes.map { |base, nest|
35
35
 
36
36
  if !nest.nil? && nest.key?('models')
37
37
  default_device = nest['device']
@@ -30,7 +30,7 @@ class DeviceDetector
30
30
  end
31
31
 
32
32
  def regex
33
- Regexp.new(regex_meta['regex'])
33
+ @regex ||= regex_meta['regex']
34
34
  end
35
35
 
36
36
  end
@@ -0,0 +1,19 @@
1
+ class DeviceDetector
2
+ class NameExtractor < MetadataExtractor
3
+
4
+ def call
5
+ if /\$[0-9]/ =~ metadata_string
6
+ extract_metadata
7
+ else
8
+ metadata_string
9
+ end
10
+ end
11
+
12
+ private
13
+
14
+ def metadata_string
15
+ regex_meta['name']
16
+ end
17
+
18
+ end
19
+ end
@@ -1,6 +1,15 @@
1
1
  class DeviceDetector
2
2
  class OS < Parser
3
3
 
4
+ def full_version
5
+ raw_version = super
6
+
7
+ # This solution won't scale, but for now it will do
8
+ if raw_version && name == 'Mac'
9
+ raw_version.split('_').join('.')
10
+ end
11
+ end
12
+
4
13
  private
5
14
 
6
15
  def filenames
@@ -4,11 +4,15 @@ class DeviceDetector
4
4
  ROOT = File.expand_path('../../..', __FILE__)
5
5
 
6
6
  def name
7
- regex_meta['name']
7
+ from_cache(['name', self.class.name, user_agent]) do
8
+ NameExtractor.new(user_agent, regex_meta).call
9
+ end
8
10
  end
9
11
 
10
12
  def full_version
11
- VersionExtractor.new(user_agent, regex_meta).call
13
+ from_cache(['full_version', self.class.name, user_agent]) do
14
+ VersionExtractor.new(user_agent, regex_meta).call
15
+ end
12
16
  end
13
17
 
14
18
  private
@@ -18,13 +22,13 @@ class DeviceDetector
18
22
  end
19
23
 
20
24
  def matching_regex
21
- DeviceDetector.cache.get_or_set([self.class.name, user_agent]) do
25
+ from_cache([self.class.name, user_agent]) do
22
26
  regexes.find { |r| user_agent =~ r['regex'] }
23
27
  end
24
28
  end
25
29
 
26
30
  def regexes
27
- self.class.regexes_for(filepaths)
31
+ @regexes ||= regexes_for(filepaths)
28
32
  end
29
33
 
30
34
  def filenames
@@ -37,34 +41,30 @@ class DeviceDetector
37
41
  end
38
42
  end
39
43
 
40
- class << self
44
+ def regexes_for(filepaths)
45
+ from_cache(['regexes', self.class]) do
46
+ raw_regexes = load_regexes
47
+ parsed_regexes = raw_regexes.map { |r| parse_regexes(r) }
41
48
 
42
- # This is a performance optimization.
43
- # We cache the regexes on the class for better performance
44
- # Thread-safety shouldn't be an issue, as we do only perform reads
45
- def regexes_for(filepaths)
46
- @regexes ||=
47
- begin
48
- regexes = load_regexes(filepaths)
49
- parsed_regexes = regexes.map { |r| parse_regexes(r) }
50
-
51
- parsed_regexes.flatten
52
- end
49
+ parsed_regexes.flatten
53
50
  end
51
+ end
54
52
 
55
- def load_regexes(filepaths)
56
- raw_files = filepaths.map { |path| File.read(path) }
53
+ def load_regexes
54
+ raw_files = filepaths.map { |path| File.read(path) }
57
55
 
58
- raw_files.map { |f| YAML.load(f) }
59
- end
56
+ raw_files.map { |f| YAML.load(f) }
57
+ end
60
58
 
61
- def parse_regexes(regexes)
62
- regexes.map do |meta|
63
- meta['regex'] = Regexp.new(meta['regex'])
64
- meta
65
- end
59
+ def parse_regexes(raw_regexes)
60
+ raw_regexes.map do |meta|
61
+ meta['regex'] = Regexp.new(meta['regex']) if meta['regex'].is_a? String
62
+ meta
66
63
  end
64
+ end
67
65
 
66
+ def from_cache(key)
67
+ DeviceDetector.cache.get_or_set(key) { yield }
68
68
  end
69
69
 
70
70
  end
@@ -1,3 +1,3 @@
1
1
  class DeviceDetector
2
- VERSION = '0.5.1'
2
+ VERSION = '0.7.0'
3
3
  end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe DeviceDetector do
4
+
5
+ subject { DeviceDetector.new(user_agent) }
6
+
7
+ alias :client :subject
8
+
9
+ describe 'mobile iPhone 5S' do
10
+
11
+ let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B440 [FBDV/iPhone6,1]' }
12
+
13
+ describe '#device_name' do
14
+
15
+ it 'returns device name' do
16
+ client.device_name.must_equal 'iPhone 5S'
17
+ end
18
+
19
+ end
20
+
21
+ describe '#device_type' do
22
+
23
+ it 'returns the device type' do
24
+ client.device_type.must_equal 'smartphone'
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ describe 'Ubuntu 10' do
32
+
33
+ let(:user_agent) { 'Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.16 (KHTML, like Gecko) Ubuntu/10.10 Chromium/10.0.648.133 Chrome/10.0.648.133 Safari/534.16' }
34
+
35
+ describe '#os_name' do
36
+
37
+ it 'returns the OS name' do
38
+ client.os_name.must_equal 'Ubuntu'
39
+ end
40
+
41
+ end
42
+
43
+ end
44
+
45
+ describe 'Mac OS X' do
46
+
47
+ let(:user_agent) { 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2227.1 Safari/537.36' }
48
+
49
+ describe '#full_version' do
50
+
51
+ it 'returns the correct OS version' do
52
+ client.os_full_version.must_equal '10.10.1'
53
+ end
54
+
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+
@@ -2,31 +2,33 @@ require 'spec_helper'
2
2
 
3
3
  describe DeviceDetector::Device do
4
4
 
5
- subject(:device) { DeviceDetector::Device.new(user_agent) }
5
+ subject { DeviceDetector::Device.new(user_agent) }
6
+
7
+ alias :device :subject
6
8
 
7
9
  describe '#name' do
8
10
 
9
- context 'when models are nested' do
11
+ describe 'when models are nested' do
10
12
  let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B466 [FBDV/iPhone7,2]' }
11
13
 
12
14
  it 'finds an Apple iPhone 6' do
13
- expect(device.name).to eq('iPhone 6')
15
+ device.name.must_equal 'iPhone 6'
14
16
  end
15
17
  end
16
18
 
17
- context 'when models are NOT nested' do
19
+ describe 'when models are NOT nested' do
18
20
  let(:user_agent) { 'AIRNESS-AIR99/REV 2.2.1/Teleca Q03B1' }
19
21
 
20
22
  it 'finds an Airness AIR99' do
21
- expect(device.name).to eq('AIR99')
23
+ device.name.must_equal 'AIR99'
22
24
  end
23
25
  end
24
26
 
25
- context 'when it cannot find a device name' do
27
+ describe 'when it cannot find a device name' do
26
28
  let(:user_agent) { 'UNKNOWN MODEL NAME' }
27
29
 
28
30
  it 'returns nil' do
29
- expect(device.name).to eq(nil)
31
+ device.name.must_be_nil
30
32
  end
31
33
  end
32
34
 
@@ -34,52 +36,52 @@ describe DeviceDetector::Device do
34
36
 
35
37
  describe '#type' do
36
38
 
37
- context 'when models are nested' do
39
+ describe 'when models are nested' do
38
40
  let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B466 [FBDV/iPhone7,2]' }
39
41
 
40
42
  it 'finds device of Apple iPhone 6' do
41
- expect(device.type).to eq('smartphone')
43
+ device.type.must_equal 'smartphone'
42
44
  end
43
45
  end
44
46
 
45
- context 'when models are NOT nested' do
47
+ describe 'when models are NOT nested' do
46
48
  let(:user_agent) { 'AIRNESS-AIR99/REV 2.2.1/Teleca Q03B1' }
47
49
 
48
50
  it 'finds the device of Airness AIR99' do
49
- expect(device.type).to eq('feature phone')
51
+ device.type.must_equal 'feature phone'
50
52
  end
51
53
  end
52
54
 
53
- context 'when it cannot find a device type' do
55
+ describe 'when it cannot find a device type' do
54
56
  let(:user_agent) { 'UNKNOWN MODEL TYPE' }
55
57
 
56
58
  it 'returns nil' do
57
- expect(device.type).to eq(nil)
59
+ device.type.must_be_nil
58
60
  end
59
61
 
60
62
  end
61
63
 
62
- context 'device not specified in nested block' do
64
+ describe 'device not specified in nested block' do
63
65
 
64
66
  let(:user_agent) { 'Mozilla/5.0 (Linux; Android 4.4.2; es-us; SAMSUNG SM-G900F Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)' }
65
67
 
66
68
  it 'falls back to top-level device' do
67
- expect(device.type).to eq('smartphone')
69
+ device.type.must_equal 'smartphone'
68
70
  end
69
71
 
70
72
  end
71
73
 
72
74
  end
73
75
 
74
- context 'concrete device types' do
76
+ describe 'concrete device types' do
75
77
 
76
78
  describe 'mobiles' do
77
79
 
78
80
  let(:user_agent) { 'Mozilla/5.0 (Linux; Android 4.4.2; es-us; SAMSUNG SM-G900F Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko)' }
79
81
 
80
82
  it 'identifies the device' do
81
- expect(device.name).to eq('GALAXY S5')
82
- expect(device.type).to eq('smartphone')
83
+ device.name.must_equal 'GALAXY S5'
84
+ device.type.must_equal 'smartphone'
83
85
  end
84
86
 
85
87
  end
@@ -89,8 +91,8 @@ describe DeviceDetector::Device do
89
91
  let(:user_agent) { 'Mozilla/5.0 (Linux; U; Android 4.0; xx-xx; EK-GC100 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30' }
90
92
 
91
93
  it 'identifies the device' do
92
- expect(device.name).to eq('GALAXY Camera')
93
- expect(device.type).to eq('camera')
94
+ device.name.must_equal 'GALAXY Camera'
95
+ device.type.must_equal 'camera'
94
96
  end
95
97
 
96
98
  end
@@ -100,8 +102,8 @@ describe DeviceDetector::Device do
100
102
  let(:user_agent) { 'Mozilla/5.0 (X11; Linux) AppleWebKit/534.34 (KHTML, like Gecko) QtCarBrowser Safari/534.34' }
101
103
 
102
104
  it 'identifies the device' do
103
- expect(device.name).to eq('Model S')
104
- expect(device.type).to eq('car browser')
105
+ device.name.must_equal 'Model S'
106
+ device.type.must_equal 'car browser'
105
107
  end
106
108
 
107
109
  end
@@ -111,8 +113,8 @@ describe DeviceDetector::Device do
111
113
  let(:user_agent) { 'Opera/9.30 (Nintendo Wii; U; ; 2047-7;en)' }
112
114
 
113
115
  it 'identifies the device' do
114
- expect(device.name).to eq('Wii')
115
- expect(device.type).to eq('console')
116
+ device.name.must_equal 'Wii'
117
+ device.type.must_equal 'console'
116
118
  end
117
119
 
118
120
  end
@@ -122,8 +124,8 @@ describe DeviceDetector::Device do
122
124
  let(:user_agent) { 'Mozilla/5.0 (iPod touch; CPU iPhone OS 7_0_6 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B651 Safari/9537.53' }
123
125
 
124
126
  it 'identifies the device' do
125
- expect(device.name).to eq('iPod Touch')
126
- expect(device.type).to eq('portable media player')
127
+ device.name.must_equal 'iPod Touch'
128
+ device.type.must_equal 'portable media player'
127
129
  end
128
130
 
129
131
  end
@@ -133,8 +135,8 @@ describe DeviceDetector::Device do
133
135
  let(:user_agent) { 'Mozilla/5.0 (Linux; NetCast; U) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.33 Safari/537.31 SmartTV/5.0' }
134
136
 
135
137
  it 'identifies the device' do
136
- expect(device.name).to eq('NetCast')
137
- expect(device.type).to eq('tv')
138
+ device.name.must_equal 'NetCast'
139
+ device.type.must_equal 'tv'
138
140
  end
139
141
 
140
142
  end
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe DeviceDetector::MemoryCache do
3
+ describe DeviceDetector::MemoryCache do
4
4
 
5
5
  let(:subject) { DeviceDetector::MemoryCache.new(config) }
6
6
 
@@ -8,26 +8,26 @@ RSpec.describe DeviceDetector::MemoryCache do
8
8
 
9
9
  describe '#set' do
10
10
 
11
- context 'string key' do
11
+ describe 'string key' do
12
12
 
13
13
  let(:key) { 'string' }
14
14
 
15
15
  it 'sets the value under the key' do
16
16
  subject.set(key, 'value')
17
17
 
18
- expect(subject.data[key]).to eq('value')
18
+ subject.data[key].must_equal 'value'
19
19
  end
20
20
 
21
21
  end
22
22
 
23
- context 'array key' do
23
+ describe 'array key' do
24
24
 
25
25
  let(:key) { ['string1', 'string2'] }
26
26
 
27
27
  it 'sets the value under the key' do
28
28
  subject.set(key, 'value')
29
29
 
30
- expect(subject.data[String(key)]).to eq('value')
30
+ subject.data[String(key)].must_equal 'value'
31
31
  end
32
32
 
33
33
  end
@@ -36,26 +36,26 @@ RSpec.describe DeviceDetector::MemoryCache do
36
36
 
37
37
  describe '#get' do
38
38
 
39
- context 'string key' do
39
+ describe 'string key' do
40
40
 
41
41
  let(:key) { 'string' }
42
42
 
43
43
  it 'gets the value for the key' do
44
44
  subject.data[key] = 'value'
45
45
 
46
- expect(subject.get(key)).to eq('value')
46
+ subject.get(key).must_equal 'value'
47
47
  end
48
48
 
49
49
  end
50
50
 
51
- context 'array key' do
51
+ describe 'array key' do
52
52
 
53
53
  let(:key) { ['string1', 'string2'] }
54
54
 
55
55
  it 'gets the value for the key' do
56
56
  subject.data[String(key)] = 'value'
57
57
 
58
- expect(subject.get(key)).to eq('value')
58
+ subject.get(key).must_equal 'value'
59
59
  end
60
60
 
61
61
  end
@@ -66,7 +66,7 @@ RSpec.describe DeviceDetector::MemoryCache do
66
66
 
67
67
  let(:key) { 'string' }
68
68
 
69
- context 'value already present' do
69
+ describe 'value already present' do
70
70
 
71
71
  it 'gets the value for the key from cache' do
72
72
  subject.data[key] = 'value'
@@ -76,13 +76,13 @@ RSpec.describe DeviceDetector::MemoryCache do
76
76
  block_called = true
77
77
  end
78
78
 
79
- expect(value).to eq('value')
80
- expect(block_called).to eq(false)
79
+ value.must_equal 'value'
80
+ block_called.must_equal false
81
81
  end
82
82
 
83
83
  end
84
84
 
85
- context 'value not yet present' do
85
+ describe 'value not yet present' do
86
86
 
87
87
  it 'evaluates the block and sets the result' do
88
88
  block_called = false
@@ -90,8 +90,8 @@ RSpec.describe DeviceDetector::MemoryCache do
90
90
  block_called = true
91
91
  end
92
92
 
93
- expect(block_called).to eq(true)
94
- expect(subject.data[key]).to eq(true)
93
+ block_called.must_equal true
94
+ subject.data[key].must_equal true
95
95
  end
96
96
 
97
97
  end
@@ -108,7 +108,7 @@ RSpec.describe DeviceDetector::MemoryCache do
108
108
  subject.set('3', 'baz')
109
109
  subject.set('4', 'boz')
110
110
 
111
- expect(subject.data.keys.size).to eq(3)
111
+ subject.data.keys.size.must_equal 3
112
112
  end
113
113
 
114
114
  end
@@ -2,11 +2,13 @@ require 'spec_helper'
2
2
 
3
3
  describe DeviceDetector::ModelExtractor do
4
4
 
5
- subject(:extractor) { DeviceDetector::ModelExtractor.new(user_agent, regex_meta) }
5
+ subject { DeviceDetector::ModelExtractor.new(user_agent, regex_meta) }
6
+
7
+ alias :extractor :subject
6
8
 
7
9
  describe '#call' do
8
10
 
9
- context 'when matching against dynamic model' do
11
+ describe 'when matching against dynamic model' do
10
12
 
11
13
  let(:regex_meta) do
12
14
  {
@@ -16,29 +18,29 @@ describe DeviceDetector::ModelExtractor do
16
18
  }
17
19
  end
18
20
 
19
- context 'when no dynamic match is found' do
21
+ describe 'when no dynamic match is found' do
20
22
  let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4' }
21
23
  let(:device_name) { 'iPhone' }
22
24
 
23
25
  it 'returns the textual portion without trailing whitespace' do
24
- expect(extractor.call).to eq(device_name)
26
+ extractor.call.must_equal device_name
25
27
  end
26
28
 
27
29
  end
28
30
 
29
- context 'when a dynamic match is found' do
31
+ describe 'when a dynamic match is found' do
30
32
  let(:user_agent) { 'Mozilla/5.0 (iPhone 5S; CPU iPhone OS 8_1_3 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Version/8.0 Mobile/12B466 Safari/600.1.4' }
31
33
  let(:device_name) { 'iPhone 5S' }
32
34
 
33
35
  it 'returns the full device name' do
34
- expect(extractor.call).to eq(device_name)
36
+ extractor.call.must_equal device_name
35
37
  end
36
38
 
37
39
  end
38
40
 
39
41
  end
40
42
 
41
- context 'when matching against static model' do
43
+ describe 'when matching against static model' do
42
44
 
43
45
  let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_0 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12A365 Weibo (iPhone7,2)' }
44
46
  let(:device_name) { 'iPhone 6' }
@@ -51,7 +53,7 @@ describe DeviceDetector::ModelExtractor do
51
53
  end
52
54
 
53
55
  it 'returns the model name' do
54
- expect(extractor.call).to eq(device_name)
56
+ extractor.call.must_equal device_name
55
57
  end
56
58
 
57
59
  end
@@ -1,12 +1,14 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe DeviceDetector::VersionExtractor do
3
+ describe DeviceDetector::VersionExtractor do
4
4
 
5
- subject(:extractor) { DeviceDetector::VersionExtractor.new(user_agent, regex_meta) }
5
+ subject { DeviceDetector::VersionExtractor.new(user_agent, regex_meta) }
6
+
7
+ alias :extractor :subject
6
8
 
7
9
  describe '#call' do
8
10
 
9
- context 'extractor without version' do
11
+ describe 'extractor without version' do
10
12
 
11
13
  let(:user_agent) { 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.1; Trident/4.0; Avant Browser; SLCC2; .NET CLR 2.0.50727; .NET CLR 3.5.30729; .NET CLR 3.0.30729; Media Center PC 6.0)' }
12
14
 
@@ -19,12 +21,12 @@ RSpec.describe DeviceDetector::VersionExtractor do
19
21
  end
20
22
 
21
23
  it 'returns nil' do
22
- expect(extractor.call).to eq('')
24
+ extractor.call.must_equal ''
23
25
  end
24
26
 
25
27
  end
26
28
 
27
- context 'regex with dynamic matching' do
29
+ describe 'regex with dynamic matching' do
28
30
 
29
31
  let(:user_agent) { 'Mozilla/5.0 (X11; U; Linux i686; nl; rv:1.8.1b2) Gecko/20060821 BonEcho/2.0b2 (Debian-1.99+2.0b2+dfsg-1)' }
30
32
  let(:version) { 'BonEcho (2.0)' }
@@ -37,17 +39,17 @@ RSpec.describe DeviceDetector::VersionExtractor do
37
39
  end
38
40
 
39
41
  it 'returns the correct version' do
40
- expect(extractor.call).to eq(version)
42
+ extractor.call.must_equal version
41
43
  end
42
44
 
43
45
  it 'removes trailing white spaces' do
44
46
  regex_meta['version'] = regex_meta['version'] + ' '
45
- expect(extractor.call).to eq(version)
47
+ extractor.call.must_equal version
46
48
  end
47
49
 
48
50
  end
49
51
 
50
- context 'extractor with fixed version' do
52
+ describe 'extractor with fixed version' do
51
53
 
52
54
  let(:user_agent) { 'Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0; Trident/4.0)' }
53
55
  let(:regex_meta) do
@@ -58,18 +60,18 @@ RSpec.describe DeviceDetector::VersionExtractor do
58
60
  end
59
61
 
60
62
  it 'returns the correct version' do
61
- expect(extractor.call).to eq('8.0')
63
+ extractor.call.must_equal '8.0'
62
64
  end
63
65
 
64
66
  end
65
67
 
66
- context 'unknown user agent' do
68
+ describe 'unknown user agent' do
67
69
 
68
70
  let(:user_agent) { 'garbage' }
69
71
  let(:regex_meta) { {} }
70
72
 
71
73
  it 'returns nil' do
72
- expect(extractor.call).to be_nil
74
+ extractor.call.must_be_nil
73
75
  end
74
76
 
75
77
  end
@@ -1,19 +1,21 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe DeviceDetector do
3
+ describe DeviceDetector do
4
4
 
5
- subject(:client) { DeviceDetector.new(user_agent) }
5
+ subject { DeviceDetector.new(user_agent) }
6
6
 
7
- context 'known user agent' do
7
+ alias :client :subject
8
8
 
9
- context 'desktop chrome browser' do
9
+ describe 'known user agent' do
10
+
11
+ describe 'desktop chrome browser' do
10
12
 
11
13
  let(:user_agent) { 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.69' }
12
14
 
13
15
  describe '#name' do
14
16
 
15
17
  it 'returns the name' do
16
- expect(client.name).to eq('Chrome')
18
+ client.name.must_equal 'Chrome'
17
19
  end
18
20
 
19
21
  end
@@ -21,7 +23,7 @@ RSpec.describe DeviceDetector do
21
23
  describe '#full_version' do
22
24
 
23
25
  it 'returns the full version' do
24
- expect(client.full_version).to eq('30.0.1599.69')
26
+ client.full_version.must_equal '30.0.1599.69'
25
27
  end
26
28
 
27
29
  end
@@ -29,7 +31,7 @@ RSpec.describe DeviceDetector do
29
31
  describe '#os_name' do
30
32
 
31
33
  it 'returns the operating system name' do
32
- expect(client.os_name).to eq('Mac')
34
+ client.os_name.must_equal 'Mac'
33
35
  end
34
36
 
35
37
  end
@@ -37,7 +39,7 @@ RSpec.describe DeviceDetector do
37
39
  describe '#os_full_version' do
38
40
 
39
41
  it 'returns the operating system full version' do
40
- expect(client.os_full_version).to eq('10_8_5')
42
+ client.os_full_version.must_equal '10.8.5'
41
43
  end
42
44
 
43
45
  end
@@ -45,7 +47,7 @@ RSpec.describe DeviceDetector do
45
47
  describe '#known?' do
46
48
 
47
49
  it 'returns true' do
48
- expect(client.known?).to eq(true)
50
+ client.known?.must_equal true
49
51
  end
50
52
 
51
53
  end
@@ -53,7 +55,7 @@ RSpec.describe DeviceDetector do
53
55
  describe '#bot?' do
54
56
 
55
57
  it 'returns false' do
56
- expect(client.bot?).to eq(false)
58
+ client.bot?.must_equal false
57
59
  end
58
60
 
59
61
  end
@@ -61,29 +63,7 @@ RSpec.describe DeviceDetector do
61
63
  describe '#bot_name' do
62
64
 
63
65
  it 'returns nil' do
64
- expect(client.bot_name).to be_nil
65
- end
66
-
67
- end
68
-
69
- end
70
-
71
- context 'mobile iPhone 5S' do
72
-
73
- let(:user_agent) { 'Mozilla/5.0 (iPhone; CPU iPhone OS 8_1_2 like Mac OS X) AppleWebKit/600.1.4 (KHTML, like Gecko) Mobile/12B440 [FBDV/iPhone6,1]' }
74
-
75
- describe '#device_name' do
76
-
77
- it 'returns device name' do
78
- expect(client.device_name).to eq('iPhone 5S')
79
- end
80
-
81
- end
82
-
83
- describe '#device_type' do
84
-
85
- it 'returns the device type' do
86
- expect(client.device_type).to eq('smartphone')
66
+ client.bot_name.must_be_nil
87
67
  end
88
68
 
89
69
  end
@@ -92,14 +72,14 @@ RSpec.describe DeviceDetector do
92
72
 
93
73
  end
94
74
 
95
- context 'unknown user agent' do
75
+ describe 'unknown user agent' do
96
76
 
97
77
  let(:user_agent) { 'garbage123' }
98
78
 
99
79
  describe '#name' do
100
80
 
101
81
  it 'returns nil' do
102
- expect(client.name).to be_nil
82
+ client.name.must_be_nil
103
83
  end
104
84
 
105
85
  end
@@ -107,7 +87,7 @@ RSpec.describe DeviceDetector do
107
87
  describe '#full_version' do
108
88
 
109
89
  it 'returns nil' do
110
- expect(client.full_version).to be_nil
90
+ client.full_version.must_be_nil
111
91
  end
112
92
 
113
93
  end
@@ -115,7 +95,7 @@ RSpec.describe DeviceDetector do
115
95
  describe '#os_name' do
116
96
 
117
97
  it 'returns nil' do
118
- expect(client.os_name).to be_nil
98
+ client.os_name.must_be_nil
119
99
  end
120
100
 
121
101
  end
@@ -123,7 +103,7 @@ RSpec.describe DeviceDetector do
123
103
  describe '#os_full_version' do
124
104
 
125
105
  it 'returns nil' do
126
- expect(client.os_full_version).to be_nil
106
+ client.os_full_version.must_be_nil
127
107
  end
128
108
 
129
109
  end
@@ -131,7 +111,7 @@ RSpec.describe DeviceDetector do
131
111
  describe '#known?' do
132
112
 
133
113
  it 'returns false' do
134
- expect(client.known?).to eq(false)
114
+ client.known?.must_equal false
135
115
  end
136
116
 
137
117
  end
@@ -139,7 +119,7 @@ RSpec.describe DeviceDetector do
139
119
  describe '#bot?' do
140
120
 
141
121
  it 'returns false' do
142
- expect(client.bot?).to eq(false)
122
+ client.bot?.must_equal false
143
123
  end
144
124
 
145
125
  end
@@ -147,21 +127,21 @@ RSpec.describe DeviceDetector do
147
127
  describe '#bot_name' do
148
128
 
149
129
  it 'returns nil' do
150
- expect(client.bot_name).to be_nil
130
+ client.bot_name.must_be_nil
151
131
  end
152
132
 
153
133
  end
154
134
 
155
135
  end
156
136
 
157
- context 'bot' do
137
+ describe 'bot' do
158
138
 
159
139
  let(:user_agent) { 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' }
160
140
 
161
141
  describe '#name' do
162
142
 
163
143
  it 'returns nil' do
164
- expect(client.name).to be_nil
144
+ client.name.must_be_nil
165
145
  end
166
146
 
167
147
  end
@@ -169,7 +149,7 @@ RSpec.describe DeviceDetector do
169
149
  describe '#full_version' do
170
150
 
171
151
  it 'returns nil' do
172
- expect(client.full_version).to be_nil
152
+ client.full_version.must_be_nil
173
153
  end
174
154
 
175
155
  end
@@ -177,7 +157,7 @@ RSpec.describe DeviceDetector do
177
157
  describe '#os_name' do
178
158
 
179
159
  it 'returns nil' do
180
- expect(client.os_name).to be_nil
160
+ client.os_name.must_be_nil
181
161
  end
182
162
 
183
163
  end
@@ -185,7 +165,7 @@ RSpec.describe DeviceDetector do
185
165
  describe '#os_full_version' do
186
166
 
187
167
  it 'returns nil' do
188
- expect(client.os_full_version).to be_nil
168
+ client.os_full_version.must_be_nil
189
169
  end
190
170
 
191
171
  end
@@ -193,7 +173,7 @@ RSpec.describe DeviceDetector do
193
173
  describe '#known?' do
194
174
 
195
175
  it 'returns false' do
196
- expect(client.known?).to eq(false)
176
+ client.known?.must_equal false
197
177
  end
198
178
 
199
179
  end
@@ -201,7 +181,7 @@ RSpec.describe DeviceDetector do
201
181
  describe '#bot?' do
202
182
 
203
183
  it 'returns true' do
204
- expect(client.bot?).to eq(true)
184
+ client.bot?.must_equal true
205
185
  end
206
186
 
207
187
  end
@@ -209,7 +189,7 @@ RSpec.describe DeviceDetector do
209
189
  describe '#bot_name' do
210
190
 
211
191
  it 'returns the name of the bot' do
212
- expect(client.bot_name).to eq('Googlebot')
192
+ client.bot_name.must_equal 'Googlebot'
213
193
  end
214
194
 
215
195
  end
data/spec/spec_helper.rb CHANGED
@@ -1,13 +1,5 @@
1
- $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
- $LOAD_PATH.unshift(File.dirname(__FILE__))
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
3
 
4
- require 'rspec'
5
- require 'device_detector'
6
- require 'pry'
4
+ require './lib/device_detector'
7
5
 
8
- # Requires supporting files with custom matchers and macros, etc,
9
- # in ./support/ and its subdirectories.
10
- Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
11
-
12
- RSpec.configure do |config|
13
- end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: device_detector
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.7.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Mati Sójka
@@ -9,28 +9,36 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2015-03-19 00:00:00.000000000 Z
12
+ date: 2015-03-31 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: rspec
15
+ name: minitest
16
16
  requirement: !ruby/object:Gem::Requirement
17
17
  requirements:
18
- - - "~>"
19
- - !ruby/object:Gem::Version
20
- version: '3.1'
21
18
  - - ">="
22
19
  - !ruby/object:Gem::Version
23
- version: 3.1.0
20
+ version: '0'
24
21
  type: :development
25
22
  prerelease: false
26
23
  version_requirements: !ruby/object:Gem::Requirement
27
24
  requirements:
28
- - - "~>"
25
+ - - ">="
29
26
  - !ruby/object:Gem::Version
30
- version: '3.1'
27
+ version: '0'
28
+ - !ruby/object:Gem::Dependency
29
+ name: rake
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
31
39
  - - ">="
32
40
  - !ruby/object:Gem::Version
33
- version: 3.1.0
41
+ version: '0'
34
42
  - !ruby/object:Gem::Dependency
35
43
  name: pry
36
44
  requirement: !ruby/object:Gem::Requirement
@@ -55,6 +63,7 @@ extra_rdoc_files: []
55
63
  files:
56
64
  - ".gitignore"
57
65
  - ".travis.yml"
66
+ - CHANGELOG.md
58
67
  - Gemfile
59
68
  - LICENSE.txt
60
69
  - README.md
@@ -67,6 +76,7 @@ files:
67
76
  - lib/device_detector/memory_cache.rb
68
77
  - lib/device_detector/metadata_extractor.rb
69
78
  - lib/device_detector/model_extractor.rb
79
+ - lib/device_detector/name_extractor.rb
70
80
  - lib/device_detector/os.rb
71
81
  - lib/device_detector/parser.rb
72
82
  - lib/device_detector/version.rb
@@ -86,6 +96,7 @@ files:
86
96
  - regexes/mobile_apps.yml
87
97
  - regexes/oss.yml
88
98
  - regexes/pim.yml
99
+ - spec/device_detector/concrete_user_agent_spec.rb
89
100
  - spec/device_detector/device_spec.rb
90
101
  - spec/device_detector/memory_cache_spec.rb
91
102
  - spec/device_detector/model_extractor_spec.rb
@@ -117,6 +128,7 @@ signing_key:
117
128
  specification_version: 4
118
129
  summary: Precise and fast user agent parser and device detector
119
130
  test_files:
131
+ - spec/device_detector/concrete_user_agent_spec.rb
120
132
  - spec/device_detector/device_spec.rb
121
133
  - spec/device_detector/memory_cache_spec.rb
122
134
  - spec/device_detector/model_extractor_spec.rb