actionpack 2.3.4 → 2.3.5
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.
- data/CHANGELOG +12 -0
- data/Rakefile +1 -1
- data/lib/action_controller.rb +3 -1
- data/lib/action_controller/assertions/dom_assertions.rb +19 -3
- data/lib/action_controller/assertions/selector_assertions.rb +16 -10
- data/lib/action_controller/base.rb +1 -1
- data/lib/action_controller/caching.rb +1 -0
- data/lib/action_controller/cookies.rb +2 -1
- data/lib/action_controller/http_authentication.rb +3 -2
- data/lib/action_controller/integration.rb +15 -3
- data/lib/action_controller/layout.rb +6 -1
- data/lib/action_controller/middlewares.rb +2 -0
- data/lib/action_controller/polymorphic_routes.rb +6 -21
- data/lib/action_controller/rack_lint_patch.rb +36 -0
- data/lib/action_controller/request_forgery_protection.rb +6 -2
- data/lib/action_controller/response.rb +2 -1
- data/lib/action_controller/string_coercion.rb +29 -0
- data/lib/action_controller/test_case.rb +6 -1
- data/lib/action_controller/test_process.rb +1 -1
- data/lib/action_controller/translation.rb +2 -2
- data/lib/action_controller/uploaded_file.rb +2 -2
- data/lib/action_controller/vendor/html-scanner/html/node.rb +1 -1
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +3 -3
- data/lib/action_view/base.rb +6 -1
- data/lib/action_view/erb/util.rb +6 -0
- data/lib/action_view/helpers.rb +2 -0
- data/lib/action_view/helpers/active_record_helper.rb +3 -3
- data/lib/action_view/helpers/asset_tag_helper.rb +2 -2
- data/lib/action_view/helpers/capture_helper.rb +2 -2
- data/lib/action_view/helpers/date_helper.rb +27 -15
- data/lib/action_view/helpers/form_helper.rb +32 -11
- data/lib/action_view/helpers/form_options_helper.rb +1 -1
- data/lib/action_view/helpers/form_tag_helper.rb +3 -3
- data/lib/action_view/helpers/number_helper.rb +6 -1
- data/lib/action_view/helpers/prototype_helper.rb +1 -1
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/sanitize_helper.rb +10 -2
- data/lib/action_view/helpers/tag_helper.rb +4 -4
- data/lib/action_view/helpers/translation_helper.rb +1 -1
- data/lib/action_view/helpers/url_helper.rb +3 -3
- data/lib/action_view/locale/en.yml +3 -0
- data/lib/action_view/partials.rb +1 -1
- data/lib/action_view/safe_buffer.rb +28 -0
- data/lib/action_view/template.rb +8 -2
- data/lib/action_view/test_case.rb +102 -27
- data/lib/actionpack.rb +1 -0
- data/test/controller/cookie_test.rb +7 -0
- data/test/controller/dom_assertions_test.rb +53 -0
- data/test/controller/filter_params_test.rb +1 -0
- data/test/controller/html-scanner/sanitizer_test.rb +1 -0
- data/test/controller/http_digest_authentication_test.rb +22 -0
- data/test/controller/integration_test.rb +38 -0
- data/test/controller/layout_test.rb +11 -0
- data/test/controller/polymorphic_routes_test.rb +4 -0
- data/test/controller/request_forgery_protection_test.rb +19 -1
- data/test/controller/routing_test.rb +23 -15
- data/test/controller/session/test_session_test.rb +2 -2
- data/test/fixtures/layout_tests/abs_path_layout.rhtml +1 -0
- data/test/fixtures/test/_from_helper.erb +1 -0
- data/test/template/active_record_helper_test.rb +1 -1
- data/test/template/asset_tag_helper_test.rb +12 -0
- data/test/template/benchmark_helper_test.rb +6 -6
- data/test/template/compiled_templates_test.rb +2 -1
- data/test/template/date_helper_i18n_test.rb +10 -9
- data/test/template/date_helper_test.rb +29 -13
- data/test/template/form_helper_test.rb +90 -10
- data/test/template/number_helper_test.rb +4 -0
- data/test/template/raw_output_helper_test.rb +21 -0
- data/test/template/sanitize_helper_test.rb +10 -1
- data/test/template/tag_helper_test.rb +1 -0
- data/test/view/safe_buffer_test.rb +36 -0
- data/test/view/test_case_test.rb +173 -5
- metadata +13 -4
@@ -207,6 +207,24 @@ class IntegrationTestTest < Test::Unit::TestCase
|
|
207
207
|
assert_equal ::ActionController::Integration::Session, session2.class
|
208
208
|
assert_not_equal session1, session2
|
209
209
|
end
|
210
|
+
|
211
|
+
# RSpec mixes Matchers (which has a #method_missing) into
|
212
|
+
# IntegrationTest's superclass. Make sure IntegrationTest does not
|
213
|
+
# try to delegate these methods to the session object.
|
214
|
+
def test_does_not_prevent_method_missing_passing_up_to_ancestors
|
215
|
+
mixin = Module.new do
|
216
|
+
def method_missing(name, *args)
|
217
|
+
name.to_s == 'foo' ? 'pass' : super
|
218
|
+
end
|
219
|
+
end
|
220
|
+
@test.class.superclass.__send__(:include, mixin)
|
221
|
+
begin
|
222
|
+
assert_equal 'pass', @test.foo
|
223
|
+
ensure
|
224
|
+
# leave other tests as unaffected as possible
|
225
|
+
mixin.__send__(:remove_method, :method_missing)
|
226
|
+
end
|
227
|
+
end
|
210
228
|
end
|
211
229
|
|
212
230
|
# Tests that integration tests don't call Controller test methods for processing.
|
@@ -443,3 +461,23 @@ class MetalTest < ActionController::IntegrationTest
|
|
443
461
|
assert_equal '', response.body
|
444
462
|
end
|
445
463
|
end
|
464
|
+
|
465
|
+
class StringSubclassBodyTest < ActionController::IntegrationTest
|
466
|
+
class SafeString < String
|
467
|
+
end
|
468
|
+
|
469
|
+
class SafeStringMiddleware
|
470
|
+
def self.call(env)
|
471
|
+
[200, {"Content-Type" => "text/plain", "Content-Length" => "12"}, [SafeString.new("Hello World!")]]
|
472
|
+
end
|
473
|
+
end
|
474
|
+
|
475
|
+
def setup
|
476
|
+
@integration_session = ActionController::Integration::Session.new(SafeStringMiddleware)
|
477
|
+
end
|
478
|
+
|
479
|
+
def test_string_subclass_body
|
480
|
+
get '/'
|
481
|
+
assert_equal 'Hello World!', response.body
|
482
|
+
end
|
483
|
+
end
|
@@ -83,6 +83,11 @@ class AbsolutePathLayoutController < LayoutTest
|
|
83
83
|
layout File.expand_path(File.expand_path(__FILE__) + '/../../fixtures/layout_tests/layouts/layout_test.rhtml')
|
84
84
|
end
|
85
85
|
|
86
|
+
class AbsolutePathWithoutLayoutsController < LayoutTest
|
87
|
+
# Absolute layout path without 'layouts' in it.
|
88
|
+
layout File.expand_path(File.expand_path(__FILE__) + '/../../fixtures/layout_tests/abs_path_layout.rhtml')
|
89
|
+
end
|
90
|
+
|
86
91
|
class HasOwnLayoutController < LayoutTest
|
87
92
|
layout 'item'
|
88
93
|
end
|
@@ -153,6 +158,12 @@ class LayoutSetInResponseTest < ActionController::TestCase
|
|
153
158
|
get :hello
|
154
159
|
assert_equal "layout_test.rhtml hello.rhtml", @response.body.strip
|
155
160
|
end
|
161
|
+
|
162
|
+
def test_absolute_pathed_layout_without_layouts_in_path
|
163
|
+
@controller = AbsolutePathWithoutLayoutsController.new
|
164
|
+
get :hello
|
165
|
+
assert_equal "abs_path_layout.rhtml hello.rhtml", @response.body.strip
|
166
|
+
end
|
156
167
|
end
|
157
168
|
|
158
169
|
class RenderWithTemplateOptionController < LayoutTest
|
@@ -22,7 +22,7 @@ module RequestForgeryProtectionActions
|
|
22
22
|
def unsafe
|
23
23
|
render :text => 'pwn'
|
24
24
|
end
|
25
|
-
|
25
|
+
|
26
26
|
def rescue_action(e) raise e end
|
27
27
|
end
|
28
28
|
|
@@ -44,6 +44,13 @@ class FreeCookieController < RequestForgeryProtectionController
|
|
44
44
|
end
|
45
45
|
end
|
46
46
|
|
47
|
+
class CustomAuthenticityParamController < RequestForgeryProtectionController
|
48
|
+
def form_authenticity_param
|
49
|
+
'foobar'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
47
54
|
# common test methods
|
48
55
|
|
49
56
|
module RequestForgeryProtectionTests
|
@@ -245,3 +252,14 @@ class FreeCookieControllerTest < ActionController::TestCase
|
|
245
252
|
end
|
246
253
|
end
|
247
254
|
end
|
255
|
+
|
256
|
+
class CustomAuthenticityParamControllerTest < ActionController::TestCase
|
257
|
+
def setup
|
258
|
+
ActionController::Base.request_forgery_protection_token = :authenticity_token
|
259
|
+
end
|
260
|
+
|
261
|
+
def test_should_allow_custom_token
|
262
|
+
post :index, :authenticity_token => 'foobar'
|
263
|
+
assert_response :ok
|
264
|
+
end
|
265
|
+
end
|
@@ -107,7 +107,11 @@ class StaticSegmentTest < Test::Unit::TestCase
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
110
|
-
class DynamicSegmentTest <
|
110
|
+
class DynamicSegmentTest < ActiveSupport::TestCase
|
111
|
+
def setup
|
112
|
+
@segment = nil
|
113
|
+
end
|
114
|
+
|
111
115
|
def segment(options = {})
|
112
116
|
unless @segment
|
113
117
|
@segment = ROUTING::DynamicSegment.new(:a, options)
|
@@ -341,7 +345,11 @@ class ControllerSegmentTest < Test::Unit::TestCase
|
|
341
345
|
end
|
342
346
|
end
|
343
347
|
|
344
|
-
class PathSegmentTest <
|
348
|
+
class PathSegmentTest < ActiveSupport::TestCase
|
349
|
+
def setup
|
350
|
+
@segment = nil
|
351
|
+
end
|
352
|
+
|
345
353
|
def segment(options = {})
|
346
354
|
unless @segment
|
347
355
|
@segment = ROUTING::PathSegment.new(:path, options)
|
@@ -754,7 +762,7 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
|
|
754
762
|
|
755
763
|
ActionController::Routing.use_controllers! %w(content admin/user admin/news_feed)
|
756
764
|
end
|
757
|
-
|
765
|
+
|
758
766
|
def teardown
|
759
767
|
@rs.clear!
|
760
768
|
end
|
@@ -1094,21 +1102,21 @@ class LegacyRouteSetTests < ActiveSupport::TestCase
|
|
1094
1102
|
map.post 'post/:id', :controller=> 'post', :action=> 'show', :requirements => {:id => /\d+/}
|
1095
1103
|
end
|
1096
1104
|
exception = assert_raise(ActionController::RoutingError) { rs.generate(:controller => 'post', :action => 'show', :bad_param => "foo", :use_route => "post") }
|
1097
|
-
assert_match
|
1105
|
+
assert_match(/^post_url failed to generate/, exception.message)
|
1098
1106
|
from_match = exception.message.match(/from \{[^\}]+\}/).to_s
|
1099
|
-
assert_match
|
1100
|
-
assert_match
|
1101
|
-
assert_match
|
1107
|
+
assert_match(/:bad_param=>"foo"/, from_match)
|
1108
|
+
assert_match(/:action=>"show"/, from_match)
|
1109
|
+
assert_match(/:controller=>"post"/, from_match)
|
1102
1110
|
|
1103
1111
|
expected_match = exception.message.match(/expected: \{[^\}]+\}/).to_s
|
1104
|
-
assert_no_match
|
1105
|
-
assert_match
|
1106
|
-
assert_match
|
1112
|
+
assert_no_match(/:bad_param=>"foo"/, expected_match)
|
1113
|
+
assert_match( /:action=>"show"/, expected_match)
|
1114
|
+
assert_match( /:controller=>"post"/, expected_match)
|
1107
1115
|
|
1108
1116
|
diff_match = exception.message.match(/diff: \{[^\}]+\}/).to_s
|
1109
|
-
assert_match
|
1110
|
-
assert_no_match
|
1111
|
-
assert_no_match
|
1117
|
+
assert_match( /:bad_param=>"foo"/, diff_match)
|
1118
|
+
assert_no_match(/:action=>"show"/, diff_match)
|
1119
|
+
assert_no_match(/:controller=>"post"/, diff_match)
|
1112
1120
|
end
|
1113
1121
|
|
1114
1122
|
# this specifies the case where your formerly would get a very confusing error message with an empty diff
|
@@ -2564,10 +2572,10 @@ class RouteLoadingTest < Test::Unit::TestCase
|
|
2564
2572
|
|
2565
2573
|
routes.reload
|
2566
2574
|
end
|
2567
|
-
|
2575
|
+
|
2568
2576
|
def test_load_multiple_configurations
|
2569
2577
|
routes.add_configuration_file("engines.rb")
|
2570
|
-
|
2578
|
+
|
2571
2579
|
File.expects(:stat).at_least_once.returns(@stat)
|
2572
2580
|
|
2573
2581
|
routes.expects(:load).with('./config/routes.rb')
|
@@ -33,11 +33,11 @@ class ActionController::TestSessionTest < ActiveSupport::TestCase
|
|
33
33
|
assert_equal('value', session[:key])
|
34
34
|
end
|
35
35
|
|
36
|
-
def
|
36
|
+
def test_calling_delete_removes_item_and_returns_its_value
|
37
37
|
session = ActionController::TestSession.new
|
38
38
|
session[:key] = 'value'
|
39
39
|
assert_equal('value', session[:key])
|
40
|
-
session.delete(:key)
|
40
|
+
assert_equal('value', session.delete(:key))
|
41
41
|
assert_nil(session[:key])
|
42
42
|
end
|
43
43
|
|
@@ -0,0 +1 @@
|
|
1
|
+
abs_path_layout.rhtml <%= yield %>
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render_from_helper %>
|
@@ -183,7 +183,7 @@ class ActiveRecordHelperTest < ActionView::TestCase
|
|
183
183
|
end
|
184
184
|
|
185
185
|
def test_form_with_action_option
|
186
|
-
|
186
|
+
output_buffer << form("post", :action => "sign")
|
187
187
|
assert_select "form[action=sign]" do |form|
|
188
188
|
assert_select "input[type=submit][value=Sign]"
|
189
189
|
end
|
@@ -164,6 +164,11 @@ class AssetTagHelperTest < ActionView::TestCase
|
|
164
164
|
assert_dom_equal(%(<script src="/javascripts/prototype.js?1" type="text/javascript"></script>\n<script src="/javascripts/effects.js?1" type="text/javascript"></script>\n<script src="/javascripts/dragdrop.js?1" type="text/javascript"></script>\n<script src="/javascripts/controls.js?1" type="text/javascript"></script>\n<script src="/javascripts/application.js?1" type="text/javascript"></script>), javascript_include_tag(:defaults))
|
165
165
|
end
|
166
166
|
|
167
|
+
def test_javascript_include_tag_is_html_safe
|
168
|
+
assert javascript_include_tag(:defaults).html_safe?
|
169
|
+
assert javascript_include_tag("prototype").html_safe?
|
170
|
+
end
|
171
|
+
|
167
172
|
def test_register_javascript_include_default
|
168
173
|
ENV["RAILS_ASSET_ID"] = ""
|
169
174
|
ActionView::Helpers::AssetTagHelper::register_javascript_include_default 'slider'
|
@@ -206,6 +211,13 @@ class AssetTagHelperTest < ActionView::TestCase
|
|
206
211
|
StyleLinkToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
|
207
212
|
end
|
208
213
|
|
214
|
+
def test_stylesheet_link_tag_is_html_safe
|
215
|
+
ENV["RAILS_ASSET_ID"] = ""
|
216
|
+
assert stylesheet_link_tag('dir/file').html_safe?
|
217
|
+
assert stylesheet_link_tag('dir/other/file', 'dir/file2').html_safe?
|
218
|
+
assert stylesheet_tag('dir/file', {}).html_safe?
|
219
|
+
end
|
220
|
+
|
209
221
|
def test_custom_stylesheet_expansions
|
210
222
|
ActionView::Helpers::AssetTagHelper::register_stylesheet_expansion :monkey => ["head", "body", "tail"]
|
211
223
|
assert_dom_equal %(<link href="/stylesheets/first.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/head.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/body.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/tail.css" media="screen" rel="stylesheet" type="text/css" />\n<link href="/stylesheets/last.css" media="screen" rel="stylesheet" type="text/css" />), stylesheet_link_tag('first', :monkey, 'last')
|
@@ -4,14 +4,14 @@ require 'action_view/helpers/benchmark_helper'
|
|
4
4
|
class BenchmarkHelperTest < ActionView::TestCase
|
5
5
|
tests ActionView::Helpers::BenchmarkHelper
|
6
6
|
|
7
|
-
def
|
8
|
-
|
7
|
+
def setup
|
8
|
+
super
|
9
|
+
controller.logger = ActiveSupport::BufferedLogger.new(StringIO.new)
|
10
|
+
controller.logger.auto_flushing = false
|
9
11
|
end
|
10
12
|
|
11
|
-
def
|
12
|
-
logger
|
13
|
-
logger.auto_flushing = false
|
14
|
-
@controller ||= Struct.new(:logger).new(logger)
|
13
|
+
def teardown
|
14
|
+
controller.logger.send(:clear_buffer)
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_without_block
|
@@ -2,8 +2,9 @@ require 'abstract_unit'
|
|
2
2
|
require 'controller/fake_models'
|
3
3
|
|
4
4
|
class CompiledTemplatesTest < Test::Unit::TestCase
|
5
|
-
|
5
|
+
|
6
6
|
def setup
|
7
|
+
@explicit_view_paths = nil
|
7
8
|
@compiled_templates = ActionView::Base::CompiledTemplates
|
8
9
|
@compiled_templates.instance_methods.each do |m|
|
9
10
|
@compiled_templates.send(:remove_method, m) if m =~ /^_run_/
|
@@ -20,15 +20,16 @@ class DateHelperDistanceOfTimeInWordsI18nTests < Test::Unit::TestCase
|
|
20
20
|
[60.seconds, true] => [:'x_minutes', 1],
|
21
21
|
|
22
22
|
# without include_seconds
|
23
|
-
[29.seconds,
|
24
|
-
[60.seconds,
|
25
|
-
[44.minutes,
|
26
|
-
[61.minutes,
|
27
|
-
[24.hours,
|
28
|
-
[30.days,
|
29
|
-
[60.days,
|
30
|
-
[1.year,
|
31
|
-
[3.years,
|
23
|
+
[29.seconds, false] => [:'less_than_x_minutes', 1],
|
24
|
+
[60.seconds, false] => [:'x_minutes', 1],
|
25
|
+
[44.minutes, false] => [:'x_minutes', 44],
|
26
|
+
[61.minutes, false] => [:'about_x_hours', 1],
|
27
|
+
[24.hours, false] => [:'x_days', 1],
|
28
|
+
[30.days, false] => [:'about_x_months', 1],
|
29
|
+
[60.days, false] => [:'x_months', 2],
|
30
|
+
[1.year, false] => [:'about_x_years', 1],
|
31
|
+
[3.years + 6.months, false] => [:'over_x_years', 3],
|
32
|
+
[3.years + 10.months, false] => [:'almost_x_years', 4]
|
32
33
|
|
33
34
|
}.each do |passed, expected|
|
34
35
|
assert_distance_of_time_in_words_translates_key passed, expected
|
@@ -53,13 +53,14 @@ class DateHelperTest < ActionView::TestCase
|
|
53
53
|
assert_equal "about 2 hours", distance_of_time_in_words(from, to + 89.minutes + 30.seconds)
|
54
54
|
assert_equal "about 24 hours", distance_of_time_in_words(from, to + 23.hours + 59.minutes + 29.seconds)
|
55
55
|
|
56
|
-
# 1440..
|
56
|
+
# 1440..2529
|
57
57
|
assert_equal "1 day", distance_of_time_in_words(from, to + 23.hours + 59.minutes + 30.seconds)
|
58
|
-
assert_equal "1 day", distance_of_time_in_words(from, to +
|
58
|
+
assert_equal "1 day", distance_of_time_in_words(from, to + 41.hours + 59.minutes + 29.seconds)
|
59
59
|
|
60
|
-
#
|
61
|
-
assert_equal "2 days", distance_of_time_in_words(from, to +
|
62
|
-
assert_equal "
|
60
|
+
# 2530..43199
|
61
|
+
assert_equal "2 days", distance_of_time_in_words(from, to + 42.hours + 59.minutes + 30.seconds)
|
62
|
+
assert_equal "3 days", distance_of_time_in_words(from, to + 2.days + 12.hours)
|
63
|
+
assert_equal "30 days", distance_of_time_in_words(from, to + 29.days + 23.hours + 59.minutes + 29.seconds)
|
63
64
|
|
64
65
|
# 43200..86399
|
65
66
|
assert_equal "about 1 month", distance_of_time_in_words(from, to + 29.days + 23.hours + 59.minutes + 30.seconds)
|
@@ -69,13 +70,28 @@ class DateHelperTest < ActionView::TestCase
|
|
69
70
|
assert_equal "2 months", distance_of_time_in_words(from, to + 59.days + 23.hours + 59.minutes + 30.seconds)
|
70
71
|
assert_equal "12 months", distance_of_time_in_words(from, to + 1.years - 31.seconds)
|
71
72
|
|
72
|
-
#
|
73
|
-
assert_equal "about 1 year",
|
74
|
-
assert_equal "about 1 year",
|
75
|
-
|
76
|
-
|
77
|
-
assert_equal "
|
78
|
-
assert_equal "
|
73
|
+
# > 525599
|
74
|
+
assert_equal "about 1 year", distance_of_time_in_words(from, to + 1.years - 30.seconds)
|
75
|
+
assert_equal "about 1 year", distance_of_time_in_words(from, to + 1.years + 3.months - 1.day)
|
76
|
+
assert_equal "over 1 year", distance_of_time_in_words(from, to + 1.years + 6.months)
|
77
|
+
|
78
|
+
assert_equal "almost 2 years", distance_of_time_in_words(from, to + 2.years - 3.months + 1.day)
|
79
|
+
assert_equal "about 2 years", distance_of_time_in_words(from, to + 2.years + 3.months - 1.day)
|
80
|
+
assert_equal "over 2 years", distance_of_time_in_words(from, to + 2.years + 3.months + 1.day)
|
81
|
+
assert_equal "over 2 years", distance_of_time_in_words(from, to + 2.years + 9.months - 1.day)
|
82
|
+
assert_equal "almost 3 years", distance_of_time_in_words(from, to + 2.years + 9.months + 1.day)
|
83
|
+
|
84
|
+
assert_equal "almost 5 years", distance_of_time_in_words(from, to + 5.years - 3.months + 1.day)
|
85
|
+
assert_equal "about 5 years", distance_of_time_in_words(from, to + 5.years + 3.months - 1.day)
|
86
|
+
assert_equal "over 5 years", distance_of_time_in_words(from, to + 5.years + 3.months + 1.day)
|
87
|
+
assert_equal "over 5 years", distance_of_time_in_words(from, to + 5.years + 9.months - 1.day)
|
88
|
+
assert_equal "almost 6 years", distance_of_time_in_words(from, to + 5.years + 9.months + 1.day)
|
89
|
+
|
90
|
+
assert_equal "almost 10 years", distance_of_time_in_words(from, to + 10.years - 3.months + 1.day)
|
91
|
+
assert_equal "about 10 years", distance_of_time_in_words(from, to + 10.years + 3.months - 1.day)
|
92
|
+
assert_equal "over 10 years", distance_of_time_in_words(from, to + 10.years + 3.months + 1.day)
|
93
|
+
assert_equal "over 10 years", distance_of_time_in_words(from, to + 10.years + 9.months - 1.day)
|
94
|
+
assert_equal "almost 11 years", distance_of_time_in_words(from, to + 10.years + 9.months + 1.day)
|
79
95
|
|
80
96
|
# test to < from
|
81
97
|
assert_equal "about 4 hours", distance_of_time_in_words(from + 4.hours, to)
|
@@ -104,7 +120,7 @@ class DateHelperTest < ActionView::TestCase
|
|
104
120
|
def test_distance_in_words_with_dates
|
105
121
|
start_date = Date.new 1975, 1, 31
|
106
122
|
end_date = Date.new 1977, 1, 31
|
107
|
-
assert_equal("
|
123
|
+
assert_equal("about 2 years", distance_of_time_in_words(start_date, end_date))
|
108
124
|
end
|
109
125
|
|
110
126
|
def test_distance_in_words_with_integers
|
@@ -697,6 +697,26 @@ class FormHelperTest < ActionView::TestCase
|
|
697
697
|
end
|
698
698
|
end
|
699
699
|
|
700
|
+
expected = '<form action="http://www.example.com" method="post">' +
|
701
|
+
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
|
702
|
+
'<input id="post_author_attributes_name" name="post[author_attributes][name]" size="30" type="text" value="author #321" />' +
|
703
|
+
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
|
704
|
+
'</form>'
|
705
|
+
|
706
|
+
assert_dom_equal expected, output_buffer
|
707
|
+
end
|
708
|
+
|
709
|
+
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_one_to_one_association_with_explicit_hidden_field_placement
|
710
|
+
@post.author = Author.new(321)
|
711
|
+
|
712
|
+
form_for(:post, @post) do |f|
|
713
|
+
concat f.text_field(:title)
|
714
|
+
f.fields_for(:author) do |af|
|
715
|
+
concat af.hidden_field(:id)
|
716
|
+
concat af.text_field(:name)
|
717
|
+
end
|
718
|
+
end
|
719
|
+
|
700
720
|
expected = '<form action="http://www.example.com" method="post">' +
|
701
721
|
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
|
702
722
|
'<input id="post_author_attributes_id" name="post[author_attributes][id]" type="hidden" value="321" />' +
|
@@ -718,6 +738,30 @@ class FormHelperTest < ActionView::TestCase
|
|
718
738
|
end
|
719
739
|
end
|
720
740
|
|
741
|
+
expected = '<form action="http://www.example.com" method="post">' +
|
742
|
+
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
|
743
|
+
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
|
744
|
+
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
|
745
|
+
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
|
746
|
+
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
|
747
|
+
'</form>'
|
748
|
+
|
749
|
+
assert_dom_equal expected, output_buffer
|
750
|
+
end
|
751
|
+
|
752
|
+
def test_nested_fields_for_with_existing_records_on_a_nested_attributes_collection_association_with_explicit_hidden_field_placement
|
753
|
+
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
|
754
|
+
|
755
|
+
form_for(:post, @post) do |f|
|
756
|
+
concat f.text_field(:title)
|
757
|
+
@post.comments.each do |comment|
|
758
|
+
f.fields_for(:comments, comment) do |cf|
|
759
|
+
concat cf.hidden_field(:id)
|
760
|
+
concat cf.text_field(:name)
|
761
|
+
end
|
762
|
+
end
|
763
|
+
end
|
764
|
+
|
721
765
|
expected = '<form action="http://www.example.com" method="post">' +
|
722
766
|
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
|
723
767
|
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
|
@@ -764,14 +808,50 @@ class FormHelperTest < ActionView::TestCase
|
|
764
808
|
|
765
809
|
expected = '<form action="http://www.example.com" method="post">' +
|
766
810
|
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
|
767
|
-
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
|
768
811
|
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
|
812
|
+
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
|
769
813
|
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
|
770
814
|
'</form>'
|
771
815
|
|
772
816
|
assert_dom_equal expected, output_buffer
|
773
817
|
end
|
774
818
|
|
819
|
+
def test_nested_fields_for_with_an_empty_supplied_attributes_collection
|
820
|
+
form_for(:post, @post) do |f|
|
821
|
+
concat f.text_field(:title)
|
822
|
+
f.fields_for(:comments, []) do |cf|
|
823
|
+
concat cf.text_field(:name)
|
824
|
+
end
|
825
|
+
end
|
826
|
+
|
827
|
+
expected = '<form action="http://www.example.com" method="post">' +
|
828
|
+
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
|
829
|
+
'</form>'
|
830
|
+
|
831
|
+
assert_dom_equal expected, output_buffer
|
832
|
+
end
|
833
|
+
|
834
|
+
def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection
|
835
|
+
@post.comments = Array.new(2) { |id| Comment.new(id + 1) }
|
836
|
+
|
837
|
+
form_for(:post, @post) do |f|
|
838
|
+
concat f.text_field(:title)
|
839
|
+
f.fields_for(:comments, @post.comments) do |cf|
|
840
|
+
concat cf.text_field(:name)
|
841
|
+
end
|
842
|
+
end
|
843
|
+
|
844
|
+
expected = '<form action="http://www.example.com" method="post">' +
|
845
|
+
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
|
846
|
+
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #1" />' +
|
847
|
+
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="1" />' +
|
848
|
+
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="comment #2" />' +
|
849
|
+
'<input id="post_comments_attributes_1_id" name="post[comments_attributes][1][id]" type="hidden" value="2" />' +
|
850
|
+
'</form>'
|
851
|
+
|
852
|
+
assert_dom_equal expected, output_buffer
|
853
|
+
end
|
854
|
+
|
775
855
|
def test_nested_fields_for_on_a_nested_attributes_collection_association_yields_only_builder
|
776
856
|
@post.comments = [Comment.new(321), Comment.new]
|
777
857
|
yielded_comments = []
|
@@ -786,8 +866,8 @@ class FormHelperTest < ActionView::TestCase
|
|
786
866
|
|
787
867
|
expected = '<form action="http://www.example.com" method="post">' +
|
788
868
|
'<input name="post[title]" size="30" type="text" id="post_title" value="Hello World" />' +
|
789
|
-
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
|
790
869
|
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
|
870
|
+
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
|
791
871
|
'<input id="post_comments_attributes_1_name" name="post[comments_attributes][1][name]" size="30" type="text" value="new comment" />' +
|
792
872
|
'</form>'
|
793
873
|
|
@@ -805,8 +885,8 @@ class FormHelperTest < ActionView::TestCase
|
|
805
885
|
end
|
806
886
|
|
807
887
|
expected = '<form action="http://www.example.com" method="post">' +
|
808
|
-
'<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
|
809
888
|
'<input id="post_comments_attributes_abc_name" name="post[comments_attributes][abc][name]" size="30" type="text" value="comment #321" />' +
|
889
|
+
'<input id="post_comments_attributes_abc_id" name="post[comments_attributes][abc][id]" type="hidden" value="321" />' +
|
810
890
|
'</form>'
|
811
891
|
|
812
892
|
assert_dom_equal expected, output_buffer
|
@@ -840,18 +920,18 @@ class FormHelperTest < ActionView::TestCase
|
|
840
920
|
end
|
841
921
|
|
842
922
|
expected = '<form action="http://www.example.com" method="post">' +
|
843
|
-
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
|
844
923
|
'<input id="post_comments_attributes_0_name" name="post[comments_attributes][0][name]" size="30" type="text" value="comment #321" />' +
|
845
|
-
'<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
|
846
924
|
'<input id="post_comments_attributes_0_relevances_attributes_0_value" name="post[comments_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="commentrelevance #314" />' +
|
847
|
-
'<input id="
|
925
|
+
'<input id="post_comments_attributes_0_relevances_attributes_0_id" name="post[comments_attributes][0][relevances_attributes][0][id]" type="hidden" value="314" />' +
|
926
|
+
'<input id="post_comments_attributes_0_id" name="post[comments_attributes][0][id]" type="hidden" value="321" />' +
|
848
927
|
'<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" size="30" type="text" value="tag #123" />' +
|
849
|
-
'<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
|
850
928
|
'<input id="post_tags_attributes_0_relevances_attributes_0_value" name="post[tags_attributes][0][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #3141" />' +
|
851
|
-
'<input id="
|
929
|
+
'<input id="post_tags_attributes_0_relevances_attributes_0_id" name="post[tags_attributes][0][relevances_attributes][0][id]" type="hidden" value="3141" />' +
|
930
|
+
'<input id="post_tags_attributes_0_id" name="post[tags_attributes][0][id]" type="hidden" value="123" />' +
|
852
931
|
'<input id="post_tags_attributes_1_value" name="post[tags_attributes][1][value]" size="30" type="text" value="tag #456" />' +
|
853
|
-
'<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
|
854
932
|
'<input id="post_tags_attributes_1_relevances_attributes_0_value" name="post[tags_attributes][1][relevances_attributes][0][value]" size="30" type="text" value="tagrelevance #31415" />' +
|
933
|
+
'<input id="post_tags_attributes_1_relevances_attributes_0_id" name="post[tags_attributes][1][relevances_attributes][0][id]" type="hidden" value="31415" />' +
|
934
|
+
'<input id="post_tags_attributes_1_id" name="post[tags_attributes][1][id]" type="hidden" value="456" />' +
|
855
935
|
'</form>'
|
856
936
|
|
857
937
|
assert_dom_equal expected, output_buffer
|
@@ -1024,7 +1104,7 @@ class FormHelperTest < ActionView::TestCase
|
|
1024
1104
|
(field_helpers - %w(hidden_field)).each do |selector|
|
1025
1105
|
src = <<-END_SRC
|
1026
1106
|
def #{selector}(field, *args, &proc)
|
1027
|
-
"<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>"
|
1107
|
+
("<label for='\#{field}'>\#{field.to_s.humanize}:</label> " + super + "<br/>").html_safe!
|
1028
1108
|
end
|
1029
1109
|
END_SRC
|
1030
1110
|
class_eval src, __FILE__, __LINE__
|