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.
Files changed (70) hide show
  1. data/README +138 -56
  2. data/Rakefile +23 -8
  3. data/app_generators/merb/templates/Rakefile +13 -0
  4. data/app_generators/merb/templates/app/helpers/global_helper.rb +1 -1
  5. data/app_generators/merb/templates/app/views/exceptions/internal_server_error.html.erb +12 -3
  6. data/app_generators/merb/templates/config/merb.yml +14 -1
  7. data/app_generators/merb/templates/spec/spec_helper.rb +6 -0
  8. data/app_generators/merb/templates/test/test_helper.rb +1 -0
  9. data/lib/merb.rb +27 -7
  10. data/lib/merb/abstract_controller.rb +76 -36
  11. data/lib/merb/caching/store/memcache.rb +20 -0
  12. data/lib/merb/constants.rb +2 -4
  13. data/lib/merb/controller.rb +44 -2
  14. data/lib/merb/core_ext/get_args.rb +23 -4
  15. data/lib/merb/core_ext/hash.rb +16 -11
  16. data/lib/merb/core_ext/inflections.rb +1 -1
  17. data/lib/merb/core_ext/kernel.rb +106 -26
  18. data/lib/merb/core_ext/numeric.rb +1 -1
  19. data/lib/merb/core_ext/string.rb +10 -13
  20. data/lib/merb/dispatcher.rb +2 -2
  21. data/lib/merb/exceptions.rb +3 -1
  22. data/lib/merb/logger.rb +15 -6
  23. data/lib/merb/mail_controller.rb +18 -2
  24. data/lib/merb/mailer.rb +1 -1
  25. data/lib/merb/mixins/controller.rb +64 -228
  26. data/lib/merb/mixins/erubis_capture.rb +1 -1
  27. data/lib/merb/mixins/general_controller.rb +258 -0
  28. data/lib/merb/mixins/render.rb +45 -24
  29. data/lib/merb/mixins/responder.rb +89 -18
  30. data/lib/merb/mixins/view_context.rb +32 -5
  31. data/lib/merb/mixins/web_controller.rb +8 -1
  32. data/lib/merb/mongrel_handler.rb +27 -17
  33. data/lib/merb/part_controller.rb +10 -0
  34. data/lib/merb/request.rb +34 -14
  35. data/lib/merb/router.rb +77 -45
  36. data/lib/merb/server.rb +116 -72
  37. data/lib/merb/session/cookie_store.rb +14 -22
  38. data/lib/merb/session/mem_cache_session.rb +2 -2
  39. data/lib/merb/session/memory_session.rb +12 -1
  40. data/lib/merb/template/erubis.rb +31 -0
  41. data/lib/merb/template/haml.rb +4 -14
  42. data/lib/merb/template/xml_builder.rb +1 -1
  43. data/lib/merb/test/helper.rb +90 -18
  44. data/lib/merb/test/rspec.rb +145 -74
  45. data/lib/merb/version.rb +11 -0
  46. data/lib/merb/view_context.rb +3 -6
  47. data/lib/patch +69 -0
  48. data/lib/tasks/merb.rake +1 -1
  49. data/spec/fixtures/config/environments/environment_config_test.yml +1 -0
  50. data/spec/fixtures/controllers/render_spec_controllers.rb +63 -4
  51. data/spec/fixtures/views/examples/template_throw_content_without_block.html.erb +3 -0
  52. data/spec/fixtures/views/partials/_erubis.html.erb +1 -1
  53. data/spec/merb/abstract_controller_spec.rb +1 -0
  54. data/spec/merb/controller_filters_spec.rb +68 -3
  55. data/spec/merb/controller_spec.rb +35 -68
  56. data/spec/merb/cookie_store_spec.rb +7 -20
  57. data/spec/merb/core_ext_spec.rb +35 -1
  58. data/spec/merb/dispatch_spec.rb +8 -2
  59. data/spec/merb/generator_spec.rb +12 -4
  60. data/spec/merb/mail_controller_spec.rb +33 -0
  61. data/spec/merb/part_controller_spec.rb +33 -1
  62. data/spec/merb/render_spec.rb +74 -0
  63. data/spec/merb/request_spec.rb +43 -0
  64. data/spec/merb/responder_spec.rb +1 -0
  65. data/spec/merb/router_spec.rb +118 -13
  66. data/spec/merb/server_spec.rb +19 -0
  67. data/spec/merb/view_context_spec.rb +31 -3
  68. data/spec/spec_helper.rb +8 -0
  69. data/spec/spec_helpers/url_shared_behaviour.rb +112 -0
  70. 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(cookie_value(:empty), @secret)
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 close and marshal cookie data" do
78
- session = Merb::CookieStore.new(cookie_value(:typical), @secret)
79
- session.modified?.should == false
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
@@ -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 form argruments" do
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
@@ -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
@@ -25,7 +25,9 @@ describe "an app generator" do
25
25
  end
26
26
 
27
27
  it "should create directory structure" do
28
- @generator.command(:create).invoke!
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
- @generator.command(:create).invoke!
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
- @generator.command(:create).invoke!
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
- @generator.command(:create).invoke!
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
@@ -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]
@@ -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
@@ -244,6 +244,7 @@ end
244
244
 
245
245
  Merb::Server.load_action_arguments
246
246
  Merb::Server.load_controller_template_path_cache
247
+ Merb::Server.load_erubis_inline_helpers
247
248
 
248
249
  describe "A Merb Responder's Content Negotiation" do
249
250
 
@@ -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
- # domain (e.g. admin.mysite.com), do some interesting stuff:
182
- r.match(:domain => /^admin\b/) do |admin|
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 => "admin/users", :action => ":path[3]",
202
+ to(:controller => "users", :action => ":path[3]",
185
203
  :first_name => ":path[1]", :last_name => ":path[2]")
186
- end.to(:controller => "admin/users", :action => "default")
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(:domain => "admin.mysite.com", :path => '/welcome', :protocol => "https://"), {})
318
- route[:controller].should == "admin/users"
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(:domain => "admin.another-site.com", :path => '/go/somewhere/else', :protocol => "https://"), {})
323
- route[:controller].should == "admin/users"
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(:domain => "admin.mysite.com", :path => '/Duane+Johnson/edit', :protocol => "https://"), {})
330
- route[:controller].should == "admin/users"
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