device_detector 1.0.1 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +1 -5
  3. data/CHANGELOG.md +3 -1
  4. data/README.md +5 -5
  5. data/Rakefile +16 -12
  6. data/lib/device_detector.rb +15 -0
  7. data/lib/device_detector/memory_cache.rb +21 -14
  8. data/lib/device_detector/os.rb +6 -3
  9. data/lib/device_detector/version.rb +3 -1
  10. data/regexes/bots.yml +73 -7
  11. data/regexes/client/browsers.yml +80 -2
  12. data/regexes/client/feed_readers.yml +7 -7
  13. data/regexes/client/libraries.yml +13 -1
  14. data/regexes/client/mediaplayers.yml +9 -5
  15. data/regexes/client/mobile_apps.yml +21 -0
  16. data/regexes/device/mobiles.yml +5616 -402
  17. data/regexes/device/televisions.yml +1 -1
  18. data/regexes/oss.yml +71 -13
  19. data/spec/device_detector/memory_cache_spec.rb +51 -19
  20. data/spec/device_detector_spec.rb +26 -55
  21. data/spec/fixtures/client/browser.yml +221 -96
  22. data/spec/fixtures/client/feed_reader.yml +0 -6
  23. data/spec/fixtures/client/library.yml +25 -1
  24. data/spec/fixtures/client/mediaplayer.yml +0 -12
  25. data/spec/fixtures/client/mobile_app.yml +24 -0
  26. data/spec/fixtures/detector/bots.yml +168 -3
  27. data/spec/fixtures/detector/desktop.yml +1422 -1422
  28. data/spec/fixtures/detector/feature_phone.yml +21 -1
  29. data/spec/fixtures/detector/feed_reader.yml +18 -5
  30. data/spec/fixtures/detector/mediaplayer.yml +33 -3
  31. data/spec/fixtures/detector/mobile_apps.yml +55 -6
  32. data/spec/fixtures/detector/phablet.yml +924 -164
  33. data/spec/fixtures/detector/smartphone-1.yml +4654 -4655
  34. data/spec/fixtures/detector/smartphone-10.yml +12362 -0
  35. data/spec/fixtures/detector/smartphone-11.yml +7639 -0
  36. data/spec/fixtures/detector/smartphone-2.yml +4232 -4247
  37. data/spec/fixtures/detector/smartphone-3.yml +4348 -4237
  38. data/spec/fixtures/detector/smartphone-4.yml +4110 -4103
  39. data/spec/fixtures/detector/smartphone-5.yml +5651 -2716
  40. data/spec/fixtures/detector/smartphone-6.yml +9896 -0
  41. data/spec/fixtures/detector/smartphone-7.yml +9899 -0
  42. data/spec/fixtures/detector/smartphone-8.yml +9945 -0
  43. data/spec/fixtures/detector/smartphone-9.yml +9916 -0
  44. data/spec/fixtures/detector/smartphone.yml +4114 -4013
  45. data/spec/fixtures/detector/tablet-1.yml +3857 -3857
  46. data/spec/fixtures/detector/tablet-2.yml +6681 -1787
  47. data/spec/fixtures/detector/tablet-3.yml +5134 -0
  48. data/spec/fixtures/detector/tablet.yml +3383 -3406
  49. data/spec/fixtures/detector/tv.yml +338 -24
  50. data/spec/fixtures/detector/unknown.yml +0 -120
  51. data/spec/fixtures/parser/oss.yml +135 -0
  52. metadata +17 -3
@@ -293,4 +293,4 @@ Videoweb:
293
293
  - regex: '(tv2n)'
294
294
  model: '$1'
295
295
  - regex: '(videowebtv)'
296
- model: 'VideoWeb TV'
296
+ model: 'VideoWeb TV'
@@ -65,6 +65,13 @@
65
65
  name: 'Windows IoT'
66
66
  version: '10'
67
67
 
68
+ ##########
69
+ # KaiOS
70
+ ##########
71
+ - regex: 'KAIOS(?:/(\d+[\.\d]+))?'
72
+ name: 'KaiOS'
73
+ version: '$1'
74
+
68
75
  ##########
69
76
  # Custom Android Roms
70
77
  ##########
@@ -84,10 +91,14 @@
84
91
  name: 'MocorDroid'
85
92
  version: '$1'
86
93
 
94
+ - regex: 'Fire OS(?:/(\d+[\.\d]*))?'
95
+ name: 'Fire OS'
96
+ version: '$1'
97
+
87
98
  ##########
88
99
  # Android
89
100
  ##########
90
- - regex: '(?:(?:Orca-)?Android|Adr)[ /](?:[a-z]+ )?(\d+[\.\d]+)'
101
+ - regex: '(?:(?:Orca-)?Android|Adr)[ /](?:[a-z]+ )?(\d+[\.\d]*)'
91
102
  name: 'Android'
92
103
  version: '$1'
93
104
 
@@ -96,6 +107,10 @@
96
107
  name: 'Android'
97
108
  version: ''
98
109
 
110
+ - regex: '(?:TwitterAndroid).*[ /](?:[a-z]+ )?(\d+[\.\d]*)'
111
+ name: 'Android'
112
+ version: '$1'
113
+
99
114
  - regex: 'BeyondPod|AntennaPod|Podkicker|DoggCatcher|Player FM|okhttp|Podcatcher Deluxe'
100
115
  name: 'Android'
101
116
  version: ''
@@ -249,12 +264,59 @@
249
264
  - regex: 'Windows'
250
265
  name: 'Windows'
251
266
  version: ''
252
-
253
-
267
+
268
+
269
+ ##########
270
+ # Haiku OS
271
+ ##########
272
+ - regex: 'Haiku'
273
+ name: 'Haiku OS'
274
+ version: ''
275
+
254
276
 
255
277
  ##########
256
278
  # iOS
257
279
  ##########
280
+ - regex: 'CFNetwork/889'
281
+ name: 'iOS'
282
+ version: '11.1'
283
+
284
+ - regex: 'CFNetwork/887.*(x86_64)'
285
+ name: 'Mac'
286
+ version: '10.13'
287
+
288
+ - regex: 'CFNetwork/887'
289
+ name: 'iOS'
290
+ version: '11.0'
291
+
292
+ - regex: 'CFNetwork/811.*(x86_64)'
293
+ name: 'Mac'
294
+ version: '10.12'
295
+
296
+ - regex: 'CFNetwork/811'
297
+ name: 'iOS'
298
+ version: '10.3'
299
+
300
+ - regex: 'CFNetwork/808\.3'
301
+ name: 'iOS'
302
+ version: '10.3'
303
+
304
+ - regex: 'CFNetwork/808\.2'
305
+ name: 'iOS'
306
+ version: '10.2'
307
+
308
+ - regex: 'CFNetwork/808\.1'
309
+ name: 'iOS'
310
+ version: '10.1'
311
+
312
+ - regex: 'CFNetwork/808\.0'
313
+ name: 'iOS'
314
+ version: '10.0'
315
+
316
+ - regex: 'CFNetwork/808'
317
+ name: 'iOS'
318
+ version: '10'
319
+
258
320
  - regex: 'CFNetwork/758\.4\.3'
259
321
  name: 'iOS'
260
322
  version: '9.3.2'
@@ -355,7 +417,7 @@
355
417
  name: 'iOS'
356
418
  version: '$1'
357
419
 
358
- - regex: 'Podcasts/(?:[\d\.]+)|Instacast(?:HD)?/(?:\d\.[\d\.abc]+)|Pocket Casts, iOS|Overcast|Castro|Podcat|i[cC]atcher'
420
+ - regex: 'Podcasts/(?:[\d\.]+)|Instacast(?:HD)?/(?:\d\.[\d\.abc]+)|Pocket Casts, iOS|Overcast|Castro|Podcat|i[cC]atcher|RSSRadio/'
359
421
  name: 'iOS'
360
422
  version: ''
361
423
 
@@ -368,6 +430,10 @@
368
430
  # Mac
369
431
  ##########
370
432
 
433
+ - regex: 'CFNetwork/807'
434
+ name: 'Mac'
435
+ version: '10.12'
436
+
371
437
  - regex: 'CFNetwork/760'
372
438
  name: 'Mac'
373
439
  version: '10.11'
@@ -408,7 +474,7 @@
408
474
  name: 'Mac'
409
475
  version: '10.2'
410
476
 
411
- - regex: 'Mac OS X(?: (?:Version )?(\d+(?:[_\.]\d+)+))?'
477
+ - regex: 'Mac[ +]OS[ +]X(?:[ /](?:Version )?(\d+(?:[_\.]\d+)+))?'
412
478
  name: 'Mac'
413
479
  version: '$1'
414
480
 
@@ -458,14 +524,6 @@
458
524
  version: ''
459
525
 
460
526
 
461
- ##########
462
- # Haiku OS
463
- ##########
464
- - regex: 'Haiku'
465
- name: 'Haiku OS'
466
- version: ''
467
-
468
-
469
527
  ##########
470
528
  # BeOS
471
529
  ##########
@@ -1,15 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative '../spec_helper'
2
4
 
3
5
  describe DeviceDetector::MemoryCache do
4
-
5
6
  let(:subject) { DeviceDetector::MemoryCache.new(config) }
6
7
 
7
8
  let(:config) { {} }
8
9
 
9
10
  describe '#set' do
10
-
11
11
  describe 'string key' do
12
-
13
12
  let(:key) { 'string' }
14
13
 
15
14
  it 'sets the value under the key' do
@@ -18,26 +17,63 @@ describe DeviceDetector::MemoryCache do
18
17
  subject.data[key].must_equal 'value'
19
18
  end
20
19
 
20
+ it 'returns the value' do
21
+ subject.set(key, 'value').must_equal 'value'
22
+ subject.set(key, false).must_equal false
23
+ assert_nil subject.set(key, nil)
24
+ end
21
25
  end
22
26
 
23
27
  describe 'array key' do
24
-
25
- let(:key) { ['string1', 'string2'] }
28
+ let(:key) { %w[string1 string2] }
26
29
 
27
30
  it 'sets the value under the key' do
28
31
  subject.set(key, 'value')
29
32
 
30
33
  subject.data[String(key)].must_equal 'value'
31
34
  end
35
+ end
36
+
37
+ describe 'nil value' do
38
+ let(:key) { 'string' }
39
+ let(:internal_value) { DeviceDetector::MemoryCache::STORES_NIL_VALUE }
40
+
41
+ it 'sets the value under the key' do
42
+ subject.set(key, nil)
32
43
 
44
+ subject.data[String(key)].must_equal internal_value
45
+ assert_nil subject.get(key)
46
+ end
47
+
48
+ it 'sets the value under the key' do
49
+ subject.get_or_set(key, nil)
50
+
51
+ subject.data[String(key)].must_equal internal_value
52
+ assert_nil subject.get(key)
53
+ end
33
54
  end
34
55
 
56
+ describe 'false value' do
57
+ let(:key) { 'string' }
58
+
59
+ it 'sets the value under the key' do
60
+ subject.set(key, false)
61
+
62
+ subject.data[String(key)].must_equal false
63
+ subject.get(key).must_equal false
64
+ end
65
+
66
+ it 'sets the value under the key' do
67
+ subject.get_or_set(key, false)
68
+
69
+ subject.data[String(key)].must_equal false
70
+ subject.get(key).must_equal false
71
+ end
72
+ end
35
73
  end
36
74
 
37
75
  describe '#get' do
38
-
39
76
  describe 'string key' do
40
-
41
77
  let(:key) { 'string' }
42
78
 
43
79
  it 'gets the value for the key' do
@@ -45,29 +81,23 @@ describe DeviceDetector::MemoryCache do
45
81
 
46
82
  subject.get(key).must_equal 'value'
47
83
  end
48
-
49
84
  end
50
85
 
51
86
  describe 'array key' do
52
-
53
- let(:key) { ['string1', 'string2'] }
87
+ let(:key) { %w[string1 string2] }
54
88
 
55
89
  it 'gets the value for the key' do
56
90
  subject.data[String(key)] = 'value'
57
91
 
58
92
  subject.get(key).must_equal 'value'
59
93
  end
60
-
61
94
  end
62
-
63
95
  end
64
96
 
65
97
  describe '#get_or_set' do
66
-
67
98
  let(:key) { 'string' }
68
99
 
69
100
  describe 'value already present' do
70
-
71
101
  it 'gets the value for the key from cache' do
72
102
  subject.data[key] = 'value'
73
103
 
@@ -80,10 +110,13 @@ describe DeviceDetector::MemoryCache do
80
110
  block_called.must_equal false
81
111
  end
82
112
 
113
+ it 'returns the value' do
114
+ subject.data[key] = 'value2'
115
+ subject.get_or_set(key, 'value').must_equal 'value2'
116
+ end
83
117
  end
84
118
 
85
119
  describe 'value not yet present' do
86
-
87
120
  it 'evaluates the block and sets the result' do
88
121
  block_called = false
89
122
  subject.get_or_set(key) do
@@ -94,12 +127,13 @@ describe DeviceDetector::MemoryCache do
94
127
  subject.data[key].must_equal true
95
128
  end
96
129
 
130
+ it 'returns the value' do
131
+ subject.get_or_set(key, 'value').must_equal 'value'
132
+ end
97
133
  end
98
-
99
134
  end
100
135
 
101
136
  describe 'cache purging' do
102
-
103
137
  let(:config) { { max_cache_keys: 3 } }
104
138
 
105
139
  it 'purges the cache when key size arrives at max' do
@@ -110,7 +144,5 @@ describe DeviceDetector::MemoryCache do
110
144
 
111
145
  subject.data.keys.size.must_equal 3
112
146
  end
113
-
114
147
  end
115
-
116
148
  end
@@ -1,218 +1,189 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative 'spec_helper'
2
4
 
3
5
  describe DeviceDetector do
4
-
5
6
  subject { DeviceDetector.new(user_agent) }
6
7
 
7
- alias :client :subject
8
+ alias_method :client, :subject
8
9
 
9
10
  describe 'known user agent' do
10
-
11
11
  describe 'desktop chrome browser' do
12
-
13
12
  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' }
14
13
 
15
14
  describe '#name' do
16
-
17
15
  it 'returns the name' do
18
16
  client.name.must_equal 'Chrome'
19
17
  end
20
-
21
18
  end
22
19
 
23
20
  describe '#full_version' do
24
-
25
21
  it 'returns the full version' do
26
22
  client.full_version.must_equal '30.0.1599.69'
27
23
  end
24
+ end
28
25
 
26
+ describe '#os_family' do
27
+ it 'returns the operating system name' do
28
+ client.os_family.must_equal 'Mac'
29
+ end
29
30
  end
30
31
 
31
32
  describe '#os_name' do
32
-
33
33
  it 'returns the operating system name' do
34
34
  client.os_name.must_equal 'Mac'
35
35
  end
36
-
37
36
  end
38
37
 
39
38
  describe '#os_full_version' do
40
-
41
39
  it 'returns the operating system full version' do
42
40
  client.os_full_version.must_equal '10.8.5'
43
41
  end
44
-
45
42
  end
46
43
 
47
44
  describe '#known?' do
48
-
49
45
  it 'returns true' do
50
46
  client.known?.must_equal true
51
47
  end
52
-
53
48
  end
54
49
 
55
50
  describe '#bot?' do
56
-
57
51
  it 'returns false' do
58
52
  client.bot?.must_equal false
59
53
  end
60
-
61
54
  end
62
55
 
63
56
  describe '#bot_name' do
64
-
65
57
  it 'returns nil' do
66
58
  client.bot_name.must_be_nil
67
59
  end
60
+ end
61
+ end
68
62
 
63
+ describe 'ubuntu linux' do
64
+ let(:user_agent) do
65
+ 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36'
66
+ end
67
+
68
+ describe '#os_family' do
69
+ it 'returns the operating system name' do
70
+ client.os_family.must_equal 'GNU/Linux'
71
+ end
69
72
  end
70
73
 
74
+ describe '#os_name' do
75
+ it 'returns the operating system name' do
76
+ client.os_name.must_equal 'Ubuntu'
77
+ end
78
+ end
71
79
  end
72
80
 
73
81
  describe 'firefox mobile phone' do
74
-
75
- let(:user_agent) {'Mozilla/5.0 (Android 7.0; Mobile; rv:53.0) Gecko/53.0 Firefox/53.0'}
82
+ let(:user_agent) { 'Mozilla/5.0 (Android 7.0; Mobile; rv:53.0) Gecko/53.0 Firefox/53.0' }
76
83
 
77
84
  it 'detects smartphone' do
78
85
  client.device_type.must_equal 'smartphone'
79
86
  end
80
-
81
87
  end
82
88
 
83
89
  describe 'firefox mobile tablet' do
84
-
85
- let(:user_agent) {'Mozilla/5.0 (Android 6.0.1; Tablet; rv:47.0) Gecko/47.0 Firefox/47.0'}
90
+ let(:user_agent) { 'Mozilla/5.0 (Android 6.0.1; Tablet; rv:47.0) Gecko/47.0 Firefox/47.0' }
86
91
 
87
92
  it 'detects tablet' do
88
93
  client.device_type.must_equal 'tablet'
89
94
  end
90
-
91
95
  end
92
-
93
96
  end
94
97
 
95
98
  describe 'unknown user agent' do
96
-
97
99
  let(:user_agent) { 'garbage123' }
98
100
 
99
101
  describe '#name' do
100
-
101
102
  it 'returns nil' do
102
103
  client.name.must_be_nil
103
104
  end
104
-
105
105
  end
106
106
 
107
107
  describe '#full_version' do
108
-
109
108
  it 'returns nil' do
110
109
  client.full_version.must_be_nil
111
110
  end
112
-
113
111
  end
114
112
 
115
113
  describe '#os_name' do
116
-
117
114
  it 'returns nil' do
118
115
  client.os_name.must_be_nil
119
116
  end
120
-
121
117
  end
122
118
 
123
119
  describe '#os_full_version' do
124
-
125
120
  it 'returns nil' do
126
121
  client.os_full_version.must_be_nil
127
122
  end
128
-
129
123
  end
130
124
 
131
125
  describe '#known?' do
132
-
133
126
  it 'returns false' do
134
127
  client.known?.must_equal false
135
128
  end
136
-
137
129
  end
138
130
 
139
131
  describe '#bot?' do
140
-
141
132
  it 'returns false' do
142
133
  client.bot?.must_equal false
143
134
  end
144
-
145
135
  end
146
136
 
147
137
  describe '#bot_name' do
148
-
149
138
  it 'returns nil' do
150
139
  client.bot_name.must_be_nil
151
140
  end
152
-
153
141
  end
154
-
155
142
  end
156
143
 
157
144
  describe 'bot' do
158
-
159
145
  let(:user_agent) { 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)' }
160
146
 
161
147
  describe '#name' do
162
-
163
148
  it 'returns nil' do
164
149
  client.name.must_be_nil
165
150
  end
166
-
167
151
  end
168
152
 
169
153
  describe '#full_version' do
170
-
171
154
  it 'returns nil' do
172
155
  client.full_version.must_be_nil
173
156
  end
174
-
175
157
  end
176
158
 
177
159
  describe '#os_name' do
178
-
179
160
  it 'returns nil' do
180
161
  client.os_name.must_be_nil
181
162
  end
182
-
183
163
  end
184
164
 
185
165
  describe '#os_full_version' do
186
-
187
166
  it 'returns nil' do
188
167
  client.os_full_version.must_be_nil
189
168
  end
190
-
191
169
  end
192
170
 
193
171
  describe '#known?' do
194
-
195
172
  it 'returns false' do
196
173
  client.known?.must_equal false
197
174
  end
198
-
199
175
  end
200
176
 
201
177
  describe '#bot?' do
202
-
203
178
  it 'returns true' do
204
179
  client.bot?.must_equal true
205
180
  end
206
-
207
181
  end
208
182
 
209
183
  describe '#bot_name' do
210
-
211
184
  it 'returns the name of the bot' do
212
185
  client.bot_name.must_equal 'Googlebot'
213
186
  end
214
-
215
187
  end
216
-
217
188
  end
218
189
  end