fork_mobu 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c5df552d2081471626626bf6143e0999831abd75dd47c98c8f64879125437aaa
4
+ data.tar.gz: 5d7984af15825ccffac4e2254640b09241e84217b84e7c04c6f7ea3e1a99a615
5
+ SHA512:
6
+ metadata.gz: f9bd8e40dfe28867f0ae72bc61157dfe204ebfa7f6f06b84d679df7f5fedc00ac8cdd061f142ce6d36ea1e300d6d01929fc92ff3060bcfeaf0ddebc5f0b15119
7
+ data.tar.gz: 67135708c45a4d33ff1425e100418e38d0b4f1b781244be2fda279548d4b8c7d85182768157848f7af28a37c816e1cdb8fcc3401192b64e47548b87754608280
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ .ruby-version
2
+ Gemfile.lock
3
+ coverage
4
+ pkg
5
+ tmp
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5.2
4
+ - 2.1.4
5
+ - 2.0.0
6
+ - 1.9.3
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'https://rubygems.org'
2
+
3
+ if ENV['TRAVIS']
4
+ gem 'coveralls', require: false
5
+ end
6
+
7
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Neighborland, Inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,79 @@
1
+ # Mobu
2
+
3
+ [![Gem Version](http://img.shields.io/gem/v/mobu.svg)](http://rubygems.org/gems/mobu)
4
+ [![Build Status](http://img.shields.io/travis/neighborland/mobu.svg)](https://travis-ci.org/neighborland/mobu)
5
+ [![Code Climate](http://img.shields.io/codeclimate/github/neighborland/mobu.svg)](https://codeclimate.com/github/neighborland/mobu)
6
+ [![Coverage Status](http://img.shields.io/coveralls/neighborland/mobu.svg)](https://coveralls.io/r/neighborland/mobu)
7
+
8
+ Mobu provides a Rails controller concern called `DetectMobile`.
9
+ Mobu does server-side User Agent detection to categorize requests as mobile, tablet, or default.
10
+
11
+ Mobu modifies your rails view paths based on the request type.
12
+ It does not require custom MIME types or separate subdomains.
13
+
14
+ _Disclaimer: It is rarely a good idea to use User Agent detection to render different HTML content.
15
+ Please read this first:_
16
+
17
+ https://developer.mozilla.org/en-US/docs/Browser_detection_using_the_user_agent
18
+
19
+ ## Install
20
+
21
+ Add this line to your Gemfile:
22
+
23
+ ```ruby
24
+ gem 'mobu'
25
+ ```
26
+
27
+ Include the module in your ApplicationController:
28
+
29
+ ```ruby
30
+ class ApplicationController
31
+ include Mobu::DetectMobile
32
+ ```
33
+
34
+ Create directories for `views_mobile` and `views_tablet`:
35
+
36
+ ```sh
37
+ mkdir app/views_mobile
38
+ mkdir app/views_tablet
39
+ ```
40
+
41
+ ## Usage
42
+
43
+ Put the view/partial files that you want to override in the appropriate directories.
44
+
45
+ When you receive a mobile request, your app will first look for view files in `app/views_mobile`
46
+ directory, then in `app/views`.
47
+
48
+ Alternately, you can switch your rendering logic using the `mobile_request?` and `tablet_request?` helper methods
49
+ in your view files or helpers:
50
+
51
+ ```haml
52
+ - if mobile_request?
53
+ .small-thing Short Text
54
+ - else
55
+ .regular-thing Much Longer Text
56
+ ```
57
+
58
+ To allow mobile users to switch to the full site view, add a link to a mobile view. For example:
59
+
60
+ ##### app/views_mobile/_footer.haml
61
+ ```haml
62
+ = link_to("View Full Site", prefer_full_site_url)
63
+ ```
64
+
65
+ To allow full site users to switch to the mobile view, add a link to a default view. For example:
66
+
67
+ ##### app/views_mobile/_footer.haml
68
+ ```haml
69
+ - if mobile_browser?
70
+ = link_to("View Mobile Site", prefer_mobile_site_url)
71
+ ```
72
+
73
+ ## Credits
74
+
75
+ The view path modification technique was taken from
76
+ [this post by Scott W. Bradley](http://scottwb.com/blog/2012/02/23/a-better-way-to-add-mobile-pages-to-a-rails-site/).
77
+
78
+ The user agent regex came from a similar project, Brendan Lim's
79
+ [mobile-fu](https://github.com/brendanlim/mobile-fu).
data/Rakefile ADDED
@@ -0,0 +1,10 @@
1
+ require "bundler/gem_tasks"
2
+ require "rake/testtask"
3
+
4
+ task default: [:test]
5
+
6
+ Rake::TestTask.new(:test) do |t|
7
+ t.libs << 'test'
8
+ t.test_files = %w(test/**/*.rb)
9
+ t.verbose = false
10
+ end
data/fork_mobu.gemspec ADDED
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'fork_mobu/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "fork_mobu"
8
+ spec.version = ForkMobu::VERSION
9
+ spec.authors = ["Tee Parham"]
10
+ spec.email = ["tee@neighborland.com"]
11
+ spec.description = %q{Rails User Agent Dependent View Paths}
12
+ spec.summary = %q{Rails server-side User Agent detection, plus view path modifications.}
13
+ spec.homepage = "https://github.com/neighborland/mobu"
14
+ spec.license = "MIT"
15
+ spec.metadata = { "source_code_uri" => "https://github.com/neighborland/mobu" }
16
+
17
+ spec.files = `git ls-files`.split($/)
18
+ spec.test_files = spec.files.grep(%r{^(test)/})
19
+ spec.require_paths = ["lib"]
20
+ spec.executables = []
21
+
22
+ spec.required_ruby_version = ">= 1.9.3"
23
+
24
+ spec.add_development_dependency "bundler", '~> 1.3', '>= 1.3.0'
25
+ spec.add_development_dependency "rake", '~> 2.0', '>= 2.0.0'
26
+ spec.add_development_dependency "minitest"
27
+ spec.add_development_dependency "mocha", "~> 1.0"
28
+
29
+ spec.add_dependency "rack", '~> 2.0', '>= 2.0.0'
30
+ spec.add_dependency "actionpack", ">= 3.2"
31
+ end
@@ -0,0 +1,107 @@
1
+ require 'active_support/concern'
2
+ require 'active_support/core_ext/object/to_param'
3
+ require 'active_support/core_ext/object/to_query'
4
+ require 'rack/utils'
5
+ require 'uri'
6
+
7
+ module ForkMobu
8
+ module DetectMobile
9
+ extend ActiveSupport::Concern
10
+
11
+ # List of mobile agents from mobile_fu:
12
+ # https://github.com/brendanlim/mobile-fu/blob/master/lib/mobile_fu.rb
13
+ MOBILE_USER_AGENTS = 'palm|blackberry|nokia|phone|midp|mobi|symbian|chtml|ericsson|minimo|' +
14
+ 'audiovox|motorola|samsung|telit|upg1|windows ce|ucweb|astel|plucker|' +
15
+ 'x320|x240|j2me|sgh|portable|sprint|docomo|kddi|softbank|android|mmp|' +
16
+ 'pdxgw|netfront|xiino|vodafone|portalmmm|sagem|mot-|sie-|ipod|up\\.b|' +
17
+ 'webos|amoi|novarra|cdm|alcatel|pocket|iphone|mobileexplorer|mobile'
18
+
19
+ TABLET_USER_AGENTS = 'ipad|android 3.0|xoom|sch-i800|playbook|tablet|kindle|honeycomb|gt-p1000'
20
+
21
+ included do
22
+ before_filter :check_mobile_site
23
+
24
+ helper_method :mobile_request?,
25
+ :mobile_browser?,
26
+ :prefer_full_site_url,
27
+ :prefer_mobile_site_url,
28
+ :tablet_request?,
29
+ :tablet_browser?
30
+ end
31
+
32
+ private
33
+
34
+ def mobile_views_path
35
+ @@mobile_views_path ||= Rails.root + 'app' + 'views_mobile'
36
+ end
37
+
38
+ def tablet_views_path
39
+ @@tablet_views_path ||= Rails.root + 'app' + 'views_tablet'
40
+ end
41
+
42
+ def prefer_full_site_url
43
+ _view_url "f"
44
+ end
45
+
46
+ def prefer_mobile_site_url
47
+ _view_url "m"
48
+ end
49
+
50
+ # preference: m, f (mobile, full)
51
+ def _view_url(preference)
52
+ uri = URI(request.url)
53
+ query = Rack::Utils.parse_nested_query(uri.query)
54
+ query["prefer"] = preference
55
+ uri.query = query.to_param
56
+ uri.to_s
57
+ end
58
+
59
+ def force_full_site
60
+ session[:prefer_full_site]
61
+ end
62
+
63
+ def mobile_request?
64
+ if defined?(@mobile_request)
65
+ @mobile_request
66
+ else
67
+ @mobile_request = !force_full_site && !tablet_request? && mobile_browser?
68
+ end
69
+ end
70
+
71
+ def mobile_browser?
72
+ user_agent_matches(MOBILE_USER_AGENTS)
73
+ end
74
+
75
+ def tablet_request?
76
+ if defined?(@tablet_request)
77
+ @tablet_request
78
+ else
79
+ @tablet_request = tablet_browser?
80
+ end
81
+ end
82
+
83
+ def tablet_browser?
84
+ user_agent_matches(TABLET_USER_AGENTS)
85
+ end
86
+
87
+ def check_mobile_site
88
+ case params.delete(:prefer)
89
+ when "f"
90
+ session[:prefer_full_site] = 1
91
+ when "m"
92
+ session.delete :prefer_full_site
93
+ end
94
+
95
+ if mobile_request?
96
+ prepend_view_path mobile_views_path
97
+ elsif tablet_request?
98
+ prepend_view_path tablet_views_path
99
+ end
100
+ end
101
+
102
+ def user_agent_matches(regex)
103
+ !!( request.user_agent.to_s.downcase =~ /(#{regex})/ )
104
+ end
105
+
106
+ end
107
+ end
@@ -0,0 +1,3 @@
1
+ module ForkMobu
2
+ VERSION = "0.0.1"
3
+ end
data/lib/fork_mobu.rb ADDED
@@ -0,0 +1,2 @@
1
+ require 'fork_mobu/version'
2
+ require 'fork_mobu/detect_mobile'
@@ -0,0 +1,173 @@
1
+ require 'test_helper'
2
+
3
+ class ForkMobuFake
4
+ class << self
5
+ def before_filter(*args) end
6
+ def helper_method(*methods) end
7
+ end
8
+
9
+ def params
10
+ {}
11
+ end
12
+
13
+ include ForkMobu::DetectMobile
14
+ end
15
+
16
+ class Rails
17
+ end
18
+
19
+ class ForkMobuTest < MiniTest::Spec
20
+
21
+ IPAD_USER_AGENT = "Mozilla/5.0 (iPad; U; CPU OS 3_2 like Mac OS X; en-us) AppleWebKit/531.21.10 (KHTML, like Gecko) Version/4.0.4 Mobile/7B334b Safari/531.21.10"
22
+ IPHONE_USER_AGENT = "Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"
23
+ FIREFOX_USER_AGENT = "Mozilla/5.0 (Windows NT 6.2; rv:22.0) Gecko/20130405 Firefox/23.0"
24
+
25
+ describe "controller" do
26
+ before do
27
+ @request = mock
28
+ @session = MockCookies.new
29
+ @controller = MobuFake.new
30
+ @controller.stubs session: @session
31
+ @controller.stubs request: @request
32
+ end
33
+
34
+ it "set and cache mobile_request?" do
35
+ @controller.stubs :mobile_browser?
36
+ @controller.stubs :tablet_request?
37
+ refute @controller.send :mobile_request?
38
+ @controller.stubs mobile_browser?: true # it ignore
39
+ refute @controller.send :mobile_request?
40
+ end
41
+
42
+ it "detect tablet and not detect mobile for iPad user agent" do
43
+ @request.stubs user_agent: IPAD_USER_AGENT
44
+ assert @controller.send(:tablet_request?)
45
+ refute @controller.send(:mobile_request?)
46
+ end
47
+
48
+ describe "with mobile user agent" do
49
+ before do
50
+ @request.stubs user_agent: IPHONE_USER_AGENT
51
+ end
52
+
53
+ it "prepend mobile views" do
54
+ expect_mobile_views
55
+ expect_no_tablet_views
56
+ @controller.send :check_mobile_site
57
+ end
58
+
59
+ it "prepend mobile views with mobile preference" do
60
+ @controller.stubs params: {prefer: "m"}
61
+ expect_mobile_views
62
+ expect_no_tablet_views
63
+ @controller.send :check_mobile_site
64
+ end
65
+
66
+ it "not prepend mobile views with prefer_full_site cookie" do
67
+ @session[:prefer_full_site] = 1
68
+ expect_no_mobile_views
69
+ expect_no_tablet_views
70
+ @controller.send :check_mobile_site
71
+ end
72
+
73
+ it "set session cookie to prefer full site with full site preference" do
74
+ @controller.stubs params: {prefer: "f"}
75
+ @controller.send :check_mobile_site
76
+ assert_equal 1, @session[:prefer_full_site]
77
+ end
78
+ end
79
+
80
+ describe "with tablet user agent" do
81
+ before do
82
+ @request.stubs user_agent: IPAD_USER_AGENT
83
+ end
84
+
85
+ it "prepend tablet views" do
86
+ expect_tablet_views
87
+ expect_no_mobile_views
88
+ @controller.send :check_mobile_site
89
+ end
90
+ end
91
+
92
+ describe "with browser user agent" do
93
+ before do
94
+ @request.stubs user_agent: FIREFOX_USER_AGENT
95
+ end
96
+
97
+ it "prepend no views" do
98
+ expect_no_tablet_views
99
+ expect_no_mobile_views
100
+ @controller.send :check_mobile_site
101
+ end
102
+
103
+ it "prepend no views with prefer_full_site cookie" do
104
+ @session[:prefer_full_site] = 1
105
+ expect_no_tablet_views
106
+ expect_no_mobile_views
107
+ @controller.send :check_mobile_site
108
+ end
109
+ end
110
+
111
+ describe "#prefer_full_site_url" do
112
+ it "add prefer=f" do
113
+ @request.stubs url: "https://neighborland.com/xyz"
114
+ assert_equal "https://neighborland.com/xyz?prefer=f", @controller.send(:prefer_full_site_url)
115
+ end
116
+
117
+ it "keep existing query params" do
118
+ @request.stubs url: "https://neighborland.com/xyz?monkeys=true&bananas=yeller"
119
+ assert_equal "https://neighborland.com/xyz?bananas=yeller&monkeys=true&prefer=f", @controller.send(:prefer_full_site_url)
120
+ end
121
+ end
122
+
123
+ describe "#prefer_mobile_site_url" do
124
+ it "add prefer=m" do
125
+ @request.stubs url: "https://neighborland.com/xyz"
126
+ assert_equal "https://neighborland.com/xyz?prefer=m", @controller.send(:prefer_mobile_site_url)
127
+ end
128
+
129
+ it "strip existing prefer value" do
130
+ @request.stubs url: "https://neighborland.com/xyz?prefer=f"
131
+ assert_equal "https://neighborland.com/xyz?prefer=m", @controller.send(:prefer_mobile_site_url)
132
+ end
133
+ end
134
+
135
+ describe "with fake Rails" do
136
+ before do
137
+ Rails.stubs root: Pathname.new("/home/snoop/yer_app/")
138
+ end
139
+
140
+ describe "#mobile_views_path" do
141
+ it "build path" do
142
+ assert_equal "/home/snoop/yer_app/app/views_mobile", @controller.send(:mobile_views_path).to_s
143
+ end
144
+ end
145
+
146
+ describe "#tablet_views_path" do
147
+ it "build path" do
148
+ assert_equal "/home/snoop/yer_app/app/views_tablet", @controller.send(:tablet_views_path).to_s
149
+ end
150
+ end
151
+ end
152
+ end
153
+
154
+ private
155
+
156
+ def expect_mobile_views
157
+ @controller.expects(:mobile_views_path).returns("mobile_views_path").once
158
+ @controller.expects(:prepend_view_path).with("mobile_views_path")
159
+ end
160
+
161
+ def expect_tablet_views
162
+ @controller.expects(:tablet_views_path).returns("tablet_views_path").once
163
+ @controller.expects(:prepend_view_path).with("tablet_views_path")
164
+ end
165
+
166
+ def expect_no_mobile_views
167
+ @controller.expects(:mobile_views_path).never
168
+ end
169
+
170
+ def expect_no_tablet_views
171
+ @controller.expects(:tablet_views_path).never
172
+ end
173
+ end
@@ -0,0 +1,21 @@
1
+ if ENV['TRAVIS']
2
+ require 'coveralls'
3
+ Coveralls.wear!
4
+ end
5
+
6
+ require 'minitest/autorun'
7
+ require 'mocha/mini_test'
8
+ require 'fork_mobu'
9
+
10
+ class MockCookies < Hash
11
+ attr_accessor :permanent
12
+
13
+ def initialize
14
+ @permanent = {}
15
+ super
16
+ end
17
+
18
+ def delete(cookie, opts={})
19
+ super cookie
20
+ end
21
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: fork_mobu
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Tee Parham
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-06-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 1.3.0
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '1.3'
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 1.3.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: rake
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: '2.0'
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 2.0.0
43
+ type: :development
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: '2.0'
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 2.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: minitest
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - ">="
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: mocha
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '1.0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '1.0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: rack
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '2.0'
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: 2.0.0
91
+ type: :runtime
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - "~>"
96
+ - !ruby/object:Gem::Version
97
+ version: '2.0'
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: 2.0.0
101
+ - !ruby/object:Gem::Dependency
102
+ name: actionpack
103
+ requirement: !ruby/object:Gem::Requirement
104
+ requirements:
105
+ - - ">="
106
+ - !ruby/object:Gem::Version
107
+ version: '3.2'
108
+ type: :runtime
109
+ prerelease: false
110
+ version_requirements: !ruby/object:Gem::Requirement
111
+ requirements:
112
+ - - ">="
113
+ - !ruby/object:Gem::Version
114
+ version: '3.2'
115
+ description: Rails User Agent Dependent View Paths
116
+ email:
117
+ - tee@neighborland.com
118
+ executables: []
119
+ extensions: []
120
+ extra_rdoc_files: []
121
+ files:
122
+ - ".gitignore"
123
+ - ".travis.yml"
124
+ - Gemfile
125
+ - LICENSE.txt
126
+ - README.md
127
+ - Rakefile
128
+ - fork_mobu.gemspec
129
+ - lib/fork_mobu.rb
130
+ - lib/fork_mobu/detect_mobile.rb
131
+ - lib/fork_mobu/version.rb
132
+ - test/detect_mobile_test.rb
133
+ - test/test_helper.rb
134
+ homepage: https://github.com/neighborland/mobu
135
+ licenses:
136
+ - MIT
137
+ metadata:
138
+ source_code_uri: https://github.com/neighborland/mobu
139
+ post_install_message:
140
+ rdoc_options: []
141
+ require_paths:
142
+ - lib
143
+ required_ruby_version: !ruby/object:Gem::Requirement
144
+ requirements:
145
+ - - ">="
146
+ - !ruby/object:Gem::Version
147
+ version: 1.9.3
148
+ required_rubygems_version: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
153
+ requirements: []
154
+ rubygems_version: 3.3.7
155
+ signing_key:
156
+ specification_version: 4
157
+ summary: Rails server-side User Agent detection, plus view path modifications.
158
+ test_files:
159
+ - test/detect_mobile_test.rb
160
+ - test/test_helper.rb