actionpack 1.8.1 → 1.9.0

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of actionpack might be problematic. Click here for more details.

Files changed (101) hide show
  1. data/CHANGELOG +309 -16
  2. data/README +1 -1
  3. data/lib/action_controller.rb +5 -0
  4. data/lib/action_controller/assertions.rb +57 -12
  5. data/lib/action_controller/auto_complete.rb +47 -0
  6. data/lib/action_controller/base.rb +288 -258
  7. data/lib/action_controller/benchmarking.rb +8 -3
  8. data/lib/action_controller/caching.rb +88 -42
  9. data/lib/action_controller/cgi_ext/cgi_ext.rb +1 -1
  10. data/lib/action_controller/cgi_ext/cgi_methods.rb +41 -11
  11. data/lib/action_controller/cgi_ext/multipart_progress.rb +169 -0
  12. data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +30 -12
  13. data/lib/action_controller/cgi_process.rb +39 -11
  14. data/lib/action_controller/code_generation.rb +235 -0
  15. data/lib/action_controller/cookies.rb +14 -8
  16. data/lib/action_controller/deprecated_renders_and_redirects.rb +76 -0
  17. data/lib/action_controller/filters.rb +8 -7
  18. data/lib/action_controller/helpers.rb +41 -6
  19. data/lib/action_controller/layout.rb +45 -16
  20. data/lib/action_controller/request.rb +86 -23
  21. data/lib/action_controller/rescue.rb +1 -0
  22. data/lib/action_controller/response.rb +1 -1
  23. data/lib/action_controller/routing.rb +536 -272
  24. data/lib/action_controller/scaffolding.rb +30 -25
  25. data/lib/action_controller/session/active_record_store.rb +251 -50
  26. data/lib/action_controller/streaming.rb +133 -0
  27. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +0 -7
  28. data/lib/action_controller/templates/scaffolds/edit.rhtml +2 -2
  29. data/lib/action_controller/templates/scaffolds/layout.rhtml +22 -18
  30. data/lib/action_controller/templates/scaffolds/list.rhtml +3 -3
  31. data/lib/action_controller/templates/scaffolds/new.rhtml +2 -2
  32. data/lib/action_controller/templates/scaffolds/show.rhtml +1 -1
  33. data/lib/action_controller/test_process.rb +68 -47
  34. data/lib/action_controller/upload_progress.rb +421 -0
  35. data/lib/action_controller/url_rewriter.rb +8 -11
  36. data/lib/action_controller/vendor/html-scanner/html/document.rb +6 -5
  37. data/lib/action_controller/vendor/html-scanner/html/node.rb +70 -14
  38. data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +17 -10
  39. data/lib/action_controller/vendor/html-scanner/html/version.rb +3 -3
  40. data/lib/action_controller/vendor/xml_simple.rb +1019 -0
  41. data/lib/action_controller/verification.rb +36 -30
  42. data/lib/action_view/base.rb +21 -14
  43. data/lib/action_view/helpers/active_record_helper.rb +15 -13
  44. data/lib/action_view/helpers/asset_tag_helper.rb +26 -9
  45. data/lib/action_view/helpers/benchmark_helper.rb +24 -0
  46. data/lib/action_view/helpers/capture_helper.rb +7 -5
  47. data/lib/action_view/helpers/date_helper.rb +63 -46
  48. data/lib/action_view/helpers/form_helper.rb +7 -1
  49. data/lib/action_view/helpers/form_options_helper.rb +19 -11
  50. data/lib/action_view/helpers/form_tag_helper.rb +5 -1
  51. data/lib/action_view/helpers/javascript_helper.rb +403 -35
  52. data/lib/action_view/helpers/javascripts/controls.js +261 -0
  53. data/lib/action_view/helpers/javascripts/dragdrop.js +476 -0
  54. data/lib/action_view/helpers/javascripts/effects.js +570 -0
  55. data/lib/action_view/helpers/javascripts/prototype.js +633 -371
  56. data/lib/action_view/helpers/number_helper.rb +11 -13
  57. data/lib/action_view/helpers/tag_helper.rb +1 -2
  58. data/lib/action_view/helpers/text_helper.rb +69 -6
  59. data/lib/action_view/helpers/upload_progress_helper.rb +433 -0
  60. data/lib/action_view/helpers/url_helper.rb +98 -3
  61. data/lib/action_view/partials.rb +14 -8
  62. data/lib/action_view/vendor/builder/xmlmarkup.rb +11 -0
  63. data/rakefile +13 -5
  64. data/test/abstract_unit.rb +1 -1
  65. data/test/controller/action_pack_assertions_test.rb +52 -9
  66. data/test/controller/active_record_assertions_test.rb +119 -120
  67. data/test/controller/active_record_store_test.rb +111 -0
  68. data/test/controller/addresses_render_test.rb +45 -0
  69. data/test/controller/caching_filestore.rb +92 -0
  70. data/test/controller/capture_test.rb +39 -0
  71. data/test/controller/cgi_test.rb +40 -3
  72. data/test/controller/helper_test.rb +65 -13
  73. data/test/controller/multipart_progress_testx.rb +365 -0
  74. data/test/controller/new_render_test.rb +263 -0
  75. data/test/controller/redirect_test.rb +64 -0
  76. data/test/controller/render_test.rb +20 -21
  77. data/test/controller/request_test.rb +83 -3
  78. data/test/controller/routing_test.rb +702 -0
  79. data/test/controller/send_file_test.rb +2 -0
  80. data/test/controller/test_test.rb +44 -8
  81. data/test/controller/upload_progress_testx.rb +89 -0
  82. data/test/controller/verification_test.rb +94 -29
  83. data/test/fixtures/addresses/list.rhtml +1 -0
  84. data/test/fixtures/test/capturing.rhtml +4 -0
  85. data/test/fixtures/test/list.rhtml +1 -1
  86. data/test/fixtures/test/update_element_with_capture.rhtml +9 -0
  87. data/test/template/active_record_helper_test.rb +30 -15
  88. data/test/template/asset_tag_helper_test.rb +12 -5
  89. data/test/template/benchmark_helper_test.rb +72 -0
  90. data/test/template/date_helper_test.rb +69 -0
  91. data/test/template/form_helper_test.rb +18 -10
  92. data/test/template/form_options_helper_test.rb +40 -5
  93. data/test/template/javascript_helper.rb +149 -2
  94. data/test/template/number_helper_test.rb +2 -0
  95. data/test/template/tag_helper_test.rb +4 -0
  96. data/test/template/text_helper_test.rb +36 -0
  97. data/test/template/upload_progress_helper_testx.rb +272 -0
  98. data/test/template/url_helper_test.rb +30 -0
  99. metadata +30 -6
  100. data/test/controller/layout_test.rb +0 -49
  101. data/test/controller/routing_tests.rb +0 -543
@@ -33,6 +33,67 @@ module ActionView
33
33
  end
34
34
  end
35
35
 
36
+ # Generates a form containing a sole button that submits to the
37
+ # URL given by _options_. Use this method instead of +link_to+
38
+ # for actions that do not have the safe HTTP GET semantics
39
+ # implied by using a hypertext link.
40
+ #
41
+ # The parameters are the same as for +link_to+. Any _html_options_
42
+ # that you pass will be applied to the inner +input+ element.
43
+ # In particular, pass
44
+ #
45
+ # :disabled => true/false
46
+ #
47
+ # as part of _html_options_ to control whether the button is
48
+ # disabled. The generated form element is given the class
49
+ # 'button-to', to which you can attach CSS styles for display
50
+ # purposes.
51
+ #
52
+ # Example 1:
53
+ #
54
+ # # inside of controller for "feeds"
55
+ # button_to "Edit", :action => 'edit', :id => 3
56
+ #
57
+ # Generates the following HTML (sans formatting):
58
+ #
59
+ # <form method="post" action="/feeds/edit/3" class="button-to">
60
+ # <div><input value="Edit" type="submit" /></div>
61
+ # </form>
62
+ #
63
+ # Example 2:
64
+ #
65
+ # button_to "Destroy", { :action => 'destroy', :id => 3 },
66
+ # :confirm => "Are you sure?"
67
+ #
68
+ # Generates the following HTML (sans formatting):
69
+ #
70
+ # <form method="post" action="/feeds/destroy/3" class="button-to">
71
+ # <div><input onclick="return confirm('Are you sure?');"
72
+ # value="Destroy" type="submit" />
73
+ # </div>
74
+ # </form>
75
+ #
76
+ # *NOTE*: This method generates HTML code that represents a form.
77
+ # Forms are "block" content, which means that you should not try to
78
+ # insert them into your HTML where only inline content is expected.
79
+ # For example, you can legally insert a form inside of a +div+ or
80
+ # +td+ element or in between +p+ elements, but not in the middle of
81
+ # a run of text, nor can you place a form within another form.
82
+ # (Bottom line: Always validate your HTML before going public.)
83
+
84
+ def button_to(name, options = {}, html_options = nil)
85
+ html_options = (html_options || {}).stringify_keys
86
+ convert_boolean_attributes!(html_options, %w( disabled ))
87
+ convert_confirm_option_to_javascript!(html_options)
88
+ url, name = options.is_a?(String) ?
89
+ [ options, name || options ] :
90
+ [ url_for(options), name || url_for(options) ]
91
+ html_options.merge!("type" => "submit", "value" => name)
92
+ "<form method=\"post\" action=\"#{h url}\" class=\"button-to\"><div>" +
93
+ tag("input", html_options) + "</div></form>"
94
+ end
95
+
96
+
36
97
  # This tag is deprecated. Combine the link_to and AssetTagHelper::image_tag yourself instead, like:
37
98
  # link_to(image_tag("rss", :size => "30x45", :border => 0), "http://www.example.com")
38
99
  def link_image_to(src, options = {}, html_options = {}, *parameters_for_method_reference)
@@ -126,6 +187,10 @@ module ActionView
126
187
  extras << "subject=#{CGI.escape(subject).gsub("+", "%20")}&" unless subject.nil?
127
188
  extras = "?" << extras.gsub!(/&?$/,"") unless extras.empty?
128
189
 
190
+ email_address_obfuscated = email_address.dup
191
+ email_address_obfuscated.gsub!(/@/, html_options.delete("replace_at")) if html_options.has_key?("replace_at")
192
+ email_address_obfuscated.gsub!(/\./, html_options.delete("replace_dot")) if html_options.has_key?("replace_dot")
193
+
129
194
  if encode == 'javascript'
130
195
  tmp = "document.write('#{content_tag("a", name || email_address, html_options.merge({ "href" => "mailto:"+email_address.to_s+extras }))}');"
131
196
  for i in 0...tmp.length
@@ -140,9 +205,9 @@ module ActionView
140
205
  string << email_address[i,1]
141
206
  end
142
207
  end
143
- content_tag "a", name || email_address, html_options.merge({ "href" => "mailto:#{string}#{extras}" })
208
+ content_tag "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{string}#{extras}" })
144
209
  else
145
- content_tag "a", name || email_address, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" })
210
+ content_tag "a", name || email_address_obfuscated, html_options.merge({ "href" => "mailto:#{email_address}#{extras}" })
146
211
  end
147
212
  end
148
213
 
@@ -157,6 +222,36 @@ module ActionView
157
222
  html_options["onclick"] = "return confirm('#{confirm.gsub(/'/, '\\\\\'')}');"
158
223
  end
159
224
  end
225
+
226
+ # Processes the _html_options_ hash, converting the boolean
227
+ # attributes from true/false form into the form required by
228
+ # HTML/XHTML. (An attribute is considered to be boolean if
229
+ # its name is listed in the given _bool_attrs_ array.)
230
+ #
231
+ # More specifically, for each boolean attribute in _html_options_
232
+ # given as:
233
+ #
234
+ # "attr" => bool_value
235
+ #
236
+ # if the the associated _bool_value_ evaluates to true, it is
237
+ # replaced with the attribute's name; otherwise the attribute is
238
+ # removed from the _html_options_ hash. (See the XHTML 1.0 spec,
239
+ # section 4.5 "Attribute Minimization" for more:
240
+ # http://www.w3.org/TR/xhtml1/#h-4.5)
241
+ #
242
+ # Returns the updated _html_options_ hash, which is also modified
243
+ # in place.
244
+ #
245
+ # Example:
246
+ #
247
+ # convert_boolean_attributes!( html_options,
248
+ # %w( checked disabled readonly ) )
249
+
250
+ def convert_boolean_attributes!(html_options, bool_attrs)
251
+ bool_attrs.each { |x| html_options[x] = x if html_options.delete(x) }
252
+ html_options
253
+ end
254
+
160
255
  end
161
256
  end
162
- end
257
+ end
@@ -5,17 +5,17 @@ module ActionView
5
5
  #
6
6
  # In a template for Advertiser#account:
7
7
  #
8
- # <%= render_partial "account" %>
8
+ # <%= render :partial => "account" %>
9
9
  #
10
10
  # This would render "advertiser/_account.rhtml" and pass the instance variable @account in as a local variable +account+ to
11
11
  # the template for display.
12
12
  #
13
13
  # In another template for Advertiser#buy, we could have:
14
14
  #
15
- # <%= render_partial "account", :account => @buyer %>
15
+ # <%= render :partial => "account", :locals => { :account => @buyer } %>
16
16
  #
17
17
  # <% for ad in @advertisements %>
18
- # <%= render_partial "ad", :ad => ad %>
18
+ # <%= render :partial => "ad", :locals => { :ad => ad } %>
19
19
  # <% end %>
20
20
  #
21
21
  # This would first render "advertiser/_account.rhtml" with @buyer passed in as the local variable +account+, then render
@@ -28,21 +28,25 @@ module ActionView
28
28
  # a partial by the same name as the elements contained within. So the three-lined example in "Using partials" can be rewritten
29
29
  # with a single line:
30
30
  #
31
- # <%= render_partial_collection "ad", @advertisements %>
31
+ # <%= render :partial => "ad", :collection => @advertisements %>
32
32
  #
33
33
  # This will render "advertiser/_ad.rhtml" and pass the local variable +ad+ to the template for display. An iteration counter
34
34
  # will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the
35
35
  # example above, the template would be fed +ad_counter+.
36
+ #
37
+ # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also just keep domain objects,
38
+ # like Active Records, in there.
36
39
  #
37
40
  # == Rendering shared partials
38
41
  #
39
42
  # Two controllers can share a set of partials and render them like this:
40
43
  #
41
- # <%= render_partial "advertisement/ad", :ad => @advertisement %>
44
+ # <%= render :partial => "advertisement/ad", :locals => { :ad => @advertisement } %>
42
45
  #
43
46
  # This will render the partial "advertisement/_ad.rhtml" regardless of which controller this is being called from.
44
47
  module Partials
45
- def render_partial(partial_path, local_assigns = {}, deprecated_local_assigns = {})
48
+ # Deprecated, use render :partial
49
+ def render_partial(partial_path, local_assigns = {}, deprecated_local_assigns = {}) #:nodoc:
46
50
  path, partial_name = partial_pieces(partial_path)
47
51
  object = extracting_object(partial_name, local_assigns, deprecated_local_assigns)
48
52
  local_assigns = extract_local_assigns(local_assigns, deprecated_local_assigns)
@@ -51,7 +55,8 @@ module ActionView
51
55
  render("#{path}/_#{partial_name}", { partial_name => object }.merge(local_assigns))
52
56
  end
53
57
 
54
- def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = {})
58
+ # Deprecated, use render :partial, :collection
59
+ def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = {}) #:nodoc:
55
60
  collection_of_partials = Array.new
56
61
  counter_name = partial_counter_name(partial_name)
57
62
  collection.each_with_index do |element, counter|
@@ -59,11 +64,12 @@ module ActionView
59
64
  end
60
65
 
61
66
  return nil if collection_of_partials.empty?
67
+
62
68
  if partial_spacer_template
63
69
  spacer_path, spacer_name = partial_pieces(partial_spacer_template)
64
70
  collection_of_partials.join(render("#{spacer_path}/_#{spacer_name}"))
65
71
  else
66
- collection_of_partials
72
+ collection_of_partials.join
67
73
  end
68
74
  end
69
75
 
@@ -239,6 +239,17 @@ module Builder
239
239
  [:version, :encoding, :standalone])
240
240
  end
241
241
 
242
+ # Surrounds the given text with a CDATA tag
243
+ #
244
+ # For example:
245
+ #
246
+ # xml.cdata! "blah blah blah"
247
+ # # => <![CDATA[blah blah blah]]>
248
+ def cdata!(text)
249
+ _ensure_no_block block_given?
250
+ _special("<![CDATA[", "]]>", text, nil)
251
+ end
252
+
242
253
  private
243
254
 
244
255
  # NOTE: All private methods of a builder object are prefixed when
data/rakefile CHANGED
@@ -8,7 +8,7 @@ require 'rake/contrib/rubyforgepublisher'
8
8
 
9
9
  PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
10
10
  PKG_NAME = 'actionpack'
11
- PKG_VERSION = '1.8.1' + PKG_BUILD
11
+ PKG_VERSION = '1.9.0' + PKG_BUILD
12
12
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
13
13
 
14
14
  RELEASE_NAME = "REL #{PKG_VERSION}"
@@ -61,7 +61,7 @@ spec = Gem::Specification.new do |s|
61
61
  s.has_rdoc = true
62
62
  s.requirements << 'none'
63
63
 
64
- s.add_dependency('activesupport', '= 1.0.4' + PKG_BUILD)
64
+ s.add_dependency('activesupport', '= 1.1.0' + PKG_BUILD)
65
65
 
66
66
  s.require_path = 'lib'
67
67
  s.autorequire = 'action_controller'
@@ -104,18 +104,26 @@ task :lines do
104
104
  puts "Total: Lines #{total_lines}, LOC #{total_codelines}"
105
105
  end
106
106
 
107
+ # Publishing ------------------------------------------------------
108
+
109
+ task :update_scriptaculous do
110
+ system("svn export --force http://dev.rubyonrails.org/svn/rails/spinoffs/scriptaculous/src/ #{File.dirname(__FILE__)}/lib/action_view/helpers/javascripts/")
111
+ end
112
+
113
+ desc "Updates actionpack to the latest version of the javascript spinoffs"
114
+ task :update_js => [:update_scriptaculous]
107
115
 
108
116
  # Publishing ------------------------------------------------------
109
117
 
110
118
  desc "Publish the API documentation"
111
119
  task :pgem => [:package] do
112
- Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.com", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
113
- `ssh davidhh@wrath.rubyonrails.com './gemupdate.sh'`
120
+ Rake::SshFilePublisher.new("davidhh@wrath.rubyonrails.org", "public_html/gems/gems", "pkg", "#{PKG_FILE_NAME}.gem").upload
121
+ `ssh davidhh@wrath.rubyonrails.org './gemupdate.sh'`
114
122
  end
115
123
 
116
124
  desc "Publish the API documentation"
117
125
  task :pdoc => [:rdoc] do
118
- Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.com", "public_html/ap", "doc").upload
126
+ Rake::SshDirPublisher.new("davidhh@wrath.rubyonrails.org", "public_html/ap", "doc").upload
119
127
  end
120
128
 
121
129
  desc "Publish the release files to RubyForge."
@@ -9,4 +9,4 @@ require 'action_controller/test_process'
9
9
 
10
10
  ActionController::Base.logger = nil
11
11
  ActionController::Base.ignore_missing_templates = true
12
- ActionController::Routing::Routes.reload
12
+ ActionController::Routing::Routes.reload rescue nil
@@ -13,12 +13,14 @@ class ActionPackAssertionsController < ActionController::Base
13
13
  def hello_xml_world() render "test/hello_xml_world"; end
14
14
 
15
15
  # a redirect to an internal location
16
- def redirect_internal() redirect_to "nothing"; end
16
+ def redirect_internal() redirect_to "/nothing"; end
17
17
 
18
18
  def redirect_to_action() redirect_to :action => "flash_me", :id => 1, :params => { "panda" => "fun" }; end
19
19
 
20
20
  def redirect_to_controller() redirect_to :controller => "elsewhere", :action => "flash_me"; end
21
21
 
22
+ def redirect_to_path() redirect_to '/some/path' end
23
+
22
24
  # a redirect to an external location
23
25
  def redirect_external() redirect_to_url "http://www.rubyonrails.org"; end
24
26
 
@@ -53,6 +55,10 @@ class ActionPackAssertionsController < ActionController::Base
53
55
  render_text "Mr. #{@params["name"]}"
54
56
  end
55
57
 
58
+ def render_url
59
+ render_text "<div>#{url_for(:action => 'flash_me', :only_path => true)}</div>"
60
+ end
61
+
56
62
  # puts something in the session
57
63
  def session_stuffing
58
64
  session['xmas'] = 'turkey'
@@ -73,7 +79,17 @@ class ActionPackAssertionsController < ActionController::Base
73
79
 
74
80
  # 911
75
81
  def rescue_action(e) raise; end
76
-
82
+ end
83
+
84
+ module Admin
85
+ class InnerModuleController < ActionController::Base
86
+ def redirect_to_absolute_controller
87
+ redirect_to :controller => '/content'
88
+ end
89
+ def redirect_to_fellow_controller
90
+ redirect_to :controller => 'user'
91
+ end
92
+ end
77
93
  end
78
94
 
79
95
  # ---------------------------------------------------------------------------
@@ -95,6 +111,11 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
95
111
 
96
112
  # -- assertion-based testing ------------------------------------------------
97
113
 
114
+ def test_assert_tag_and_url_for
115
+ get :render_url
116
+ assert_tag :content => "/action_pack_assertions/flash_me"
117
+ end
118
+
98
119
  # test the session assertion to make sure something is there.
99
120
  def test_assert_session_has
100
121
  process :session_stuffing
@@ -188,13 +209,13 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
188
209
  process :hello_world
189
210
  assert_rendered_file 'test/hello_world'
190
211
  assert_rendered_file 'hello_world'
191
- assert_rendered_file
192
212
  end
193
213
 
194
214
  # test the assert_success assertion
195
215
  def test_assert_success
196
216
  process :nothing
197
217
  assert_success
218
+ assert_rendered_file
198
219
  end
199
220
 
200
221
  # -- standard request/response object testing --------------------------------
@@ -268,7 +289,7 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
268
289
  # check the redirection location
269
290
  def test_redirection_location
270
291
  process :redirect_internal
271
- assert_equal 'nothing', @response.redirect_url
292
+ assert_equal 'http://test.host/nothing', @response.redirect_url
272
293
 
273
294
  process :redirect_external
274
295
  assert_equal 'http://www.rubyonrails.org', @response.redirect_url
@@ -357,7 +378,7 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
357
378
  assert_redirected_to :action => "flash_me"
358
379
 
359
380
  follow_redirect
360
- assert_equal 1, @request.parameters["id"]
381
+ assert_equal 1, @request.parameters["id"].to_i
361
382
 
362
383
  assert "Inconceivable!", @response.body
363
384
  end
@@ -368,6 +389,28 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
368
389
 
369
390
  assert_raises(RuntimeError, "Can't follow redirects outside of current controller (elsewhere)") { follow_redirect }
370
391
  end
392
+
393
+ def test_redirected_to_url_leadling_slash
394
+ process :redirect_to_path
395
+ assert_redirected_to '/some/path'
396
+ end
397
+ def test_redirected_to_url_no_leadling_slash
398
+ process :redirect_to_path
399
+ assert_redirected_to 'some/path'
400
+ end
401
+ def test_redirected_to_url_full_url
402
+ process :redirect_to_path
403
+ assert_redirected_to 'http://test.host/some/path'
404
+ end
405
+
406
+ def test_redirected_to_with_nested_controller
407
+ @controller = Admin::InnerModuleController.new
408
+ get :redirect_to_absolute_controller
409
+ assert_redirected_to :controller => 'content'
410
+
411
+ get :redirect_to_fellow_controller
412
+ assert_redirected_to :controller => 'admin/user'
413
+ end
371
414
  end
372
415
 
373
416
  class ActionPackHeaderTest < Test::Unit::TestCase
@@ -380,8 +423,8 @@ class ActionPackHeaderTest < Test::Unit::TestCase
380
423
  assert_equal('text/xml', @controller.headers['Content-Type'])
381
424
  end
382
425
  def test_rendering_xml_respects_content_type
383
- @response.headers['Content-Type'] = 'application/pdf'
384
- process :hello_xml_world
385
- assert_equal('application/pdf', @controller.headers['Content-Type'])
426
+ @response.headers['Content-Type'] = 'application/pdf'
427
+ process :hello_xml_world
428
+ assert_equal('application/pdf', @controller.headers['Content-Type'])
386
429
  end
387
- end
430
+ end
@@ -1,128 +1,127 @@
1
+ require "#{File.dirname(__FILE__)}/../abstract_unit"
2
+
3
+ # Unfurl the safety net.
1
4
  path_to_ar = File.dirname(__FILE__) + '/../../../activerecord'
5
+ if Object.const_defined?(:ActiveRecord) || File.exist?(path_to_ar)
6
+ begin
2
7
 
3
- if Object.const_defined?("ActiveRecord") || File.exist?(path_to_ar)
4
-
5
- # This test is very different than the others. It requires ActiveRecord to
6
- # run. There's a bunch of stuff we are assuming here:
7
- #
8
- # 1. activerecord exists as a sibling directory to actionpack
9
- # (i.e., actionpack/../activerecord)
10
- # 2. you've created the appropriate database to run the active_record unit tests
11
- # 3. you set the appropriate database connection below
8
+ # These tests require Active Record, so you're going to need AR in a
9
+ # sibling directory to AP and have SQLite installed.
12
10
 
13
- begin
11
+ unless Object.const_defined?(:ActiveRecord)
12
+ require "#{path_to_ar}/lib/active_record"
13
+ end
14
14
 
15
- driver_to_use = 'native_sqlite'
16
-
17
- $: << path_to_ar + '/lib/'
18
- $: << path_to_ar + '/test/'
19
- require 'active_record' unless Object.const_defined?("ActiveRecord")
20
- require "connections/#{driver_to_use}/connection"
21
- require 'fixtures/company'
22
-
23
- # -----------------------------------------------------------------------------
24
-
25
- # add some validation rules to trip up the assertions
26
- class Company
27
- protected
28
- def validate
29
- errors.add_on_empty('name')
30
- errors.add('rating', 'rating should not be 2') if rating == 2
31
- errors.add_to_base('oh oh') if rating == 3
32
- end
33
- end
34
-
35
- # -----------------------------------------------------------------------------
36
-
37
- require File.dirname(__FILE__) + '/../abstract_unit'
38
-
39
- # a controller class to handle the AR assertions
40
- class ActiveRecordAssertionsController < ActionController::Base
41
- # fail with 1 bad column
42
- def nasty_columns_1
43
- @company = Company.new
44
- @company.name = "B"
45
- @company.rating = 2
46
- render_text "snicker...."
47
- end
48
-
49
- # fail with 2 bad column
50
- def nasty_columns_2
51
- @company = Company.new
52
- @company.name = ""
53
- @company.rating = 2
54
- render_text "double snicker...."
55
- end
56
-
57
- # this will pass validation
58
- def good_company
59
- @company = Company.new
60
- @company.name = "A"
61
- @company.rating = 69
62
- render_text "Goodness Gracious!"
63
- end
64
-
65
- # this will fail validation
66
- def bad_company
67
- @company = Company.new
68
- render_text "Who's Bad?"
69
- end
70
-
71
- # the safety dance......
72
- def rescue_action(e) raise; end
73
- end
74
-
75
- # -----------------------------------------------------------------------------
76
-
77
- ActiveRecordAssertionsController.template_root = File.dirname(__FILE__) + "/../fixtures/"
78
-
79
- # The test case to try the AR assertions
80
- class ActiveRecordAssertionsControllerTest < Test::Unit::TestCase
81
- # set it up
82
- def setup
83
- @request = ActionController::TestRequest.new
84
- @response = ActionController::TestResponse.new
85
- @controller = ActiveRecordAssertionsController.new
86
- end
87
-
88
- # test for 1 bad apple column
89
- def test_some_invalid_columns
90
- process :nasty_columns_1
91
- assert_success
92
- assert_invalid_record 'company'
93
- assert_invalid_column_on_record 'company', 'rating'
94
- assert_valid_column_on_record 'company', 'name'
95
- assert_valid_column_on_record 'company', ['name','id']
96
- end
97
-
98
- # test for 2 bad apples columns
99
- def test_all_invalid_columns
100
- process :nasty_columns_2
101
- assert_success
102
- assert_invalid_record 'company'
103
- assert_invalid_column_on_record 'company', 'rating'
104
- assert_invalid_column_on_record 'company', 'name'
105
- assert_invalid_column_on_record 'company', ['name','rating']
106
- end
107
-
108
- # ensure we have no problems with an ActiveRecord
109
- def test_valid_record
110
- process :good_company
111
- assert_success
112
- assert_valid_record 'company'
113
- end
114
-
115
- # ensure we have problems with an ActiveRecord
116
- def test_invalid_record
117
- process :bad_company
118
- assert_success
119
- assert_invalid_record 'company'
120
- end
121
- end
15
+ begin
16
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :dbfile => ':memory:')
17
+ ActiveRecord::Base.connection
18
+ rescue Object
19
+ $stderr.puts 'SQLite 3 unavailable; falling to SQLite 2.'
20
+ ActiveRecord::Base.establish_connection(:adapter => 'sqlite', :dbfile => ':memory:')
21
+ ActiveRecord::Base.connection
22
+ end
122
23
 
123
- rescue Object => e
124
- puts "Skipping active record based tests"
125
- puts e.message
24
+ # Set up company fixtures.
25
+ $LOAD_PATH << "#{path_to_ar}/test"
26
+ require 'fixtures/company'
27
+ File.read("#{path_to_ar}/test/fixtures/db_definitions/sqlite.sql").split(';').each do |sql|
28
+ ActiveRecord::Base.connection.execute(sql) unless sql.blank?
29
+ end
30
+
31
+ # Add some validation rules to trip up the assertions.
32
+ class Company
33
+ protected
34
+ def validate
35
+ errors.add_on_empty('name')
36
+ errors.add('rating', 'rating should not be 2') if rating == 2
37
+ errors.add_to_base('oh oh') if rating == 3
38
+ end
39
+ end
40
+
41
+ # A controller to host the assertions.
42
+ class ActiveRecordAssertionsController < ActionController::Base
43
+ self.template_root = "#{File.dirname(__FILE__)}/../fixtures/"
44
+
45
+ # fail with 1 bad column
46
+ def nasty_columns_1
47
+ @company = Company.new
48
+ @company.name = "B"
49
+ @company.rating = 2
50
+ render_text "snicker...."
51
+ end
52
+
53
+ # fail with 2 bad columns
54
+ def nasty_columns_2
55
+ @company = Company.new
56
+ @company.name = ""
57
+ @company.rating = 2
58
+ render_text "double snicker...."
59
+ end
60
+
61
+ # this will pass validation
62
+ def good_company
63
+ @company = Company.new
64
+ @company.name = "A"
65
+ @company.rating = 69
66
+ render_text "Goodness Gracious!"
67
+ end
68
+
69
+ # this will fail validation
70
+ def bad_company
71
+ @company = Company.new
72
+ render_text "Who's Bad?"
73
+ end
74
+
75
+ # the safety dance......
76
+ def rescue_action(e) raise; end
77
+ end
78
+
79
+
80
+ class ActiveRecordAssertionsControllerTest < Test::Unit::TestCase
81
+ def setup
82
+ @request = ActionController::TestRequest.new
83
+ @response = ActionController::TestResponse.new
84
+ @controller = ActiveRecordAssertionsController.new
85
+ end
86
+
87
+ # test for 1 bad apple column
88
+ def test_some_invalid_columns
89
+ process :nasty_columns_1
90
+ assert_success
91
+ assert_invalid_record 'company'
92
+ assert_invalid_column_on_record 'company', 'rating'
93
+ assert_valid_column_on_record 'company', 'name'
94
+ assert_valid_column_on_record 'company', %w(name id)
126
95
  end
127
96
 
97
+ # test for 2 bad apples columns
98
+ def test_all_invalid_columns
99
+ process :nasty_columns_2
100
+ assert_success
101
+ assert_invalid_record 'company'
102
+ assert_invalid_column_on_record 'company', 'rating'
103
+ assert_invalid_column_on_record 'company', 'name'
104
+ assert_invalid_column_on_record 'company', %w(name rating)
105
+ end
106
+
107
+ # ensure we have no problems with an ActiveRecord
108
+ def test_valid_record
109
+ process :good_company
110
+ assert_success
111
+ assert_valid_record 'company'
112
+ end
113
+
114
+ # ensure we have problems with an ActiveRecord
115
+ def test_invalid_record
116
+ process :bad_company
117
+ assert_success
118
+ assert_invalid_record 'company'
119
+ end
120
+ end
121
+
122
+ # End of safety net.
123
+ rescue Object => e
124
+ $stderr.puts "Skipping Active Record assertion tests: #{e}"
125
+ #$stderr.puts " #{e.backtrace.join("\n ")}"
126
+ end
128
127
  end