benhutton-remarkable_rails 4.0.0.alpha4
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.
- data/CHANGELOG +105 -0
- data/LICENSE +20 -0
- data/README +116 -0
- data/benhutton-remarkable_rails.gemspec +73 -0
- data/lib/remarkable_rails.rb +48 -0
- data/lib/remarkable_rails/action_controller.rb +22 -0
- data/lib/remarkable_rails/action_controller/base.rb +31 -0
- data/lib/remarkable_rails/action_controller/macro_stubs.rb +594 -0
- data/lib/remarkable_rails/action_controller/matchers/assign_to_matcher.rb +95 -0
- data/lib/remarkable_rails/action_controller/matchers/filter_params_matcher.rb +41 -0
- data/lib/remarkable_rails/action_controller/matchers/redirect_to_matcher.rb +118 -0
- data/lib/remarkable_rails/action_controller/matchers/render_template_matcher.rb +16 -0
- data/lib/remarkable_rails/action_controller/matchers/respond_with_matcher.rb +136 -0
- data/lib/remarkable_rails/action_controller/matchers/route_matcher.rb +135 -0
- data/lib/remarkable_rails/action_controller/matchers/set_cookies_matcher.rb +85 -0
- data/lib/remarkable_rails/action_controller/matchers/set_session_matcher.rb +108 -0
- data/lib/remarkable_rails/action_controller/matchers/set_the_flash_matcher.rb +56 -0
- data/lib/remarkable_rails/action_view.rb +18 -0
- data/lib/remarkable_rails/action_view/base.rb +7 -0
- data/lib/remarkable_rails/active_orm.rb +19 -0
- data/locale/en.yml +110 -0
- data/remarkable_rails.gemspec +71 -0
- metadata +156 -0
@@ -0,0 +1,95 @@
|
|
1
|
+
module Remarkable
|
2
|
+
module ActionController
|
3
|
+
module Matchers
|
4
|
+
class AssignToMatcher < Remarkable::ActionController::Base #:nodoc:
|
5
|
+
arguments :collection => :names, :as => :name, :block => true
|
6
|
+
|
7
|
+
optional :with, :block => true
|
8
|
+
optional :with_kind_of
|
9
|
+
|
10
|
+
collection_assertions :assigned_value?, :is_kind_of?, :is_equal_value?
|
11
|
+
|
12
|
+
before_assert :evaluate_expected_value
|
13
|
+
|
14
|
+
protected
|
15
|
+
|
16
|
+
def assigned_value?
|
17
|
+
assigns.key?(@name)
|
18
|
+
end
|
19
|
+
|
20
|
+
def is_kind_of?
|
21
|
+
return true unless @options[:with_kind_of]
|
22
|
+
return assigns[@name].kind_of?(@options[:with_kind_of])
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns true if :with is not given and no block is given.
|
26
|
+
# In case :with is a proc or a block is given, we evaluate it in the
|
27
|
+
# @spec scope.
|
28
|
+
#
|
29
|
+
def is_equal_value?
|
30
|
+
return true unless value_to_compare?
|
31
|
+
assigns[@name] == @options[:with]
|
32
|
+
end
|
33
|
+
|
34
|
+
def assigns
|
35
|
+
#@subject.response.template.assigns.with_indifferent_access
|
36
|
+
@subject.instance_variable_get(:@assigns).with_indifferent_access
|
37
|
+
end
|
38
|
+
|
39
|
+
def value_to_compare?
|
40
|
+
@options.key?(:with) || @block
|
41
|
+
end
|
42
|
+
|
43
|
+
# Update interpolation options
|
44
|
+
def interpolation_options
|
45
|
+
if @subject && @subject.response
|
46
|
+
{ :assign_inspect => assigns[@name].inspect, :assign_class => assigns[@name].class.name }
|
47
|
+
else
|
48
|
+
{ }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
# Evaluate procs before assert to avoid them appearing in descriptions.
|
53
|
+
def evaluate_expected_value
|
54
|
+
if value_to_compare?
|
55
|
+
value = @options.key?(:with) ? @options[:with] : @block
|
56
|
+
value = @spec.instance_eval(&value) if value.is_a?(Proc)
|
57
|
+
@options[:with] = value
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
# Checks if the controller assigned the variables given by name. If you
|
64
|
+
# want to check that a variable is not being assigned, please do:
|
65
|
+
#
|
66
|
+
# should_not_assign_to(:user)
|
67
|
+
#
|
68
|
+
# If you want to assure that a variable is being assigned to nil, do instead:
|
69
|
+
#
|
70
|
+
# should_assign_to(:user).with(nil)
|
71
|
+
#
|
72
|
+
# == Options
|
73
|
+
#
|
74
|
+
# * <tt>:with</tt> - The value to compare the assign.
|
75
|
+
# It can be also be supplied as proc or as a block (see examples below)
|
76
|
+
#
|
77
|
+
# * <tt>:with_kind_of</tt> - The expected class of the assign.
|
78
|
+
#
|
79
|
+
# == Examples
|
80
|
+
#
|
81
|
+
# should_assign_to :user, :with_kind_of => User
|
82
|
+
# should_assign_to :user, :with => proc{ users(:first) }
|
83
|
+
# should_assign_to(:user){ users(:first) }
|
84
|
+
#
|
85
|
+
# it { should assign_to(:user) }
|
86
|
+
# it { should assign_to(:user, :with => users(:first)) }
|
87
|
+
# it { should assign_to(:user, :with_kind_of => User) }
|
88
|
+
#
|
89
|
+
def assign_to(*args, &block)
|
90
|
+
AssignToMatcher.new(*args, &block).spec(self)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module Remarkable
|
2
|
+
module ActionController
|
3
|
+
module Matchers
|
4
|
+
# Do not inherit from ActionController::Base since it don't need all macro stubs behavior.
|
5
|
+
class FilterParamsMatcher < Remarkable::Base #:nodoc:
|
6
|
+
arguments :collection => :params, :as => :param
|
7
|
+
|
8
|
+
assertions :respond_to_filter_params?
|
9
|
+
collection_assertions :is_filtered?
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def respond_to_filter_params?
|
14
|
+
@subject.respond_to?(:filter_parameters)
|
15
|
+
end
|
16
|
+
|
17
|
+
def is_filtered?
|
18
|
+
filtered = @subject.send(:filter_parameters, { @param.to_s => @param.to_s })
|
19
|
+
filtered[@param.to_s] == '[FILTERED]'
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
23
|
+
|
24
|
+
# Checks if the controller filters the given params.
|
25
|
+
#
|
26
|
+
# == Examples
|
27
|
+
#
|
28
|
+
# should_filter_params :password
|
29
|
+
# should_not_filter_params :username
|
30
|
+
#
|
31
|
+
# it { should filter_params(:password) }
|
32
|
+
# it { should_not filter_params(:username) }
|
33
|
+
#
|
34
|
+
def filter_params(*params, &block)
|
35
|
+
FilterParamsMatcher.new(*params, &block).spec(self)
|
36
|
+
end
|
37
|
+
alias :filter_param :filter_params
|
38
|
+
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Remarkable
|
2
|
+
module ActionController
|
3
|
+
module Matchers
|
4
|
+
class RedirectToMatcher < Remarkable::ActionController::Base #:nodoc:
|
5
|
+
|
6
|
+
arguments :expected, :block => true
|
7
|
+
optional :with, :block => true
|
8
|
+
|
9
|
+
assertions :redirected?, :status_matches?, :url_matches?
|
10
|
+
|
11
|
+
before_assert :evaluate_expected_value
|
12
|
+
|
13
|
+
before_assert do
|
14
|
+
@response = @subject.respond_to?(:response) ? @subject.response : @subject
|
15
|
+
@request = @response.instance_variable_get('@request')
|
16
|
+
end
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def redirected?
|
21
|
+
@response.redirect?
|
22
|
+
end
|
23
|
+
|
24
|
+
def status_matches?
|
25
|
+
return true unless @options.key?(:with)
|
26
|
+
|
27
|
+
actual_status = @response.response_code
|
28
|
+
expected_status = @options[:with]
|
29
|
+
|
30
|
+
return actual_status == expected_status, :status => @response.response_code.inspect
|
31
|
+
end
|
32
|
+
|
33
|
+
def url_matches?
|
34
|
+
@actual = @response.redirect_url
|
35
|
+
|
36
|
+
if @expected.instance_of?(Hash)
|
37
|
+
return false unless @actual =~ /^\w+:\/\/#{@request.host}/ && actual_hash
|
38
|
+
actual_hash == expected_hash
|
39
|
+
else
|
40
|
+
@actual == expected_url
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def actual_hash
|
45
|
+
hash_from_url @actual
|
46
|
+
end
|
47
|
+
|
48
|
+
def expected_hash
|
49
|
+
hash_from_url expected_url
|
50
|
+
end
|
51
|
+
|
52
|
+
def hash_from_url(url)
|
53
|
+
query_hash(url).merge(path_hash(url)).with_indifferent_access
|
54
|
+
end
|
55
|
+
|
56
|
+
def path_hash(url)
|
57
|
+
path = url.sub(/^\w+:\/\/#{@request.host}(?::\d+)?/, "").split("?", 2)[0]
|
58
|
+
::Rails.application.routes.recognize_path path, { :method => :get }
|
59
|
+
end
|
60
|
+
|
61
|
+
def query_hash(url)
|
62
|
+
query = url.split("?", 2)[1] || ""
|
63
|
+
|
64
|
+
if defined?(::Rack::Utils)
|
65
|
+
::Rack::Utils.parse_query(query)
|
66
|
+
else
|
67
|
+
@request.class.parse_query_parameters(query)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def expected_url
|
72
|
+
case @expected
|
73
|
+
when Hash
|
74
|
+
return @subject.url_for(@expected)
|
75
|
+
when :back
|
76
|
+
return @request.env['HTTP_REFERER']
|
77
|
+
when %r{^\w+://.*}
|
78
|
+
return @expected
|
79
|
+
else
|
80
|
+
return "http://#{@request.host}" + (@expected.split('')[0] == '/' ? '' : '/') + @expected
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def interpolation_options
|
85
|
+
{ :expected => @expected.inspect, :actual => @actual.inspect }
|
86
|
+
end
|
87
|
+
|
88
|
+
def evaluate_expected_value
|
89
|
+
@expected ||= @block if @block
|
90
|
+
@expected = @spec.instance_eval(&@expected) if @expected.is_a?(Proc)
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
# Passes if the response redirects to the given url. The url can be a string,
|
96
|
+
# a hash or can be supplied as a block (see examples below).
|
97
|
+
#
|
98
|
+
# == Options
|
99
|
+
#
|
100
|
+
# * <tt>:with</tt> - The status 30X used when redirecting.
|
101
|
+
#
|
102
|
+
# == Examples
|
103
|
+
#
|
104
|
+
# should_redirect_to{ users_url }
|
105
|
+
# should_redirect_to(:action => 'index')
|
106
|
+
# should_not_redirect_to(:controller => 'users', :action => 'new')
|
107
|
+
#
|
108
|
+
# it { should redirect_to(users_url).with(302) }
|
109
|
+
# it { should redirect_to(:action => 'index') }
|
110
|
+
# it { should_not redirect_to(:controller => 'users', :action => 'new') }
|
111
|
+
#
|
112
|
+
def redirect_to(expected=nil, options={}, &block)
|
113
|
+
RedirectToMatcher.new(expected, options, &block).spec(self)
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module RSpec::Rails::Matchers
|
2
|
+
module RenderTemplate
|
3
|
+
extend RSpec::Matchers::DSL
|
4
|
+
matcher :render_template do |options, message|
|
5
|
+
$matcher_execution_context.send(:run_action!)
|
6
|
+
match_unless_raises Test::Unit::AssertionFailedError do |_|
|
7
|
+
options = options.to_s if Symbol === options
|
8
|
+
assert_template options, message
|
9
|
+
end
|
10
|
+
|
11
|
+
failure_message_for_should do
|
12
|
+
rescued_exception.message
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,136 @@
|
|
1
|
+
module Remarkable
|
2
|
+
module ActionController
|
3
|
+
module Matchers
|
4
|
+
class RespondWithMatcher < Remarkable::ActionController::Base #:nodoc:
|
5
|
+
arguments :block => true
|
6
|
+
|
7
|
+
optional :with, :body, :content_type
|
8
|
+
|
9
|
+
before_assert do
|
10
|
+
@response = @subject.respond_to?(:response) ? @subject.response : @subject
|
11
|
+
@controller = @spec.instance_variable_get('@controller')
|
12
|
+
end
|
13
|
+
|
14
|
+
before_assert :evaluate_content_type, :evaluate_body
|
15
|
+
|
16
|
+
assertions :status_matches?, :body_matches?, :content_type_matches?
|
17
|
+
|
18
|
+
protected
|
19
|
+
|
20
|
+
def status_matches?
|
21
|
+
return true unless @options[:with] # only continue if not nil
|
22
|
+
|
23
|
+
case @options[:with]
|
24
|
+
when :success, :missing, :redirect, :error
|
25
|
+
@response.send("#{@options[:with]}?")
|
26
|
+
when Fixnum
|
27
|
+
@response.response_code == @options[:with]
|
28
|
+
when Symbol, String
|
29
|
+
@response.response_code == ::ActionController::StatusCodes::SYMBOL_TO_STATUS_CODE[@options[:with].to_sym]
|
30
|
+
when Range
|
31
|
+
@options[:with].include?(@response.response_code)
|
32
|
+
else
|
33
|
+
raise ArgumentError, "I don't know how to interpret status #{@options[:with].inspect}, " <<
|
34
|
+
"please give me a Fixnum, Symbol, String or Range."
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def body_matches?
|
39
|
+
return true unless @options.key?(:body)
|
40
|
+
assert_contains(@response.body, @options[:body])
|
41
|
+
end
|
42
|
+
|
43
|
+
def content_type_matches?
|
44
|
+
return true unless @options.key?(:content_type)
|
45
|
+
assert_contains(@response.content_type, @options[:content_type])
|
46
|
+
end
|
47
|
+
|
48
|
+
def evaluate_content_type
|
49
|
+
return unless @options.key?(:content_type)
|
50
|
+
|
51
|
+
@options[:content_type] = case @options[:content_type]
|
52
|
+
when Symbol
|
53
|
+
Mime::Type.lookup_by_extension(@options[:content_type].to_s).to_s
|
54
|
+
when Regexp
|
55
|
+
@options[:content_type]
|
56
|
+
else
|
57
|
+
@options[:content_type].to_s
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def evaluate_body
|
62
|
+
if @options.key?(:body) || @block
|
63
|
+
value = @options.key?(:body) ? @options[:body] : @block
|
64
|
+
value = @spec.instance_eval(&value) if value.is_a?(Proc)
|
65
|
+
@options[:body] = value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def interpolation_options
|
70
|
+
if @response
|
71
|
+
{ :actual_body => @response.body.inspect,
|
72
|
+
:actual_status => @response.response_code.inspect,
|
73
|
+
:actual_content_type => @response.content_type.inspect }
|
74
|
+
else
|
75
|
+
{ }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
# Passes if the response has the given status. Status can be a Symbol lik
|
82
|
+
# :success, :missing, :redirect and :error. Can be also a Fixnum, Range o
|
83
|
+
# any other symbol which matches to any of Rails status codes.
|
84
|
+
#
|
85
|
+
# == Options
|
86
|
+
#
|
87
|
+
# * <tt>:body</tt> - The body of the response. It accepts strings and or
|
88
|
+
# regular expressions. Altought you might be running your tests without
|
89
|
+
# integrating your views, this is useful when rendering :xml or :text.
|
90
|
+
#
|
91
|
+
# * <tt>:content_type</tt> - The content type of the response.
|
92
|
+
# It accepts strings ('application/rss+xml'), mime constants (Mime::RSS),
|
93
|
+
# symbols (:rss) and regular expressions /rss/.
|
94
|
+
#
|
95
|
+
# == Examples
|
96
|
+
#
|
97
|
+
# should_respond_with :success
|
98
|
+
# should_respond_with :error, :body => /System error/
|
99
|
+
# should_respond_with 301, :content_type => Mime::XML
|
100
|
+
# should_respond_with 300..399, :content_type => Mime::XML
|
101
|
+
#
|
102
|
+
# it { should respond_with(:success) }
|
103
|
+
# it { should respond_with(:error).body(/System error/) }
|
104
|
+
# it { should respond_with(301).content_type(Mime::XML) }
|
105
|
+
# it { should respond_with(300..399).content_type(Mime::XML) }
|
106
|
+
#
|
107
|
+
def respond_with(*args, &block)
|
108
|
+
options = args.extract_options!
|
109
|
+
options.merge!(:with => args.first)
|
110
|
+
RespondWithMatcher.new(options, &block).spec(self)
|
111
|
+
end
|
112
|
+
|
113
|
+
# This is just a shortcut for respond_with :body => body. Check respond_with
|
114
|
+
# for more information.
|
115
|
+
#
|
116
|
+
def respond_with_body(*args, &block)
|
117
|
+
options = args.extract_options!
|
118
|
+
# Since body can be also given as block, only merge if any arguments was
|
119
|
+
# actually sent.
|
120
|
+
options.merge!(:body => args.first) unless args.empty?
|
121
|
+
RespondWithMatcher.new(options, &block).spec(self)
|
122
|
+
end
|
123
|
+
|
124
|
+
# This is just a shortcut for respond_with :content_type => content_type.
|
125
|
+
# It's also used for Shoulda compatibility. Check respond_with for more
|
126
|
+
# information.
|
127
|
+
#
|
128
|
+
def respond_with_content_type(*args, &block)
|
129
|
+
options = args.extract_options!
|
130
|
+
options.merge!(:content_type => args.first)
|
131
|
+
RespondWithMatcher.new(options, &block).spec(self)
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
@@ -0,0 +1,135 @@
|
|
1
|
+
module Remarkable
|
2
|
+
module ActionController
|
3
|
+
module Matchers
|
4
|
+
# Do not inherit from ActionController::Base since it don't need all macro stubs behavior.
|
5
|
+
class RouteMatcher < Remarkable::Base #:nodoc:
|
6
|
+
arguments :method, :path
|
7
|
+
assertions :map_to_path?, :generate_params?
|
8
|
+
|
9
|
+
# Small hack to allow should route().to/from syntax.
|
10
|
+
#
|
11
|
+
after_initialize do
|
12
|
+
if @path.is_a?(Hash)
|
13
|
+
@options.merge!(@path)
|
14
|
+
@path = nil
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
before_assert do
|
19
|
+
@options[:controller] ||= controller_name
|
20
|
+
@populated_path = @path.dup
|
21
|
+
|
22
|
+
@options.each do |key, value|
|
23
|
+
@options[key] = value.to_param if value.respond_to?(:to_param)
|
24
|
+
@populated_path.gsub!(key.inspect, value.to_s)
|
25
|
+
end
|
26
|
+
|
27
|
+
::ActionController::Routing::Routes.reload if ::ActionController::Routing::Routes.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def to(value)
|
31
|
+
@options.merge!(value)
|
32
|
+
self
|
33
|
+
end
|
34
|
+
|
35
|
+
def from(value)
|
36
|
+
@path = value
|
37
|
+
self
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
def map_to_path?
|
43
|
+
route_for = ::ActionController::Routing::Routes.generate(@options) rescue nil
|
44
|
+
return route_for == @populated_path, :actual => route_for.inspect
|
45
|
+
end
|
46
|
+
|
47
|
+
def generate_params?
|
48
|
+
env = ::ActionController::Routing::Routes.extract_request_environment(request) if request
|
49
|
+
|
50
|
+
env ||= {}
|
51
|
+
env[:method] = @method.to_sym
|
52
|
+
params_from = ::ActionController::Routing::Routes.recognize_path(@populated_path, env) rescue nil
|
53
|
+
return params_from == @options, :actual => params_from.inspect
|
54
|
+
end
|
55
|
+
|
56
|
+
def controller
|
57
|
+
@controller ||= if @subject.is_a?(::ActionController::Base)
|
58
|
+
@subject
|
59
|
+
elsif @spec.respond_to?(:controller)
|
60
|
+
@spec.controller
|
61
|
+
else
|
62
|
+
raise "Could not find a controller for route specs."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# First tries to get the controller name from the subject, then from
|
67
|
+
# the spec class using controller class or finally, from the described
|
68
|
+
# class.
|
69
|
+
#
|
70
|
+
# We have to try the described class because we don't have neither the
|
71
|
+
# subject or the controller class in the RoutingExampleGroup.
|
72
|
+
#
|
73
|
+
def controller_name
|
74
|
+
if controller_class
|
75
|
+
controller_class.name.gsub(/Controller$/, '').tableize
|
76
|
+
else
|
77
|
+
raise ArgumentError, "I cannot guess the controller name in route. Please supply :controller as option"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
def controller_class
|
82
|
+
@controller_class ||= begin
|
83
|
+
spec_class = @spec.class unless @spec.class == Class
|
84
|
+
|
85
|
+
attempts = []
|
86
|
+
attempts << controller.class if controller
|
87
|
+
attempts << spec_class.controller_class if spec_class.respond_to?(:controller_class)
|
88
|
+
attempts << spec_class.described_class if spec_class.respond_to?(:described_class)
|
89
|
+
|
90
|
+
# Check for not blank names to address an odd rspec/rails behavior.
|
91
|
+
attempts.find { |klass| ::ActionController::Base >= klass && !klass.name.blank? }
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def request
|
96
|
+
controller.request
|
97
|
+
end
|
98
|
+
|
99
|
+
def interpolation_options
|
100
|
+
{ :options => @options.inspect, :method => @method.to_s.upcase, :path => @path.inspect }
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
# Assert route generation AND route recognition.
|
105
|
+
#
|
106
|
+
# == Examples
|
107
|
+
#
|
108
|
+
# # autodetects the :controller
|
109
|
+
# should_route :get, '/posts', :action => :index
|
110
|
+
#
|
111
|
+
# # explicitly specify :controller
|
112
|
+
# should_route :post, '/posts', :controller => :posts, :action => :create
|
113
|
+
#
|
114
|
+
# # non-string parameter
|
115
|
+
# should_route :get, '/posts/1', :controller => :posts, :action => :show, :id => 1
|
116
|
+
#
|
117
|
+
# # string-parameter
|
118
|
+
# should_route :put, '/posts/1', :controller => :posts, :action => :update, :id => "1"
|
119
|
+
# should_route :delete, '/posts/1', :controller => :posts, :action => :destroy, :id => 1
|
120
|
+
# should_route :get, '/posts/new', :controller => :posts, :action => :new
|
121
|
+
#
|
122
|
+
# # nested routes
|
123
|
+
# should_route :get, '/users/5/posts', :controller => :posts, :action => :index, :user_id => 5
|
124
|
+
# should_route :post, '/users/5/posts', :controller => :posts, :action => :create, :user_id => 5
|
125
|
+
#
|
126
|
+
# # it example
|
127
|
+
# it { should route(:get, :action => :index).to('/users/5/posts') }
|
128
|
+
#
|
129
|
+
def route(*params, &block)
|
130
|
+
RouteMatcher.new(*params, &block).spec(self)
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|