Permalink
Browse files

specs passing on a first version

  • Loading branch information...
1 parent 72a7908 commit 212a54fc91930068f18d823e3e7d59d4ac8e74ae @mdp committed Feb 17, 2010
Showing with 213 additions and 34 deletions.
  1. +50 −0 README.markdown
  2. +0 −17 README.rdoc
  3. +1 −0 VERSION
  4. +89 −0 lib/divining_rod.rb
  5. +70 −0 spec/basic_spec.rb
  6. +3 −0 spec/spec_helper.rb
  7. +0 −10 test/helper.rb
  8. +0 −7 test/test_divining_rod.rb
View
@@ -0,0 +1,50 @@
+# Divining Rod
+
+A tool to help format your sites mobile pages. The goal is to have the ability to do things in your
+views like this
+
+ <%- if request.dv_profile.youtube_capable? %>
+ <%= link_to "YouTube Video", @link.youtube_url %>
+ <%- else %>
+ Sorry, you have a shitty phone.
+ <% end %>
+
+## Installation
+
+ gem install divining_rod
+
+## Usage
+
+ require 'divining_rod'
+
+ DiviningRod::Matchers.define do |map|
+ map.ua /iPhone/, :webkit, :tags => [:iphone, :youtube_capable]
+ map.ua /Android/, :webkit, :tags => [:youtube_capable, :google_gears]
+ map.default :unknown
+ end
+
+ profile = DiviningRod::Profile(request) #profile and incoming iphone request
+ profile.format #=> :webkit
+ profile.iphone? #=> true
+
+## Note on the development
+
+This is still very much in beta, but we are using in extensively in production. We plan
+to keep the API the same.
+
+The user agent definitions will be updated here later this week.
+
+
+### Note on Patches/Pull Requests
+
+* Fork the project.
+* Make your feature addition or bug fix.
+* Add tests for it. This is important so I don't break it in a
+ future version unintentionally.
+* Commit, do not mess with rakefile, version, or history.
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
+* Send me a pull request. Bonus points for topic branches.
+
+### Copyright
+
+Copyright (c) 2010 Mark Percival. See LICENSE for details.
View
@@ -1,17 +0,0 @@
-= divining_rod
-
-Description goes here.
-
-== Note on Patches/Pull Requests
-
-* Fork the project.
-* Make your feature addition or bug fix.
-* Add tests for it. This is important so I don't break it in a
- future version unintentionally.
-* Commit, do not mess with rakefile, version, or history.
- (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
-* Send me a pull request. Bonus points for topic branches.
-
-== Copyright
-
-Copyright (c) 2010 Mark Percival. See LICENSE for details.
View
@@ -0,0 +1 @@
+0.1.1
View
@@ -0,0 +1,89 @@
+require 'yaml'
+
+module DiviningRod
+
+ class UndefinedDefault < StandardError
+
+ end
+
+ class Profile
+
+ attr_reader :match
+
+ def initialize(request)
+ matchers.each do |matcher|
+ @match = matcher if matcher.matches?(request)
+ break if @match
+ end
+ raise UndefinedDefault, "Please define a default group for DiviningRod" unless @match
+ end
+
+ def group
+ @match.group
+ end
+ alias_method :format, :group
+
+ def method_missing(meth)
+ if meth.to_s.match(/(.+)\?$/)
+ tag = $1
+ @match.tags.include?(tag.to_s) || @match.tags.include?(tag.to_sym) || @match.tags == tag
+ else
+ super
+ end
+ end
+
+ def matchers
+ DiviningRod::Matchers.definitions || []
+ end
+
+ end
+
+ class Matchers
+
+ class << self
+
+ attr_accessor :definitions
+
+ def define
+ yield(self)
+ end
+
+ def clear_definitions
+ @definitions = []
+ end
+
+ def ua(pattern, group, opts={})
+ @definitions ||= []
+ @definitions << Definition.new(group, opts) { |request|
+ if pattern.match(request.user_agent)
+ true
+ end
+ }
+ end
+
+ def default(group, opts = {})
+ @definitions ||= []
+ @definitions << Definition.new(group, opts) { |request| true }
+ end
+
+ end
+
+ end
+
+ class Definition
+
+ attr_accessor :prc, :tags, :group
+
+ def initialize(group, opts={}, &blk)
+ @group = group
+ @tags = opts[:tags] || []
+ @prc = blk
+ end
+
+ def matches?(request)
+ !!@prc.call(request)
+ end
+
+ end
+
+end
View
@@ -0,0 +1,70 @@
+require 'spec_helper'
+
+describe DiviningRod do
+
+ before :each do
+ @request = mock("rails_request", :user_agent => 'My iPhone')
+ DiviningRod::Matchers.clear_definitions
+ DiviningRod::Matchers.define do |map|
+ map.ua /iPhone/, :webkit, :tags => [:iphone, :youtube, :geolocate]
+ map.default(:unknown)
+ end
+ end
+
+ it "should recognize an iPhone" do
+ profile = DiviningRod::Profile.new(@request)
+ profile.format.should eql(:webkit)
+ end
+
+ it "should know if it belongs to a category tag" do
+ profile = DiviningRod::Profile.new(@request)
+ profile.geolocate?.should be_true
+ end
+
+ it "should know if it does not belongs to a category" do
+ profile = DiviningRod::Profile.new(@request)
+ profile.wap?.should be_false
+ end
+
+ it "should use the default group for unknown phones" do
+ @request = mock("rails_request", :user_agent => 'My Foo Phone')
+ profile = DiviningRod::Profile.new(@request)
+ profile.wap?.should be_false
+ end
+
+end
+
+
+describe DiviningRod::Matchers do
+
+ before :each do
+ @request = mock("rails_request", :user_agent => 'iPhone Foo')
+ DiviningRod::Matchers.clear_definitions
+ DiviningRod::Matchers.define do |map|
+ map.ua /iPhone/, :iphone, :tags => [:iphone, :youtube]
+ end
+ end
+
+ it "should recognize an iPhone" do
+ DiviningRod::Matchers.definitions.first.matches?(@request).should be_true
+ DiviningRod::Matchers.definitions.first.group.should eql(:iphone)
+ end
+
+ describe "defining a default definition" do
+
+ before :each do
+ @request = mock("rails_request", :user_agent => 'Foo Fone')
+ DiviningRod::Matchers.clear_definitions
+ DiviningRod::Matchers.define do |map|
+ map.default :unknown, :tags => [:html]
+ end
+ end
+
+ it "should use the default route if no other match is found" do
+ DiviningRod::Matchers.definitions.first.matches?(@request).should be_true
+ DiviningRod::Matchers.definitions.first.group.should eql(:unknown)
+ end
+
+ end
+
+end
View
@@ -0,0 +1,3 @@
+require 'rubygems'
+require 'spec'
+require File.expand_path('../../lib/divining_rod', __FILE__)
View
@@ -1,10 +0,0 @@
-require 'rubygems'
-require 'test/unit'
-require 'shoulda'
-
-$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
-$LOAD_PATH.unshift(File.dirname(__FILE__))
-require 'divining_rod'
-
-class Test::Unit::TestCase
-end
@@ -1,7 +0,0 @@
-require 'helper'
-
-class TestDiviningRod < Test::Unit::TestCase
- should "probably rename this file and start testing for real" do
- flunk "hey buddy, you should probably rename this file and start testing for real"
- end
-end

0 comments on commit 212a54f

Please sign in to comment.