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.
- 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,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
|