merb 0.4.1 → 0.4.2
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/README +138 -56
- data/Rakefile +23 -8
- data/app_generators/merb/templates/Rakefile +13 -0
- data/app_generators/merb/templates/app/helpers/global_helper.rb +1 -1
- data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +12 -3
- data/app_generators/merb/templates/config/merb.yml +14 -1
- data/app_generators/merb/templates/spec/spec_helper.rb +6 -0
- data/app_generators/merb/templates/test/test_helper.rb +1 -0
- data/lib/merb.rb +27 -7
- data/lib/merb/abstract_controller.rb +76 -36
- data/lib/merb/caching/store/memcache.rb +20 -0
- data/lib/merb/constants.rb +2 -4
- data/lib/merb/controller.rb +44 -2
- data/lib/merb/core_ext/get_args.rb +23 -4
- data/lib/merb/core_ext/hash.rb +16 -11
- data/lib/merb/core_ext/inflections.rb +1 -1
- data/lib/merb/core_ext/kernel.rb +106 -26
- data/lib/merb/core_ext/numeric.rb +1 -1
- data/lib/merb/core_ext/string.rb +10 -13
- data/lib/merb/dispatcher.rb +2 -2
- data/lib/merb/exceptions.rb +3 -1
- data/lib/merb/logger.rb +15 -6
- data/lib/merb/mail_controller.rb +18 -2
- data/lib/merb/mailer.rb +1 -1
- data/lib/merb/mixins/controller.rb +64 -228
- data/lib/merb/mixins/erubis_capture.rb +1 -1
- data/lib/merb/mixins/general_controller.rb +258 -0
- data/lib/merb/mixins/render.rb +45 -24
- data/lib/merb/mixins/responder.rb +89 -18
- data/lib/merb/mixins/view_context.rb +32 -5
- data/lib/merb/mixins/web_controller.rb +8 -1
- data/lib/merb/mongrel_handler.rb +27 -17
- data/lib/merb/part_controller.rb +10 -0
- data/lib/merb/request.rb +34 -14
- data/lib/merb/router.rb +77 -45
- data/lib/merb/server.rb +116 -72
- data/lib/merb/session/cookie_store.rb +14 -22
- data/lib/merb/session/mem_cache_session.rb +2 -2
- data/lib/merb/session/memory_session.rb +12 -1
- data/lib/merb/template/erubis.rb +31 -0
- data/lib/merb/template/haml.rb +4 -14
- data/lib/merb/template/xml_builder.rb +1 -1
- data/lib/merb/test/helper.rb +90 -18
- data/lib/merb/test/rspec.rb +145 -74
- data/lib/merb/version.rb +11 -0
- data/lib/merb/view_context.rb +3 -6
- data/lib/patch +69 -0
- data/lib/tasks/merb.rake +1 -1
- data/spec/fixtures/config/environments/environment_config_test.yml +1 -0
- data/spec/fixtures/controllers/render_spec_controllers.rb +63 -4
- data/spec/fixtures/views/examples/template_throw_content_without_block.html.erb +3 -0
- data/spec/fixtures/views/partials/_erubis.html.erb +1 -1
- data/spec/merb/abstract_controller_spec.rb +1 -0
- data/spec/merb/controller_filters_spec.rb +68 -3
- data/spec/merb/controller_spec.rb +35 -68
- data/spec/merb/cookie_store_spec.rb +7 -20
- data/spec/merb/core_ext_spec.rb +35 -1
- data/spec/merb/dispatch_spec.rb +8 -2
- data/spec/merb/generator_spec.rb +12 -4
- data/spec/merb/mail_controller_spec.rb +33 -0
- data/spec/merb/part_controller_spec.rb +33 -1
- data/spec/merb/render_spec.rb +74 -0
- data/spec/merb/request_spec.rb +43 -0
- data/spec/merb/responder_spec.rb +1 -0
- data/spec/merb/router_spec.rb +118 -13
- data/spec/merb/server_spec.rb +19 -0
- data/spec/merb/view_context_spec.rb +31 -3
- data/spec/spec_helper.rb +8 -0
- data/spec/spec_helpers/url_shared_behaviour.rb +112 -0
- metadata +124 -87
@@ -30,14 +30,6 @@ end
|
|
30
30
|
|
31
31
|
describe Merb::CookieStore do
|
32
32
|
|
33
|
-
def cookies(*which)
|
34
|
-
@cookies.values_at(*which)
|
35
|
-
end
|
36
|
-
|
37
|
-
def cookie_value(which)
|
38
|
-
@cookies[which].first
|
39
|
-
end
|
40
|
-
|
41
33
|
before(:each) do
|
42
34
|
@secret = 'Keep it secret; keep it safe.'
|
43
35
|
@cookies = {
|
@@ -47,15 +39,13 @@ describe Merb::CookieStore do
|
|
47
39
|
:flashed => ['BAh7ByIMdXNlcl9pZGkBeyIKZmxhc2h7AA%3D%3D--bf9785a666d3c4ac09f7fe3353496b437546cfbf', { 'user_id' => 123, 'flash' => {} }]
|
48
40
|
}
|
49
41
|
end
|
50
|
-
|
51
|
-
|
52
|
-
|
42
|
+
|
53
43
|
it "should raise argument error if missing secret key" do
|
54
44
|
lambda { Merb::CookieStore.new(nil, nil) }.should raise_error(ArgumentError)
|
55
45
|
end
|
56
46
|
|
57
47
|
it "should restore and unmarshal good cookies" do
|
58
|
-
cookies(:empty, :a_one, :typical).each do |value, expected|
|
48
|
+
@cookies.values_at(:empty, :a_one, :typical).each do |value, expected|
|
59
49
|
session = Merb::CookieStore.new(value, @secret)
|
60
50
|
session['lazy loads the data hash'].should be_nil
|
61
51
|
session.data.should == expected
|
@@ -68,18 +58,15 @@ describe Merb::CookieStore do
|
|
68
58
|
end
|
69
59
|
|
70
60
|
it "should raise when data overflows" do
|
71
|
-
session = Merb::CookieStore.new(
|
61
|
+
session = Merb::CookieStore.new(@cookies[:empty].first, @secret)
|
72
62
|
session['overflow'] = 'bye!' * 1024
|
73
63
|
lambda { session.read_cookie }.should
|
74
64
|
raise_error(Merb::CookieStore::CookieOverflow)
|
75
65
|
end
|
76
|
-
|
77
|
-
it "should
|
78
|
-
session =
|
79
|
-
session.
|
80
|
-
session['flash'] = {}
|
81
|
-
session.modified?.should == true
|
82
|
-
session.read_cookie.should == cookie_value(:flashed)
|
66
|
+
|
67
|
+
it "should delete entries in the session" do
|
68
|
+
session = Merb::CookieStore.new(@cookies[:a_one].first, @secret)
|
69
|
+
session.delete('a').should == 1
|
83
70
|
end
|
84
71
|
|
85
72
|
end
|
data/spec/merb/core_ext_spec.rb
CHANGED
@@ -401,9 +401,14 @@ describe "A String" do
|
|
401
401
|
end.should raise_error(String::InvalidPathConversion)
|
402
402
|
end.should_not raise_error(Timeout::Error)
|
403
403
|
end
|
404
|
+
|
405
|
+
it "should remove any indentation and add +indentation+ number of spaces" do
|
406
|
+
"foo\n bar\n".indent(3).should == " foo\n bar\n"
|
407
|
+
" foo\n bar\n".indent(3).should == " foo\n bar\n"
|
408
|
+
end
|
404
409
|
end
|
405
410
|
|
406
|
-
describe "extracting options
|
411
|
+
describe "extracting options from arguments" do
|
407
412
|
|
408
413
|
def the_method(*args)
|
409
414
|
[extract_options_from_args!(args),args]
|
@@ -428,3 +433,32 @@ describe "extracting options form argruments" do
|
|
428
433
|
end
|
429
434
|
|
430
435
|
end
|
436
|
+
|
437
|
+
describe Inflector do
|
438
|
+
it "should transform words from singular to plural" do
|
439
|
+
"post".pluralize.should == "posts"
|
440
|
+
"octopus".pluralize.should =="octopi"
|
441
|
+
"the blue mailman".pluralize.should == "the blue mailmen"
|
442
|
+
"CamelOctopus".pluralize.should == "CamelOctopi"
|
443
|
+
end
|
444
|
+
it "should transform words from plural to singular" do
|
445
|
+
"posts".singularize.should == "post"
|
446
|
+
"octopi".singularize.should == "octopus"
|
447
|
+
"the blue mailmen".singularize.should == "the blue mailman"
|
448
|
+
"CamelOctopi".singularize.should == "CamelOctopus"
|
449
|
+
end
|
450
|
+
it "should transform class names to table names" do
|
451
|
+
"RawScaledScorer".tableize.should == "raw_scaled_scorers"
|
452
|
+
"egg_and_ham".tableize.should == "egg_and_hams"
|
453
|
+
"fancyCategory".tableize.should == "fancy_categories"
|
454
|
+
end
|
455
|
+
it "should tranform table names to class names" do
|
456
|
+
"egg_and_hams".classify.should == "EggAndHam"
|
457
|
+
"post".classify.should == "Post"
|
458
|
+
end
|
459
|
+
it "should create a foreign key name from a class name" do
|
460
|
+
"Message".foreign_key.should == "message_id"
|
461
|
+
"Message".foreign_key(false).should == "messageid"
|
462
|
+
"Admin::Post".foreign_key.should == "post_id"
|
463
|
+
end
|
464
|
+
end
|
data/spec/merb/dispatch_spec.rb
CHANGED
@@ -4,7 +4,7 @@ require File.dirname(__FILE__) + '/../fixtures/controllers/dispatch_spec_control
|
|
4
4
|
$TESTING = true
|
5
5
|
|
6
6
|
describe Merb::Dispatcher do
|
7
|
-
|
7
|
+
|
8
8
|
before(:all) do
|
9
9
|
Merb::Server.config[:allow_reloading] = false
|
10
10
|
Merb::Router.prepare do |r|
|
@@ -24,9 +24,15 @@ describe Merb::Dispatcher do
|
|
24
24
|
end
|
25
25
|
r.default_routes
|
26
26
|
end
|
27
|
-
puts Merb::Router.named_routes[:new_comment].generate(:post_id => 1)
|
28
27
|
end
|
29
28
|
|
29
|
+
it "should not overwrite url params with query string params" do
|
30
|
+
controller, action = request(:get, '/foo/bar/42?id=24')
|
31
|
+
controller.class.should == Foo
|
32
|
+
action.should == "bar"
|
33
|
+
controller.params[:id].should == '42'
|
34
|
+
end
|
35
|
+
|
30
36
|
it "should not allow private and protected methods to be called" do
|
31
37
|
controller, action = request(:get, '/foo/call_filters')
|
32
38
|
controller.status.should == Merb::ControllerExceptions::ActionNotFound::STATUS
|
data/spec/merb/generator_spec.rb
CHANGED
@@ -25,7 +25,9 @@ describe "an app generator" do
|
|
25
25
|
end
|
26
26
|
|
27
27
|
it "should create directory structure" do
|
28
|
-
|
28
|
+
silence_generator do
|
29
|
+
@generator.command(:create).invoke!
|
30
|
+
end
|
29
31
|
%w{
|
30
32
|
app
|
31
33
|
app/controllers
|
@@ -51,7 +53,9 @@ describe "an app generator" do
|
|
51
53
|
end
|
52
54
|
|
53
55
|
it "should create files from templates" do
|
54
|
-
|
56
|
+
silence_generator do
|
57
|
+
@generator.command(:create).invoke!
|
58
|
+
end
|
55
59
|
%w{
|
56
60
|
app/controllers/application.rb
|
57
61
|
app/helpers/global_helper.rb
|
@@ -73,7 +77,9 @@ describe "an app generator" do
|
|
73
77
|
end
|
74
78
|
|
75
79
|
it "should create files from rubigen dependency" do
|
76
|
-
|
80
|
+
silence_generator do
|
81
|
+
@generator.command(:create).invoke!
|
82
|
+
end
|
77
83
|
%w{
|
78
84
|
script/generate
|
79
85
|
script/destroy
|
@@ -81,7 +87,9 @@ describe "an app generator" do
|
|
81
87
|
end
|
82
88
|
|
83
89
|
it "should make script files executable" do
|
84
|
-
|
90
|
+
silence_generator do
|
91
|
+
@generator.command(:create).invoke!
|
92
|
+
end
|
85
93
|
|
86
94
|
%w{
|
87
95
|
script/stop_merb
|
@@ -6,6 +6,7 @@ module Merb
|
|
6
6
|
end
|
7
7
|
end
|
8
8
|
Merb::Server.load_controller_template_path_cache
|
9
|
+
Merb::Server.load_erubis_inline_helpers
|
9
10
|
|
10
11
|
class Merb::Mailer
|
11
12
|
self.delivery_method = :test_send
|
@@ -141,4 +142,36 @@ describe "A Merb Mail controller" do
|
|
141
142
|
deliver :tenth
|
142
143
|
end
|
143
144
|
|
145
|
+
end
|
146
|
+
|
147
|
+
describe "Merb::MailController with url generation" do
|
148
|
+
|
149
|
+
it_should_behave_like "class with general url generation"
|
150
|
+
it_should_behave_like "non routeable controller with url mixin"
|
151
|
+
|
152
|
+
def new_url_controller(route, params = {:action => 'show', :controller => 'Test'})
|
153
|
+
request = OpenStruct.new
|
154
|
+
request.route = route
|
155
|
+
request.params = params
|
156
|
+
response = OpenStruct.new
|
157
|
+
response.read = ""
|
158
|
+
|
159
|
+
@controller = Merb::Controller.build(request, response)
|
160
|
+
TestMailController.new(params, @controller)
|
161
|
+
end
|
162
|
+
|
163
|
+
it "should raise an error if no controller is specified and the base controller is not set" do
|
164
|
+
c = new_url_controller(@default_route, {})
|
165
|
+
lambda do
|
166
|
+
the_url = c.url(:action => "bar")
|
167
|
+
end.should raise_error
|
168
|
+
end
|
169
|
+
|
170
|
+
it "should use the base controller when it is set to generate a url when no :controller option is specified" do
|
171
|
+
c = new_url_controller(@defualt_route, :controller => "foo")
|
172
|
+
lambda do
|
173
|
+
the_url = c.url(:action => "bar")
|
174
|
+
the_url.should == "/foo/bar"
|
175
|
+
end.should_not raise_error
|
176
|
+
end
|
144
177
|
end
|
@@ -89,4 +89,36 @@ describe "A Merb PartController" do
|
|
89
89
|
controller.body.should match(/part_js_format/m)
|
90
90
|
end
|
91
91
|
|
92
|
-
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe "A Merb Part Controller with urls" do
|
95
|
+
|
96
|
+
it_should_behave_like "class with general url generation"
|
97
|
+
it_should_behave_like "non routeable controller with url mixin"
|
98
|
+
|
99
|
+
def new_url_controller(route, params = {:action => 'show', :controller => 'Test'})
|
100
|
+
request = OpenStruct.new
|
101
|
+
request.route = route
|
102
|
+
request.params = params
|
103
|
+
response = OpenStruct.new
|
104
|
+
response.read = ""
|
105
|
+
|
106
|
+
@controller = Merb::Controller.build(request, response)
|
107
|
+
TodoPart.new(@controller)
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should use the web_controllers type if no controller is specified" do
|
111
|
+
c = new_url_controller(@default_route, :controller => "my_controller")
|
112
|
+
the_url = c.url(:action => "bar")
|
113
|
+
the_url.should == "/my_controller/bar"
|
114
|
+
end
|
115
|
+
|
116
|
+
it "should raise an error if the web_controller's params[:controller] is not set" do
|
117
|
+
c = new_url_controller(@default_route, {})
|
118
|
+
lambda do
|
119
|
+
the_url = c.url(:action => "bar")
|
120
|
+
the_url.should == "/my_controller/bar"
|
121
|
+
end.should raise_error
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
data/spec/merb/render_spec.rb
CHANGED
@@ -21,6 +21,12 @@ describe "rendering engines except XMLBuilder", :shared => true do
|
|
21
21
|
content.clean.should == "Locals!"
|
22
22
|
end
|
23
23
|
|
24
|
+
it "should render a partial with nil locals" do
|
25
|
+
c = new_controller
|
26
|
+
content = c.partial "partials/#{@engine}", :yo => nil
|
27
|
+
content.clean.should == "No Locals!"
|
28
|
+
end
|
29
|
+
|
24
30
|
it "should render a partial using the :partial method" do
|
25
31
|
c = new_controller
|
26
32
|
content = c.partial("partials/#{@engine}")
|
@@ -108,6 +114,14 @@ describe "rendering engines except XMLBuilder", :shared => true do
|
|
108
114
|
content.should match( /Start Tester Block\s*In Tester Block\s*Finish Tester Block/m)
|
109
115
|
end
|
110
116
|
|
117
|
+
it "should bind the concat to independent render buffers" do
|
118
|
+
c = new_controller
|
119
|
+
content = c.render :template => "template_views/interface_concat_#{@engine}", :layout => :none
|
120
|
+
content.should match( /Start Tester Block\s*In Tester Block\s*Finish Tester Block/m)
|
121
|
+
content = c.render :template => "template_views/interface_concat_#{@engine}", :layout => :none
|
122
|
+
content.should match( /Start Tester Block\s*In Tester Block\s*Finish Tester Block/m)
|
123
|
+
end
|
124
|
+
|
111
125
|
it "should implement a capture( &block ) method" do
|
112
126
|
c = new_controller
|
113
127
|
content = c.render :template => "template_views/interface_capture_#{@engine}", :layout => :none
|
@@ -368,6 +382,66 @@ describe "Merb rendering with an object calls to_json or to_xml on the object" d
|
|
368
382
|
|
369
383
|
end
|
370
384
|
|
385
|
+
describe "Merb rendering with an object calls to_json or to_xml on the object (using specified arguments)" do
|
386
|
+
|
387
|
+
it "render @foo should call @foo.to_json when json is requested (using default options)" do
|
388
|
+
c = new_spec_controller(:format => 'json', :controller => 'RenderObjectWithArgumentsController')
|
389
|
+
c.provided_format_arguments_for(:json).should == ["foo", "bar"]
|
390
|
+
c.dispatch(:render_standard)
|
391
|
+
c.body.should == "['foo','bar']"
|
392
|
+
end
|
393
|
+
|
394
|
+
it "render @foo should call @foo.to_json when json is requested (using action options)" do
|
395
|
+
c = new_spec_controller(:format => 'json', :controller => 'RenderObjectWithArgumentsController')
|
396
|
+
c.dispatch(:render_specific)
|
397
|
+
c.body.should == "['foo','bar','baz']"
|
398
|
+
end
|
399
|
+
|
400
|
+
it "render @foo should call @foo.to_xml when xml is requested (using default options)" do
|
401
|
+
c = new_spec_controller(:format => 'xml', :controller => 'RenderObjectWithArgumentsController')
|
402
|
+
c.provided_format_arguments_for(:xml).should == [{:foo=>"bar"}]
|
403
|
+
c.dispatch(:render_standard)
|
404
|
+
c.body.should == "<foo>bar</foo>"
|
405
|
+
end
|
406
|
+
|
407
|
+
it "render @foo should call @foo.to_xml when xml is requested (using action options)" do
|
408
|
+
c = new_spec_controller(:format => 'xml', :controller => 'RenderObjectWithArgumentsController')
|
409
|
+
c.dispatch(:render_specific)
|
410
|
+
c.body.should == "<biz>baz</biz><foo>bar</foo>"
|
411
|
+
end
|
412
|
+
|
413
|
+
end
|
414
|
+
|
415
|
+
describe "Merb rendering with an object and using a block/lambda for provides" do
|
416
|
+
|
417
|
+
it "render @foo should use the default block when xml is requested" do
|
418
|
+
c = new_spec_controller(:format => 'xml', :controller => 'RenderObjectWithBlockController')
|
419
|
+
c.provided_format_arguments_for(:xml).should be_kind_of(Proc)
|
420
|
+
c.dispatch(:render_standard)
|
421
|
+
c.body.should == "<foo>RenderObjectWithBlockController</foo>"
|
422
|
+
end
|
423
|
+
|
424
|
+
it "render @foo should use the default block when json is requested" do
|
425
|
+
c = new_spec_controller(:format => 'json', :controller => 'RenderObjectWithBlockController')
|
426
|
+
c.provided_format_arguments_for(:json).should be_kind_of(Proc)
|
427
|
+
c.dispatch(:render_standard)
|
428
|
+
c.body.should == "['foo']"
|
429
|
+
end
|
430
|
+
|
431
|
+
it "render @foo should use the specific proc when xml is requested" do
|
432
|
+
c = new_spec_controller(:format => 'xml', :controller => 'RenderObjectWithBlockController')
|
433
|
+
c.dispatch(:render_specific)
|
434
|
+
c.body.should == "<foo>RENDEROBJECTWITHBLOCKCONTROLLER</foo>"
|
435
|
+
end
|
436
|
+
|
437
|
+
it "render @foo should use the specific proc when json is requested" do
|
438
|
+
c = new_spec_controller(:format => 'json', :controller => 'RenderObjectWithBlockController')
|
439
|
+
c.dispatch(:render_specific)
|
440
|
+
c.body.should == "['RenderObjectWithBlockController','foo','bar','baz']"
|
441
|
+
end
|
442
|
+
|
443
|
+
end
|
444
|
+
|
371
445
|
def new_spec_controller(options={})
|
372
446
|
params = {:controller => 'ExtensionTemplateController'}
|
373
447
|
params.update(:format => options.delete(:format)) if options[:format]
|
data/spec/merb/request_spec.rb
CHANGED
@@ -132,6 +132,24 @@ describe Merb::Request do
|
|
132
132
|
Merb::Request::parse_json_params = true
|
133
133
|
end
|
134
134
|
|
135
|
+
it "should parse a JSON body into params when charset provided" do
|
136
|
+
@in.post_body = "{\"title\":\"hello there\",\"body\":\"some text\"}"
|
137
|
+
@in['REQUEST_METHOD'] = 'POST'
|
138
|
+
@in['CONTENT_TYPE'] = "text/x-json; charset=utf-8"
|
139
|
+
request = Merb::Request.new(@in)
|
140
|
+
request.params[:title].should == "hello there"
|
141
|
+
request.params[:body].should == "some text"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should parse an XML body into params when charset provided" do
|
145
|
+
@in.post_body = "<root><title>hello there</title><body>some text</body></root>"
|
146
|
+
@in['REQUEST_METHOD'] = 'POST'
|
147
|
+
@in['CONTENT_TYPE'] = "text/xml; charset=utf-8"
|
148
|
+
request = Merb::Request.new(@in)
|
149
|
+
request.params[:root][:title].should == "hello there"
|
150
|
+
request.params[:root][:body].should == "some text"
|
151
|
+
end
|
152
|
+
|
135
153
|
it "should handle hash-style form fields in multipart/form-data" do
|
136
154
|
m = Merb::Test::Multipart::Post.new :foo => 'bario',
|
137
155
|
'files[foo][file]' => File.open(FIXTURES / 'foo.rb'),
|
@@ -240,4 +258,29 @@ describe Merb::Request do
|
|
240
258
|
request = Merb::Request.new(@in)
|
241
259
|
request.accept.should == "*/*"
|
242
260
|
end
|
261
|
+
|
262
|
+
it "should be able to tell you the HTTP method for POST requests without an error" do
|
263
|
+
@in['REQUEST_METHOD'] = 'POST'
|
264
|
+
request = Merb::Request.new(@in)
|
265
|
+
lambda {request.method}.should_not raise_error
|
266
|
+
request.method.should == :post
|
267
|
+
end
|
268
|
+
|
269
|
+
it "should be able to tell you the HTTP method for GET requests without an error" do
|
270
|
+
@in['REQUEST_METHOD'] = 'GET'
|
271
|
+
request = Merb::Request.new(@in)
|
272
|
+
lambda {request.method}.should_not raise_error
|
273
|
+
request.method.should == :get
|
274
|
+
end
|
275
|
+
|
276
|
+
it "multipart_params should return an empty hash if the request is not multipart" do
|
277
|
+
request = Merb::Request.new(@in)
|
278
|
+
request.send(:multipart_params).should == {}
|
279
|
+
end
|
280
|
+
|
281
|
+
it "should add namespace to controller name" do
|
282
|
+
request = Merb::Request.new(@in)
|
283
|
+
request.stubs(:route_params).returns({:controller => 'bar', :namespace => 'foo'})
|
284
|
+
request.controller_name.should == "foo/bar"
|
285
|
+
end
|
243
286
|
end
|
data/spec/merb/responder_spec.rb
CHANGED
data/spec/merb/router_spec.rb
CHANGED
@@ -72,6 +72,15 @@ describe Merb::Router do
|
|
72
72
|
Merb::Router.routes[0].should == r1
|
73
73
|
Merb::Router.routes[1].should == r2
|
74
74
|
end
|
75
|
+
|
76
|
+
it "should have a spec helper to match routes" do
|
77
|
+
Merb::Router.prepare{ |r| r.default_routes }
|
78
|
+
with_route("/pages/show/1", "GET") do |params|
|
79
|
+
params[:controller].should == "pages"
|
80
|
+
params[:action].should == "show"
|
81
|
+
params[:id].should == "1"
|
82
|
+
end
|
83
|
+
end
|
75
84
|
|
76
85
|
# it "should be fast" do
|
77
86
|
# Merb::Router.prepare do |r|
|
@@ -177,13 +186,22 @@ describe Merb::Router, "when doing route matching with a big set of example rout
|
|
177
186
|
r.match("/::/users/::").
|
178
187
|
to(:controller => "users", :action => "[2]", :id => "[1]")
|
179
188
|
|
189
|
+
# Namespace can be used to specify the module
|
190
|
+
r.match('/bar').to(:controller => 'bar', :namespace => 'foo')
|
191
|
+
|
192
|
+
# Namespace can be used to provide path prefix
|
193
|
+
r.match('/admin').to(:namespace => 'admin') do |foo|
|
194
|
+
foo.match('/foo').to(:controller => 'foo')
|
195
|
+
end
|
196
|
+
r.match('/foo').to(:controller => 'foo')
|
197
|
+
|
180
198
|
# Putting it all together, and adding the requirement that we use an "admin" prefix on the
|
181
|
-
#
|
182
|
-
r.match(:
|
199
|
+
# host (e.g. admin.mysite.com), do some interesting stuff:
|
200
|
+
r.match(:host => /^admin\b/).to(:namespace => 'admin') do |admin|
|
183
201
|
admin.match(%r[/([A-Z]\w+)\+([A-Z]\w+)/::]).
|
184
|
-
to(:controller => "
|
202
|
+
to(:controller => "users", :action => ":path[3]",
|
185
203
|
:first_name => ":path[1]", :last_name => ":path[2]")
|
186
|
-
end.to(:controller => "
|
204
|
+
end.to(:controller => "users", :action => "default")
|
187
205
|
# Note that the last line above sends all traffic in the "admin" subdomain to the
|
188
206
|
# Admin::Users#default action if no other route is matched.
|
189
207
|
|
@@ -313,25 +331,51 @@ describe Merb::Router, "when doing route matching with a big set of example rout
|
|
313
331
|
should_only_have_keys(route, :controller, :action, :id)
|
314
332
|
end
|
315
333
|
|
334
|
+
it "should use namespace" do
|
335
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/bar', :method => :get), {})
|
336
|
+
route[:namespace].should == 'foo'
|
337
|
+
route[:controller].should == 'bar'
|
338
|
+
route[:action].should == 'index'
|
339
|
+
should_only_have_keys(route, :namespace, :controller, :action)
|
340
|
+
end
|
341
|
+
|
342
|
+
it "should have namespace 'admin' if path is '/admin/foo'" do
|
343
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/admin/foo', :method => :get), {})
|
344
|
+
route[:namespace].should == 'admin'
|
345
|
+
route[:controller].should == 'foo'
|
346
|
+
route[:action].should == 'index'
|
347
|
+
should_only_have_keys(route, :namespace, :controller, :action)
|
348
|
+
end
|
349
|
+
|
350
|
+
it "should not have namespace if path is just '/foo'" do
|
351
|
+
index, route = Merb::Router.match(SimpleRequest.new(:path => '/foo', :method => :get), {})
|
352
|
+
route[:controller].should == 'foo'
|
353
|
+
route[:action].should == 'index'
|
354
|
+
should_only_have_keys(route, :controller, :action)
|
355
|
+
end
|
356
|
+
|
316
357
|
it "should send all admin.* domains to the 'admin/users' controller, and 'default' action" do
|
317
|
-
index, route = Merb::Router.match(SimpleRequest.new(:
|
318
|
-
route[:
|
358
|
+
index, route = Merb::Router.match(SimpleRequest.new(:host => "admin.mysite.com", :path => '/welcome', :protocol => "https://"), {})
|
359
|
+
route[:namespace].should == "admin"
|
360
|
+
route[:controller].should == "users"
|
319
361
|
route[:action].should == "default"
|
320
|
-
should_only_have_keys(route, :controller, :action)
|
362
|
+
should_only_have_keys(route, :namespace, :controller, :action)
|
321
363
|
|
322
|
-
index, route = Merb::Router.match(SimpleRequest.new(:
|
323
|
-
route[:
|
364
|
+
index, route = Merb::Router.match(SimpleRequest.new(:host => "admin.another-site.com", :path => '/go/somewhere/else', :protocol => "https://"), {})
|
365
|
+
route[:namespace].should == "admin"
|
366
|
+
route[:controller].should == "users"
|
324
367
|
route[:action].should == "default"
|
325
|
-
should_only_have_keys(route, :controller, :action)
|
368
|
+
should_only_have_keys(route, :namespace, :controller, :action)
|
326
369
|
end
|
327
370
|
|
328
371
|
it "should decipher the first-name / last-name pairs on an admin.* domain" do
|
329
|
-
index, route = Merb::Router.match(SimpleRequest.new(:
|
330
|
-
route[:
|
372
|
+
index, route = Merb::Router.match(SimpleRequest.new(:host => "admin.mysite.com", :path => '/Duane+Johnson/edit', :protocol => "https://"), {})
|
373
|
+
route[:namespace].should == "admin"
|
374
|
+
route[:controller].should == "users"
|
331
375
|
route[:action].should == "edit"
|
332
376
|
route[:first_name].should == "Duane"
|
333
377
|
route[:last_name].should == "Johnson"
|
334
|
-
should_only_have_keys(route, :controller, :action, :first_name, :last_name)
|
378
|
+
should_only_have_keys(route, :namespace, :controller, :action, :first_name, :last_name)
|
335
379
|
end
|
336
380
|
|
337
381
|
it "should defer to the Ajax controller for xhr requests" do
|
@@ -723,4 +767,65 @@ describe Merb::Router::Behavior, "class methods" do
|
|
723
767
|
@b.array_to_code(["one string"]).should == "\"one string\""
|
724
768
|
@b.array_to_code(["string", :var, :var2, "other"]).should == "\"string\" + var + var2 + \"other\""
|
725
769
|
end
|
770
|
+
end
|
771
|
+
|
772
|
+
describe "Merb::Route", "rendered as a string" do
|
773
|
+
before(:all) do
|
774
|
+
Merb::Router.prepare do |r|
|
775
|
+
r.default_routes
|
776
|
+
end
|
777
|
+
@routes = Merb::Router.routes
|
778
|
+
end
|
779
|
+
|
780
|
+
it "should show the default route" do
|
781
|
+
@routes.last.to_s.should == "/:controller(/:action(/:id)?)?(\\.:format)?"
|
782
|
+
end
|
783
|
+
end
|
784
|
+
|
785
|
+
describe Merb::Router, "with resources using namespace 'admin'" do
|
786
|
+
before(:each) do
|
787
|
+
Merb::Router.prepare do |r|
|
788
|
+
#Declare one in the nested style
|
789
|
+
r.match(:host => /^.*$/).to(:namespace => 'admin') do |admin|
|
790
|
+
admin.resources :oranges
|
791
|
+
end
|
792
|
+
#Declare one in the non-nested style
|
793
|
+
r.resources :ape, :namespace => 'admin'
|
794
|
+
#Declare resources without a namespace to make sure it's not overridden
|
795
|
+
r.resources :oranges
|
796
|
+
r.resource :ape
|
797
|
+
end
|
798
|
+
end
|
799
|
+
|
800
|
+
it "should generate admin_oranges path" do
|
801
|
+
Merb::Router.generate(:admin_oranges).should == '/oranges'
|
802
|
+
end
|
803
|
+
|
804
|
+
it "should generate admin_orange path" do
|
805
|
+
Merb::Router.generate(:admin_orange, {:id => 1}).should == '/oranges/1'
|
806
|
+
b = Blogposts.new
|
807
|
+
Merb::Router.generate(:admin_orange, b).should == '/oranges/42'
|
808
|
+
Merb::Router.generate(:admin_orange, :id => b).should == '/oranges/42'
|
809
|
+
end
|
810
|
+
|
811
|
+
it "should generate new_admin_orange path" do
|
812
|
+
Merb::Router.generate(:new_admin_orange).should == '/oranges/new'
|
813
|
+
end
|
814
|
+
|
815
|
+
it "should generate edit_admin_orange path" do
|
816
|
+
Merb::Router.generate(:edit_admin_orange, {:id => 1}).should == '/oranges/1/edit'
|
817
|
+
end
|
818
|
+
|
819
|
+
it "should generate admin_ape path" do
|
820
|
+
Merb::Router.generate(:admin_ape).should == '/ape'
|
821
|
+
end
|
822
|
+
|
823
|
+
it "should generate new_admin_ape path" do
|
824
|
+
Merb::Router.generate(:new_admin_ape).should == '/ape/new'
|
825
|
+
end
|
826
|
+
|
827
|
+
it "should generate edit_admin_ape path" do
|
828
|
+
Merb::Router.generate(:edit_admin_ape).should == '/ape/edit'
|
829
|
+
end
|
830
|
+
|
726
831
|
end
|