browserino 4.0.0 → 4.1.0

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.
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Browserino
3
- class Identity
4
+ class Matcher
4
5
  attr_reader :pattern, :properties
5
6
 
6
7
  SETTINGS = { name: nil, type: :unknown }.freeze
@@ -14,7 +15,11 @@ module Browserino
14
15
  end
15
16
 
16
17
  def matches?(user_agent)
17
- pattern =~ user_agent if pattern.is_a? Regexp
18
+ pattern =~ user_agent
19
+ end
20
+
21
+ def =~(other)
22
+ pattern =~ other
18
23
  end
19
24
 
20
25
  def ===(other)
@@ -24,7 +29,7 @@ module Browserino
24
29
  when Regexp then other =~ properties[:name]
25
30
  when String then other.to_sym == properties[:name]
26
31
  when Symbol then other == properties[:name]
27
- when Identity then other.properties[:name] == properties[:name]
32
+ when Matcher then other.properties[:name] == properties[:name]
28
33
  else false
29
34
  end
30
35
  end
@@ -33,17 +38,13 @@ module Browserino
33
38
  properties[:name].to_s
34
39
  end
35
40
 
36
- def =~(other)
37
- self === other
38
- end
39
-
40
41
  def ==(other)
41
42
  self === other
42
43
  end
43
44
 
44
45
  def method_missing(sym, *args, &block)
45
- return @properties[sym] = block if block
46
46
  return @properties[sym] = args.shift if args.any?
47
+ return @properties[sym] = block if block
47
48
 
48
49
  @properties[sym]
49
50
  end
@@ -1,35 +1,39 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Browserino
3
- def self.analyze(user_agent, identity = nil)
4
- props = [*config.global_identities, identity].compact.map(&:properties)
5
- .reduce(&:merge)
6
- like = props.delete :like if props.key? :like
7
- props = collect(props, user_agent)
8
- props = normalize props
9
- props = with_smart_matchers props
10
- left = props.select { |_, val| val.is_a? Regexp }
11
- props = props.merge normalize(collect(left, user_agent)) if left.any?
12
- props = with_labels props
13
-
14
- if like
15
- repl = user_agent =~ %r{#{like}}i && '' || like.to_s
16
- like = parse user_agent.gsub identity.pattern, repl
17
- end
4
+ def self.analyze(ua, matcher = nil)
5
+ @defaults ||= config.global_matchers.map(&:properties).reduce(&:merge)
6
+
7
+ props = @defaults.merge(matcher && matcher.properties || {})
8
+ like = props.delete :like
9
+ props = collect props, ua
10
+ props = collect_with_smart_watchers props, ua
11
+ props = with_labels props
12
+ like = Client.new props.merge(like_attrs(props, like, ua)) if like
18
13
 
19
14
  Client.new props, like
20
15
  end
21
16
 
17
+ def self.like_attrs(props, like, user_agent)
18
+ lattrs = config.matchers.select { |m| m == like }.first.properties
19
+ fattrs = { name: like }
20
+ fattrs[:version] = lattrs[:version] if lattrs[:version].is_a? Regexp
21
+ fattrs[:version] ||= smart_matchers(fattrs)[:version]
22
+
23
+ props.dup.merge collect(fattrs, user_agent)
24
+ end
25
+
22
26
  def self.config
23
- @config ||= Config.new({ before_parse: [],
24
- global_identities: [],
25
- properties: [],
26
- types: [:unknown],
27
- names: [],
28
- smart_matchers: {},
29
- identities: [],
30
- labels: Hash.new { |h, k| h[k] = [] },
31
- filters: Hash.new { |h, k| h[k] = [] },
32
- aliasses: Hash.new { |h, k| h[k] = [] } })
27
+ @config ||= Config.new(before_parse: [],
28
+ global_matchers: [],
29
+ properties: [],
30
+ types: [:unknown],
31
+ names: [],
32
+ smart_matchers: {},
33
+ matchers: [],
34
+ labels: Hash.new { |h, k| h[k] = [] },
35
+ filters: Hash.new { |h, k| h[k] = [] },
36
+ aliasses: Hash.new { |h, k| h[k] = [] })
33
37
  end
34
38
 
35
39
  def self.label_for(target_name, version = nil)
@@ -37,16 +41,13 @@ module Browserino
37
41
  version = Version.new version unless version.is_a? Version
38
42
  return unless version > 0
39
43
  config.labels[target_name].each do |candidate|
40
- min = Version.new candidate[:range].min
41
- max = Version.new candidate[:range].max
42
-
43
- return candidate[:name] if version >= min && version <= max
44
+ return candidate[:name] if version.between? candidate[:range]
44
45
  end
45
46
  nil
46
47
  end
47
48
 
48
49
  def self.with_labels(properties)
49
- [:name, :engine, :platform].each do |prop|
50
+ %i[name engine platform].each do |prop|
50
51
  lbl_prop = (prop == :name) && :label || "#{prop}_label".to_sym
51
52
  ver_prop = (prop == :name) && :version || "#{prop}_version".to_sym
52
53
  properties[lbl_prop] ||= label_for properties[prop], properties[ver_prop]
@@ -55,9 +56,14 @@ module Browserino
55
56
  properties
56
57
  end
57
58
 
58
- def self.with_smart_matchers(properties)
59
- config.smart_matchers.each_with_object properties do |(prop, detector), props|
60
- props[prop] ||= parse_detector detector, properties
59
+ def self.collect_with_smart_watchers(properties, user_agent)
60
+ properties.merge collect(smart_matchers(properties), user_agent)
61
+ end
62
+
63
+ def self.smart_matchers(properties)
64
+ config.smart_matchers.each_with_object({}) do |(prop, detector), props|
65
+ next if properties.key? prop
66
+ props[prop] = parse_detector detector, properties
61
67
  end
62
68
  end
63
69
 
@@ -71,23 +77,14 @@ module Browserino
71
77
  end
72
78
 
73
79
  def self.collect(properties, ua)
74
- properties.each_with_object({}) do |(prop, value), res|
75
- res[prop] = case value
76
- when Regexp then value.match(ua).to_a[1]
77
- else value
78
- end
79
- end
80
- end
81
-
82
- def self.normalize(properties)
83
- properties.each_with_object({}) do |(prop, value), store|
84
- store[prop] = convert value, format: prop
80
+ properties.each_with_object({}) do |(n, v), r|
81
+ r[n] = convert (v.is_a?(Regexp) ? v.match(ua).to_a[1] : v), format: n
85
82
  end
86
83
  end
87
84
 
88
85
  def self.convert(val, **opts)
89
86
  filters = config.filters[:global] + config.filters[opts[:format]]
90
- filters.compact.each do |fmt|
87
+ filters.each do |fmt|
91
88
  val = fmt.call val
92
89
  end
93
90
 
@@ -1,16 +1,17 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Browserino
3
4
  class Options
4
5
  def initialize(options = {})
5
6
  @options = options
6
7
  end
7
8
 
8
- def method_missing(sym, *args, &block)
9
+ def method_missing(sym, *args, &___)
9
10
  return @options[opt(sym)] == args.first if args.any?
10
11
  @options[opt(sym)]
11
12
  end
12
13
 
13
- def respond_to_missing?(sym, *args, &block)
14
+ def respond_to_missing?(sym, *_, &___)
14
15
  option? sym
15
16
  end
16
17
 
@@ -1,9 +1,10 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  module Browserino
3
- VERSION = '4.0.0'.freeze
4
+ VERSION = '4.1.0'.freeze
4
5
 
5
6
  def self.version
6
- @verion ||= Version.new VERSION.dup
7
+ @version ||= Version.new VERSION.dup
7
8
  end
8
9
 
9
10
  # This class makes versions easily comparable using logical operators
@@ -50,11 +51,19 @@ module Browserino
50
51
  compare :!=, other
51
52
  end
52
53
 
54
+ def between?(min, max = nil)
55
+ if min.is_a? Range
56
+ max = min.max
57
+ min = min.min
58
+ end
59
+
60
+ (self >= Version.new(min)) && (self <= Version.new(max))
61
+ end
62
+
53
63
  private
54
64
 
55
65
  def parse_params(val, *rest)
56
66
  case val
57
- when Float then val.to_s.split '.'
58
67
  when Integer then [val, *rest]
59
68
  when String then val.tr('_', '.').split '.'
60
69
  when Array then val
data/lib/browserino.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  require_relative 'browserino/integrate/rails' if defined?(::Rails)
3
4
 
4
5
  require_relative 'browserino/options'
@@ -6,7 +7,7 @@ require_relative 'browserino/config'
6
7
  require_relative 'browserino/methods'
7
8
  require_relative 'browserino/client'
8
9
  require_relative 'browserino/version'
9
- require_relative 'browserino/identity'
10
+ require_relative 'browserino/matcher'
10
11
 
11
12
  require_relative 'browserino/definitions/matchers'
12
13
  require_relative 'browserino/definitions/aliasses'
@@ -16,10 +17,9 @@ require_relative 'browserino/definitions/labels'
16
17
  module Browserino
17
18
  def self.parse(ua)
18
19
  config.before_parse.each { |b| ua = b.call ua } if config.before_parse.any?
19
- config.identities.each do |identity|
20
- return analyze ua, identity if identity.matches? ua
20
+ config.matchers.each do |matcher|
21
+ return analyze ua, matcher if matcher.matches? ua
21
22
  end
22
-
23
23
  analyze ua
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: browserino
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.0.0
4
+ version: 4.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sidney Liebrand
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-04-23 00:00:00.000000000 Z
11
+ date: 2017-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -52,6 +52,20 @@ dependencies:
52
52
  - - ">="
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rubocop
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
55
69
  - !ruby/object:Gem::Dependency
56
70
  name: coveralls
57
71
  requirement: !ruby/object:Gem::Requirement
@@ -109,9 +123,9 @@ files:
109
123
  - lib/browserino/definitions/filters.rb
110
124
  - lib/browserino/definitions/labels.rb
111
125
  - lib/browserino/definitions/matchers.rb
112
- - lib/browserino/identity.rb
113
126
  - lib/browserino/integrate/action_controller.rb
114
127
  - lib/browserino/integrate/rails.rb
128
+ - lib/browserino/matcher.rb
115
129
  - lib/browserino/methods.rb
116
130
  - lib/browserino/options.rb
117
131
  - lib/browserino/version.rb