Permalink
Browse files

Add misc. route changes and add specs for the recognition process

  • Loading branch information...
1 parent 8f55fce commit d4e99fed5246d2ff02106016642f72e179a6658d Darcy Laycock committed Jan 27, 2011
Showing with 138 additions and 21 deletions.
  1. +2 −0 .rspec
  2. +18 −0 Rakefile
  3. +10 −0 lib/rocket_pants.rb
  4. +0 −4 lib/rocket_pants/railtie.rb
  5. +8 −17 lib/rocket_pants/routing.rb
  6. +79 −0 spec/rocket_pants/routing_spec.rb
  7. +14 −0 spec/spec_helper.rb
  8. +7 −0 spec/support/controller.rb
View
2 .rspec
@@ -0,0 +1,2 @@
+--colour
+--format=documentation
View
18 Rakefile
@@ -0,0 +1,18 @@
+require 'rubygems'
+require 'rake'
+require 'rspec/core'
+require 'rspec/core/rake_task'
+
+task :default => :spec
+
+desc "Run all specs in spec directory (excluding plugin specs)"
+RSpec::Core::RakeTask.new(:spec)
+
+namespace :spec do
+ desc "Run all specs with rcov"
+ RSpec::Core::RakeTask.new(:rcov) do |t|
+ t.rcov = true
+ t.pattern = "./spec/**/*_spec.rb"
+ t.rcov_opts = '--exclude spec/,/gems/,/Library/,/usr/,lib/tasks,.bundle,config,/lib/rspec/,/lib/rspec-'
+ end
+end
View
10 lib/rocket_pants.rb
@@ -1,6 +1,16 @@
+require 'active_support/all'
+require 'action_dispatch'
+require 'action_dispatch/routing'
+require 'action_controller'
+
module RocketPants
require 'rocket_pants/exceptions'
+
+ # Set up the routing in advance.
require 'rocket_pants/routing'
+ ActionDispatch::Routing::Mapper.send :include, RocketPants::Routing
+
require 'rocket_pants/railtie' if defined?(Rails::Railtie)
autoload :Base, 'rocket_pants/base'
+
end
View
4 lib/rocket_pants/railtie.rb
@@ -21,10 +21,6 @@ class Railtie < Rails::Railtie
include ActionController::Testing if Rails.env.test?
end
end
-
- initializer "rocket_pants.setup_router" do |app|
- ActionDispatch::Routing::Mapper.send :include, RocketPants::Routing
- end
end
end
View
25 lib/rocket_pants/routing.rb
@@ -1,34 +1,25 @@
-require 'ruby-debug'
-
module RocketPants
module Routing
- class VersionConstraint
-
- def initialize(versions)
- @versions = versions
- end
-
- def matches?(req)
- @versions.include? req.path_parameters[:version]
- end
-
- end
-
# Scopes a set of given api routes, allowing for option versions.
# @param [Hash] options options to pass through to the route e.g. `:module`.
# @option options [Array<Integer>, Integer] :versions the versions to support
# @option options [Array<Integer>, Integer] :version the single version to support
# @raise [ArgumentError] raised when the version isn't provided.
def rocket_pants(options = {}, &blk)
- versions = (Array(options[:versions]) + Array(options[:version])).flatten.map(&:to_s)
- raise ArgumentError, 'please provider atleast one version' if versions.empty?
+ versions = (Array(options.delete(:versions)) + Array(options.delete(:version))).flatten.map(&:to_s)
+ versions.each do |version|
+ raise ArgumentError, "Got invalid version: '#{version}'" unless version =~ /\A\d+\Z/
+ end
+ versions_regexp = /(#{versions.uniq.join("|")})/
+ raise ArgumentError, 'please provide atleast one version' if versions.empty?
options = options.deep_merge({
- :constraints => VersionConstraint.new(versions),
+ :constraints => {:version => versions_regexp},
:path => ':version'
})
scope options, &blk
end
+ alias api rocket_pants
end
end
View
79 spec/rocket_pants/routing_spec.rb
@@ -0,0 +1,79 @@
+require 'spec_helper'
+
+describe RocketPants::Routing do
+
+ let(:router) { ActionDispatch::Routing::RouteSet.new }
+
+ def draw_routes(&blk)
+ router.draw(&blk)
+ router.finalize!
+ end
+
+ def recognize_path(path, env = {})
+ router.recognize_path(path, env)
+ end
+
+ def expect_options(*args)
+ expect do
+ router.draw do
+ api(*args) do
+ get 'echo', :to => 'test#echo'
+ end
+ end
+ end
+ end
+
+ context 'a basic set of api routes' do
+
+ before :each do
+ draw_routes do
+ api :version => 1 do
+ get 'a', :to => 'test#echo'
+ end
+ api :versions => %w(2 3) do
+ get 'b', :to => 'test#echo'
+ end
+ end
+ end
+
+ it 'should recognise a path to a single version' do
+ recognize_path('/1/a').should == {:controller => 'test', :action => 'echo', :version => '1'}
+ recognize_path('/2/b').should == {:controller => 'test', :action => 'echo', :version => '2'}
+ recognize_path('/3/b').should == {:controller => 'test', :action => 'echo', :version => '3'}
+ end
+
+ it 'should not recognise a path to other versions' do
+ expect { recognize_path('/1/b') }.to raise_error(ActionController::RoutingError)
+ expect { recognize_path('/2/a') }.to raise_error(ActionController::RoutingError)
+ expect { recognize_path('/3/a') }.to raise_error(ActionController::RoutingError)
+ end
+
+ end
+
+ it 'should not let you draw a route without a version' do
+ expect_options.to raise_error(ArgumentError)
+ expect_options(:version => []).to raise_error(ArgumentError)
+ expect_options(:version => %w()).to raise_error(ArgumentError)
+ expect_options(:version => nil).to raise_error(ArgumentError)
+ expect_options(:version => []).to raise_error(ArgumentError)
+ expect_options(:version => %w()).to raise_error(ArgumentError)
+ expect_options(:versions => nil).to raise_error(ArgumentError)
+ expect_options(:versions => []).to raise_error(ArgumentError)
+ expect_options(:versions => %w()).to raise_error(ArgumentError)
+ end
+
+ it 'should not let you draw a route with an invalid version' do
+ expect_options(:version => ' ').to raise_error(ArgumentError)
+ expect_options(:version => '1.1').to raise_error(ArgumentError)
+ expect_options(:version => 'test-version').to raise_error(ArgumentError)
+ expect_options(:version => 'v1').to raise_error(ArgumentError)
+ end
+
+ it 'should not let you draw a route with an invalid version in multiple versions' do
+ expect_options(:versions => ['', '2', ' ']).to raise_error(ArgumentError)
+ expect_options(:versions => %w(1 . 1)).to raise_error(ArgumentError)
+ expect_options(:versions => [1, 'a', 2]).to raise_error(ArgumentError)
+ expect_options(:versions => %w(v1 v2)).to raise_error(ArgumentError)
+ end
+
+end
View
14 spec/spec_helper.rb
@@ -0,0 +1,14 @@
+ENV["RAILS_ENV"] ||= 'test'
+$LOAD_PATH.unshift Pathname(__FILE__).dirname.dirname.join("lib").to_s
+
+require 'bundler/setup'
+Bundler.setup
+Bundler.require :default, :test
+
+require 'rocket_pants'
+
+Dir[Pathname(__FILE__).dirname.join("support/**/*.rb")].each { |f| require f }
+
+RSpec.configure do |config|
+ config.mock_with :rr
+end
View
7 spec/support/controller.rb
@@ -0,0 +1,7 @@
+class TestController < RocketPants::Base
+
+ def echo
+ expose :echo => params[:echo]
+ end
+
+end

0 comments on commit d4e99fe

Please sign in to comment.