lib/shoulda/matchers/action_controller/route_matcher.rb
module Shoulda # :nodoc: module Matchers module ActionController # :nodoc: # Ensures that requesting +path+ using +method+ routes to +options+. # # If you don't specify a controller, it will use the controller from the # example group. # # +to_param+ is called on the +options+ given. # # Examples: # # it { should route(:get, '/posts'). # to(:controller => :posts, :action => :index) } # it { should route(:get, '/posts/new').to(:action => :new) } # it { should route(:post, '/posts').to(:action => :create) } # it { should route(:get, '/posts/1').to(:action => :show, :id => 1) } # it { should route(:get, '/posts/1/edit').to(:action => :edit, :id => 1) } # it { should route(:put, '/posts/1').to(:action => :update, :id => 1) } # it { should route(:delete, '/posts/1'). # to(:action => :destroy, :id => 1) } # it { should route(:get, '/users/1/posts/1'). # to(:action => :show, :id => 1, :user_id => 1) } def route(method, path) RouteMatcher.new(method, path, self) end class RouteMatcher # :nodoc: def initialize(method, path, context) @method = method @path = path @context = context end attr_reader :failure_message_for_should, :failure_message_for_should_not def to(params) @params = stringify_params(params) self end def in_context(context) @context = context self end def matches?(controller) guess_controller!(controller) route_recognized? end def description "route #{@method.to_s.upcase} #{@path} to/from #{@params.inspect}" end private def guess_controller!(controller) @params[:controller] ||= controller.controller_path end def stringify_params(params) params.each do |key, value| params[key] = stringify(value) end end def stringify(value) if value.is_a?(Array) value.map(&:to_param) else value.to_param end end def route_recognized? begin @context.send(:assert_routing, { :method => @method, :path => @path }, @params) @failure_message_for_should_not = "Didn't expect to #{description}" true rescue ::ActionController::RoutingError => error @failure_message_for_should = error.message false rescue Shoulda::Matchers::AssertionError => error @failure_message_for_should = error.message false end end end end end end