merb 0.4.0 → 0.4.1

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 (143) hide show
  1. data/README +23 -160
  2. data/Rakefile +15 -14
  3. data/app_generators/merb/merb_generator.rb +4 -3
  4. data/app_generators/merb/templates/Rakefile +1 -6
  5. data/app_generators/merb/templates/app/mailers/views/layout/{application.erb → application.html.erb} +0 -0
  6. data/app_generators/merb/templates/app/mailers/views/layout/application.text.erb +1 -0
  7. data/app_generators/merb/templates/app/parts/views/layout/application.html.erb +1 -0
  8. data/app_generators/merb/templates/app/views/layout/application.html.erb +2 -2
  9. data/app_generators/merb/templates/config/dependencies.rb +1 -1
  10. data/app_generators/merb/templates/config/router.rb +4 -1
  11. data/app_generators/merb/templates/spec/spec_helper.rb +2 -3
  12. data/lib/autotest/merb_rspec.rb +1 -0
  13. data/lib/merb/abstract_controller.rb +31 -2
  14. data/lib/merb/controller.rb +5 -5
  15. data/lib/merb/core_ext/get_args.rb +5 -1
  16. data/lib/merb/exceptions.rb +17 -0
  17. data/lib/merb/generators/merb_app/merb_app.rb +4 -1
  18. data/lib/merb/generators/merb_plugin.rb +4 -1
  19. data/lib/merb/logger.rb +5 -1
  20. data/lib/merb/mail_controller.rb +1 -1
  21. data/lib/merb/mailer.rb +2 -2
  22. data/lib/merb/mixins/controller.rb +5 -1
  23. data/lib/merb/mixins/render.rb +57 -27
  24. data/lib/merb/part_controller.rb +1 -1
  25. data/lib/merb/request.rb +2 -2
  26. data/lib/merb/server.rb +33 -5
  27. data/lib/merb/template/erubis.rb +1 -1
  28. data/lib/merb.rb +15 -5
  29. data/merb_generators/resource/resource_generator.rb +9 -2
  30. data/spec/fixtures/config/merb.yml +18 -0
  31. data/spec/fixtures/controllers/dispatch_spec_controllers.rb +227 -0
  32. data/spec/fixtures/controllers/render_spec_controllers.rb +115 -0
  33. data/spec/fixtures/foo.rb +3 -0
  34. data/spec/fixtures/mailers/views/layout/application.html.erb +3 -0
  35. data/spec/fixtures/mailers/views/layout/application.text.erb +3 -0
  36. data/spec/fixtures/mailers/views/test_mail_controller/eighth.html.erb +1 -0
  37. data/spec/fixtures/mailers/views/test_mail_controller/eighth.text.erb +1 -0
  38. data/spec/fixtures/mailers/views/test_mail_controller/first.html.erb +1 -0
  39. data/spec/fixtures/mailers/views/test_mail_controller/first.text.erb +1 -0
  40. data/spec/fixtures/mailers/views/test_mail_controller/ninth.html.erb +1 -0
  41. data/spec/fixtures/mailers/views/test_mail_controller/ninth.text.erb +1 -0
  42. data/spec/fixtures/mailers/views/test_mail_controller/second.text.erb +1 -0
  43. data/spec/fixtures/mailers/views/test_mail_controller/third.html.erb +1 -0
  44. data/spec/fixtures/models/router_spec_models.rb +20 -0
  45. data/spec/fixtures/parts/views/layout/todo_part.html.erb +3 -0
  46. data/spec/fixtures/parts/views/layout/todo_part.xml.erb +3 -0
  47. data/spec/fixtures/parts/views/todo_part/formatted_output.html.erb +1 -0
  48. data/spec/fixtures/parts/views/todo_part/formatted_output.js.erb +1 -0
  49. data/spec/fixtures/parts/views/todo_part/formatted_output.xml.erb +1 -0
  50. data/spec/fixtures/parts/views/todo_part/list.html.erb +3 -0
  51. data/spec/fixtures/sample.txt +1 -0
  52. data/spec/fixtures/views/erubis.html.erb +1 -0
  53. data/spec/fixtures/views/examples/_erubis.html.erb +1 -0
  54. data/spec/fixtures/views/examples/_haml.html.haml +1 -0
  55. data/spec/fixtures/views/examples/_markaby.html.mab +1 -0
  56. data/spec/fixtures/views/examples/_throw_content.html.erb +6 -0
  57. data/spec/fixtures/views/examples/hello.xml.builder +1 -0
  58. data/spec/fixtures/views/examples/js.js.erb +1 -0
  59. data/spec/fixtures/views/examples/template_catch_content.html.erb +15 -0
  60. data/spec/fixtures/views/examples/template_catch_content_from_partial.html.erb +6 -0
  61. data/spec/fixtures/views/examples/template_throw_content.html.erb +10 -0
  62. data/spec/fixtures/views/exceptions/admin_access_required.html.erb +1 -0
  63. data/spec/fixtures/views/extension_template_controller/_nested_js.js.erb +1 -0
  64. data/spec/fixtures/views/extension_template_controller/_nested_xml.xml.erb +1 -0
  65. data/spec/fixtures/views/extension_template_controller/_render_partial_multiple_times.html.erb +1 -0
  66. data/spec/fixtures/views/extension_template_controller/erubis_templates.html.erb +1 -0
  67. data/spec/fixtures/views/extension_template_controller/erubis_templates.js.erb +1 -0
  68. data/spec/fixtures/views/extension_template_controller/erubis_templates.rhtml +1 -0
  69. data/spec/fixtures/views/extension_template_controller/erubis_templates.xml.erb +1 -0
  70. data/spec/fixtures/views/extension_template_controller/haml_index.html.haml +0 -0
  71. data/spec/fixtures/views/extension_template_controller/haml_templates.html.haml +1 -0
  72. data/spec/fixtures/views/extension_template_controller/haml_templates.js.haml +1 -0
  73. data/spec/fixtures/views/extension_template_controller/haml_templates.xml.haml +1 -0
  74. data/spec/fixtures/views/extension_template_controller/index.html.erb +0 -0
  75. data/spec/fixtures/views/extension_template_controller/markaby_index.html.mab +0 -0
  76. data/spec/fixtures/views/extension_template_controller/markaby_templates.html.mab +1 -0
  77. data/spec/fixtures/views/extension_template_controller/markaby_templates.js.mab +1 -0
  78. data/spec/fixtures/views/extension_template_controller/markaby_templates.xml.mab +1 -0
  79. data/spec/fixtures/views/extension_template_controller/render_multiple_partials.html.erb +4 -0
  80. data/spec/fixtures/views/extension_template_controller/render_nested_js.js.erb +1 -0
  81. data/spec/fixtures/views/extension_template_controller/render_nested_xml.xml.erb +1 -0
  82. data/spec/fixtures/views/haml.html.haml +1 -0
  83. data/spec/fixtures/views/haml.xml.haml +2 -0
  84. data/spec/fixtures/views/layout/application.html.erb +1 -0
  85. data/spec/fixtures/views/layout/application.xml.erb +1 -0
  86. data/spec/fixtures/views/layout/nested/example.html.erb +1 -0
  87. data/spec/fixtures/views/markaby.html.mab +1 -0
  88. data/spec/fixtures/views/nested/example/test.html.erb +1 -0
  89. data/spec/fixtures/views/partials/_erubis.html.erb +1 -0
  90. data/spec/fixtures/views/partials/_erubis_collection.html.erb +1 -0
  91. data/spec/fixtures/views/partials/_erubis_collection_with_locals.html.erb +1 -0
  92. data/spec/fixtures/views/partials/_erubis_new.html.erb +1 -0
  93. data/spec/fixtures/views/partials/_haml.html.haml +1 -0
  94. data/spec/fixtures/views/partials/_haml_collection.html.haml +1 -0
  95. data/spec/fixtures/views/partials/_haml_collection_with_locals.html.haml +1 -0
  96. data/spec/fixtures/views/partials/_haml_new.html.haml +1 -0
  97. data/spec/fixtures/views/partials/_markaby.html.mab +1 -0
  98. data/spec/fixtures/views/partials/_markaby_collection.html.mab +1 -0
  99. data/spec/fixtures/views/partials/_markaby_collection_with_locals.html.mab +1 -0
  100. data/spec/fixtures/views/partials/_markaby_new.html.mab +1 -0
  101. data/spec/fixtures/views/render_object_controller/render_object_with_template.html.erb +1 -0
  102. data/spec/fixtures/views/render_object_controller/render_object_with_template.js.erb +1 -0
  103. data/spec/fixtures/views/render_object_controller/render_object_with_template.xml.erb +1 -0
  104. data/spec/fixtures/views/template_views/interface__buffer_erubis.html.erb +4 -0
  105. data/spec/fixtures/views/template_views/interface__buffer_haml.html.haml +7 -0
  106. data/spec/fixtures/views/template_views/interface__buffer_markaby.html.mab +7 -0
  107. data/spec/fixtures/views/template_views/interface_capture_erubis.html.erb +15 -0
  108. data/spec/fixtures/views/template_views/interface_capture_haml.html.haml +15 -0
  109. data/spec/fixtures/views/template_views/interface_capture_markaby.html.mab +4 -0
  110. data/spec/fixtures/views/template_views/interface_concat_erubis.html.erb +12 -0
  111. data/spec/fixtures/views/template_views/interface_concat_haml.html.haml +11 -0
  112. data/spec/fixtures/views/template_views/interface_concat_markaby.html.mab +14 -0
  113. data/spec/fixtures/views/test.dir/the_template.html.erb +1 -0
  114. data/spec/merb/abstract_controller_spec.rb +37 -0
  115. data/spec/merb/caching_spec.rb +102 -0
  116. data/spec/merb/config_spec.rb +29 -0
  117. data/spec/merb/controller_filters_spec.rb +188 -0
  118. data/spec/merb/controller_spec.rb +144 -0
  119. data/spec/merb/cookie_store_spec.rb +85 -0
  120. data/spec/merb/core_ext_spec.rb +430 -0
  121. data/spec/merb/dispatch_spec.rb +514 -0
  122. data/spec/merb/fake_request_spec.rb +72 -0
  123. data/spec/merb/form_control_mixin_spec.rb +431 -0
  124. data/spec/merb/generator_spec.rb +121 -0
  125. data/spec/merb/handler_spec.rb +169 -0
  126. data/spec/merb/mail_controller_spec.rb +144 -0
  127. data/spec/merb/mailer_spec.rb +87 -0
  128. data/spec/merb/multipart_spec.rb +49 -0
  129. data/spec/merb/part_controller_spec.rb +92 -0
  130. data/spec/merb/plugins_spec.rb +80 -0
  131. data/spec/merb/render_spec.rb +378 -0
  132. data/spec/merb/request_spec.rb +243 -0
  133. data/spec/merb/responder_spec.rb +561 -0
  134. data/spec/merb/router_spec.rb +726 -0
  135. data/spec/merb/template_spec.rb +41 -0
  136. data/spec/merb/upload_handler_spec.rb +101 -0
  137. data/spec/merb/view_context_spec.rb +148 -0
  138. data/spec/spec_generator_helper.rb +19 -0
  139. data/spec/spec_helper.rb +88 -0
  140. metadata +203 -65
  141. data/lib/merb/caching/store/memcache.rb +0 -20
  142. data/script/destroy +0 -14
  143. data/script/generate +0 -14
@@ -0,0 +1,169 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe MerbHandler, "process" do
4
+
5
+ def do_process
6
+ @handler.process( @request, @response )
7
+ end
8
+
9
+ def log_info_with( with_param )
10
+ MERB_LOGGER.should_receive(:info).with( with_param )
11
+ end
12
+
13
+ before(:each) do
14
+ @params = { Mongrel::Const::REQUEST_METHOD => "GET",
15
+ Mongrel::Const::PATH_INFO => "PUBLIC",
16
+ Mongrel::Const::REQUEST_URI => "www.example.com/file" }
17
+
18
+
19
+ @static_file_handler = mock( "mongrel_dir_handler", :null_object => true )
20
+ @static_file_handler.stub!( :can_serve ).and_return( false )
21
+ Mongrel::DirHandler.stub!(:new).and_return( @static_file_handler ) # Need to get a handle on the dir handler in initialize
22
+
23
+ @handler = MerbHandler.new( "public" )
24
+
25
+ @response = mock( "response", :null_object => true )
26
+ @response.stub!( :socket ).and_return( mock( "socket" ) )
27
+ @response.socket.stub!( :closed? ).and_return( false )
28
+
29
+ @request = mock( "request", :null_object => true )
30
+ @request.stub!( :params ).and_return( @params )
31
+
32
+ @benchmarks = { :setup_time => 1 }
33
+ @controller = mock( "controller", :null_object => true )
34
+ @controller.stub!(:class).and_return( "CONTROLLER_CLASS" )
35
+ @controller.stub!(:_benchmarks).and_return( @benchmarks )
36
+ @action = "ACTION"
37
+ Merb::Dispatcher.stub!( :handle ).and_return( [@controller, @action] )
38
+
39
+ MERB_LOGGER.stub!(:info)
40
+ end
41
+
42
+ it "should return nil if the socket is closed" do
43
+ @response.socket.stub!( :closed? ).and_return( true )
44
+ do_process.should be_nil
45
+ end
46
+
47
+ it "should log the request URI to the MERB_LOGGER.info" do
48
+ log_info_with( /REQUEST_URI/ )
49
+ do_process
50
+ end
51
+
52
+
53
+ it "should serve static files" do
54
+ @static_file_handler.stub!( :can_serve ).and_return( true )
55
+ log_info_with( /static/i )
56
+ @static_file_handler.should_receive( :process ).with( @request, @response )
57
+ do_process
58
+ end
59
+
60
+ it "should fall back to .html and try and serve the file" do
61
+ @static_file_handler.should_receive( :can_serve ).with( "PUBLIC.html" ).and_return( true )
62
+ @static_file_handler.should_receive( :process ).with( @request, @response )
63
+ log_info_with( /static/i )
64
+ do_process
65
+ @request.params[Mongrel::Const::PATH_INFO].should == "PUBLIC.html"
66
+ end
67
+
68
+ it "should ask the Dispatcher for the controller and action" do
69
+ Merb::Dispatcher.should_receive( :handle ).with( @request, @response )
70
+ do_process
71
+ end
72
+
73
+ it "should log any exceptions that reach the handler and return 500" do
74
+ @out = ""
75
+ @head = {}
76
+ Merb::Dispatcher.should_receive( :handle ).and_raise( Exception )
77
+ @response.should_receive( :send_status ).with( 500 )
78
+ MERB_LOGGER.should_receive(:error)
79
+ do_process
80
+ end
81
+
82
+ it "should set the response.status to the controller.status" do
83
+ @controller.should_receive( :status ).and_return( "SPEC_STATUS" )
84
+ @response.should_receive( :status= ).with( "SPEC_STATUS" )
85
+ do_process
86
+ end
87
+
88
+ it "should handle the X-SENDFILE header" do
89
+ @controller.should_receive( :headers ).and_return( { "X-SENDFILE" => __FILE__ } )
90
+ log_info_with( /X-SENDFILE/im )
91
+ @response.should_receive( :status= ).with( 200 )
92
+ @response.header.should_receive( :[]= ).with( Mongrel::Const::LAST_MODIFIED, an_instance_of( String ) )
93
+ @response.header.should_receive( :[]= ).with( Mongrel::Const::ETAG, anything() )
94
+ @response.should_recieve( :send_status ).with( File.size( __FILE__ ) )
95
+ @response.should_receive( :send_header )
96
+ @response.should_receive( :send_file )
97
+
98
+ do_process
99
+ end
100
+
101
+ it "should setup the headers" do
102
+ @response_header = {}
103
+ @controller.should_receive( :headers ).and_return( { "X-MY_HEADER" => "MY_HEADER_CONTENT" } )
104
+ @response.should_receive( :header ).and_return( @response_header )
105
+ @response_header.should_receive( :[]= ).with( "X-MY_HEADER", "MY_HEADER_CONTENT" )
106
+ do_process
107
+ end
108
+
109
+
110
+ it "should handle a controller body that can be read" do
111
+ # This is a bit dependent on implementation
112
+ @controller.should_receive( :headers ).and_return( { "CONTENT-LENGTH" => 5 } )
113
+ @body = Object.new
114
+ @body.stub!( :close ).and_return( true )
115
+ @body.stub!( :read ).and_return( false )
116
+ @body.should_receive( :read ).and_return( true, true, false )
117
+ @controller.stub!( :body ).and_return( @body )
118
+ @response.should_receive( :send_status ).with( 5 )
119
+ @response.should_receive( :send_header )
120
+ @response.should_receive( :write ).at_least( :once )
121
+ @body.should_receive( :close )
122
+
123
+ do_process
124
+ end
125
+
126
+ it "should handle a controller body that is a proc" do
127
+ @proc = Proc.new { "PROC_CONTENTS" }
128
+ @controller.should_receive( :body ).at_least(:once).and_return( @proc )
129
+ @proc.should_receive( :call )
130
+ do_process
131
+ end
132
+
133
+ it "should spit out a normal rendering of the controller" do
134
+ @body = "CONTROLLER_BODY"
135
+ @controller.stub!( :body ).and_return( @body )
136
+ @controller.should_receieve( :body ).at_least( :once ).and_return( @body )
137
+
138
+ @response.should_receive( :send_status ).with( @body.length )
139
+ @response.should_receive( :send_header )
140
+ @response.should_receive( :write ).with( @body )
141
+
142
+ do_process
143
+ end
144
+
145
+ it "should log the controller and action called" do
146
+ log_info_with( /Routing to.+CONTROLLER_CLASS.+ACTION/ )
147
+ do_process
148
+ end
149
+
150
+ it "should render the request times" do
151
+ log_info_with( /request times/i )
152
+ do_process
153
+ end
154
+
155
+ it "should render the Response status" do
156
+ log_info_with( /response status/i )
157
+ do_process
158
+ end
159
+
160
+ it "should remove path_prefix from the request_uri and path_info environment variables" do
161
+ MerbHandler.path_prefix = "/prefix"
162
+ @request.params[Mongrel::Const::PATH_INFO] = "/prefix/PUBLIC"
163
+ @request.params[Mongrel::Const::REQUEST_URI] = "/prefix/file"
164
+ do_process
165
+ @request.params[Mongrel::Const::PATH_INFO].should == "/PUBLIC"
166
+ @request.params[Mongrel::Const::REQUEST_URI].should == "/file"
167
+ MerbHandler.path_prefix = nil
168
+ end
169
+ end
@@ -0,0 +1,144 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ module Merb
4
+ class MailController
5
+ self._template_root = File.expand_path(File.join(File.dirname(__FILE__), '..', "fixtures/mailers/views"))
6
+ end
7
+ end
8
+ Merb::Server.load_controller_template_path_cache
9
+
10
+ class Merb::Mailer
11
+ self.delivery_method = :test_send
12
+ end
13
+
14
+ class TestMailController < Merb::MailController
15
+
16
+ def first
17
+ render_mail
18
+ end
19
+
20
+ def second
21
+ render_mail
22
+ end
23
+
24
+ def third
25
+ render_mail :text => :first, :html => :third
26
+ end
27
+
28
+ def fourth
29
+ render_mail :text => "FOURTH_TEXT", :html => "FOURTH_HTML"
30
+ end
31
+
32
+ def fifth
33
+ render_mail :action => {:text => :first, :html => :third}
34
+ end
35
+
36
+ def sixth
37
+ render_mail :action => {:text => :first}, :html => "SIXTH_HTML"
38
+ end
39
+
40
+ def seventh
41
+ render_mail :text => :first, :html => "SEVENTH_HTML"
42
+ end
43
+
44
+ def eighth
45
+ @testing = "TEST"
46
+ render_mail
47
+ end
48
+
49
+ def ninth
50
+ render_mail
51
+ end
52
+
53
+ def tenth
54
+ render_mail
55
+ end
56
+
57
+ end
58
+
59
+ class TestController < Merb::Controller
60
+
61
+ def one
62
+ send_mail TestMailController, :ninth, {:from => "foo@bar.com", :to => "foo@bar.com"}, {:x => "ONE_CONTROLLER"}
63
+ end
64
+
65
+ end
66
+
67
+ describe "A Merb Mail controller" do
68
+
69
+ def deliver(action)
70
+ TestMailController.dispatch_and_deliver action, :from => "foo@bar.com", :to => "foo@bar.com"
71
+ @delivery = Merb::Mailer.deliveries.last
72
+ end
73
+
74
+ undef :call_action if defined?(call_action)
75
+ def call_action(action)
76
+ @c = new_controller(action, TestController)
77
+ @c.dispatch(action)
78
+ @delivery = Merb::Mailer.deliveries.last
79
+ end
80
+
81
+ it "should render files in its directory by default" do
82
+ deliver :first
83
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
84
+ end
85
+
86
+ it "should render files in its directory without a mimetype extension by default" do
87
+ deliver :second
88
+ @delivery.text.should == "TEXT\nSECOND\nENDTEXT"
89
+ end
90
+
91
+ it "should be able to accept a :text => :sym, :html => :sym render_mail" do
92
+ deliver :third
93
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
94
+ @delivery.html.should == "BASIC\nTHIRDHTML\nLAYOUT"
95
+ end
96
+
97
+ it "should be able to accept a :text => STRING, :html => STRING render_mail" do
98
+ deliver :fourth
99
+ @delivery.text.should == "FOURTH_TEXT"
100
+ @delivery.html.should == "FOURTH_HTML"
101
+ end
102
+
103
+ it "should be able to accept an :action => {:text => :sym, :html => :sym}" do
104
+ deliver :fifth
105
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
106
+ @delivery.html.should == "BASIC\nTHIRDHTML\nLAYOUT"
107
+ end
108
+
109
+ it "should be able to accept a mix of action and :html => STRING" do
110
+ deliver :sixth
111
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
112
+ @delivery.html.should == "SIXTH_HTML"
113
+ end
114
+
115
+ it "should be able to accept a mix of :text => :sym and :html => STRING" do
116
+ deliver :seventh
117
+ @delivery.text.should == "TEXT\nFIRST\nENDTEXT"
118
+ @delivery.html.should == "SEVENTH_HTML"
119
+ end
120
+
121
+ it "should hold onto instance variables" do
122
+ deliver :eighth
123
+ @delivery.html.should == "BASIC\nTEST\nLAYOUT"
124
+ end
125
+
126
+ it "should have access to the params sent by the calling controller" do
127
+ @in = Merb::Test::FakeRequest.new
128
+ @res = StringIO.new
129
+ call_action :one
130
+ @delivery.html.should == "BASIC\nONE_CONTROLLER\nLAYOUT"
131
+ end
132
+
133
+ it "should not raise an error if there are no templates" do
134
+ lambda do
135
+ deliver :tenth
136
+ end.should_not raise_error
137
+ end
138
+
139
+ it "should log an error if there are no templates available" do
140
+ MERB_LOGGER.should_receive(:error).once
141
+ deliver :tenth
142
+ end
143
+
144
+ end
@@ -0,0 +1,87 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ class TestMailer < Merb::Mailer
4
+ self.delivery_method = :test_send
5
+ end
6
+
7
+ class TestSMTPMailer < Merb::Mailer
8
+ self.delivery_method = :net_smtp
9
+ self.config = { :host => 'smtp.yourserver.com',
10
+ :port => '25',
11
+ :user => 'user',
12
+ :pass => 'pass',
13
+ :auth => :plain }
14
+
15
+ end
16
+
17
+ class TestSendmailMailer < Merb::Mailer
18
+ self.delivery_method = :sendmail
19
+ end
20
+
21
+ def setup_test_mailer klass = TestMailer
22
+ @m = klass.new :to => "test@test.com",
23
+ :from => "foo@bar.com",
24
+ :subject => "Test Subject",
25
+ :body => "Test"
26
+ end
27
+
28
+ describe "a merb mailer" do
29
+
30
+ it "should be able to send test emails" do
31
+ setup_test_mailer
32
+ @m.deliver!
33
+ TestMailer.deliveries.size.should == 1
34
+ delivery = TestMailer.deliveries.last
35
+ delivery.to.should include("test@test.com")
36
+ delivery.from.should include("foo@bar.com")
37
+ delivery.subject.should include("Test Subject")
38
+ delivery.body.should include("Test")
39
+ end
40
+
41
+ it "should be able to accept attachments" do
42
+ setup_test_mailer
43
+ @m.attach File.open("README")
44
+ @m.deliver!
45
+ delivery = TestMailer.deliveries.last
46
+ delivery.instance_variable_get("@attachments").size.should == 1
47
+ end
48
+
49
+ it "should be able to accept multiple attachments" do
50
+ setup_test_mailer
51
+ @m.attach [[File.open("README")], [File.open("LICENSE")]]
52
+ @m.deliver!
53
+ delivery = TestMailer.deliveries.last
54
+ delivery.instance_variable_get("@attachments").size.should == 2
55
+ end
56
+
57
+ it "should be able to send mails via SMTP" do
58
+ setup_test_mailer TestSMTPMailer
59
+ Net::SMTP.stub!(:start).and_return(true)
60
+ Net::SMTP.should_receive(:start).with("smtp.yourserver.com", 25, nil, "user", "pass", :plain)
61
+ @m.deliver!
62
+ end
63
+
64
+ it "should send mails via SMTP with no auth" do
65
+ setup_test_mailer TestSMTPMailer
66
+ @m.config[:auth] = nil
67
+ Net::SMTP.stub!(:start).and_return(true)
68
+ Net::SMTP.should_receive(:start).with("smtp.yourserver.com", 25, nil, "user", "pass", nil)
69
+ @m.deliver!
70
+ end
71
+
72
+ it "should be able to send mails via sendmail" do
73
+ sendmail = mock("/usr/sbin/sendmail", :null_object => true)
74
+ setup_test_mailer TestSendmailMailer
75
+ IO.should_receive(:popen).with("/usr/sbin/sendmail #{@m.mail.to}", "w+").and_return(sendmail)
76
+ @m.deliver!
77
+ end
78
+
79
+ it "should be able to use a different sendmail path" do
80
+ sendmail = mock("/somewhere/sendmail", :null_object => true)
81
+ setup_test_mailer TestSendmailMailer
82
+ @m.config[:sendmail_path] = '/somewhere/sendmail'
83
+ IO.should_receive(:popen).with("/somewhere/sendmail #{@m.mail.to}", "w+").and_return(sendmail)
84
+ @m.deliver!
85
+ end
86
+
87
+ end
@@ -0,0 +1,49 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Merb::Test::Multipart::Param, '.to_multipart' do
4
+ it "should represent the key and value correctly" do
5
+ param = Merb::Test::Multipart::Param.new('foo', 'bar')
6
+ param.to_multipart.should == %(Content-Disposition: form-data; name="foo"\r\n\r\nbar\r\n)
7
+ end
8
+ end
9
+
10
+ describe Merb::Test::Multipart::FileParam, '.to_multipart' do
11
+ it "should represent the key, filename and content correctly" do
12
+ param = Merb::Test::Multipart::FileParam.new('foo', '/bar.txt', 'baz')
13
+ param.to_multipart.should == %(Content-Disposition: form-data; name="foo"; filename="/bar.txt"\r\nContent-Type: text/plain\r\n\r\nbaz\r\n)
14
+ end
15
+ end
16
+
17
+ describe Merb::Test::Multipart::Post, '.push_params(params) param parsing' do
18
+ before(:each) do
19
+ @fake_return_param = mock('fake return_param')
20
+ end
21
+
22
+ it "should create Param from params when param doesn't respond to read" do
23
+ params = { 'normal' => 'normal_param' }
24
+ Merb::Test::Multipart::Param.should_receive(:new).with('normal', 'normal_param').and_return(@fake_return_param)
25
+ Merb::Test::Multipart::Post.new.push_params(params)
26
+ end
27
+
28
+ it "should create FileParam from params when param does response to read" do
29
+ file_param = mock('file param')
30
+ file_param.should_receive(:read).and_return('file contents')
31
+ file_param.should_receive(:path).and_return('file.txt')
32
+ params = { 'file' => file_param }
33
+ Merb::Test::Multipart::FileParam.should_receive(:new).with('file', 'file.txt', 'file contents').and_return(@fake_return_param)
34
+ Merb::Test::Multipart::Post.new.push_params(params)
35
+ end
36
+ end
37
+
38
+ describe Merb::Test::Multipart::Post, '.to_multipart' do
39
+ it "should create a multipart request from the params" do
40
+ file_param = mock('file param')
41
+ file_param.should_receive(:read).and_return('file contents')
42
+ file_param.should_receive(:path).and_return('file.txt')
43
+ params = { 'file' => file_param, 'normal' => 'normal_param' }
44
+ multipart = Merb::Test::Multipart::Post.new(params)
45
+ query, content_type = multipart.to_multipart
46
+ content_type.should == "multipart/form-data, boundary=----------0xKhTmLbOuNdArY"
47
+ query.should == "------------0xKhTmLbOuNdArY\r\nContent-Disposition: form-data; name=\"file\"; filename=\"file.txt\"\r\nContent-Type: text/plain\r\n\r\nfile contents\r\n------------0xKhTmLbOuNdArY\r\nContent-Disposition: form-data; name=\"normal\"\r\n\r\nnormal_param\r\n------------0xKhTmLbOuNdArY--"
48
+ end
49
+ end
@@ -0,0 +1,92 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ Merb::Template::Erubis # Need to initialise the Erubis template
3
+
4
+ class Main < Merb::Controller
5
+
6
+ def index
7
+ part TodoPart => :list
8
+ end
9
+
10
+ def index2
11
+ part TodoPart => :one
12
+ end
13
+
14
+ def index3
15
+ part(TodoPart => :one) + part(TodoPart => :list)
16
+ end
17
+
18
+ def index4
19
+ provides [:xml, :js]
20
+ part(TodoPart => :formatted_output)
21
+ end
22
+
23
+ end
24
+
25
+
26
+ class TodoPart < Merb::PartController
27
+ self._template_root = File.expand_path(File.join(File.dirname(__FILE__), '..', "fixtures/parts/views"))
28
+
29
+ before :load_todos
30
+
31
+ def list
32
+ render
33
+ end
34
+
35
+ def one
36
+ render :layout => :none, :action => :list
37
+ end
38
+
39
+ def load_todos
40
+ @todos = ["Do this", "Do that", 'Do the other thing']
41
+ end
42
+
43
+ def formatted_output
44
+ render
45
+ end
46
+
47
+ end
48
+
49
+ describe "A Merb PartController" do
50
+
51
+ before(:each) do
52
+ Merb::Router.prepare do |r|
53
+ r.default_routes
54
+ end
55
+ end
56
+
57
+ it "should render a part template with no layout" do
58
+ controller,action = request(:get, '/main/index2')
59
+ controller.body.should ==
60
+ "TODOPART\nDo this|Do that|Do the other thing\nTODOPART"
61
+ end
62
+
63
+ it "should render a part template with it's own layout" do
64
+ controller,_ = request(:get, '/main/index')
65
+ controller.body.should ==
66
+ "TODOLAYOUT\nTODOPART\nDo this|Do that|Do the other thing\nTODOPART\nTODOLAYOUT"
67
+ end
68
+
69
+ it "should render multiple parts if more then one part is passed in" do
70
+ controller,_ = request(:get, '/main/index3')
71
+ controller.body.should ==
72
+ "TODOPART\nDo this|Do that|Do the other thing\nTODOPART" +
73
+ "TODOLAYOUT\nTODOPART\nDo this|Do that|Do the other thing\nTODOPART\nTODOLAYOUT"
74
+ end
75
+
76
+ it "should render the html format by default to the controller that set it" do
77
+ controller,_ = request(:get, '/main/index4')
78
+ controller.body.should match(/part_html_format/m)
79
+
80
+ end
81
+
82
+ it "should render the xml format according to the controller" do
83
+ controller,_ = request(:get, '/main/index4.xml')
84
+ controller.body.should match(/part_xml_format/m)
85
+ end
86
+
87
+ it "should render the xml format according to the controller" do
88
+ controller,_ = request(:get, '/main/index4.js')
89
+ controller.body.should match(/part_js_format/m)
90
+ end
91
+
92
+ end
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "Plugins", "default GENERATOR_SCOPE" do
4
+ it "should have :merb_default first" do
5
+ Merb::GENERATOR_SCOPE.first.should == :merb_default
6
+ end
7
+
8
+ it "should have :merb" do
9
+ Merb::GENERATOR_SCOPE.should include(:merb)
10
+ end
11
+
12
+ it "should have :rspec last" do
13
+ Merb::GENERATOR_SCOPE.last.should == :rspec
14
+ end
15
+ end
16
+
17
+ describe "Plugins","use_orm" do
18
+ before(:each) do
19
+ Merb::GENERATOR_SCOPE.replace [:merb_default, :merb, :rspec]
20
+ Kernel.stub!(:dependency)
21
+ end
22
+
23
+ it "should raise an error if use_orm is called twice" do
24
+ use_orm(:activerecord)
25
+ lambda { use_orm(:datamapper) }.should raise_error
26
+ end
27
+
28
+ it "should not have :merb_default in GENERATOR_SCOPE with use_orm(:activerecord)" do
29
+ use_orm(:activerecord)
30
+ Merb::GENERATOR_SCOPE.should_not include(:merb_default)
31
+ end
32
+
33
+ it "should have :activerecord in GENERATOR_SCOPE with use_orm(:activerecord)" do
34
+ use_orm(:activerecord)
35
+ Merb::GENERATOR_SCOPE.should include(:activerecord)
36
+ end
37
+
38
+ it "should have :activerecord first in GENERATOR_SCOPE with use_orm(:activerecord)" do
39
+ use_orm(:activerecord)
40
+ Merb::GENERATOR_SCOPE.first.should == :activerecord
41
+ end
42
+
43
+ it "should call dependency :merb_activerecord with use_orm(:activerecord)" do
44
+ Kernel.should_receive(:dependency).with("merb_activerecord").once.
45
+ and_return(true)
46
+ use_orm(:activerecord)
47
+ end
48
+
49
+ end
50
+
51
+ describe "Plugins","use_test" do
52
+ before(:each) do
53
+ Merb::GENERATOR_SCOPE.replace [:merb_default, :merb, :rspec]
54
+ end
55
+
56
+ it "should have :rspec in GENERATOR_SCOPE by default" do
57
+ Merb::GENERATOR_SCOPE.should include(:rspec)
58
+ end
59
+
60
+ it "should not have :rspec in GENERATOR_SCOPE with use_test(:test_unit)" do
61
+ use_test(:test_unit)
62
+ Merb::GENERATOR_SCOPE.should_not include(:rspec)
63
+ end
64
+
65
+ it "should have :test_unit in GENERATOR_SCOPE with use_test(:test_unit)" do
66
+ use_test(:test_unit)
67
+ Merb::GENERATOR_SCOPE.should include(:test_unit)
68
+ end
69
+
70
+ it "should have :test_unit last in GENERATOR_SCOPE with use_test(:test_unit)" do
71
+ use_test(:test_unit)
72
+ Merb::GENERATOR_SCOPE.last.should == :test_unit
73
+ end
74
+
75
+ it "should raise an error if called with an unsupported test framework" do
76
+ lambda { use_test(:fiddlefaddle) }.should raise_error
77
+ end
78
+
79
+ it "should allow adding more than test_unit or rspec via plugins"
80
+ end