mobvious 0.1.0.pre

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,5 @@
1
+ /.bundle
2
+ /.yardoc
3
+ /doc
4
+ /Gemfile.lock
5
+ /vendor/ruby
@@ -0,0 +1 @@
1
+ -m markdown
data/Gemfile ADDED
@@ -0,0 +1,13 @@
1
+ source :rubygems
2
+
3
+ gemspec
4
+
5
+
6
+ gem 'mobileesp', git: 'git://github.com/jistr/mobileesp'
7
+
8
+ # == SPECIAL DEVELOPMENT DEPS HANDLING ==
9
+
10
+ # temporarily switched for this fork, because the current version of guard-minitest has broken notifications
11
+ gem 'guard-minitest', git: 'git://github.com/aspiers/guard-minitest', ref: '4b660261d35'
12
+ gem 'mocha', require: false
13
+ gem 'turn', require: false
@@ -0,0 +1,5 @@
1
+ guard 'minitest' do
2
+ watch(%r|^spec/(.*)_spec\.rb|)
3
+ watch(%r|^lib/(.*)\.rb|) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch(%r|^spec/spec_helper\.rb|) { "spec" }
5
+ end
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,21 @@
1
+ require "mobvious/version"
2
+
3
+ require "mobvious/config"
4
+ require "mobvious/manager"
5
+
6
+ # A library (Rack middleware) to detect device types (mobile, tablet, desktop etc.)
7
+ # from requests.
8
+ #
9
+ # See {Mobvious::Manager} for the actual Rack middleware.
10
+ #
11
+ # See {Mobvious::Config} for configuration options (and set them via calling
12
+ # {Mobvious.config Mobvious.config}).
13
+ #
14
+ # See {Mobvious::Strategies} for predefined strategies or roll out your own.
15
+ module Mobvious
16
+ # An accessor for the global Mobvious configuration object.
17
+ # See {Config} for configuration options.
18
+ def self.config
19
+ @config ||= Mobvious::Config.new
20
+ end
21
+ end
@@ -0,0 +1,26 @@
1
+ module Mobvious
2
+ # Class encapsulating Mobvious configuration.
3
+ #
4
+ # Set configuration options them via calling {Mobvious.config Mobvious.config}.
5
+ class Config
6
+ # Creates a new configuration with no strategies and default device type `:desktop`.
7
+ def initialize()
8
+ self.clear
9
+ end
10
+
11
+ # Resets a configuration to no strategies and default device type `:desktop`.
12
+ def clear
13
+ @strategies = []
14
+ @default_device_type = :desktop
15
+ end
16
+
17
+ # Strategies used to determine device type from a request. They are evaluated
18
+ # in the order they are inserted. Result of the first successful strategy
19
+ # (returning something else than nil) is used.
20
+ attr_accessor :strategies
21
+
22
+ # Default device type is used when no strategy was successful (all return nil
23
+ # or none is present).
24
+ attr_accessor :default_device_type
25
+ end
26
+ end
@@ -0,0 +1,57 @@
1
+ require 'rack'
2
+
3
+ module Mobvious
4
+ # Rack middleware that enables device type detection for requests.
5
+ #
6
+ # Use `Mobvious.config` to set which strategies to use.
7
+ #
8
+ # Look into `Mobvious::Strategies` for predefined strategies or write your own.
9
+ class Manager
10
+ # Create a new instance of this rack middleware.
11
+ #
12
+ # @param app Rack application that can be called.
13
+ def initialize(app)
14
+ @app = app
15
+ end
16
+
17
+ # Perform the device type detection and call the inner Rack application.
18
+ #
19
+ # @param env Rack environment.
20
+ # @return rack response `[status, headers, body]`
21
+ def call(env)
22
+ request = Rack::Request.new(env)
23
+ assign_device_type(request)
24
+
25
+ status, headers, body = @app.call(env)
26
+
27
+ response = Rack::Response.new(body, status, headers)
28
+ response_callback(request, response)
29
+
30
+ [status, headers, body]
31
+ end
32
+
33
+ private
34
+ def assign_device_type(request)
35
+ request.env['mobvious.device_type'] =
36
+ get_device_type_using_strategies(request) || config.default_device_type
37
+ end
38
+
39
+ def response_callback(request, response)
40
+ config.strategies.each do |strategy|
41
+ strategy.response_callback(request, response) if strategy.respond_to? :response_callback
42
+ end
43
+ end
44
+
45
+ def get_device_type_using_strategies(request)
46
+ config.strategies.each do |strategy|
47
+ result = strategy.get_device_type(request)
48
+ return result.to_sym if result
49
+ end
50
+ nil
51
+ end
52
+
53
+ def config
54
+ Mobvious.config
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,55 @@
1
+ module Mobvious
2
+ module Strategies
3
+ # Mobvious device detection strategy that saves and loads a cookie that precisely
4
+ # specifies which device type should be used for current client.
5
+ #
6
+ # Usually, you will want to set the device type via cookie only when you are absolutely
7
+ # sure that user wants it this way (e.g. after manual switch between mobile/desktop
8
+ # interface versions performed by user). Also make sure to use this strategy with high
9
+ # priority, (e.g. put it before user-agent based detection) so it does not get overriden.
10
+ #
11
+ # Use `set_device_type_cookie` method to set the device type and the strategy will then
12
+ # recognize it on subsequent requests.
13
+ class Cookie
14
+ # Creates a new Cookie strategy instance.
15
+ #
16
+ # @param cookie_expires [Integer]
17
+ # Amount of seconds to hold device type cookie. Defaults to one year (365*24*60*60).
18
+ def initialize(cookie_expires = (365*24*60*60))
19
+ @cookie_expires = cookie_expires
20
+ end
21
+
22
+ # Gets device type using a pre-set cookie. Returns nil if the cookie is not set.
23
+ #
24
+ # @param request [Rack::Request]
25
+ # @return [Symbol] device type or nil
26
+ def get_device_type(request)
27
+ request.cookies['mobvious.device_type'].to_sym if request.cookies['mobvious.device_type']
28
+ end
29
+
30
+ # Automatically sets the device type cookie again to prolong its expiration date.
31
+ #
32
+ # @param request [Rack::Request]
33
+ # @param response [Rack::Response]
34
+ def response_callback(request, response)
35
+ response_cookie_already_set = !!response.headers["Set-Cookie"] &&
36
+ !!response.headers["Set-Cookie"]["mobvious.device_type"]
37
+ request_cookie = request.cookies['mobvious.device_type']
38
+
39
+ # re-set the cookie to renew the expiration date
40
+ if request_cookie && !response_cookie_already_set
41
+ set_device_type_cookie(response, request_cookie)
42
+ end
43
+ end
44
+
45
+ # Sets the device type cookie.
46
+ #
47
+ # @param response [Rack::Response]
48
+ # @param device_type [Symbol] A device type symbol (or string).
49
+ def set_device_type_cookie(response, device_type)
50
+ response.set_cookie('mobvious.device_type',
51
+ { value: device_type.to_s, path: '/', expires: Time.now + @cookie_expires })
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,43 @@
1
+ require 'mobileesp'
2
+
3
+ module Mobvious
4
+ module Strategies
5
+ # Mobvious device detection strategy that uses user-agent sniffing provided by
6
+ # the MobileESP library.
7
+ class Mobileesp
8
+ # Detection procedure that classifies mobile phones as `:mobile` and anything
9
+ # else as `:desktop`.
10
+ DEVICE_TYPES_MOBILE_DESKTOP = lambda {|mobileesp|
11
+ return :mobile if mobileesp.is_tier_generic_mobile || mobileesp.is_tier_iphone
12
+ return :desktop
13
+ }
14
+
15
+ # Detection procedure that classifies mobile phones as `:mobile`, tablets as
16
+ # `:tablet` and anything else as `:desktop`.
17
+ DEVICE_TYPES_MOBILE_TABLET_DESKTOP = lambda {|mobileesp|
18
+ return :mobile if mobileesp.is_tier_generic_mobile || mobileesp.is_tier_iphone
19
+ return :tablet if mobileesp.is_tier_tablet
20
+ return :desktop
21
+ }
22
+
23
+ # Creates a new instance of MobileESP strategy.
24
+ #
25
+ # @param detection_procedure
26
+ # A lambda function that gets one parameter (`MobileESP::UserAgentInfo` instance)
27
+ # and returns device type symbol or nil.
28
+ def initialize(detection_procedure = DEVICE_TYPES_MOBILE_DESKTOP)
29
+ @detection_procedure = detection_procedure
30
+ end
31
+
32
+ # Gets device type using user-agent sniffing. Can return nil if the used
33
+ # detection procedure does so.
34
+ #
35
+ # @param request [Rack::Request]
36
+ # @return [Symbol] device type or nil
37
+ def get_device_type(request)
38
+ mobileesp = MobileESP::UserAgentInfo.new(request.user_agent, request.accept)
39
+ @detection_procedure.call(mobileesp)
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,30 @@
1
+ module Mobvious
2
+ module Strategies
3
+ # Mobvious device detection strategy that uses URL pattern matching.
4
+ class URL
5
+ # Rule set with only one rule for domains that begin with `m.` matching as `:mobile`.
6
+ MOBILE_PATH_RULES = { /^\w+:\/\/m\./ => :mobile }
7
+
8
+ # Creates a new URL strategy instance.
9
+ #
10
+ # @param rules
11
+ # A hash containing regular expressions mapped to symbols. The regular expression
12
+ # is evaluated against the whole URL of the request (including `http://`). If matching,
13
+ # the corresponding symbol is returned as the device type.
14
+ def initialize(rules = MOBILE_PATH_RULE)
15
+ @rules = rules
16
+ end
17
+
18
+ # Gets device type using URL pattern matching. Returns nil if no match found.
19
+ #
20
+ # @param request [Rack::Request]
21
+ # @return [Symbol] device type or nil
22
+ def get_device_type(request)
23
+ @rules.each do |regex, device_type|
24
+ return device_type if request.url =~ regex
25
+ end
26
+ nil
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,3 @@
1
+ module Mobvious
2
+ VERSION = "0.1.0.pre"
3
+ end
@@ -0,0 +1,42 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "mobvious/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "mobvious"
7
+ s.version = Mobvious::VERSION
8
+ s.authors = ["Jiří Stránský"]
9
+ s.email = ["jistr@jistr.com"]
10
+ s.homepage = "http://github.com/jistr/mobvious"
11
+ s.summary = %q{Rack middleware for choosing a version of an interface to render for given request}
12
+ s.description = %q{Rack middleware for choosing a version of an interface to render for given request}
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_runtime_dependency "rack", ">= 1.2.0"
20
+ s.add_runtime_dependency "mobileesp"
21
+
22
+
23
+ # == DEVELOPMENT DEPENDENCIES ==
24
+ # Smart irb
25
+ s.add_development_dependency 'pry'
26
+
27
+ # Specs
28
+ s.add_development_dependency 'minitest'
29
+ s.add_development_dependency 'mocha'
30
+ s.add_development_dependency 'rack-test'
31
+
32
+ # Running tests during development
33
+ s.add_development_dependency 'guard'
34
+ s.add_development_dependency 'guard-minitest'
35
+ # Linux Guard watching
36
+ s.add_development_dependency 'rb-inotify'
37
+ # Linux Guard notifications
38
+ s.add_development_dependency 'libnotify'
39
+
40
+ # Pretty printed test output
41
+ s.add_development_dependency 'turn'
42
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ module Mobvious
4
+ class ManagerSpec < MiniTest::Spec
5
+ describe Manager do
6
+ before do
7
+ @app = mock 'app'
8
+ @env = mock 'env'
9
+ @manager = Mobvious::Manager.new(@app)
10
+ @return_value = [200, ['My-Header'], ['body_part_1']]
11
+
12
+ @app.stubs(:call).with(@env).returns(@return_value)
13
+ end
14
+
15
+ after do
16
+ Mobvious.config.clear
17
+ end
18
+
19
+ it "calls the app and returns what app returns" do
20
+ @env.stub_everything
21
+ @app.expects(:call).with(@env).returns(@return_value)
22
+ @manager.call(@env).must_equal @return_value
23
+ end
24
+
25
+ describe "having strategies" do
26
+ before do
27
+ @strategy1 = mock 'strategy1'
28
+ @strategy2 = mock 'strategy2'
29
+ @strategy3 = mock 'strategy3'
30
+ Mobvious.config.strategies << @strategy1
31
+ Mobvious.config.strategies << @strategy2
32
+ Mobvious.config.strategies << @strategy3
33
+ end
34
+
35
+ it "uses the result of the first successful strategy" do
36
+ @app.stub_everything
37
+ @app.expects(:call).with(@env).returns(@return_value)
38
+ @strategy1.expects(:get_device_type).returns(nil)
39
+ @strategy2.expects(:get_device_type).returns(:strategy_2_result)
40
+ @env.expects('[]=').with('mobvious.device_type', :strategy_2_result)
41
+ @manager.call(@env)
42
+ end
43
+
44
+ it "calls strategies with a request object" do
45
+ @app.stub_everything
46
+ @env.stub_everything
47
+ @strategy1.expects(:get_device_type).returns(:result).with() {|param|
48
+ param.must_be_instance_of Rack::Request
49
+ (param.env == @env).must_equal true
50
+ }
51
+ @manager.call(@env)
52
+ end
53
+
54
+ it "uses default value if no strategy is successful" do
55
+ @app.stub_everything
56
+ @strategy1.stub_everything
57
+ @strategy2.stub_everything
58
+ @strategy3.stub_everything
59
+ Mobvious.config.default_device_type = :test_default_type
60
+ @env.expects('[]=').with('mobvious.device_type', :test_default_type)
61
+ @manager.call(@env)
62
+ end
63
+
64
+ it "calls the response callback on strategies that have it defined" do
65
+ @env.stub_everything
66
+ @strategy1.stubs(:get_device_type)
67
+ @strategy1.stubs(:respond_to?).with(:response_callback).returns(true)
68
+ @strategy1.expects(:response_callback).with() {|request, response|
69
+ request.must_be_instance_of Rack::Request
70
+ (request.env == @env).must_equal true
71
+ response.must_be_instance_of Rack::Response
72
+ response.body.must_equal @return_value[2]
73
+ }
74
+
75
+ @strategy2.stub_everything
76
+ @strategy3.stub_everything
77
+ @manager.call(@env)
78
+ end
79
+ end
80
+
81
+ describe "not having strategies" do
82
+ it "uses default value" do
83
+ @app.stub_everything
84
+ Mobvious.config.default_device_type = :test_default_type
85
+ @env.expects('[]=').with('mobvious.device_type', :test_default_type)
86
+ @manager.call(@env)
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+ require 'mobvious/strategies/cookie'
3
+
4
+ module Mobvious::Strategies
5
+ class CookieSpec < MiniTest::Spec
6
+ describe Cookie do
7
+ before do
8
+ @strategy = Cookie.new
9
+ @app = mock 'app'
10
+ @uri = URI("http://foo.com/")
11
+
12
+ @env = Rack::MockRequest::DEFAULT_ENV
13
+ @request = Rack::Request.new(@env)
14
+ @response = Rack::Response.new(['body'], 200, {})
15
+
16
+ @mock_session = Rack::MockSession.new(@app)
17
+ @mock_session.after_request do
18
+ @strategy.response_callback(@request, @response)
19
+ end
20
+ end
21
+
22
+ describe "with no device type cookie set" do
23
+ it "returns nil as device type" do
24
+ @strategy.get_device_type(@request).must_equal nil
25
+ end
26
+
27
+ describe "when device type set during the app execution" do
28
+ it "sets the cookie on response" do
29
+ @app.expects(:call).returns([@response.status, @response.headers, @response.body])
30
+ .with do |env|
31
+ @strategy.set_device_type_cookie(@response, :tablet)
32
+ true
33
+ end
34
+ @mock_session.request @uri, @env
35
+ cookies = Mobvious::CookieParser.new(@response.headers['Set-Cookie'])
36
+ cookies['mobvious.device_type']['value'].must_equal 'tablet'
37
+ end
38
+ end
39
+ end
40
+
41
+ describe "with set device type cookie" do
42
+ before do
43
+ @request = Rack::Request.new(@env)
44
+ @request.cookies['mobvious.device_type'] = 'tablet'
45
+ end
46
+
47
+ it "gets device type from cookie" do
48
+ @app.expects(:call).returns([@response.status, @response.headers, @response.body])
49
+ .with do |env|
50
+ @strategy.get_device_type(@request).must_equal :tablet
51
+ true
52
+ end
53
+ mock_response = @mock_session.request @uri, @env
54
+ end
55
+
56
+ it "refreshes the cookie expiration date with every request" do
57
+ @app.expects(:call).returns([@response.status, @response.headers, @response.body])
58
+ mock_response = @mock_session.request @uri, @env
59
+ cookies = Mobvious::CookieParser.new(@response.headers['Set-Cookie'])
60
+ cookies['mobvious.device_type'].wont_be_nil
61
+ cookies['mobvious.device_type']['value'].must_equal 'tablet'
62
+ cookies['mobvious.device_type']['expires'].wont_be_nil
63
+ end
64
+
65
+ describe "when device type set during the app execution" do
66
+ it "sets the response cookie to the new value, not the old one" do
67
+ @app.expects(:call).returns([@response.status, @response.headers, @response.body])
68
+ .with do |env|
69
+ @strategy.set_device_type_cookie(@response, :mobile)
70
+ true
71
+ end
72
+ @mock_session.request @uri, @env
73
+ cookies = Mobvious::CookieParser.new(@response.headers['Set-Cookie'])
74
+ cookies['mobvious.device_type'].wont_be_nil
75
+ cookies['mobvious.device_type']['value'].must_equal 'mobile'
76
+ cookies['mobvious.device_type']['expires'].wont_be_nil
77
+ end
78
+ end
79
+ end
80
+ end
81
+ end
82
+ end
83
+
@@ -0,0 +1,56 @@
1
+ require 'spec_helper'
2
+ require 'mobvious/strategies/mobileesp'
3
+
4
+ module Mobvious::Strategies
5
+ class MobileespSpec < MiniTest::Spec
6
+ describe Mobileesp do
7
+ describe "using mobile_desktop strategy" do
8
+ before do
9
+ @strategy = Mobvious::Strategies::Mobileesp.new
10
+ @request = mock 'request'
11
+ @request.stubs(:accept).returns('text/html')
12
+ end
13
+
14
+ it "categorizes iPhone as :mobile" do
15
+ @request.stubs(:user_agent).returns("Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7")
16
+ @strategy.get_device_type(@request).must_equal :mobile
17
+ end
18
+
19
+ it "categorizes Android tablet as :desktop" do
20
+ @request.stubs(:user_agent).returns("Mozilla/5.0 (Linux; U; Android 3.0; xx-xx; Xoom Build/HRI39) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2")
21
+ @strategy.get_device_type(@request).must_equal :desktop
22
+ end
23
+
24
+ it "categorizes Chrome on Linux as :desktop" do
25
+ @request.stubs(:user_agent).returns("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.46 Safari/535.11")
26
+ @strategy.get_device_type(@request).must_equal :desktop
27
+ end
28
+ end
29
+
30
+ describe "using mobile_tablet_desktop strategy" do
31
+ before do
32
+ @strategy = Mobvious::Strategies::Mobileesp.new(
33
+ Mobvious::Strategies::Mobileesp::DEVICE_TYPES_MOBILE_TABLET_DESKTOP)
34
+ @request = mock 'request'
35
+ @request.stubs(:accept).returns('text/html')
36
+ end
37
+
38
+ it "categorizes iPhone as :mobile" do
39
+ @request.stubs(:user_agent).returns("Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_0 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8A293 Safari/6531.22.7")
40
+ @strategy.get_device_type(@request).must_equal :mobile
41
+ end
42
+
43
+ it "categorizes Android tablet as :tablet" do
44
+ @request.stubs(:user_agent).returns("Mozilla/5.0 (Linux; U; Android 3.0; xx-xx; Xoom Build/HRI39) AppleWebKit/525.10+ (KHTML, like Gecko) Version/3.0.4 Mobile Safari/523.12.2")
45
+ @strategy.get_device_type(@request).must_equal :tablet
46
+ end
47
+
48
+ it "categorizes Chrome on Linux as :desktop" do
49
+ @request.stubs(:user_agent).returns("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.46 Safari/535.11")
50
+ @strategy.get_device_type(@request).must_equal :desktop
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+ require 'mobvious/strategies/url'
3
+
4
+ module Mobvious::Strategies
5
+ class URLSpec < MiniTest::Spec
6
+ describe URL do
7
+ before do
8
+ @env = Rack::MockRequest::DEFAULT_ENV
9
+ @env.merge!({
10
+ 'rack.url_scheme' => 'http',
11
+ 'HTTP_HOST' => 'm.foo.com',
12
+ 'SERVER_PORT' => 80,
13
+ 'SCRIPT_NAME' => '',
14
+ 'PATH_INFO' => '/some_path'
15
+ })
16
+ @request = Rack::Request.new(@env)
17
+ @strategy = URL.new(URL::MOBILE_PATH_RULES)
18
+ end
19
+
20
+ it "returns the right device type when matching rule found" do
21
+ puts @request.url
22
+ @strategy.get_device_type(@request).must_equal :mobile
23
+ end
24
+
25
+ it "returns nil if no matching rule found" do
26
+ @env['HTTP_HOST'] = 'www.foo.com'
27
+ @strategy.get_device_type(@request).must_equal nil
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,34 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+ begin; require 'turn'; rescue LoadError; end
4
+ require 'mocha'
5
+ require 'rack/test'
6
+ require 'mobvious'
7
+
8
+ module Mobvious
9
+ class CookieParser
10
+ attr_reader :cookies
11
+
12
+ def initialize(cookie_header_content)
13
+ @cookies = {}
14
+ return unless cookie_header_content
15
+
16
+ cookie_header_content.split("\n").each do |cookie_string|
17
+ cookie_parts = cookie_string.split(';')
18
+
19
+ name, cookie_value = cookie_parts.first.split('=')
20
+ cookie = { 'value' => cookie_value }
21
+
22
+ cookie_parts[1..-1].each do |cookie_part|
23
+ key, value = cookie_part.split('=')
24
+ cookie[key.strip] = value
25
+ end
26
+ @cookies[name.strip] = cookie
27
+ end
28
+ end
29
+
30
+ def [](*args)
31
+ @cookies[*args]
32
+ end
33
+ end
34
+ end
metadata ADDED
@@ -0,0 +1,189 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: mobvious
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.pre
5
+ prerelease: 6
6
+ platform: ruby
7
+ authors:
8
+ - Jiří Stránský
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-02-14 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: &12623500 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: 1.2.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *12623500
25
+ - !ruby/object:Gem::Dependency
26
+ name: mobileesp
27
+ requirement: &12623000 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *12623000
36
+ - !ruby/object:Gem::Dependency
37
+ name: pry
38
+ requirement: &12622080 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *12622080
47
+ - !ruby/object:Gem::Dependency
48
+ name: minitest
49
+ requirement: &12621480 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *12621480
58
+ - !ruby/object:Gem::Dependency
59
+ name: mocha
60
+ requirement: &12620840 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *12620840
69
+ - !ruby/object:Gem::Dependency
70
+ name: rack-test
71
+ requirement: &12619900 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: *12619900
80
+ - !ruby/object:Gem::Dependency
81
+ name: guard
82
+ requirement: &12619220 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: *12619220
91
+ - !ruby/object:Gem::Dependency
92
+ name: guard-minitest
93
+ requirement: &12618320 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ! '>='
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ type: :development
100
+ prerelease: false
101
+ version_requirements: *12618320
102
+ - !ruby/object:Gem::Dependency
103
+ name: rb-inotify
104
+ requirement: &12617600 !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: *12617600
113
+ - !ruby/object:Gem::Dependency
114
+ name: libnotify
115
+ requirement: &12616840 !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ! '>='
119
+ - !ruby/object:Gem::Version
120
+ version: '0'
121
+ type: :development
122
+ prerelease: false
123
+ version_requirements: *12616840
124
+ - !ruby/object:Gem::Dependency
125
+ name: turn
126
+ requirement: &12616080 !ruby/object:Gem::Requirement
127
+ none: false
128
+ requirements:
129
+ - - ! '>='
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: *12616080
135
+ description: Rack middleware for choosing a version of an interface to render for
136
+ given request
137
+ email:
138
+ - jistr@jistr.com
139
+ executables: []
140
+ extensions: []
141
+ extra_rdoc_files: []
142
+ files:
143
+ - .gitignore
144
+ - .yardopts
145
+ - Gemfile
146
+ - Guardfile
147
+ - Rakefile
148
+ - lib/mobvious.rb
149
+ - lib/mobvious/config.rb
150
+ - lib/mobvious/manager.rb
151
+ - lib/mobvious/strategies/cookie.rb
152
+ - lib/mobvious/strategies/mobileesp.rb
153
+ - lib/mobvious/strategies/url.rb
154
+ - lib/mobvious/version.rb
155
+ - mobvious.gemspec
156
+ - spec/mobvious/manager_spec.rb
157
+ - spec/mobvious/strategies/cookie_spec.rb
158
+ - spec/mobvious/strategies/mobileesp_spec.rb
159
+ - spec/mobvious/strategies/url_spec.rb
160
+ - spec/spec_helper.rb
161
+ homepage: http://github.com/jistr/mobvious
162
+ licenses: []
163
+ post_install_message:
164
+ rdoc_options: []
165
+ require_paths:
166
+ - lib
167
+ required_ruby_version: !ruby/object:Gem::Requirement
168
+ none: false
169
+ requirements:
170
+ - - ! '>='
171
+ - !ruby/object:Gem::Version
172
+ version: '0'
173
+ segments:
174
+ - 0
175
+ hash: 816301950663841186
176
+ required_rubygems_version: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ! '>'
180
+ - !ruby/object:Gem::Version
181
+ version: 1.3.1
182
+ requirements: []
183
+ rubyforge_project:
184
+ rubygems_version: 1.8.11
185
+ signing_key:
186
+ specification_version: 3
187
+ summary: Rack middleware for choosing a version of an interface to render for given
188
+ request
189
+ test_files: []