module Browser

def self.[](key)

def self.[](key)
  user_agents.fetch(key)
end

def self.bot_user_agents

def self.bot_user_agents
  @bot_user_agents ||= YAML.load_file(Browser.root.join("test/ua_bots.yml"))
end

def self.browser_user_agents

def self.browser_user_agents
  @browser_user_agents ||= YAML.load_file(Browser.root.join("test/ua.yml"))
end

def self.matchers

Order is important.
Hold the list of browser matchers.
def self.matchers
  @matchers ||= [
    Nokia,
    UCBrowser,
    PhantomJS,
    BlackBerry,
    Opera,
    Edge,
    InternetExplorer,
    Firefox,
    Weibo,                # must be placed before Chrome and Safari
    Chrome,
    Safari,
    MicroMessenger,
    Generic
  ]
end

def self.modern_rules


Browser.modern_rules << -> b { b.chrome? && b.version >= "37" }
Browser.modern_rules.clear
# Only Chrome Canary is considered modern.

To redefine all rules, clear the existing rules before adding your own.

=== and accepts the browser object.
A rule must be a proc/lambda or any object that implements the method
Define the rules which define a modern browser.
def self.modern_rules
  @modern_rules ||= []
end

def self.new(user_agent, **kwargs)

def self.new(user_agent, **kwargs)
  matchers
    .map {|klass| klass.new(user_agent || EMPTY_STRING, **kwargs) }
    .find(&:match?)
end

def self.root

def self.root
  @root ||= Pathname.new(File.expand_path("../..", __FILE__))
end

def self.search_engine_user_agents

def self.search_engine_user_agents
  @search_engine_user_agents ||= YAML.load_file(Browser.root.join("test/ua_search_engines.yml"))
end

def self.user_agents

def self.user_agents
  @user_agents ||= browser_user_agents
                   .merge(bot_user_agents)
                   .merge(search_engine_user_agents)
end