-
-
Notifications
You must be signed in to change notification settings - Fork 1k
/
routing_matchers.rb
99 lines (88 loc) · 2.83 KB
/
routing_matchers.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
module RSpec::Rails::Matchers
module RoutingMatchers
extend RSpec::Matchers::DSL
class RouteToMatcher
include RSpec::Matchers::BaseMatcher
def initialize(scope, *expected)
@scope = scope
@expected_options = expected[1] || {}
if Hash === expected[0]
@expected_options.merge!(expected[0])
else
controller, action = expected[0].split('#')
@expected_options.merge!(:controller => controller, :action => action)
end
end
# @api private
def matches?(verb_to_path_map)
match_unless_raises ActiveSupport::TestCase::Assertion do
path, query = *verb_to_path_map.values.first.split('?')
@scope.assert_recognizes(
@expected_options,
{:method => verb_to_path_map.keys.first, :path => path},
Rack::Utils::parse_query(query)
)
end
end
# @api private
def failure_message_for_should
rescued_exception.message
end
end
# Delegates to `assert_recognizes`. Supports short-hand controller/action
# declarations (e.g. `"controller#action"`).
#
# @example
#
# { :get => "/things/special" }.should route_to(
# :controller => "things",
# :action => "special"
# )
#
# { :get => "/things/special" }.should route_to("things#special")
#
# @see http://api.rubyonrails.org/classes/ActionDispatch/Assertions/RoutingAssertions.html#method-i-assert_recognizes
def route_to(*expected)
RouteToMatcher.new(self, *expected)
end
class BeRoutableMatcher
include RSpec::Matchers::BaseMatcher
def initialize(scope)
@scope = scope
end
# @api private
def matches?(path)
super(path)
match_unless_raises ActionController::RoutingError do
@routing_options = @scope.routes.recognize_path(
path.values.first, :method => path.keys.first
)
end
end
# @api private
def failure_message_for_should_not
"expected #{actual.inspect} not to be routable, but it routes to #{@routing_options.inspect}"
end
end
# Passes if the route expression is recognized by the Rails router based on
# the declarations in `config/routes.rb`. Delegates to
# `RouteSet#recognize_path`.
#
# @example
#
# You can use route helpers provided by rspec-rails.
# {:get => "/a/path"}.should be_routable
# {:post => "/another/path"}.should be_routable
# {:put => "/yet/another/path"}.should_not be_routable
def be_routable
BeRoutableMatcher.new(self)
end
module RouteHelpers
%w(get post put delete options head).each do |method|
define_method method do |path|
{ method.to_sym => path }
end
end
end
end
end