actionpack 1.9.1 → 1.10.1

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 (123) hide show
  1. data/CHANGELOG +237 -0
  2. data/README +12 -12
  3. data/lib/action_controller.rb +17 -12
  4. data/lib/action_controller/assertions.rb +119 -67
  5. data/lib/action_controller/base.rb +184 -102
  6. data/lib/action_controller/benchmarking.rb +35 -6
  7. data/lib/action_controller/caching.rb +115 -58
  8. data/lib/action_controller/cgi_ext/cgi_methods.rb +54 -21
  9. data/lib/action_controller/cgi_ext/cookie_performance_fix.rb +39 -35
  10. data/lib/action_controller/cgi_ext/raw_post_data_fix.rb +34 -21
  11. data/lib/action_controller/cgi_process.rb +23 -20
  12. data/lib/action_controller/components.rb +11 -2
  13. data/lib/action_controller/dependencies.rb +0 -5
  14. data/lib/action_controller/deprecated_redirects.rb +17 -0
  15. data/lib/action_controller/filters.rb +13 -9
  16. data/lib/action_controller/flash.rb +7 -7
  17. data/lib/action_controller/helpers.rb +1 -14
  18. data/lib/action_controller/layout.rb +40 -29
  19. data/lib/action_controller/macros/auto_complete.rb +52 -0
  20. data/lib/action_controller/macros/in_place_editing.rb +32 -0
  21. data/lib/action_controller/pagination.rb +44 -28
  22. data/lib/action_controller/request.rb +54 -40
  23. data/lib/action_controller/rescue.rb +8 -6
  24. data/lib/action_controller/routing.rb +77 -28
  25. data/lib/action_controller/scaffolding.rb +10 -14
  26. data/lib/action_controller/session/active_record_store.rb +36 -7
  27. data/lib/action_controller/session_management.rb +126 -0
  28. data/lib/action_controller/streaming.rb +14 -5
  29. data/lib/action_controller/templates/rescues/_request_and_response.rhtml +1 -1
  30. data/lib/action_controller/templates/rescues/_trace.rhtml +24 -0
  31. data/lib/action_controller/templates/rescues/diagnostics.rhtml +2 -13
  32. data/lib/action_controller/templates/rescues/template_error.rhtml +4 -2
  33. data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
  34. data/lib/action_controller/test_process.rb +35 -17
  35. data/lib/action_controller/upload_progress.rb +52 -0
  36. data/lib/action_controller/url_rewriter.rb +21 -16
  37. data/lib/action_controller/vendor/html-scanner/html/document.rb +2 -2
  38. data/lib/action_controller/vendor/html-scanner/html/node.rb +30 -3
  39. data/lib/action_pack/version.rb +9 -0
  40. data/lib/action_view.rb +1 -1
  41. data/lib/action_view/base.rb +204 -60
  42. data/lib/action_view/compiled_templates.rb +70 -0
  43. data/lib/action_view/helpers/active_record_helper.rb +7 -3
  44. data/lib/action_view/helpers/asset_tag_helper.rb +22 -12
  45. data/lib/action_view/helpers/capture_helper.rb +2 -10
  46. data/lib/action_view/helpers/date_helper.rb +21 -13
  47. data/lib/action_view/helpers/form_helper.rb +14 -10
  48. data/lib/action_view/helpers/form_options_helper.rb +4 -4
  49. data/lib/action_view/helpers/form_tag_helper.rb +59 -25
  50. data/lib/action_view/helpers/java_script_macros_helper.rb +188 -0
  51. data/lib/action_view/helpers/javascript_helper.rb +68 -133
  52. data/lib/action_view/helpers/javascripts/controls.js +427 -165
  53. data/lib/action_view/helpers/javascripts/dragdrop.js +256 -277
  54. data/lib/action_view/helpers/javascripts/effects.js +766 -277
  55. data/lib/action_view/helpers/javascripts/prototype.js +906 -218
  56. data/lib/action_view/helpers/javascripts/slider.js +258 -0
  57. data/lib/action_view/helpers/number_helper.rb +4 -3
  58. data/lib/action_view/helpers/pagination_helper.rb +42 -27
  59. data/lib/action_view/helpers/tag_helper.rb +25 -11
  60. data/lib/action_view/helpers/text_helper.rb +119 -13
  61. data/lib/action_view/helpers/upload_progress_helper.rb +2 -2
  62. data/lib/action_view/helpers/url_helper.rb +68 -21
  63. data/lib/action_view/partials.rb +17 -6
  64. data/lib/action_view/template_error.rb +19 -24
  65. data/rakefile +4 -3
  66. data/test/abstract_unit.rb +2 -1
  67. data/test/controller/action_pack_assertions_test.rb +62 -2
  68. data/test/controller/active_record_assertions_test.rb +5 -6
  69. data/test/controller/active_record_store_test.rb +23 -1
  70. data/test/controller/addresses_render_test.rb +4 -0
  71. data/test/controller/{base_tests.rb → base_test.rb} +4 -3
  72. data/test/controller/benchmark_test.rb +36 -0
  73. data/test/controller/caching_filestore.rb +22 -40
  74. data/test/controller/capture_test.rb +10 -1
  75. data/test/controller/cgi_test.rb +145 -23
  76. data/test/controller/components_test.rb +50 -0
  77. data/test/controller/custom_handler_test.rb +3 -3
  78. data/test/controller/fake_controllers.rb +24 -0
  79. data/test/controller/filters_test.rb +6 -6
  80. data/test/controller/flash_test.rb +6 -6
  81. data/test/controller/fragment_store_setting_test.rb +45 -0
  82. data/test/controller/helper_test.rb +1 -3
  83. data/test/controller/new_render_test.rb +119 -7
  84. data/test/controller/redirect_test.rb +11 -1
  85. data/test/controller/render_test.rb +34 -1
  86. data/test/controller/request_test.rb +14 -5
  87. data/test/controller/routing_test.rb +238 -42
  88. data/test/controller/send_file_test.rb +11 -10
  89. data/test/controller/session_management_test.rb +94 -0
  90. data/test/controller/test_test.rb +194 -5
  91. data/test/controller/url_rewriter_test.rb +46 -0
  92. data/test/fixtures/layouts/talk_from_action.rhtml +2 -0
  93. data/test/fixtures/layouts/yield.rhtml +2 -0
  94. data/test/fixtures/multipart/binary_file +0 -0
  95. data/test/fixtures/multipart/large_text_file +10 -0
  96. data/test/fixtures/multipart/mixed_files +0 -0
  97. data/test/fixtures/multipart/single_parameter +5 -0
  98. data/test/fixtures/multipart/text_file +10 -0
  99. data/test/fixtures/test/_customer_greeting.rhtml +1 -0
  100. data/test/fixtures/test/_hash_object.rhtml +1 -0
  101. data/test/fixtures/test/_person.rhtml +2 -0
  102. data/test/fixtures/test/action_talk_to_layout.rhtml +2 -0
  103. data/test/fixtures/test/content_for.rhtml +2 -0
  104. data/test/fixtures/test/potential_conflicts.rhtml +4 -0
  105. data/test/template/active_record_helper_test.rb +15 -8
  106. data/test/template/asset_tag_helper_test.rb +40 -16
  107. data/test/template/compiled_templates_tests.rb +63 -0
  108. data/test/template/date_helper_test.rb +80 -4
  109. data/test/template/form_helper_test.rb +48 -42
  110. data/test/template/form_options_helper_test.rb +40 -40
  111. data/test/template/form_tag_helper_test.rb +21 -15
  112. data/test/template/java_script_macros_helper_test.rb +56 -0
  113. data/test/template/javascript_helper_test.rb +70 -47
  114. data/test/template/number_helper_test.rb +2 -0
  115. data/test/template/tag_helper_test.rb +9 -0
  116. data/test/template/text_helper_test.rb +146 -1
  117. data/test/template/upload_progress_helper_testx.rb +11 -147
  118. data/test/template/url_helper_test.rb +90 -22
  119. data/test/testing_sandbox.rb +26 -0
  120. metadata +37 -7
  121. data/lib/action_controller/auto_complete.rb +0 -47
  122. data/lib/action_controller/deprecated_renders_and_redirects.rb +0 -76
  123. data/lib/action_controller/session.rb +0 -14
@@ -196,7 +196,7 @@ module ActionView
196
196
 
197
197
  updater = "if (#{upload_update_object}) { #{upload_update_object}.stop(); }"
198
198
  updater << "#{upload_update_object} = new Ajax.PeriodicalUpdater('#{status_tag_id}',"
199
- updater << "'#{status_url}', #{options_for_ajax(options)}.extend(#{updater_options}))"
199
+ updater << "'#{status_url}', Object.extend(#{options_for_ajax(options)},#{updater_options}))"
200
200
 
201
201
  updater = "#{options[:begin]}; #{updater}" if options[:begin]
202
202
  updater = "#{upload_progress_update_bar_js(0)}; #{updater}"
@@ -384,7 +384,7 @@ module ActionView
384
384
  end.to_i
385
385
 
386
386
  # TODO do animation instead of jumping
387
- "$('#{progress_bar_id}').firstChild.firstChild.style.width='#{percent}%'"
387
+ "if($('#{progress_bar_id}')){$('#{progress_bar_id}').firstChild.firstChild.style.width='#{percent}%'}"
388
388
  end
389
389
 
390
390
  # Generates a nicely formatted string of current upload progress for
@@ -1,3 +1,5 @@
1
+ require File.dirname(__FILE__) + '/javascript_helper'
2
+
1
3
  module ActionView
2
4
  module Helpers
3
5
  # Provides a set of methods for making easy links and getting urls that depend on the controller and action. This means that
@@ -5,32 +7,47 @@ module ActionView
5
7
  # synchronously, so link_to uses that same url as is generated by url_for, which again is the same url used for
6
8
  # redirection in redirect_to.
7
9
  module UrlHelper
10
+ include JavaScriptHelper
11
+
8
12
  # Returns the URL for the set of +options+ provided. This takes the same options
9
13
  # as url_for. For a list, see the url_for documentation in link:classes/ActionController/Base.html#M000079.
14
+ # Note that it'll set :only_path => true so you'll get /controller/action instead of the
15
+ # http://example.com/controller/action part (makes it harder to parse httpd log files)
10
16
  def url_for(options = {}, *parameters_for_method_reference)
11
17
  options = { :only_path => true }.update(options.symbolize_keys) if options.kind_of? Hash
12
18
  @controller.send(:url_for, options, *parameters_for_method_reference)
13
19
  end
14
20
 
15
21
  # Creates a link tag of the given +name+ using an URL created by the set of +options+. See the valid options in
16
- # link:classes/ActionController/Base.html#M000021. It's also possible to pass a string instead of an options hash to
22
+ # link:classes/ActionView/Helpers/UrlHelper.html#M000304. It's also possible to pass a string instead of an options hash to
17
23
  # get a link tag that just points without consideration. If nil is passed as a name, the link itself will become the name.
18
- # The html_options have a special feature for creating javascript confirm alerts where if you pass :confirm => 'Are you sure?',
24
+ #
25
+ # The html_options has three special features. One for creating javascript confirm alerts where if you pass :confirm => 'Are you sure?',
19
26
  # the link will be guarded with a JS popup asking that question. If the user accepts, the link is processed, otherwise not.
20
27
  #
21
- # Example:
28
+ # Another for creating a popup window, which is done by either passing :popup with true or the options of the window in
29
+ # Javascript form.
30
+ #
31
+ # And a third for making the link do a POST request (instead of the regular GET) through a dynamically added form element that
32
+ # is instantly submitted. Note that if the user has turned off Javascript, the request will fall back on the GET. So its
33
+ # your responsibility to determine what the action should be once it arrives at the controller. The POST form is turned on by
34
+ # passing :post as true. Note, it's not possible to use POST requests and popup targets at the same time (an exception will be thrown).
35
+ #
36
+ # Examples:
22
37
  # link_to "Delete this page", { :action => "destroy", :id => @page.id }, :confirm => "Are you sure?"
38
+ # link_to "Help", { :action => "help" }, :popup => true
39
+ # link_to "Busy loop", { :action => "busy" }, :popup => ['new_window', 'height=300,width=600']
40
+ # link_to "Destroy account", { :action => "destroy" }, :confirm => "Are you sure?", :post => true
23
41
  def link_to(name, options = {}, html_options = nil, *parameters_for_method_reference)
24
- html_options = (html_options || {}).stringify_keys
25
- convert_confirm_option_to_javascript!(html_options)
26
- if options.is_a?(String)
27
- content_tag "a", name || options, (html_options || {}).merge("href" => options)
42
+ if html_options
43
+ html_options = html_options.stringify_keys
44
+ convert_options_to_javascript!(html_options)
45
+ tag_options = tag_options(html_options)
28
46
  else
29
- content_tag(
30
- "a", name || url_for(options, *parameters_for_method_reference),
31
- (html_options || {}).merge("href" => url_for(options, *parameters_for_method_reference))
32
- )
47
+ tag_options = nil
33
48
  end
49
+ url = html_escape(options.is_a?(String) ? options : url_for(options, *parameters_for_method_reference))
50
+ "<a href=\"#{url}\"#{tag_options}>#{name||url}</a>"
34
51
  end
35
52
 
36
53
  # Generates a form containing a sole button that submits to the
@@ -80,15 +97,20 @@ module ActionView
80
97
  # +td+ element or in between +p+ elements, but not in the middle of
81
98
  # a run of text, nor can you place a form within another form.
82
99
  # (Bottom line: Always validate your HTML before going public.)
83
-
84
100
  def button_to(name, options = {}, html_options = nil)
85
101
  html_options = (html_options || {}).stringify_keys
86
102
  convert_boolean_attributes!(html_options, %w( disabled ))
87
- convert_confirm_option_to_javascript!(html_options)
88
- url, name = options.is_a?(String) ?
103
+
104
+ if confirm = html_options.delete("confirm")
105
+ html_options["onclick"] = "return #{confirm_javascript_function(confirm)};"
106
+ end
107
+
108
+ url, name = options.is_a?(String) ?
89
109
  [ options, name || options ] :
90
- [ url_for(options), name || url_for(options) ]
110
+ [ url_for(options), name || html_escape(url_for(options)) ]
111
+
91
112
  html_options.merge!("type" => "submit", "value" => name)
113
+
92
114
  "<form method=\"post\" action=\"#{h url}\" class=\"button-to\"><div>" +
93
115
  tag("input", html_options) + "</div></form>"
94
116
  end
@@ -213,15 +235,42 @@ module ActionView
213
235
 
214
236
  # Returns true if the current page uri is generated by the options passed (in url_for format).
215
237
  def current_page?(options)
216
- url_for(options) == @request.request_uri
238
+ url_for(options) == @controller.request.request_uri
217
239
  end
218
240
 
219
241
  private
220
- def convert_confirm_option_to_javascript!(html_options)
221
- if confirm = html_options.delete("confirm")
222
- html_options["onclick"] = "return confirm('#{confirm.gsub(/'/, '\\\\\'')}');"
242
+ def convert_options_to_javascript!(html_options)
243
+ confirm, popup, post = html_options.delete("confirm"), html_options.delete("popup"), html_options.delete("post")
244
+
245
+ html_options["onclick"] = case
246
+ when popup && post
247
+ raise ActionView::ActionViewError, "You can't use :popup and :post in the same link"
248
+ when confirm && popup
249
+ "if (#{confirm_javascript_function(confirm)}) { #{popup_javascript_function(popup)} };return false;"
250
+ when confirm && post
251
+ "if (#{confirm_javascript_function(confirm)}) { #{post_javascript_function} };return false;"
252
+ when confirm
253
+ "return #{confirm_javascript_function(confirm)};"
254
+ when post
255
+ "#{post_javascript_function}return false;"
256
+ when popup
257
+ popup_javascript_function(popup) + 'return false;'
258
+ else
259
+ html_options["onclick"]
223
260
  end
224
261
  end
262
+
263
+ def confirm_javascript_function(confirm)
264
+ "confirm('#{escape_javascript(confirm)}')"
265
+ end
266
+
267
+ def popup_javascript_function(popup)
268
+ popup.is_a?(Array) ? "window.open(this.href,'#{popup.first}','#{popup.last}');" : "window.open(this.href);"
269
+ end
270
+
271
+ def post_javascript_function
272
+ "f = document.createElement('form'); document.body.appendChild(f); f.method = 'POST'; f.action = this.href; f.submit();"
273
+ end
225
274
 
226
275
  # Processes the _html_options_ hash, converting the boolean
227
276
  # attributes from true/false form into the form required by
@@ -246,12 +295,10 @@ module ActionView
246
295
  #
247
296
  # convert_boolean_attributes!( html_options,
248
297
  # %w( checked disabled readonly ) )
249
-
250
298
  def convert_boolean_attributes!(html_options, bool_attrs)
251
299
  bool_attrs.each { |x| html_options[x] = x if html_options.delete(x) }
252
300
  html_options
253
301
  end
254
-
255
302
  end
256
303
  end
257
304
  end
@@ -46,24 +46,30 @@ module ActionView
46
46
  # This will render the partial "advertisement/_ad.rhtml" regardless of which controller this is being called from.
47
47
  module Partials
48
48
  # Deprecated, use render :partial
49
- def render_partial(partial_path, local_assigns = {}, deprecated_local_assigns = {}) #:nodoc:
49
+ def render_partial(partial_path, local_assigns = nil, deprecated_local_assigns = nil) #:nodoc:
50
50
  path, partial_name = partial_pieces(partial_path)
51
51
  object = extracting_object(partial_name, local_assigns, deprecated_local_assigns)
52
52
  local_assigns = extract_local_assigns(local_assigns, deprecated_local_assigns)
53
+ local_assigns = local_assigns ? local_assigns.clone : {}
53
54
  add_counter_to_local_assigns!(partial_name, local_assigns)
55
+ add_object_to_local_assigns!(partial_name, local_assigns, object)
54
56
 
55
- render("#{path}/_#{partial_name}", { partial_name => object }.merge(local_assigns))
57
+ ActionController::Base.benchmark("Rendered #{path}/_#{partial_name}", Logger::DEBUG, false) do
58
+ render("#{path}/_#{partial_name}", local_assigns)
59
+ end
56
60
  end
57
61
 
58
62
  # Deprecated, use render :partial, :collection
59
- def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = {}) #:nodoc:
63
+ def render_partial_collection(partial_name, collection, partial_spacer_template = nil, local_assigns = nil) #:nodoc:
60
64
  collection_of_partials = Array.new
61
65
  counter_name = partial_counter_name(partial_name)
66
+ local_assigns = local_assigns ? local_assigns.clone : {}
62
67
  collection.each_with_index do |element, counter|
63
- collection_of_partials.push(render_partial(partial_name, element, { counter_name => counter }.merge(local_assigns)))
68
+ local_assigns[counter_name] = counter
69
+ collection_of_partials.push(render_partial(partial_name, element, local_assigns))
64
70
  end
65
71
 
66
- return nil if collection_of_partials.empty?
72
+ return " " if collection_of_partials.empty?
67
73
 
68
74
  if partial_spacer_template
69
75
  spacer_path, spacer_name = partial_pieces(partial_spacer_template)
@@ -85,7 +91,7 @@ module ActionView
85
91
  end
86
92
 
87
93
  def partial_counter_name(partial_name)
88
- "#{partial_name.split('/').last}_counter"
94
+ "#{partial_name.split('/').last}_counter".intern
89
95
  end
90
96
 
91
97
  def extracting_object(partial_name, local_assigns, deprecated_local_assigns)
@@ -105,5 +111,10 @@ module ActionView
105
111
  counter_name = partial_counter_name(partial_name)
106
112
  local_assigns[counter_name] = 1 unless local_assigns.has_key?(counter_name)
107
113
  end
114
+
115
+ def add_object_to_local_assigns!(partial_name, local_assigns, object)
116
+ local_assigns[partial_name.intern] ||= object.is_a?(ActionView::Base::ObjectWrapper) ? object.value : object
117
+ local_assigns[partial_name.intern] ||= controller.instance_variable_get("@#{partial_name}")
118
+ end
108
119
  end
109
120
  end
@@ -7,16 +7,13 @@ module ActionView
7
7
  attr_reader :original_exception
8
8
 
9
9
  def initialize(base_path, file_name, assigns, source, original_exception)
10
- @base_path, @file_name, @assigns, @source, @original_exception =
11
- base_path, file_name, assigns, source, original_exception
10
+ @base_path, @assigns, @source, @original_exception =
11
+ base_path, assigns, source, original_exception
12
+ @file_name = file_name
12
13
  end
13
14
 
14
15
  def message
15
- if original_exception.message.include?("(eval):")
16
- original_exception.message.scan(/\(eval\):(?:[0-9]*):in `.*'(.*)/).first.first
17
- else
18
- original_exception.message
19
- end
16
+ original_exception.message
20
17
  end
21
18
 
22
19
  def sub_template_message
@@ -42,49 +39,47 @@ module ActionView
42
39
 
43
40
  extract.join
44
41
  end
45
-
42
+
46
43
  def sub_template_of(file_name)
47
44
  @sub_templates ||= []
48
45
  @sub_templates << file_name
49
46
  end
50
47
 
51
48
  def line_number
52
- trace = @original_exception.backtrace.join
53
- if trace.include?("erb):")
54
- trace.scan(/\((?:erb)\):([0-9]*)/).first.first.to_i
55
- elsif trace.include?("eval):")
56
- trace.scan(/\((?:eval)\):([0-9]*)/).first.first.to_i
57
- else
58
- 1
49
+ if file_name
50
+ regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)\s*$/
51
+ [@original_exception.message, @original_exception.clean_backtrace].flatten.each do |line|
52
+ return $1.to_i if regexp =~ line
53
+ end
59
54
  end
55
+ 0
60
56
  end
61
57
 
62
58
  def file_name
63
- strip_base_path(@file_name)
59
+ stripped = strip_base_path(@file_name)
60
+ stripped[0] == ?/ ? stripped[1..-1] : stripped
64
61
  end
65
62
 
66
63
  def to_s
67
64
  "\n\n#{self.class} (#{message}) on line ##{line_number} of #{file_name}:\n" +
68
65
  source_extract + "\n " +
69
- clean_backtrace(original_exception).join("\n ") +
66
+ original_exception.clean_backtrace.join("\n ") +
70
67
  "\n\n"
71
68
  end
72
69
 
73
70
  def backtrace
74
71
  [
75
72
  "On line ##{line_number} of #{file_name}\n\n#{source_extract(4)}\n " +
76
- clean_backtrace(original_exception).join("\n ")
73
+ original_exception.clean_backtrace.join("\n ")
77
74
  ]
78
75
  end
79
76
 
80
77
  private
81
78
  def strip_base_path(file_name)
79
+ file_name = File.expand_path(file_name).gsub(/^#{Regexp.escape File.expand_path(RAILS_ROOT)}/, '')
82
80
  file_name.gsub(@base_path, "")
83
81
  end
84
-
85
- def clean_backtrace(exception)
86
- base_dir = File.expand_path(File.dirname(__FILE__) + "/../../../../")
87
- exception.backtrace.collect { |line| line.gsub(base_dir, "").gsub("/public/../config/environments/../../", "").gsub("/public/../", "") }
88
- end
89
82
  end
90
- end
83
+ end
84
+
85
+ Exception::TraceSubstitutions << [/:in\s+`_run_(html|xml).*'\s*$/, ''] if defined?(Exception::TraceSubstitutions)
data/rakefile CHANGED
@@ -5,10 +5,11 @@ require 'rake/rdoctask'
5
5
  require 'rake/packagetask'
6
6
  require 'rake/gempackagetask'
7
7
  require 'rake/contrib/rubyforgepublisher'
8
+ require File.join(File.dirname(__FILE__), 'lib', 'action_pack', 'version')
8
9
 
9
10
  PKG_BUILD = ENV['PKG_BUILD'] ? '.' + ENV['PKG_BUILD'] : ''
10
11
  PKG_NAME = 'actionpack'
11
- PKG_VERSION = '1.9.1' + PKG_BUILD
12
+ PKG_VERSION = ActionPack::Version::STRING + PKG_BUILD
12
13
  PKG_FILE_NAME = "#{PKG_NAME}-#{PKG_VERSION}"
13
14
 
14
15
  RELEASE_NAME = "REL #{PKG_VERSION}"
@@ -61,7 +62,7 @@ spec = Gem::Specification.new do |s|
61
62
  s.has_rdoc = true
62
63
  s.requirements << 'none'
63
64
 
64
- s.add_dependency('activesupport', '= 1.1.1' + PKG_BUILD)
65
+ s.add_dependency('activesupport', '= 1.2.1' + PKG_BUILD)
65
66
 
66
67
  s.require_path = 'lib'
67
68
  s.autorequire = 'action_controller'
@@ -239,4 +240,4 @@ task :release => [:package] do
239
240
  first_file = false
240
241
  end
241
242
  end
242
- end
243
+ end
@@ -8,5 +8,6 @@ require 'action_controller'
8
8
  require 'action_controller/test_process'
9
9
 
10
10
  ActionController::Base.logger = nil
11
- ActionController::Base.ignore_missing_templates = true
11
+ ActionController::Base.ignore_missing_templates = false
12
12
  ActionController::Routing::Routes.reload rescue nil
13
+
@@ -20,6 +20,8 @@ class ActionPackAssertionsController < ActionController::Base
20
20
  def redirect_to_controller() redirect_to :controller => "elsewhere", :action => "flash_me"; end
21
21
 
22
22
  def redirect_to_path() redirect_to '/some/path' end
23
+
24
+ def redirect_to_named_route() redirect_to route_one_url end
23
25
 
24
26
  # a redirect to an external location
25
27
  def redirect_external() redirect_to_url "http://www.rubyonrails.org"; end
@@ -48,7 +50,7 @@ class ActionPackAssertionsController < ActionController::Base
48
50
  # assign some template instance variables
49
51
  def assign_this
50
52
  @howdy = "ho"
51
- render_text "Mr. Henke"
53
+ render :inline => "Mr. Henke"
52
54
  end
53
55
 
54
56
  def render_based_on_parameters
@@ -75,6 +77,41 @@ class ActionPackAssertionsController < ActionController::Base
75
77
  def raise_on_post
76
78
  raise "post" if @request.post?
77
79
  render_text "request method: #{@request.env['REQUEST_METHOD']}"
80
+ end
81
+
82
+ def get_valid_record
83
+ @record = Class.new do
84
+ def valid?
85
+ true
86
+ end
87
+
88
+ def errors
89
+ Class.new do
90
+ def full_messages; '...stuff...'; end
91
+ end.new
92
+ end
93
+
94
+ end.new
95
+
96
+ render :nothing => true
97
+ end
98
+
99
+
100
+ def get_invalid_record
101
+ @record = Class.new do
102
+
103
+ def valid?
104
+ false
105
+ end
106
+
107
+ def errors
108
+ Class.new do
109
+ def full_messages; '...stuff...'; end
110
+ end.new
111
+ end
112
+ end.new
113
+
114
+ render :nothing => true
78
115
  end
79
116
 
80
117
  # 911
@@ -185,6 +222,14 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
185
222
  process :redirect_external
186
223
  assert_redirect_url_match /ruby/
187
224
  end
225
+
226
+ # test the redirection to a named route
227
+ def test_assert_redirect_to_named_route
228
+ process :redirect_to_named_route
229
+ assert_raise(Test::Unit::AssertionFailedError) do
230
+ assert_redirected_to 'http://test.host/route_two'
231
+ end
232
+ end
188
233
 
189
234
  # test the flash-based assertions with something is in the flash
190
235
  def test_flash_assertions_full
@@ -410,6 +455,21 @@ class ActionPackAssertionsControllerTest < Test::Unit::TestCase
410
455
 
411
456
  get :redirect_to_fellow_controller
412
457
  assert_redirected_to :controller => 'admin/user'
458
+ end
459
+
460
+ def test_assert_valid
461
+ get :get_valid_record
462
+ assert_valid assigns('record')
463
+ end
464
+
465
+ def test_assert_valid_failing
466
+ get :get_invalid_record
467
+
468
+ begin
469
+ assert_valid assigns('record')
470
+ assert false
471
+ rescue Test::Unit::AssertionFailedError => e
472
+ end
413
473
  end
414
474
  end
415
475
 
@@ -427,4 +487,4 @@ class ActionPackHeaderTest < Test::Unit::TestCase
427
487
  process :hello_xml_world
428
488
  assert_equal('application/pdf', @controller.headers['Content-Type'])
429
489
  end
430
- end
490
+ end
@@ -47,7 +47,7 @@ class ActiveRecordAssertionsController < ActionController::Base
47
47
  @company = Company.new
48
48
  @company.name = "B"
49
49
  @company.rating = 2
50
- render_text "snicker...."
50
+ render :inline => "snicker...."
51
51
  end
52
52
 
53
53
  # fail with 2 bad columns
@@ -55,7 +55,7 @@ class ActiveRecordAssertionsController < ActionController::Base
55
55
  @company = Company.new
56
56
  @company.name = ""
57
57
  @company.rating = 2
58
- render_text "double snicker...."
58
+ render :inline => "double snicker...."
59
59
  end
60
60
 
61
61
  # this will pass validation
@@ -63,20 +63,19 @@ class ActiveRecordAssertionsController < ActionController::Base
63
63
  @company = Company.new
64
64
  @company.name = "A"
65
65
  @company.rating = 69
66
- render_text "Goodness Gracious!"
66
+ render :inline => "Goodness Gracious!"
67
67
  end
68
68
 
69
69
  # this will fail validation
70
70
  def bad_company
71
71
  @company = Company.new
72
- render_text "Who's Bad?"
72
+ render :inline => "Who's Bad?"
73
73
  end
74
74
 
75
75
  # the safety dance......
76
76
  def rescue_action(e) raise; end
77
77
  end
78
-
79
-
78
+
80
79
  class ActiveRecordAssertionsControllerTest < Test::Unit::TestCase
81
80
  def setup
82
81
  @request = ActionController::TestRequest.new