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,41 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Merb::Template do
4
+
5
+ it "should register the extensions for a given engine" do
6
+ Merb::Template::EXTENSIONS["tester_ext"].should be_nil
7
+ Merb::Template::EXTENSIONS["ext"].should be_nil
8
+ Merb::Template.register_extensions(:tester, %w[tester_ext ext])
9
+ Merb::Template::EXTENSIONS["tester_ext"].should == :tester
10
+ Merb::Template::EXTENSIONS["ext"].should == :tester
11
+ end
12
+
13
+ it "should raise an error when registering extensions if the engine is not a symbol" do
14
+ lambda do
15
+ Merb::Template.register_extensions("tester", %w(thing))
16
+ end.should raise_error(ArgumentError)
17
+ end
18
+
19
+ it "should raise an error when registering extensions if the extensions are not an array" do
20
+ lambda do
21
+ Merb::Template.register_extensions(:tester, "tester")
22
+ end.should raise_error(ArgumentError)
23
+ end
24
+
25
+ it "should select the engine for an erubis file" do
26
+ Merb::Template.engine_for("test.html.erb").should == Merb::Template::Erubis
27
+ end
28
+
29
+ it "should select the engine for an haml file" do
30
+ Merb::Template.engine_for("test.html.haml").should == Merb::Template::Haml
31
+ end
32
+
33
+ it "should select the engine for a markaby file" do
34
+ Merb::Template.engine_for("test.html.mab").should == Merb::Template::Markaby
35
+ end
36
+
37
+ it "should select the builder engine" do
38
+ Merb::Template.engine_for("test.xml.builder").should == Merb::Template::XMLBuilder
39
+ end
40
+
41
+ end
@@ -0,0 +1,101 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe MerbUploadHandler do
4
+ before(:each) do
5
+ @progress = mock(:upload_progress)
6
+ @progress.stub!(:debug)
7
+ @progress.stub!(:update_checked_time)
8
+ @progress.stub!(:add)
9
+ @progress.stub!(:mark)
10
+ @progress.stub!(:finish)
11
+ @progress.stub!(:last_checked).and_return Time.now - 10
12
+ Merb::UploadProgress.stub!(:new).and_return(@progress)
13
+ @handler = MerbUploadHandler.new(:upload_frequency => 3, :upload_path_match => '^/files/\d+')
14
+ @upload_id = '880b7835-8a67-400e-a8f1-dec18691d604'
15
+ @params = {
16
+ 'CONTENT_LENGTH' => "10",
17
+ 'PATH_INFO' => '/files/23',
18
+ 'REQUEST_METHOD' => 'POST',
19
+ 'QUERY_STRING' => "upload_id=#{@upload_id}"
20
+ }
21
+ @request = mock(:request)
22
+ @request.stub!(:params).and_return(@params)
23
+ @response = mock(:response)
24
+ end
25
+
26
+ after(:each) do
27
+ Mongrel.class_eval do
28
+ remove_const :Uploads
29
+ end
30
+ end
31
+
32
+ it "should consider requests as invalid if the path regex does not match" do
33
+ @handler.send(:valid_upload?, {
34
+ 'CONTENT_LENGTH' => "10",
35
+ 'PATH_INFO' => '/spoons/',
36
+ 'REQUEST_METHOD' => 'POST',
37
+ 'QUERY_STRING' => "upload_id=#{@upload_id}"
38
+ }).should == nil
39
+ end
40
+
41
+ it "should send a message to Mongrel::Uploads when calling upload_notify" do
42
+ Mongrel::Uploads.should_receive(:add)
43
+ @handler.send(:upload_notify, :add, @params)
44
+ end
45
+
46
+ it "should receive upload_notify with :add when the request begins" do
47
+ @handler.should_receive(:upload_notify).with(:add, @params, 10)
48
+ @handler.request_begins(@params)
49
+ end
50
+
51
+ it "should receive upload_notify with :mark when progress is checked" do
52
+ @handler.should_receive(:upload_notify).with(:mark, @params, 7)
53
+ @handler.request_progress(@params, 7, 10)
54
+ end
55
+
56
+ it "should receive upload_notify with :finish when ready to process the request" do
57
+ @handler.should_receive(:upload_notify).with(:finish, @params)
58
+ @handler.process(@request,@response)
59
+ end
60
+
61
+ it "should send Mongrel::Uploads :finish if the request is a valid upload" do
62
+ Mongrel::Uploads.should_receive(:finish).with(@upload_id)
63
+ @handler.stub!(:valid_upload?).and_return(@upload_id)
64
+ @handler.request_aborted(@params)
65
+ end
66
+
67
+ it "should not send Mongrel::Uploads :finish unless the request is a valid upload" do
68
+ Mongrel::Uploads.should_not_receive(:finish)
69
+ @handler.stub!(:valid_upload?).and_return(false)
70
+ @handler.request_aborted(@params)
71
+ end
72
+
73
+ it "should return an upload_id for a valid upload" do
74
+ @handler.send(:valid_upload?, @params).should == @upload_id
75
+ end
76
+
77
+ it "should not consider a GET a valid upload" do
78
+ @params['REQUEST_METHOD'] = 'GET'
79
+ @handler.send(:valid_upload?, @params).should be_false
80
+ end
81
+
82
+ it "should consider a PUT a valid upload" do
83
+ @params['REQUEST_METHOD'] = 'PUT'
84
+ @handler.send(:valid_upload?, @params).should == @upload_id
85
+ end
86
+
87
+ it "should update Mongrel::Uploads' last checked time when calling upload_notify" do
88
+ Mongrel::Uploads.should_receive(:update_checked_time).with(@upload_id)
89
+ @handler.send(:upload_notify, :add, @params)
90
+ end
91
+
92
+ it "should not update Mongrel::Uploads' last checked time when calling upload_notify if the action is :finish" do
93
+ Mongrel::Uploads.should_not_receive(:update_checked_time)
94
+ @handler.send(:upload_notify, :finish, @params)
95
+ end
96
+
97
+ it "should not allow progress checks more frequently than the specified frequency" do
98
+ Mongrel::Uploads.update_checked_time(@upload_id)
99
+ @handler.request_progress(@params,7,10).should be_nil
100
+ end
101
+ end
@@ -0,0 +1,148 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe "View Context", "image tag" do
4
+
5
+ include Merb::ViewContextMixin
6
+ it "should render an link" do
7
+ the_link = link_to( "NAME", "http://example.com", :title => "TITLE", :target => "TARGET" )
8
+ the_link.should match( /<a.+>NAME<\/a>/ )
9
+ the_link.should match( /href="http:\/\/example.com"/)
10
+ the_link.should match( /title="TITLE"/)
11
+ the_link.should match( /target="TARGET"/ )
12
+ end
13
+
14
+ it "should render local image" do
15
+ image_tag('foo.gif').clean.should == %[<img src="/images/foo.gif"/>].clean
16
+ end
17
+
18
+ it "should render local image with class" do
19
+ image_tag('foo.gif', :class => 'bar').clean.should == %[<img src="/images/foo.gif" class="bar" />].clean
20
+ end
21
+
22
+ it "should render local image with class and explicit path" do
23
+ image_tag('foo.gif', :class => 'bar', :path => '/files/').clean.should == %[<img src="/files/foo.gif" class="bar" />].clean
24
+ end
25
+
26
+ it "should render remote image" do
27
+ image_tag('http://test.com/foo.gif').clean.should == %[<img src="http://test.com/foo.gif"/>].clean
28
+ end
29
+
30
+ it "should render remote SSL image" do
31
+ image_tag('https://test.com/foo.gif').clean.should == %[<img src="https://test.com/foo.gif"/>].clean
32
+ end
33
+
34
+ end
35
+
36
+ describe "View Context", "css tag" do
37
+
38
+ include Merb::ViewContextMixin
39
+
40
+ it "should render a link tag with the css_include_tag method" do
41
+ css_include_tag('foo.css').clean.should ==
42
+ %[<link href="/stylesheets/foo.css" media="all" rel="Stylesheet" type="text/css"/>].clean
43
+
44
+ css_include_tag('foo').should == css_include_tag('foo.css')
45
+
46
+ css_include_tag('foo', 'bar').should ==
47
+ css_include_tag('foo') +
48
+ css_include_tag('bar')
49
+ end
50
+ it "should not generate a script tag with the include_required_css" do
51
+ include_required_css.clean.should == ''
52
+ end
53
+ it "should generate script tags with the include_required_css" do
54
+ require_css('foo')
55
+ require_css('bar')
56
+ include_required_css.should ==
57
+ css_include_tag('foo') + css_include_tag('bar')
58
+ end
59
+ end
60
+
61
+ describe "View Context", "script tag" do
62
+
63
+ include Merb::ViewContextMixin
64
+
65
+ it "should render a script tag with the js_include_tag method" do
66
+ js_include_tag('foo.js').clean.should == %[<script src="/javascripts/foo.js" type="text/javascript">//</script>].clean
67
+
68
+ js_include_tag('foo').should == js_include_tag('foo.js')
69
+
70
+ js_include_tag('foo', 'bar').should ==
71
+ js_include_tag('foo') +
72
+ js_include_tag('bar')
73
+ end
74
+ it "should not generate a script tag with the include_required_js" do
75
+ include_required_js.clean.should == ''
76
+ end
77
+ it "should generate script tags with the include_required_js" do
78
+ require_js('foo')
79
+ require_js('bar')
80
+ include_required_js.should == js_include_tag('foo') + js_include_tag('bar')
81
+ end
82
+ end
83
+
84
+ describe "View Context", "throw_content, catch_content" do
85
+
86
+ include Merb::ViewContextMixin
87
+
88
+ it "should throw content" do
89
+ c = new_controller
90
+ content = c.render :template => "examples/template_throw_content", :layout => :none
91
+ content.should match( /THROWN CONTENT/m )
92
+ end
93
+
94
+ it "should throw content including a partial" do
95
+ c = new_controller
96
+ content = c.render :template => "examples/template_catch_content_from_partial", :layout => :none
97
+ content.should match( /CONTENT THROWN FROM PARTIAL/m )
98
+ end
99
+
100
+ it "should catch content" do
101
+ c = new_controller
102
+ content = c.render :template => "examples/template_catch_content", :layout => :none
103
+ content.should match( /CAUGHT CONTENT/m)
104
+ end
105
+
106
+ it "should catch content with multiple throws" do
107
+ c = new_controller
108
+ content = c.render :template => "examples/template_catch_content", :layout => :none
109
+ content.should match( /CAUGHT FOOTER/m )
110
+ content.should match( /START FOOTER\s+CAUGHT FOOTER\s+END FOOTER/m )
111
+ end
112
+
113
+ it "should not render the block inline" do
114
+ c = new_controller
115
+ content = c.render :template => "examples/template_catch_content", :layout => :none
116
+ content.should match( /\A\s*START HEADER\s*CAUGHT CONTENT\s*END HEADER\s*START FOOTER\s*CAUGHT FOOTER\s*END FOOTER\s*\Z/m)
117
+ end
118
+
119
+
120
+ end
121
+
122
+ describe Merb::ViewContextMixin do
123
+
124
+ it "should render the start of a tag" do
125
+ open_tag(:div).should == "<div>"
126
+ end
127
+
128
+ it "should render the start of a tag with attributes" do
129
+ tag = open_tag(:div, :id => 1, :class => "CLASS")
130
+ tag.should match( /^<div /)
131
+ tag.should match( /id="1"/)
132
+ tag.should match( /class="CLASS"/)
133
+ tag.should match( />$/ )
134
+ end
135
+
136
+ it "should render a self closing tag" do
137
+ self_closing_tag( :br ).should == "<br/>"
138
+ end
139
+
140
+ it "should render a self closing tag with attributes" do
141
+ self_closing_tag(:img, :src => "SOURCE" ).should == "<img src=\"SOURCE\"/>"
142
+ end
143
+
144
+ it "should render a closing tag" do
145
+ close_tag(:div).should == "</div>"
146
+ end
147
+
148
+ end
@@ -0,0 +1,19 @@
1
+ require 'fileutils'
2
+
3
+ # Must set before requiring generator libs.
4
+ TMP_ROOT = File.dirname(__FILE__) + "/tmp" unless defined?(TMP_ROOT)
5
+ PROJECT_NAME = "myproject" unless defined?(PROJECT_NAME)
6
+ app_root = File.join(TMP_ROOT, PROJECT_NAME)
7
+ if defined?(APP_ROOT)
8
+ APP_ROOT.replace(app_root)
9
+ else
10
+ APP_ROOT = app_root
11
+ end
12
+
13
+ begin
14
+ require 'rubigen'
15
+ rescue LoadError
16
+ require 'rubygems'
17
+ require 'rubigen'
18
+ end
19
+ require 'rubigen/helpers/generator_test_helper'
@@ -0,0 +1,88 @@
1
+ $TESTING=true
2
+ require 'timeout'
3
+ require 'open-uri'
4
+ require 'net/http'
5
+ require 'rubygems'
6
+ require 'spec'
7
+ require 'mocha'
8
+ require 'hpricot'
9
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib')
10
+ $:.push File.join(File.dirname(__FILE__), '..', 'lib', 'server')
11
+ require 'merb'
12
+ require 'merb/test/helper'
13
+
14
+ FIXTURES = File.expand_path(File.join(File.dirname(__FILE__), 'fixtures'))
15
+
16
+
17
+ # Creates a new controller, e.g.
18
+ # c = new_controller('index', Examples) do |request|
19
+ # request.post_body = "blah"
20
+ # end
21
+ def new_controller(action = 'index', controller = nil, additional_params = {})
22
+ request = OpenStruct.new
23
+ request.params = {:action => action, :controller => (controller.to_s || "Test")}
24
+ request.params.update(additional_params)
25
+ request.cookies = {}
26
+ request.accept ||= '*/*'
27
+
28
+ yield request if block_given?
29
+
30
+ response = OpenStruct.new
31
+ response.read = ""
32
+ (controller || Merb::Controller).build(request, response)
33
+ end
34
+
35
+ class Merb::Controller
36
+ require "lib/merb/session/memory_session"
37
+ Merb::MemorySessionContainer.setup
38
+ include ::Merb::SessionMixin
39
+ end
40
+
41
+ class String
42
+ def clean
43
+ Hpricot(chomp).to_s
44
+ end
45
+ end
46
+
47
+
48
+ # -- Global custom matchers --
49
+
50
+ # A better +be_kind_of+ with more informative error messages.
51
+ #
52
+ # The default +be_kind_of+ just says
53
+ #
54
+ # "expected to return true but got false"
55
+ #
56
+ # This one says
57
+ #
58
+ # "expected File but got Tempfile"
59
+
60
+ class BeKindOf
61
+
62
+ def initialize(expected) # + args
63
+ @expected = expected
64
+ end
65
+
66
+ def matches?(target)
67
+ @target = target
68
+ @target.kind_of?(@expected)
69
+ end
70
+
71
+ def failure_message
72
+ "expected #{@expected} but got #{@target.class}"
73
+ end
74
+
75
+ def negative_failure_message
76
+ "expected #{@expected} to not be #{@target.class}"
77
+ end
78
+
79
+ def description
80
+ "be_kind_of #{@target}"
81
+ end
82
+
83
+ end
84
+
85
+ def be_kind_of(expected) # + args
86
+ BeKindOf.new(expected)
87
+ end
88
+