merb 0.4.0 → 0.4.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +23 -160
- data/Rakefile +15 -14
- data/app_generators/merb/merb_generator.rb +4 -3
- data/app_generators/merb/templates/Rakefile +1 -6
- data/app_generators/merb/templates/app/mailers/views/layout/{application.erb → application.html.erb} +0 -0
- data/app_generators/merb/templates/app/mailers/views/layout/application.text.erb +1 -0
- data/app_generators/merb/templates/app/parts/views/layout/application.html.erb +1 -0
- data/app_generators/merb/templates/app/views/layout/application.html.erb +2 -2
- data/app_generators/merb/templates/config/dependencies.rb +1 -1
- data/app_generators/merb/templates/config/router.rb +4 -1
- data/app_generators/merb/templates/spec/spec_helper.rb +2 -3
- data/lib/autotest/merb_rspec.rb +1 -0
- data/lib/merb/abstract_controller.rb +31 -2
- data/lib/merb/controller.rb +5 -5
- data/lib/merb/core_ext/get_args.rb +5 -1
- data/lib/merb/exceptions.rb +17 -0
- data/lib/merb/generators/merb_app/merb_app.rb +4 -1
- data/lib/merb/generators/merb_plugin.rb +4 -1
- data/lib/merb/logger.rb +5 -1
- data/lib/merb/mail_controller.rb +1 -1
- data/lib/merb/mailer.rb +2 -2
- data/lib/merb/mixins/controller.rb +5 -1
- data/lib/merb/mixins/render.rb +57 -27
- data/lib/merb/part_controller.rb +1 -1
- data/lib/merb/request.rb +2 -2
- data/lib/merb/server.rb +33 -5
- data/lib/merb/template/erubis.rb +1 -1
- data/lib/merb.rb +15 -5
- data/merb_generators/resource/resource_generator.rb +9 -2
- data/spec/fixtures/config/merb.yml +18 -0
- data/spec/fixtures/controllers/dispatch_spec_controllers.rb +227 -0
- data/spec/fixtures/controllers/render_spec_controllers.rb +115 -0
- data/spec/fixtures/foo.rb +3 -0
- data/spec/fixtures/mailers/views/layout/application.html.erb +3 -0
- data/spec/fixtures/mailers/views/layout/application.text.erb +3 -0
- data/spec/fixtures/mailers/views/test_mail_controller/eighth.html.erb +1 -0
- data/spec/fixtures/mailers/views/test_mail_controller/eighth.text.erb +1 -0
- data/spec/fixtures/mailers/views/test_mail_controller/first.html.erb +1 -0
- data/spec/fixtures/mailers/views/test_mail_controller/first.text.erb +1 -0
- data/spec/fixtures/mailers/views/test_mail_controller/ninth.html.erb +1 -0
- data/spec/fixtures/mailers/views/test_mail_controller/ninth.text.erb +1 -0
- data/spec/fixtures/mailers/views/test_mail_controller/second.text.erb +1 -0
- data/spec/fixtures/mailers/views/test_mail_controller/third.html.erb +1 -0
- data/spec/fixtures/models/router_spec_models.rb +20 -0
- data/spec/fixtures/parts/views/layout/todo_part.html.erb +3 -0
- data/spec/fixtures/parts/views/layout/todo_part.xml.erb +3 -0
- data/spec/fixtures/parts/views/todo_part/formatted_output.html.erb +1 -0
- data/spec/fixtures/parts/views/todo_part/formatted_output.js.erb +1 -0
- data/spec/fixtures/parts/views/todo_part/formatted_output.xml.erb +1 -0
- data/spec/fixtures/parts/views/todo_part/list.html.erb +3 -0
- data/spec/fixtures/sample.txt +1 -0
- data/spec/fixtures/views/erubis.html.erb +1 -0
- data/spec/fixtures/views/examples/_erubis.html.erb +1 -0
- data/spec/fixtures/views/examples/_haml.html.haml +1 -0
- data/spec/fixtures/views/examples/_markaby.html.mab +1 -0
- data/spec/fixtures/views/examples/_throw_content.html.erb +6 -0
- data/spec/fixtures/views/examples/hello.xml.builder +1 -0
- data/spec/fixtures/views/examples/js.js.erb +1 -0
- data/spec/fixtures/views/examples/template_catch_content.html.erb +15 -0
- data/spec/fixtures/views/examples/template_catch_content_from_partial.html.erb +6 -0
- data/spec/fixtures/views/examples/template_throw_content.html.erb +10 -0
- data/spec/fixtures/views/exceptions/admin_access_required.html.erb +1 -0
- data/spec/fixtures/views/extension_template_controller/_nested_js.js.erb +1 -0
- data/spec/fixtures/views/extension_template_controller/_nested_xml.xml.erb +1 -0
- data/spec/fixtures/views/extension_template_controller/_render_partial_multiple_times.html.erb +1 -0
- data/spec/fixtures/views/extension_template_controller/erubis_templates.html.erb +1 -0
- data/spec/fixtures/views/extension_template_controller/erubis_templates.js.erb +1 -0
- data/spec/fixtures/views/extension_template_controller/erubis_templates.rhtml +1 -0
- data/spec/fixtures/views/extension_template_controller/erubis_templates.xml.erb +1 -0
- data/spec/fixtures/views/extension_template_controller/haml_index.html.haml +0 -0
- data/spec/fixtures/views/extension_template_controller/haml_templates.html.haml +1 -0
- data/spec/fixtures/views/extension_template_controller/haml_templates.js.haml +1 -0
- data/spec/fixtures/views/extension_template_controller/haml_templates.xml.haml +1 -0
- data/spec/fixtures/views/extension_template_controller/index.html.erb +0 -0
- data/spec/fixtures/views/extension_template_controller/markaby_index.html.mab +0 -0
- data/spec/fixtures/views/extension_template_controller/markaby_templates.html.mab +1 -0
- data/spec/fixtures/views/extension_template_controller/markaby_templates.js.mab +1 -0
- data/spec/fixtures/views/extension_template_controller/markaby_templates.xml.mab +1 -0
- data/spec/fixtures/views/extension_template_controller/render_multiple_partials.html.erb +4 -0
- data/spec/fixtures/views/extension_template_controller/render_nested_js.js.erb +1 -0
- data/spec/fixtures/views/extension_template_controller/render_nested_xml.xml.erb +1 -0
- data/spec/fixtures/views/haml.html.haml +1 -0
- data/spec/fixtures/views/haml.xml.haml +2 -0
- data/spec/fixtures/views/layout/application.html.erb +1 -0
- data/spec/fixtures/views/layout/application.xml.erb +1 -0
- data/spec/fixtures/views/layout/nested/example.html.erb +1 -0
- data/spec/fixtures/views/markaby.html.mab +1 -0
- data/spec/fixtures/views/nested/example/test.html.erb +1 -0
- data/spec/fixtures/views/partials/_erubis.html.erb +1 -0
- data/spec/fixtures/views/partials/_erubis_collection.html.erb +1 -0
- data/spec/fixtures/views/partials/_erubis_collection_with_locals.html.erb +1 -0
- data/spec/fixtures/views/partials/_erubis_new.html.erb +1 -0
- data/spec/fixtures/views/partials/_haml.html.haml +1 -0
- data/spec/fixtures/views/partials/_haml_collection.html.haml +1 -0
- data/spec/fixtures/views/partials/_haml_collection_with_locals.html.haml +1 -0
- data/spec/fixtures/views/partials/_haml_new.html.haml +1 -0
- data/spec/fixtures/views/partials/_markaby.html.mab +1 -0
- data/spec/fixtures/views/partials/_markaby_collection.html.mab +1 -0
- data/spec/fixtures/views/partials/_markaby_collection_with_locals.html.mab +1 -0
- data/spec/fixtures/views/partials/_markaby_new.html.mab +1 -0
- data/spec/fixtures/views/render_object_controller/render_object_with_template.html.erb +1 -0
- data/spec/fixtures/views/render_object_controller/render_object_with_template.js.erb +1 -0
- data/spec/fixtures/views/render_object_controller/render_object_with_template.xml.erb +1 -0
- data/spec/fixtures/views/template_views/interface__buffer_erubis.html.erb +4 -0
- data/spec/fixtures/views/template_views/interface__buffer_haml.html.haml +7 -0
- data/spec/fixtures/views/template_views/interface__buffer_markaby.html.mab +7 -0
- data/spec/fixtures/views/template_views/interface_capture_erubis.html.erb +15 -0
- data/spec/fixtures/views/template_views/interface_capture_haml.html.haml +15 -0
- data/spec/fixtures/views/template_views/interface_capture_markaby.html.mab +4 -0
- data/spec/fixtures/views/template_views/interface_concat_erubis.html.erb +12 -0
- data/spec/fixtures/views/template_views/interface_concat_haml.html.haml +11 -0
- data/spec/fixtures/views/template_views/interface_concat_markaby.html.mab +14 -0
- data/spec/fixtures/views/test.dir/the_template.html.erb +1 -0
- data/spec/merb/abstract_controller_spec.rb +37 -0
- data/spec/merb/caching_spec.rb +102 -0
- data/spec/merb/config_spec.rb +29 -0
- data/spec/merb/controller_filters_spec.rb +188 -0
- data/spec/merb/controller_spec.rb +144 -0
- data/spec/merb/cookie_store_spec.rb +85 -0
- data/spec/merb/core_ext_spec.rb +430 -0
- data/spec/merb/dispatch_spec.rb +514 -0
- data/spec/merb/fake_request_spec.rb +72 -0
- data/spec/merb/form_control_mixin_spec.rb +431 -0
- data/spec/merb/generator_spec.rb +121 -0
- data/spec/merb/handler_spec.rb +169 -0
- data/spec/merb/mail_controller_spec.rb +144 -0
- data/spec/merb/mailer_spec.rb +87 -0
- data/spec/merb/multipart_spec.rb +49 -0
- data/spec/merb/part_controller_spec.rb +92 -0
- data/spec/merb/plugins_spec.rb +80 -0
- data/spec/merb/render_spec.rb +378 -0
- data/spec/merb/request_spec.rb +243 -0
- data/spec/merb/responder_spec.rb +561 -0
- data/spec/merb/router_spec.rb +726 -0
- data/spec/merb/template_spec.rb +41 -0
- data/spec/merb/upload_handler_spec.rb +101 -0
- data/spec/merb/view_context_spec.rb +148 -0
- data/spec/spec_generator_helper.rb +19 -0
- data/spec/spec_helper.rb +88 -0
- metadata +203 -65
- data/lib/merb/caching/store/memcache.rb +0 -20
- data/script/destroy +0 -14
- data/script/generate +0 -14
@@ -0,0 +1,726 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
require 'benchmark'
|
3
|
+
include Benchmark
|
4
|
+
|
5
|
+
require FIXTURES / 'models/router_spec_models'
|
6
|
+
$TESTING = true
|
7
|
+
|
8
|
+
# OpenStruct fails to return 'method' correctly, which we require for our Request object
|
9
|
+
class SimpleRequest < OpenStruct
|
10
|
+
def method() @table[:method] end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Merb::Router::CachedProc do
|
14
|
+
it "should register a regular expression" do
|
15
|
+
regexp = /t.*e.*s.*t/
|
16
|
+
cc = Merb::Router::CachedProc.new(regexp)
|
17
|
+
Merb::Router::CachedProc[cc.index].cache.should == regexp
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should register a proc" do
|
21
|
+
testproc = proc { puts 'test' }
|
22
|
+
cc = Merb::Router::CachedProc.new(testproc)
|
23
|
+
Merb::Router::CachedProc[cc.index].cache.should == testproc
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should return ruby code as an evaluatable string" do
|
27
|
+
testproc = proc { 'test proc' }
|
28
|
+
cc = Merb::Router::CachedProc.new(testproc)
|
29
|
+
"#{cc}".should == "CachedProc[#{cc.index}].cache"
|
30
|
+
eval("Merb::Router::#{cc}.call").should == "test proc"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe Merb::Router do
|
35
|
+
it "should compile to an if / elsif statement" do
|
36
|
+
lambda {
|
37
|
+
Merb::Router.prepare do |r|
|
38
|
+
r.match('/:controller/:action').to_resources(:controller => '/admin/:controller')
|
39
|
+
end
|
40
|
+
Merb::Router.compiled_statement.should match(/^\s*if/m)
|
41
|
+
}.should_not raise_error
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should match against requests" do
|
45
|
+
Merb::Router.prepare do |r|
|
46
|
+
r.match('/:controller/:action').to_resources(:controller => '/admin/:controller')
|
47
|
+
end
|
48
|
+
request = Merb::Test::FakeRequest.new(:request_uri => "/test/request")
|
49
|
+
result = Merb::Router.match(request, {})
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should be able to prepend routes to the @@routes list" do
|
53
|
+
r1, r2 = nil, nil
|
54
|
+
Merb::Router.prepare do |r|
|
55
|
+
r1 = r.match('/:controller/:action').to(:controller => '/admin/:controller')
|
56
|
+
end
|
57
|
+
Merb::Router.prepend do |r|
|
58
|
+
r2 = r.match('/:controller/:action').to(:controller => '/admin/:controller')
|
59
|
+
end
|
60
|
+
Merb::Router.routes[0].should == r2
|
61
|
+
Merb::Router.routes[1].should == r1
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should be able to append routes to the @@routes list" do
|
65
|
+
r1, r2 = nil, nil
|
66
|
+
Merb::Router.prepare do |r|
|
67
|
+
r1 = r.match('/:controller/:action').to(:controller => '/admin/:controller')
|
68
|
+
end
|
69
|
+
Merb::Router.append do |r|
|
70
|
+
r2 = r.match('/:controller/:action').to(:controller => '/admin/:controller')
|
71
|
+
end
|
72
|
+
Merb::Router.routes[0].should == r1
|
73
|
+
Merb::Router.routes[1].should == r2
|
74
|
+
end
|
75
|
+
|
76
|
+
# it "should be fast" do
|
77
|
+
# Merb::Router.prepare do |r|
|
78
|
+
# r.resource :icon
|
79
|
+
# r.resources :posts, :member => {:stats => [:get, :put]},
|
80
|
+
# :collection => {:filter => [:get]} do |post|
|
81
|
+
# post.resources :comments, :member => {:stats => [:get, :put]}
|
82
|
+
# post.resource :profile
|
83
|
+
# end
|
84
|
+
# r.resources :as do |a|
|
85
|
+
# a.resources :bs do |b|
|
86
|
+
# b.resources :cs
|
87
|
+
# end
|
88
|
+
# end
|
89
|
+
# r.match("/admin") do |admin|
|
90
|
+
# admin.resources :tags
|
91
|
+
# end
|
92
|
+
# r.default_routes
|
93
|
+
# end
|
94
|
+
# request = Merb::Test::FakeRequest.new(:request_uri => "/test/request")
|
95
|
+
#
|
96
|
+
# bm(12) do |test|
|
97
|
+
# # user system total real
|
98
|
+
# # with CachedCode 4.510000 0.050000 4.560000 ( 5.244656)
|
99
|
+
# # with in-place regexps 2.130000 0.030000 2.160000 ( 2.272443)
|
100
|
+
# test.report("with in-place regexps") do
|
101
|
+
# 20_000.times do
|
102
|
+
# Merb::Router.match(request)
|
103
|
+
# end
|
104
|
+
# end
|
105
|
+
# end
|
106
|
+
# end
|
107
|
+
end
|
108
|
+
|
109
|
+
describe Merb::Router, "when doing route matching with a big set of example routes" do
|
110
|
+
require 'set'
|
111
|
+
def should_only_have_keys(hash, *keys)
|
112
|
+
Set.new(hash.keys).should == Set.new(keys)
|
113
|
+
end
|
114
|
+
|
115
|
+
before(:all) do
|
116
|
+
Merb::Router.prepare do |r|
|
117
|
+
# A simple route match, sends "/contact" to Info#contact
|
118
|
+
# (i.e. the 'contact' method inside the 'Info' controller)
|
119
|
+
r.match("/contact").
|
120
|
+
to(:controller => "info", :action => "contact")
|
121
|
+
|
122
|
+
# Use placeholders (e.g. :book_id) in the match, and they will be passed along to params
|
123
|
+
r.match("/books/:book_id/:action").
|
124
|
+
to(:controller => "books")
|
125
|
+
|
126
|
+
# Use placeholders in the "to" results for more complicated routing, e.g. for modules
|
127
|
+
r.match("/admin/:module/:controller/:action").
|
128
|
+
to(:controller => ":module/:controller")
|
129
|
+
r.match("/admin/:module/:controller/:action/:id").
|
130
|
+
to(:controller => ":module/:controller")
|
131
|
+
|
132
|
+
# Use a 'match' block to factor out repetitive 'match' parts
|
133
|
+
r.match("/accounts") do |a|
|
134
|
+
# The following will match "/accounts/overview" and route to Accounts#overview
|
135
|
+
a.match("/overview").
|
136
|
+
to(:controller => "accounts", :action => "overview")
|
137
|
+
a.match("/:id/:action").
|
138
|
+
to(:controller => "accounts")
|
139
|
+
a.match("/:id/:action.:format").
|
140
|
+
to(:controller => "accounts")
|
141
|
+
end
|
142
|
+
|
143
|
+
# Use a 'to' block to factor out repetitive 'to' parts
|
144
|
+
r.to(:controller => "accounts") do |a|
|
145
|
+
$r = a.match("/reports").
|
146
|
+
to(:action => "reports") # maps to Accounts#reports
|
147
|
+
|
148
|
+
a.match("/slideshow/:id").
|
149
|
+
to(:action => "slideshow") # maps to Accounts#slideshow
|
150
|
+
end
|
151
|
+
|
152
|
+
# Use a regular expression as the path matcher. Note that you must specify the
|
153
|
+
# ^ (beginning of line) and $ (end of line) boundaries if you desire them.
|
154
|
+
r.match(%r{^/movies/:id/movie-[a-z][a-zA-Z\-]+$}).
|
155
|
+
to(:controller => "movies", :action => "search_engine_optimizer")
|
156
|
+
|
157
|
+
# Use square-bracket notation to replace param results with captures from the path
|
158
|
+
r.match(%r[^/movies/(\d+)-(\d+)-(\d+)$]).
|
159
|
+
to(:controller => "movies", :movie_id => "[1][2][3]", :action => "show")
|
160
|
+
|
161
|
+
# Use the second optional argument of 'match' to be more specific about the request;
|
162
|
+
# in this case, only accept the POST method for the /movies/create action
|
163
|
+
r.match("/movies/create", :method => "post").
|
164
|
+
to(:controller => "movies", :action => "create")
|
165
|
+
|
166
|
+
# Use variables from the 'match' as results sent to the controller in the params hash,
|
167
|
+
# e.g. :user_agent[1] will be replaced with either 'MSIE' or 'Gecko' in the following case:
|
168
|
+
r.match(%r[^/movies/(.+)], :user_agent => /(MSIE|Gecko)/).
|
169
|
+
to(:controller => "movies", :title => "[1]", :action => "show", :agent => ":user_agent[1]")
|
170
|
+
|
171
|
+
# The 'match' method can also be called without the path string or regexp.
|
172
|
+
# In this example, direct all insecure traffic to a Insecure#index
|
173
|
+
r.match(:protocol => "http://").
|
174
|
+
to(:controller => "insecure", :action => "index")
|
175
|
+
|
176
|
+
# Use anonymous placeholders in place of the ugly-looking pattern, /([^\/.,;?]+)/
|
177
|
+
r.match("/::/users/::").
|
178
|
+
to(:controller => "users", :action => "[2]", :id => "[1]")
|
179
|
+
|
180
|
+
# Putting it all together, and adding the requirement that we use an "admin" prefix on the
|
181
|
+
# domain (e.g. admin.mysite.com), do some interesting stuff:
|
182
|
+
r.match(:domain => /^admin\b/) do |admin|
|
183
|
+
admin.match(%r[/([A-Z]\w+)\+([A-Z]\w+)/::]).
|
184
|
+
to(:controller => "admin/users", :action => ":path[3]",
|
185
|
+
:first_name => ":path[1]", :last_name => ":path[2]")
|
186
|
+
end.to(:controller => "admin/users", :action => "default")
|
187
|
+
# Note that the last line above sends all traffic in the "admin" subdomain to the
|
188
|
+
# Admin::Users#default action if no other route is matched.
|
189
|
+
|
190
|
+
# Create a deferred route. In this case, the decision of whether or not the route
|
191
|
+
# is a match is made via the .xhr? call. Note that it's ok to put the hash in a
|
192
|
+
# conditional because if the "if" statement is false, ruby returns nil (i.e. no match).
|
193
|
+
r.match(%r[^/deferred]).defer_to do |request, params|
|
194
|
+
{:controller => "ajax", :action => "index"} if request.xhr?
|
195
|
+
end
|
196
|
+
|
197
|
+
# Use the placeholders in a the deferred route
|
198
|
+
r.match("/deferred/:action").defer_to do |request, params|
|
199
|
+
params.merge(:controller => "deferred")
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
it "should connect '/contact' to Info#contact" do
|
205
|
+
index, route = Merb::Router.match(SimpleRequest.new(:protocol => "http://", :path => '/contact'), {})
|
206
|
+
route[:controller].should == "info"
|
207
|
+
route[:action].should == "contact"
|
208
|
+
should_only_have_keys(route, :controller, :action)
|
209
|
+
end
|
210
|
+
|
211
|
+
it "should use placeholders in the match and pass them along to the params" do
|
212
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/books/12/show'), {})
|
213
|
+
route[:controller].should == "books"
|
214
|
+
route[:action].should == "show"
|
215
|
+
route[:book_id].should == "12"
|
216
|
+
should_only_have_keys(route, :controller, :action, :book_id)
|
217
|
+
end
|
218
|
+
|
219
|
+
it "should allow placeholders to be used in the params to construct results from matches" do
|
220
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/admin/accounts/users/index'), {})
|
221
|
+
route[:controller].should == "accounts/users"
|
222
|
+
route[:action].should == "index"
|
223
|
+
should_only_have_keys(route, :module, :controller, :action)
|
224
|
+
|
225
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/admin/payment/processors/edit/4'), {})
|
226
|
+
route[:controller].should == "payment/processors"
|
227
|
+
route[:action].should == "edit"
|
228
|
+
route[:id].should == "4"
|
229
|
+
should_only_have_keys(route, :module, :controller, :action, :id)
|
230
|
+
end
|
231
|
+
|
232
|
+
it "should allow 'match' to use a block to factor out repetitive parts, merging the path as it goes" do
|
233
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/accounts/overview'), {})
|
234
|
+
route[:controller].should == "accounts"
|
235
|
+
route[:action].should == "overview"
|
236
|
+
should_only_have_keys(route, :controller, :action)
|
237
|
+
|
238
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/accounts/12/show.xml'), {})
|
239
|
+
route[:controller].should == "accounts"
|
240
|
+
route[:action].should == "show"
|
241
|
+
route[:id].should == "12"
|
242
|
+
route[:format].should == "xml"
|
243
|
+
should_only_have_keys(route, :controller, :action, :id, :format)
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should allow 'to' to use a block to factor out repetitive params" do
|
247
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/reports'), {})
|
248
|
+
route[:controller].should == "accounts"
|
249
|
+
route[:action].should == "reports"
|
250
|
+
should_only_have_keys(route, :controller, :action)
|
251
|
+
|
252
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/slideshow/2'), {})
|
253
|
+
route[:controller].should == "accounts"
|
254
|
+
route[:action].should == "slideshow"
|
255
|
+
route[:id].should == "2"
|
256
|
+
should_only_have_keys(route, :controller, :action, :id)
|
257
|
+
end
|
258
|
+
|
259
|
+
it "should be able to use a regular expression instead of a string as the path-matcher" do
|
260
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/movies/5/movie-an-adventure-in-wonderland'), {})
|
261
|
+
route[:controller].should == "movies"
|
262
|
+
route[:action].should == "search_engine_optimizer"
|
263
|
+
route[:id].should == "5"
|
264
|
+
should_only_have_keys(route, :controller, :action, :id)
|
265
|
+
end
|
266
|
+
|
267
|
+
it "should be able to use square bracket notation to replace param results with captures from the path" do
|
268
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/movies/123-1-9999'), {})
|
269
|
+
route[:controller].should == "movies"
|
270
|
+
route[:action].should == "show"
|
271
|
+
route[:movie_id].should == "12319999"
|
272
|
+
should_only_have_keys(route, :controller, :action, :movie_id)
|
273
|
+
end
|
274
|
+
|
275
|
+
it "should only allow the POST method to '/movies/create'" do
|
276
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/movies/create', :method => "get"), {})
|
277
|
+
route[:controller].should be_nil
|
278
|
+
route[:action].should be_nil
|
279
|
+
should_only_have_keys(route)
|
280
|
+
|
281
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/movies/create', :method => "post"), {})
|
282
|
+
route[:controller].should == "movies"
|
283
|
+
route[:action].should == "create"
|
284
|
+
should_only_have_keys(route, :controller, :action)
|
285
|
+
end
|
286
|
+
|
287
|
+
it "should use variables from the 'match' as a result sent to the controller in the params hash" do
|
288
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/movies/harry-potter-3', :user_agent => "Internet Explorer (MSIE)"), {})
|
289
|
+
route[:controller].should == "movies"
|
290
|
+
route[:action].should == "show"
|
291
|
+
route[:title].should == "harry-potter-3"
|
292
|
+
route[:agent].should == "MSIE"
|
293
|
+
should_only_have_keys(route, :controller, :action, :title, :agent)
|
294
|
+
end
|
295
|
+
|
296
|
+
it "should be able to match without the use of a path, sending all HTTP traffic to 'insecure' controller" do
|
297
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/visit', :protocol => "http://"), {})
|
298
|
+
route[:controller].should == "insecure"
|
299
|
+
route[:action].should == "index"
|
300
|
+
should_only_have_keys(route, :controller, :action)
|
301
|
+
|
302
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/3/users/show', :protocol => "http://"), {})
|
303
|
+
route[:controller].should == "insecure"
|
304
|
+
route[:action].should == "index"
|
305
|
+
should_only_have_keys(route, :controller, :action)
|
306
|
+
end
|
307
|
+
|
308
|
+
it "should use anonymous placeholders" do
|
309
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/5/users/show', :protocol => "https://"), {})
|
310
|
+
route[:controller].should == "users"
|
311
|
+
route[:action].should == "show"
|
312
|
+
route[:id].should == "5"
|
313
|
+
should_only_have_keys(route, :controller, :action, :id)
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should send all admin.* domains to the 'admin/users' controller, and 'default' action" do
|
317
|
+
index, route = Merb::Router.match(SimpleRequest.new(:domain => "admin.mysite.com", :path => '/welcome', :protocol => "https://"), {})
|
318
|
+
route[:controller].should == "admin/users"
|
319
|
+
route[:action].should == "default"
|
320
|
+
should_only_have_keys(route, :controller, :action)
|
321
|
+
|
322
|
+
index, route = Merb::Router.match(SimpleRequest.new(:domain => "admin.another-site.com", :path => '/go/somewhere/else', :protocol => "https://"), {})
|
323
|
+
route[:controller].should == "admin/users"
|
324
|
+
route[:action].should == "default"
|
325
|
+
should_only_have_keys(route, :controller, :action)
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should decipher the first-name / last-name pairs on an admin.* domain" do
|
329
|
+
index, route = Merb::Router.match(SimpleRequest.new(:domain => "admin.mysite.com", :path => '/Duane+Johnson/edit', :protocol => "https://"), {})
|
330
|
+
route[:controller].should == "admin/users"
|
331
|
+
route[:action].should == "edit"
|
332
|
+
route[:first_name].should == "Duane"
|
333
|
+
route[:last_name].should == "Johnson"
|
334
|
+
should_only_have_keys(route, :controller, :action, :first_name, :last_name)
|
335
|
+
end
|
336
|
+
|
337
|
+
it "should defer to the Ajax controller for xhr requests" do
|
338
|
+
index, route = Merb::Router.match(SimpleRequest.new(:xhr? => true, :path => '/deferred/to/somewhere', :protocol => "https://"), {})
|
339
|
+
route[:controller].should == "ajax"
|
340
|
+
route[:action].should == "index"
|
341
|
+
should_only_have_keys(route, :controller, :action)
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should let a deferred block use the path's MatchData" do
|
345
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/deferred/elsewhere', :protocol => "https://"), {})
|
346
|
+
route[:controller].should == "deferred"
|
347
|
+
route[:action].should == "elsewhere"
|
348
|
+
should_only_have_keys(route, :controller, :action)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
|
352
|
+
describe Merb::Router, "with a single resource, 'blogposts' with 'comments'" do
|
353
|
+
before(:each) do
|
354
|
+
Merb::Router.prepare do |r|
|
355
|
+
r.resources :blogposts do |bposts|
|
356
|
+
bposts.resources :comments
|
357
|
+
end
|
358
|
+
end
|
359
|
+
end
|
360
|
+
|
361
|
+
it "should match /blogposts" do
|
362
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts', :method => :get), {})
|
363
|
+
route[:controller].should == 'blogposts'
|
364
|
+
route[:action].should == 'index'
|
365
|
+
|
366
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts', :method => :post), {})
|
367
|
+
route[:controller].should == 'blogposts'
|
368
|
+
route[:action].should == 'create'
|
369
|
+
end
|
370
|
+
|
371
|
+
it "should match /blogposts/new" do
|
372
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts/new', :method => :get), {})
|
373
|
+
route[:controller].should == 'blogposts'
|
374
|
+
route[:action].should == 'new'
|
375
|
+
end
|
376
|
+
|
377
|
+
it "should match /blogposts/1" do
|
378
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts/1', :method => :get), {})
|
379
|
+
route[:controller].should == 'blogposts'
|
380
|
+
route[:action].should == 'show'
|
381
|
+
route[:id].should == '1'
|
382
|
+
|
383
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts/1', :method => :put), {})
|
384
|
+
route[:controller].should == 'blogposts'
|
385
|
+
route[:action].should == 'update'
|
386
|
+
route[:id].should == '1'
|
387
|
+
|
388
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts/1', :method => :delete), {})
|
389
|
+
route[:controller].should == 'blogposts'
|
390
|
+
route[:action].should == 'destroy'
|
391
|
+
route[:id].should == '1'
|
392
|
+
end
|
393
|
+
|
394
|
+
it "should match /blogposts/1;edit" do
|
395
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts/1;edit', :method => :get), {})
|
396
|
+
route[:controller].should == 'blogposts'
|
397
|
+
route[:action].should == 'edit'
|
398
|
+
route[:id].should == '1'
|
399
|
+
|
400
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts/1;edit', :method => :put), {})
|
401
|
+
route[:controller].should be_nil
|
402
|
+
route[:action].should be_nil
|
403
|
+
end
|
404
|
+
|
405
|
+
it "should match /blogposts/1/edit" do
|
406
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts/1/edit', :method => :get), {})
|
407
|
+
route[:controller].should == 'blogposts'
|
408
|
+
route[:action].should == 'edit'
|
409
|
+
route[:id].should == '1'
|
410
|
+
|
411
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/blogposts/1/edit', :method => :put), {})
|
412
|
+
route[:controller].should be_nil
|
413
|
+
route[:action].should be_nil
|
414
|
+
end
|
415
|
+
|
416
|
+
it "should generate blogposts path" do
|
417
|
+
Merb::Router.generate(:blogposts).should == '/blogposts'
|
418
|
+
end
|
419
|
+
|
420
|
+
it "should generate blogpost path" do
|
421
|
+
Merb::Router.generate(:blogpost, {:id => 1}).should == '/blogposts/1'
|
422
|
+
b = Blogposts.new
|
423
|
+
Merb::Router.generate(:blogpost, b).should == '/blogposts/42'
|
424
|
+
Merb::Router.generate(:blogpost, :id => b).should == '/blogposts/42'
|
425
|
+
end
|
426
|
+
|
427
|
+
it "should generate new_blogpost path" do
|
428
|
+
Merb::Router.generate(:new_blogpost).should == '/blogposts/new'
|
429
|
+
end
|
430
|
+
|
431
|
+
it "should generate edit_blogpost path" do
|
432
|
+
Merb::Router.generate(:edit_blogpost, {:id => 1}).should == '/blogposts/1/edit'
|
433
|
+
end
|
434
|
+
|
435
|
+
it "should generate comments path" do
|
436
|
+
c = Comment.new
|
437
|
+
Merb::Router.generate(:comments, c).should == '/blogposts/42/comments'
|
438
|
+
end
|
439
|
+
|
440
|
+
it "should generate comment path" do
|
441
|
+
c = Comment.new
|
442
|
+
Merb::Router.generate(:comment, c).should == '/blogposts/42/comments/24'
|
443
|
+
end
|
444
|
+
|
445
|
+
end
|
446
|
+
|
447
|
+
|
448
|
+
describe Merb::Router, "with resources using name_prefix, 'oranges' and 'ape'" do
|
449
|
+
before(:each) do
|
450
|
+
Merb::Router.prepare do |r|
|
451
|
+
r.resources :oranges, :name_prefix => "florida_"
|
452
|
+
r.resource :ape, :name_prefix => "grape_"
|
453
|
+
end
|
454
|
+
end
|
455
|
+
|
456
|
+
it "should match /oranges" do
|
457
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/oranges', :method => :get), {})
|
458
|
+
route[:controller].should == 'oranges'
|
459
|
+
route[:action].should == 'index'
|
460
|
+
end
|
461
|
+
|
462
|
+
it "should generate florida_oranges path" do
|
463
|
+
Merb::Router.generate(:florida_oranges).should == '/oranges'
|
464
|
+
end
|
465
|
+
|
466
|
+
it "should generate florida_orange path" do
|
467
|
+
Merb::Router.generate(:florida_orange, {:id => 1}).should == '/oranges/1'
|
468
|
+
b = Blogposts.new
|
469
|
+
Merb::Router.generate(:florida_orange, b).should == '/oranges/42'
|
470
|
+
Merb::Router.generate(:florida_orange, :id => b).should == '/oranges/42'
|
471
|
+
end
|
472
|
+
|
473
|
+
it "should generate new_florida_orange path" do
|
474
|
+
Merb::Router.generate(:new_florida_orange).should == '/oranges/new'
|
475
|
+
end
|
476
|
+
|
477
|
+
it "should generate edit_florida_orange path" do
|
478
|
+
Merb::Router.generate(:edit_florida_orange, {:id => 1}).should == '/oranges/1/edit'
|
479
|
+
end
|
480
|
+
|
481
|
+
it "should match /ape" do
|
482
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/ape', :method => :get), {})
|
483
|
+
route[:controller].should == 'ape'
|
484
|
+
route[:action].should == 'show'
|
485
|
+
end
|
486
|
+
|
487
|
+
it "should generate grape_ape path" do
|
488
|
+
Merb::Router.generate(:grape_ape).should == '/ape'
|
489
|
+
end
|
490
|
+
|
491
|
+
it "should generate new_grape_ape path" do
|
492
|
+
Merb::Router.generate(:new_grape_ape).should == '/ape/new'
|
493
|
+
end
|
494
|
+
|
495
|
+
it "should generate edit_grape_ape path" do
|
496
|
+
Merb::Router.generate(:edit_grape_ape).should == '/ape/edit'
|
497
|
+
end
|
498
|
+
end
|
499
|
+
|
500
|
+
describe Merb::Router, "with resources using a collection action" do
|
501
|
+
before(:each) do
|
502
|
+
Merb::Router.prepare do |r|
|
503
|
+
r.resources :flowers, :collection => { :random => [:get] }
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
it "should generate random_flowers path" do
|
508
|
+
Merb::Router.generate(:random_flowers).should == '/flowers/random'
|
509
|
+
end
|
510
|
+
end
|
511
|
+
|
512
|
+
describe Merb::Router, "with resources using a member action" do
|
513
|
+
before(:each) do
|
514
|
+
Merb::Router.prepare do |r|
|
515
|
+
r.resources :flowers, :member => { :pick => [:get] }
|
516
|
+
end
|
517
|
+
end
|
518
|
+
|
519
|
+
it 'should generate pick_flower path' do
|
520
|
+
Merb::Router.generate(:pick_flower, { :id => 1 }).should == '/flowers/1/pick'
|
521
|
+
end
|
522
|
+
end
|
523
|
+
|
524
|
+
describe Merb::Router::Behavior do
|
525
|
+
before(:all) do
|
526
|
+
@behavior = Merb::Router::Behavior
|
527
|
+
end
|
528
|
+
|
529
|
+
it "should leave strings as strings and add ^...$ in the @conditions hash" do
|
530
|
+
@behavior.new({:path => "/one/two"}).conditions[:path].should == "^/one/two$"
|
531
|
+
end
|
532
|
+
|
533
|
+
it "should replace special characters in strings with their escaped equivalents" do
|
534
|
+
@behavior.new({:path => "test.xml"}).conditions[:path].should == "^test\\.xml$"
|
535
|
+
end
|
536
|
+
|
537
|
+
it "should convert symbols to strings and add ^...$ in the @conditions hash" do
|
538
|
+
@behavior.new({:method => :get}).conditions[:method].should == "^get$"
|
539
|
+
end
|
540
|
+
|
541
|
+
it "should convert regular expressions to strings in the @conditions hash" do
|
542
|
+
@behavior.new({:protocol => /https?/}).conditions[:protocol].should == "https?"
|
543
|
+
end
|
544
|
+
|
545
|
+
it "should deduce placeholders from the @conditions hash" do
|
546
|
+
ph = @behavior.new({:path => "/:controller/:action"}).placeholders
|
547
|
+
ph[:controller].should == [:path, 1]
|
548
|
+
ph[:action].should == [:path, 2]
|
549
|
+
end
|
550
|
+
|
551
|
+
it "should deduce placeholders from the @conditions hash, even when they contain numbers" do
|
552
|
+
ph = @behavior.new({:path => "/:part1/:part2"}).placeholders
|
553
|
+
ph[:part1].should == [:path, 1]
|
554
|
+
ph[:part2].should == [:path, 2]
|
555
|
+
end
|
556
|
+
|
557
|
+
it "should deduce placeholders within regular expressions that contain prefixed captures" do
|
558
|
+
ph = @behavior.new({:path => %r[/(\d+)/:controller/:action]}).placeholders
|
559
|
+
ph[:controller].should == [:path, 2]
|
560
|
+
ph[:action].should == [:path, 3]
|
561
|
+
|
562
|
+
ph = @behavior.new({:path => %r[/:controller/:action/(\d+)]}).placeholders
|
563
|
+
ph[:controller].should == [:path, 1]
|
564
|
+
ph[:action].should == [:path, 2]
|
565
|
+
end
|
566
|
+
|
567
|
+
it "should deduce placeholder positions in nested captures" do
|
568
|
+
ph = @behavior.new({:path => %r[(/(\d+)/:controller)/:action]}).placeholders
|
569
|
+
ph[:controller].should == [:path, 3]
|
570
|
+
ph[:action].should == [:path, 4]
|
571
|
+
|
572
|
+
ph = @behavior.new({:path => %r[/(\d+)/(:controller)/:action]}).placeholders
|
573
|
+
ph[:controller].should == [:path, 3]
|
574
|
+
ph[:action].should == [:path, 4]
|
575
|
+
|
576
|
+
ph = @behavior.new({:path => %r[/(\d+)/:controller/(:action)]}).placeholders
|
577
|
+
ph[:controller].should == [:path, 2]
|
578
|
+
ph[:action].should == [:path, 4]
|
579
|
+
|
580
|
+
ph = @behavior.new({:path => %r[(/(\d+)/(:controller/((:action))))]}).placeholders
|
581
|
+
ph[:controller].should == [:path, 4]
|
582
|
+
ph[:action].should == [:path, 7]
|
583
|
+
end
|
584
|
+
|
585
|
+
it "should replace any placeholders found within @conditions strings with segment regular expressions" do
|
586
|
+
m = @behavior.new({:path => "/:my/:place:holders/:here"}).conditions
|
587
|
+
m[:path].should == "^/([^/.,;?]+)/([^/.,;?]+)([^/.,;?]+)/([^/.,;?]+)$"
|
588
|
+
end
|
589
|
+
|
590
|
+
it "should set default values for params that came from placeholders" do
|
591
|
+
p = @behavior.new({:path => "/:my/:place:holders/:here"}).params
|
592
|
+
p[:my].should == ":my"
|
593
|
+
p[:place].should == ":place"
|
594
|
+
p[:holders].should == ":holders"
|
595
|
+
p[:here].should == ":here"
|
596
|
+
end
|
597
|
+
|
598
|
+
it "should merge params with its ancestors" do
|
599
|
+
b = @behavior.new({}, {:controller => "my_controller", :action => "index"})
|
600
|
+
c = @behavior.new({}, {:action => "show"}, b)
|
601
|
+
c.merged_params.should == {:controller => "my_controller", :action => "show"}
|
602
|
+
end
|
603
|
+
|
604
|
+
# it "should have a default action and controller for merged params" do
|
605
|
+
# a = @behavior.new
|
606
|
+
# a.merged_params.should == {:controller => "application", :action => "index"}
|
607
|
+
#
|
608
|
+
# b = @behavior.new({}, {:controller => "admin"})
|
609
|
+
# b.merged_params.should == {:controller => "admin", :action => "index"}
|
610
|
+
#
|
611
|
+
# c = @behavior.new({}, {:action => "show"})
|
612
|
+
# c.merged_params.should == {:controller => "application", :action => "show"}
|
613
|
+
# end
|
614
|
+
|
615
|
+
it "should merge conditions with its ancestors" do
|
616
|
+
b = @behavior.new({:method => "get", :protocol => "http"})
|
617
|
+
c = @behavior.new({:method => "put"}, {}, b)
|
618
|
+
c.merged_conditions.should == {:method => "^put$", :protocol => "^http$"}
|
619
|
+
end
|
620
|
+
|
621
|
+
it "should merge placeholders with its ancestors" do
|
622
|
+
b = @behavior.new({:method => "get", :protocol => ":ssl"}, {:action => ":method"})
|
623
|
+
c = @behavior.new({:method => "put"}, {:action => ":ssl"}, b)
|
624
|
+
c.merged_placeholders.should == {:ssl => [:protocol, 1]}
|
625
|
+
end
|
626
|
+
|
627
|
+
it "should add the number of path captures in the ancestors' paths to placeholders that hold a place for :path captures" do
|
628
|
+
b = @behavior.new({:path => "/:controller/:action"})
|
629
|
+
b.placeholders.should == {:controller => [:path, 1], :action => [:path, 2]}
|
630
|
+
c = @behavior.new({:path => "/:id"}, {}, b)
|
631
|
+
c.placeholders.should == {:id => [:path, 1]}
|
632
|
+
|
633
|
+
c.merged_placeholders.should == {:controller => [:path, 1], :action => [:path, 2], :id => [:path, 3]}
|
634
|
+
end
|
635
|
+
|
636
|
+
it "should merge the :path differently than other @conditions keys -- it should concatenate" do
|
637
|
+
b = @behavior.new({:method => "get", :protocol => "http"})
|
638
|
+
c = @behavior.new({:path => "/test", :method => "put"}, {}, b)
|
639
|
+
c.merged_conditions.should == {:method => "^put$", :protocol => "^http$", :path => "^/test$"}
|
640
|
+
|
641
|
+
b = @behavior.new({:path => "/test", :method => "get", :protocol => "http"})
|
642
|
+
c = @behavior.new({:method => "put"}, {}, b)
|
643
|
+
c.merged_conditions.should == {:method => "^put$", :protocol => "^http$", :path => "^/test$"}
|
644
|
+
|
645
|
+
b = @behavior.new({:path => "/admin", :method => "get", :protocol => "http"})
|
646
|
+
c = @behavior.new({:path => "/test", :method => "put"}, {}, b)
|
647
|
+
c.merged_conditions.should == {:method => "^put$", :protocol => "^http$", :path => "^/admin/test$"}
|
648
|
+
end
|
649
|
+
|
650
|
+
it "should be able to compile the @params to strings and request matches" do
|
651
|
+
b = @behavior.new({:path => "/admin/:controller/:action", :method => "get"})
|
652
|
+
cp = b.send(:compiled_params)
|
653
|
+
cp[:controller].should == "path1"
|
654
|
+
cp[:action].should == "path2"
|
655
|
+
|
656
|
+
b = @behavior.new(
|
657
|
+
{:path => "/admin/:controller/:action/:postfix", :method => "get"},
|
658
|
+
{:controller => "/admin/:controller", :action => "neat_o_:action:postfix"})
|
659
|
+
cp = b.send(:compiled_params)
|
660
|
+
cp[:controller].should == "\"/admin/\" + path1"
|
661
|
+
cp[:action].should == "\"neat_o_\" + path2 + path3"
|
662
|
+
end
|
663
|
+
|
664
|
+
it "should allow a bracketed number such as [3] to compile to path3" do
|
665
|
+
b = @behavior.new(
|
666
|
+
{:path => "/admin/:controller/:action/(.+)", :method => "get"},
|
667
|
+
{:catchall => "[3]"})
|
668
|
+
cp = b.send(:compiled_params)
|
669
|
+
cp[:catchall].should == "path3"
|
670
|
+
end
|
671
|
+
|
672
|
+
it "should allow a backslash to escape an underscore in the compiled params" do
|
673
|
+
b = @behavior.new(
|
674
|
+
{:path => "/admin/:controller/:action", :method => "get"},
|
675
|
+
{:action => "some_prefix_:action\\_other"})
|
676
|
+
cp = b.send(:compiled_params)
|
677
|
+
cp[:action].should == "\"some_prefix_\" + path2 + \"_other\""
|
678
|
+
end
|
679
|
+
|
680
|
+
it "should return a Route object containing compiled conditions and params when .to is called" do
|
681
|
+
a = @behavior.new({:path => "/admin"})
|
682
|
+
b = a.match("/:controller/:action", :method => "get")
|
683
|
+
route = b.to(:controller => "/admin/:controller")
|
684
|
+
route.conditions[:path].to_s.should == /^\/admin\/([^\/.,;?]+)\/([^\/.,;?]+)$/.to_s
|
685
|
+
route.conditions[:method].should == /^get$/
|
686
|
+
route.params.should == {:controller => "\"/admin/\" + path1", :action => "path2"}
|
687
|
+
end
|
688
|
+
|
689
|
+
it "should allow for conditional blocks using the 'defer_to' method" do
|
690
|
+
b = @behavior.new({:path => "/admin"})
|
691
|
+
route = b.defer_to { |request| {:controller => "late_bound", :action => "place"} }
|
692
|
+
route.conditional_block.should be_an_instance_of(Proc)
|
693
|
+
route.compile.should match(/block_result/m)
|
694
|
+
end
|
695
|
+
end
|
696
|
+
|
697
|
+
describe Merb::Router::Behavior, "class methods" do
|
698
|
+
before(:all) do
|
699
|
+
@b = Merb::Router::Behavior
|
700
|
+
end
|
701
|
+
|
702
|
+
it "should count opening parentheses" do
|
703
|
+
@b.count_parens_up_to(" ( )", 1).should == 1
|
704
|
+
@b.count_parens_up_to(" ( )", 50).should == 1
|
705
|
+
@b.count_parens_up_to(" (() )", 1).should == 1
|
706
|
+
@b.count_parens_up_to(" (() )", 2).should == 2
|
707
|
+
# TODO: skip escaped open parens
|
708
|
+
end
|
709
|
+
|
710
|
+
it "should concatenate strings without endcaps" do
|
711
|
+
@b.concat_without_endcaps(nil, nil).should be_nil
|
712
|
+
@b.concat_without_endcaps(nil, "^test").should == "^test"
|
713
|
+
@b.concat_without_endcaps("my$", nil).should == "my$"
|
714
|
+
@b.concat_without_endcaps("my", "test").should == "mytest"
|
715
|
+
@b.concat_without_endcaps("my$", "test").should == "mytest"
|
716
|
+
@b.concat_without_endcaps("my^", "test").should == "my^test"
|
717
|
+
@b.concat_without_endcaps("my$", "^test").should == "mytest"
|
718
|
+
@b.concat_without_endcaps("^my$", "^test$").should == "^mytest$"
|
719
|
+
end
|
720
|
+
|
721
|
+
it "should compile arrays with strings and symbols into code" do
|
722
|
+
@b.array_to_code([:var, "this string"]).should == "var + \"this string\""
|
723
|
+
@b.array_to_code(["one string"]).should == "\"one string\""
|
724
|
+
@b.array_to_code(["string", :var, :var2, "other"]).should == "\"string\" + var + var2 + \"other\""
|
725
|
+
end
|
726
|
+
end
|