aboutsummaryrefslogtreecommitdiffstats
path: root/actionview/test/template
diff options
context:
space:
mode:
Diffstat (limited to 'actionview/test/template')
-rw-r--r--actionview/test/template/asset_tag_helper_test.rb50
-rw-r--r--actionview/test/template/atom_feed_helper_test.rb10
-rw-r--r--actionview/test/template/capture_helper_test.rb23
-rw-r--r--actionview/test/template/compiled_templates_test.rb11
-rw-r--r--actionview/test/template/date_helper_test.rb59
-rw-r--r--actionview/test/template/debug_helper_test.rb8
-rw-r--r--actionview/test/template/dependency_tracker_test.rb130
-rw-r--r--actionview/test/template/digestor_test.rb54
-rw-r--r--actionview/test/template/erb_util_test.rb3
-rw-r--r--actionview/test/template/form_collections_helper_test.rb124
-rw-r--r--actionview/test/template/form_helper_test.rb565
-rw-r--r--actionview/test/template/form_options_helper_test.rb35
-rw-r--r--actionview/test/template/form_tag_helper_test.rb39
-rw-r--r--actionview/test/template/html-scanner/cdata_node_test.rb15
-rw-r--r--actionview/test/template/html-scanner/document_test.rb148
-rw-r--r--actionview/test/template/html-scanner/node_test.rb89
-rw-r--r--actionview/test/template/html-scanner/sanitizer_test.rb330
-rw-r--r--actionview/test/template/html-scanner/tag_node_test.rb243
-rw-r--r--actionview/test/template/html-scanner/text_node_test.rb50
-rw-r--r--actionview/test/template/html-scanner/tokenizer_test.rb131
-rw-r--r--actionview/test/template/html_test.rb17
-rw-r--r--actionview/test/template/javascript_helper_test.rb6
-rw-r--r--actionview/test/template/lookup_context_test.rb14
-rw-r--r--actionview/test/template/number_helper_test.rb45
-rw-r--r--actionview/test/template/output_buffer_test.rb59
-rw-r--r--actionview/test/template/output_safety_helper_test.rb9
-rw-r--r--actionview/test/template/partial_iteration_test.rb33
-rw-r--r--actionview/test/template/record_identifier_test.rb44
-rw-r--r--actionview/test/template/render_test.rb86
-rw-r--r--actionview/test/template/sanitize_helper_test.rb20
-rw-r--r--actionview/test/template/tag_helper_test.rb42
-rw-r--r--actionview/test/template/test_case_test.rb16
-rw-r--r--actionview/test/template/test_test.rb18
-rw-r--r--actionview/test/template/text_helper_test.rb33
-rw-r--r--actionview/test/template/text_test.rb17
-rw-r--r--actionview/test/template/translation_helper_test.rb53
-rw-r--r--actionview/test/template/url_helper_test.rb51
37 files changed, 1317 insertions, 1363 deletions
diff --git a/actionview/test/template/asset_tag_helper_test.rb b/actionview/test/template/asset_tag_helper_test.rb
index 3ca71d3376..dac1c7024d 100644
--- a/actionview/test/template/asset_tag_helper_test.rb
+++ b/actionview/test/template/asset_tag_helper_test.rb
@@ -195,9 +195,9 @@ class AssetTagHelperTest < ActionView::TestCase
}
FaviconLinkToTag = {
- %(favicon_link_tag) => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />),
- %(favicon_link_tag 'favicon.ico') => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/vnd.microsoft.icon" />),
- %(favicon_link_tag 'favicon.ico', :rel => 'foo') => %(<link href="/images/favicon.ico" rel="foo" type="image/vnd.microsoft.icon" />),
+ %(favicon_link_tag) => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/x-icon" />),
+ %(favicon_link_tag 'favicon.ico') => %(<link href="/images/favicon.ico" rel="shortcut icon" type="image/x-icon" />),
+ %(favicon_link_tag 'favicon.ico', :rel => 'foo') => %(<link href="/images/favicon.ico" rel="foo" type="image/x-icon" />),
%(favicon_link_tag 'favicon.ico', :rel => 'foo', :type => 'bar') => %(<link href="/images/favicon.ico" rel="foo" type="bar" />),
%(favicon_link_tag 'mb-icon.png', :rel => 'apple-touch-icon', :type => 'image/png') => %(<link href="/images/mb-icon.png" rel="apple-touch-icon" type="image/png" />)
}
@@ -302,13 +302,21 @@ class AssetTagHelperTest < ActionView::TestCase
def test_autodiscovery_link_tag_with_unknown_type
result = auto_discovery_link_tag(:xml, '/feed.xml', :type => 'application/xml')
expected = %(<link href="/feed.xml" rel="alternate" title="XML" type="application/xml" />)
- assert_equal expected, result
+ assert_dom_equal expected, result
end
def test_asset_path_tag
AssetPathToTag.each { |method, tag| assert_dom_equal(tag, eval(method)) }
end
+ def test_asset_path_tag_to_not_create_duplicate_slashes
+ @controller.config.asset_host = "host/"
+ assert_dom_equal('http://host/foo', asset_path("foo"))
+
+ @controller.config.relative_url_root = '/some/root/'
+ assert_dom_equal('http://host/some/root/foo', asset_path("foo"))
+ end
+
def test_compute_asset_public_path
assert_equal "/robots.txt", compute_asset_path("robots.txt")
assert_equal "/robots.txt", compute_asset_path("/robots.txt")
@@ -527,6 +535,17 @@ class AssetTagHelperTest < ActionView::TestCase
assert_equal copy, source
end
+ class PlaceholderImage
+ def blank?; true; end
+ def to_s; 'no-image-yet.png'; end
+ end
+ def test_image_tag_with_blank_placeholder
+ assert_equal '<img alt="" src="/images/no-image-yet.png" />', image_tag(PlaceholderImage.new, alt: "")
+ end
+ def test_image_path_with_blank_placeholder
+ assert_equal '/images/no-image-yet.png', image_path(PlaceholderImage.new)
+ end
+
def test_image_path_with_asset_host_proc_returning_nil
@controller.config.asset_host = Proc.new do |source|
unless source.end_with?("tiff")
@@ -538,6 +557,14 @@ class AssetTagHelperTest < ActionView::TestCase
assert_equal "http://cdn.example.com/images/file.png", image_path("file.png")
end
+ def test_image_url_with_asset_host_proc_returning_nil
+ @controller.config.asset_host = Proc.new { nil }
+ @controller.request = Struct.new(:base_url, :script_name).new("http://www.example.com", nil)
+
+ assert_equal "/images/rails.png", image_path("rails.png")
+ assert_equal "http://www.example.com/images/rails.png", image_url("rails.png")
+ end
+
def test_caching_image_path_with_caching_and_proc_asset_host_using_request
@controller.config.asset_host = Proc.new do |source, request|
if request.ssl?
@@ -588,6 +615,10 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase
assert_equal "gopher://www.example.com", compute_asset_host("foo", :protocol => :request)
end
+ def test_should_return_custom_host_if_passed_in_options
+ assert_equal "http://custom.example.com", compute_asset_host("foo", :host => "http://custom.example.com")
+ end
+
def test_should_ignore_relative_root_path_on_complete_url
assert_dom_equal(%(http://www.example.com/images/xml.png), image_path("http://www.example.com/images/xml.png"))
end
@@ -751,4 +782,15 @@ class AssetUrlHelperEmptyModuleTest < ActionView::TestCase
assert @module.config.asset_host
assert_equal "http://www.example.com/foo", @module.asset_url("foo")
end
+
+ def test_asset_url_with_custom_asset_host
+ @module.instance_eval do
+ def config
+ Struct.new(:asset_host).new("http://www.example.com")
+ end
+ end
+
+ assert @module.config.asset_host
+ assert_equal "http://custom.example.com/foo", @module.asset_url("foo", :host => "http://custom.example.com")
+ end
end
diff --git a/actionview/test/template/atom_feed_helper_test.rb b/actionview/test/template/atom_feed_helper_test.rb
index 63b5ac0fab..68b44c4f0d 100644
--- a/actionview/test/template/atom_feed_helper_test.rb
+++ b/actionview/test/template/atom_feed_helper_test.rb
@@ -254,7 +254,7 @@ class AtomFeedTest < ActionController::TestCase
def test_self_url_should_default_to_current_request_url
with_restful_routing(:scrolls) do
get :index, :id => "defaults"
- assert_select "link[rel=self][href=http://www.nextangle.com/scrolls?id=defaults]"
+ assert_select "link[rel=self][href=\"http://www.nextangle.com/scrolls?id=defaults\"]"
end
end
@@ -318,22 +318,22 @@ class AtomFeedTest < ActionController::TestCase
with_restful_routing(:scrolls) do
get :index, :id => "feed_with_xhtml_content"
assert_match %r{xmlns="http://www.w3.org/1999/xhtml"}, @response.body
- assert_select "summary div p", :text => "Something Boring"
- assert_select "summary div p", :text => "after 2"
+ assert_select "summary", :text => /Something Boring/
+ assert_select "summary", :text => /after 2/
end
end
def test_feed_entry_type_option_default_to_text_html
with_restful_routing(:scrolls) do
get :index, :id => 'defaults'
- assert_select "entry link[rel=alternate][type=text/html]"
+ assert_select "entry link[rel=alternate][type=\"text/html\"]"
end
end
def test_feed_entry_type_option_specified
with_restful_routing(:scrolls) do
get :index, :id => 'entry_type_options'
- assert_select "entry link[rel=alternate][type=text/xml]"
+ assert_select "entry link[rel=alternate][type=\"text/xml\"]"
end
end
diff --git a/actionview/test/template/capture_helper_test.rb b/actionview/test/template/capture_helper_test.rb
index 938f1c3e54..f213da5934 100644
--- a/actionview/test/template/capture_helper_test.rb
+++ b/actionview/test/template/capture_helper_test.rb
@@ -207,29 +207,6 @@ class CaptureHelperTest < ActionView::TestCase
assert_equal "", @av.with_output_buffer {}
end
- def test_flush_output_buffer_concats_output_buffer_to_response
- view = view_with_controller
- assert_equal [], view.response.body_parts
-
- view.output_buffer << 'OMG'
- view.flush_output_buffer
- assert_equal ['OMG'], view.response.body_parts
- assert_equal '', view.output_buffer
-
- view.output_buffer << 'foobar'
- view.flush_output_buffer
- assert_equal ['OMG', 'foobar'], view.response.body_parts
- assert_equal '', view.output_buffer
- end
-
- def test_flush_output_buffer_preserves_the_encoding_of_the_output_buffer
- view = view_with_controller
- alt_encoding = alt_encoding(view.output_buffer)
- view.output_buffer.force_encoding(alt_encoding)
- flush_output_buffer
- assert_equal alt_encoding, view.output_buffer.encoding
- end
-
def alt_encoding(output_buffer)
output_buffer.encoding == Encoding::US_ASCII ? Encoding::UTF_8 : Encoding::US_ASCII
end
diff --git a/actionview/test/template/compiled_templates_test.rb b/actionview/test/template/compiled_templates_test.rb
index 2336321f3e..f6c1283b92 100644
--- a/actionview/test/template/compiled_templates_test.rb
+++ b/actionview/test/template/compiled_templates_test.rb
@@ -1,15 +1,12 @@
require 'abstract_unit'
class CompiledTemplatesTest < ActiveSupport::TestCase
- def setup
- # Clean up any details key cached to expose failures
- # that otherwise would appear just on isolated tests
+ teardown do
ActionView::LookupContext::DetailsKey.clear
+ end
- @compiled_templates = ActionView::CompiledTemplates
- @compiled_templates.instance_methods.each do |m|
- @compiled_templates.send(:remove_method, m) if m =~ /^_render_template_/
- end
+ def test_template_with_nil_erb_return
+ assert_equal "This is nil: \n", render(:template => "test/nil_return")
end
def test_template_gets_recompiled_when_using_different_keys_in_local_assigns
diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb
index 5f09aef249..bfb073680e 100644
--- a/actionview/test/template/date_helper_test.rb
+++ b/actionview/test/template/date_helper_test.rb
@@ -326,6 +326,16 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, select_month(8, :add_month_numbers => true)
end
+ def test_select_month_with_format_string
+ expected = %(<select id="date_month" name="date[month]">\n)
+ expected << %(<option value="1">January (01)</option>\n<option value="2">February (02)</option>\n<option value="3">March (03)</option>\n<option value="4">April (04)</option>\n<option value="5">May (05)</option>\n<option value="6">June (06)</option>\n<option value="7">July (07)</option>\n<option value="8" selected="selected">August (08)</option>\n<option value="9">September (09)</option>\n<option value="10">October (10)</option>\n<option value="11">November (11)</option>\n<option value="12">December (12)</option>\n)
+ expected << "</select>\n"
+
+ format_string = '%{name} (%<number>02d)'
+ assert_dom_equal expected, select_month(Time.mktime(2003, 8, 16), :month_format_string => format_string)
+ assert_dom_equal expected, select_month(8, :month_format_string => format_string)
+ end
+
def test_select_month_with_numbers_and_names_with_abbv
expected = %(<select id="date_month" name="date[month]">\n)
expected << %(<option value="1">1 - Jan</option>\n<option value="2">2 - Feb</option>\n<option value="3">3 - Mar</option>\n<option value="4">4 - Apr</option>\n<option value="5">5 - May</option>\n<option value="6">6 - Jun</option>\n<option value="7">7 - Jul</option>\n<option value="8" selected="selected">8 - Aug</option>\n<option value="9">9 - Sep</option>\n<option value="10">10 - Oct</option>\n<option value="11">11 - Nov</option>\n<option value="12">12 - Dec</option>\n)
@@ -1030,6 +1040,22 @@ class DateHelperTest < ActionView::TestCase
assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), {:start_year => 2003, :end_year => 2005, :prefix => "date[first]", :with_css_classes => true})
end
+ def test_select_date_with_css_classes_option_and_html_class_option
+ expected = %(<select id="date_first_year" name="date[first][year]" class="datetime optional year">\n)
+ expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
+ expected << "</select>\n"
+
+ expected << %(<select id="date_first_month" name="date[first][month]" class="datetime optional month">\n)
+ expected << %(<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option value="6">June</option>\n<option value="7">July</option>\n<option value="8" selected="selected">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n)
+ expected << "</select>\n"
+
+ expected << %(<select id="date_first_day" name="date[first][day]" class="datetime optional day">\n)
+ expected << %(<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16" selected="selected">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n)
+ expected << "</select>\n"
+
+ assert_dom_equal expected, select_date(Time.mktime(2003, 8, 16), {:start_year => 2003, :end_year => 2005, :prefix => "date[first]", :with_css_classes => true}, { class: 'datetime optional' })
+ end
+
def test_select_datetime
expected = %(<select id="date_first_year" name="date[first][year]">\n)
expected << %(<option value="2003" selected="selected">2003</option>\n<option value="2004">2004</option>\n<option value="2005">2005</option>\n)
@@ -1478,7 +1504,7 @@ class DateHelperTest < ActionView::TestCase
expected << %(<option value="">Choose seconds</option>\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18" selected="selected">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n)
expected << "</select>\n"
- assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), :prompt => true, :include_seconds => true,
+ assert_dom_equal expected, select_time(Time.mktime(2003, 8, 16, 8, 4, 18), :include_seconds => true,
:prompt => {:hour => 'Choose hour', :minute => 'Choose minute', :second => 'Choose seconds'})
end
@@ -1626,9 +1652,9 @@ class DateHelperTest < ActionView::TestCase
concat f.date_select(:written_on)
end
- expected = "<select id='post_written_on_1i' name='post[written_on(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
- expected << "<select id='post_written_on_2i' name='post[written_on(2i)]'>\n<option value='1'>January</option>\n<option value='2'>February</option>\n<option value='3'>March</option>\n<option value='4'>April</option>\n<option value='5'>May</option>\n<option selected='selected' value='6'>June</option>\n<option value='7'>July</option>\n<option value='8'>August</option>\n<option value='9'>September</option>\n<option value='10'>October</option>\n<option value='11'>November</option>\n<option value='12'>December</option>\n</select>\n"
- expected << "<select id='post_written_on_3i' name='post[written_on(3i)]'>\n<option value='1'>1</option>\n<option value='2'>2</option>\n<option value='3'>3</option>\n<option value='4'>4</option>\n<option value='5'>5</option>\n<option value='6'>6</option>\n<option value='7'>7</option>\n<option value='8'>8</option>\n<option value='9'>9</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option selected='selected' value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n</select>\n"
+ expected = %{<select id="post_written_on_1i" name="post[written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}
+ expected << %{<select id="post_written_on_2i" name="post[written_on(2i)]">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option selected="selected" value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n}
+ expected << %{<select id="post_written_on_3i" name="post[written_on(3i)]">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option selected="selected" value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n}
assert_dom_equal(expected, output_buffer)
end
@@ -1642,9 +1668,9 @@ class DateHelperTest < ActionView::TestCase
concat f.date_select(:written_on)
end
- expected = "<select id='post_#{id}_written_on_1i' name='post[#{id}][written_on(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
- expected << "<select id='post_#{id}_written_on_2i' name='post[#{id}][written_on(2i)]'>\n<option value='1'>January</option>\n<option value='2'>February</option>\n<option value='3'>March</option>\n<option value='4'>April</option>\n<option value='5'>May</option>\n<option selected='selected' value='6'>June</option>\n<option value='7'>July</option>\n<option value='8'>August</option>\n<option value='9'>September</option>\n<option value='10'>October</option>\n<option value='11'>November</option>\n<option value='12'>December</option>\n</select>\n"
- expected << "<select id='post_#{id}_written_on_3i' name='post[#{id}][written_on(3i)]'>\n<option value='1'>1</option>\n<option value='2'>2</option>\n<option value='3'>3</option>\n<option value='4'>4</option>\n<option value='5'>5</option>\n<option value='6'>6</option>\n<option value='7'>7</option>\n<option value='8'>8</option>\n<option value='9'>9</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option selected='selected' value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n</select>\n"
+ expected = %{<select id="post_#{id}_written_on_1i" name="post[#{id}][written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}
+ expected << %{<select id="post_#{id}_written_on_2i" name="post[#{id}][written_on(2i)]">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option selected="selected" value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n}
+ expected << %{<select id="post_#{id}_written_on_3i" name="post[#{id}][written_on(3i)]">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option selected="selected" value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n}
assert_dom_equal(expected, output_buffer)
end
@@ -1658,9 +1684,10 @@ class DateHelperTest < ActionView::TestCase
concat f.date_select(:written_on)
end
- expected = "<select id='post_#{id}_written_on_1i' name='post[#{id}][written_on(1i)]'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
- expected << "<select id='post_#{id}_written_on_2i' name='post[#{id}][written_on(2i)]'>\n<option value='1'>January</option>\n<option value='2'>February</option>\n<option value='3'>March</option>\n<option value='4'>April</option>\n<option value='5'>May</option>\n<option selected='selected' value='6'>June</option>\n<option value='7'>July</option>\n<option value='8'>August</option>\n<option value='9'>September</option>\n<option value='10'>October</option>\n<option value='11'>November</option>\n<option value='12'>December</option>\n</select>\n"
- expected << "<select id='post_#{id}_written_on_3i' name='post[#{id}][written_on(3i)]'>\n<option value='1'>1</option>\n<option value='2'>2</option>\n<option value='3'>3</option>\n<option value='4'>4</option>\n<option value='5'>5</option>\n<option value='6'>6</option>\n<option value='7'>7</option>\n<option value='8'>8</option>\n<option value='9'>9</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option selected='selected' value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n</select>\n"
+
+ expected = %{<select id="post_#{id}_written_on_1i" name="post[#{id}][written_on(1i)]">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}
+ expected << %{<select id="post_#{id}_written_on_2i" name="post[#{id}][written_on(2i)]">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option selected="selected" value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n}
+ expected << %{<select id="post_#{id}_written_on_3i" name="post[#{id}][written_on(3i)]">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option selected="selected" value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n}
assert_dom_equal(expected, output_buffer)
end
@@ -2303,7 +2330,7 @@ class DateHelperTest < ActionView::TestCase
# The love zone is UTC+0
mytz = Class.new(ActiveSupport::TimeZone) {
attr_accessor :now
- }.create('tenderlove', 0)
+ }.create('tenderlove', 0, ActiveSupport::TimeZone.find_tzinfo('UTC'))
now = Time.mktime(2004, 6, 15, 16, 35, 0)
mytz.now = now
@@ -2348,11 +2375,11 @@ class DateHelperTest < ActionView::TestCase
concat f.datetime_select(:updated_at, {}, :class => 'selector')
end
- expected = "<select id='post_updated_at_1i' name='post[updated_at(1i)]' class='selector'>\n<option value='1999'>1999</option>\n<option value='2000'>2000</option>\n<option value='2001'>2001</option>\n<option value='2002'>2002</option>\n<option value='2003'>2003</option>\n<option selected='selected' value='2004'>2004</option>\n<option value='2005'>2005</option>\n<option value='2006'>2006</option>\n<option value='2007'>2007</option>\n<option value='2008'>2008</option>\n<option value='2009'>2009</option>\n</select>\n"
- expected << "<select id='post_updated_at_2i' name='post[updated_at(2i)]' class='selector'>\n<option value='1'>January</option>\n<option value='2'>February</option>\n<option value='3'>March</option>\n<option value='4'>April</option>\n<option value='5'>May</option>\n<option selected='selected' value='6'>June</option>\n<option value='7'>July</option>\n<option value='8'>August</option>\n<option value='9'>September</option>\n<option value='10'>October</option>\n<option value='11'>November</option>\n<option value='12'>December</option>\n</select>\n"
- expected << "<select id='post_updated_at_3i' name='post[updated_at(3i)]' class='selector'>\n<option value='1'>1</option>\n<option value='2'>2</option>\n<option value='3'>3</option>\n<option value='4'>4</option>\n<option value='5'>5</option>\n<option value='6'>6</option>\n<option value='7'>7</option>\n<option value='8'>8</option>\n<option value='9'>9</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option selected='selected' value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n</select>\n"
- expected << " &mdash; <select id='post_updated_at_4i' name='post[updated_at(4i)]' class='selector'>\n<option value='00'>00</option>\n<option value='01'>01</option>\n<option value='02'>02</option>\n<option value='03'>03</option>\n<option value='04'>04</option>\n<option value='05'>05</option>\n<option value='06'>06</option>\n<option value='07'>07</option>\n<option value='08'>08</option>\n<option value='09'>09</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option value='15'>15</option>\n<option selected='selected' value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n</select>\n"
- expected << " : <select id='post_updated_at_5i' name='post[updated_at(5i)]' class='selector'>\n<option value='00'>00</option>\n<option value='01'>01</option>\n<option value='02'>02</option>\n<option value='03'>03</option>\n<option value='04'>04</option>\n<option value='05'>05</option>\n<option value='06'>06</option>\n<option value='07'>07</option>\n<option value='08'>08</option>\n<option value='09'>09</option>\n<option value='10'>10</option>\n<option value='11'>11</option>\n<option value='12'>12</option>\n<option value='13'>13</option>\n<option value='14'>14</option>\n<option value='15'>15</option>\n<option value='16'>16</option>\n<option value='17'>17</option>\n<option value='18'>18</option>\n<option value='19'>19</option>\n<option value='20'>20</option>\n<option value='21'>21</option>\n<option value='22'>22</option>\n<option value='23'>23</option>\n<option value='24'>24</option>\n<option value='25'>25</option>\n<option value='26'>26</option>\n<option value='27'>27</option>\n<option value='28'>28</option>\n<option value='29'>29</option>\n<option value='30'>30</option>\n<option value='31'>31</option>\n<option value='32'>32</option>\n<option value='33'>33</option>\n<option value='34'>34</option>\n<option selected='selected' value='35'>35</option>\n<option value='36'>36</option>\n<option value='37'>37</option>\n<option value='38'>38</option>\n<option value='39'>39</option>\n<option value='40'>40</option>\n<option value='41'>41</option>\n<option value='42'>42</option>\n<option value='43'>43</option>\n<option value='44'>44</option>\n<option value='45'>45</option>\n<option value='46'>46</option>\n<option value='47'>47</option>\n<option value='48'>48</option>\n<option value='49'>49</option>\n<option value='50'>50</option>\n<option value='51'>51</option>\n<option value='52'>52</option>\n<option value='53'>53</option>\n<option value='54'>54</option>\n<option value='55'>55</option>\n<option value='56'>56</option>\n<option value='57'>57</option>\n<option value='58'>58</option>\n<option value='59'>59</option>\n</select>\n"
+ expected = %{<select id="post_updated_at_1i" name="post[updated_at(1i)]" class="selector">\n<option value="1999">1999</option>\n<option value="2000">2000</option>\n<option value="2001">2001</option>\n<option value="2002">2002</option>\n<option value="2003">2003</option>\n<option selected="selected" value="2004">2004</option>\n<option value="2005">2005</option>\n<option value="2006">2006</option>\n<option value="2007">2007</option>\n<option value="2008">2008</option>\n<option value="2009">2009</option>\n</select>\n}
+ expected << %{<select id="post_updated_at_2i" name="post[updated_at(2i)]" class="selector">\n<option value="1">January</option>\n<option value="2">February</option>\n<option value="3">March</option>\n<option value="4">April</option>\n<option value="5">May</option>\n<option selected="selected" value="6">June</option>\n<option value="7">July</option>\n<option value="8">August</option>\n<option value="9">September</option>\n<option value="10">October</option>\n<option value="11">November</option>\n<option value="12">December</option>\n</select>\n}
+ expected << %{<select id="post_updated_at_3i" name="post[updated_at(3i)]" class="selector">\n<option value="1">1</option>\n<option value="2">2</option>\n<option value="3">3</option>\n<option value="4">4</option>\n<option value="5">5</option>\n<option value="6">6</option>\n<option value="7">7</option>\n<option value="8">8</option>\n<option value="9">9</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option selected="selected" value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n</select>\n}
+ expected << %{ &mdash; <select id="post_updated_at_4i" name="post[updated_at(4i)]" class="selector">\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option selected="selected" value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n</select>\n}
+ expected << %{ : <select id="post_updated_at_5i" name="post[updated_at(5i)]" class="selector">\n<option value="00">00</option>\n<option value="01">01</option>\n<option value="02">02</option>\n<option value="03">03</option>\n<option value="04">04</option>\n<option value="05">05</option>\n<option value="06">06</option>\n<option value="07">07</option>\n<option value="08">08</option>\n<option value="09">09</option>\n<option value="10">10</option>\n<option value="11">11</option>\n<option value="12">12</option>\n<option value="13">13</option>\n<option value="14">14</option>\n<option value="15">15</option>\n<option value="16">16</option>\n<option value="17">17</option>\n<option value="18">18</option>\n<option value="19">19</option>\n<option value="20">20</option>\n<option value="21">21</option>\n<option value="22">22</option>\n<option value="23">23</option>\n<option value="24">24</option>\n<option value="25">25</option>\n<option value="26">26</option>\n<option value="27">27</option>\n<option value="28">28</option>\n<option value="29">29</option>\n<option value="30">30</option>\n<option value="31">31</option>\n<option value="32">32</option>\n<option value="33">33</option>\n<option value="34">34</option>\n<option selected="selected" value="35">35</option>\n<option value="36">36</option>\n<option value="37">37</option>\n<option value="38">38</option>\n<option value="39">39</option>\n<option value="40">40</option>\n<option value="41">41</option>\n<option value="42">42</option>\n<option value="43">43</option>\n<option value="44">44</option>\n<option value="45">45</option>\n<option value="46">46</option>\n<option value="47">47</option>\n<option value="48">48</option>\n<option value="49">49</option>\n<option value="50">50</option>\n<option value="51">51</option>\n<option value="52">52</option>\n<option value="53">53</option>\n<option value="54">54</option>\n<option value="55">55</option>\n<option value="56">56</option>\n<option value="57">57</option>\n<option value="58">58</option>\n<option value="59">59</option>\n</select>\n}
assert_dom_equal expected, output_buffer
end
diff --git a/actionview/test/template/debug_helper_test.rb b/actionview/test/template/debug_helper_test.rb
deleted file mode 100644
index 42d06bd9ff..0000000000
--- a/actionview/test/template/debug_helper_test.rb
+++ /dev/null
@@ -1,8 +0,0 @@
-require 'active_record_unit'
-
-class DebugHelperTest < ActionView::TestCase
- def test_debug
- company = Company.new(name: "firebase")
- assert_match "&nbsp; name: firebase", debug(company)
- end
-end
diff --git a/actionview/test/template/dependency_tracker_test.rb b/actionview/test/template/dependency_tracker_test.rb
index 7a9b4b26ac..bb375076c6 100644
--- a/actionview/test/template/dependency_tracker_test.rb
+++ b/actionview/test/template/dependency_tracker_test.rb
@@ -1,3 +1,5 @@
+# encoding: utf-8
+
require 'abstract_unit'
require 'action_view/dependency_tracker'
@@ -29,6 +31,7 @@ class DependencyTrackerTest < ActionView::TestCase
end
def teardown
+ ActionView::Template.unregister_template_handler :neckbeard
tracker.remove_tracker(:neckbeard)
end
@@ -52,23 +55,142 @@ class ERBTrackerTest < Minitest::Test
def test_dependency_of_erb_template_with_number_in_filename
template = FakeTemplate.new("<%# render 'messages/message123' %>", :erb)
- tracker = make_tracker('messages/_message123', template)
+ tracker = make_tracker("messages/_message123", template)
assert_equal ["messages/message123"], tracker.dependencies
end
+ def test_dependency_of_template_partial_with_layout
+ skip # FIXME: Needs to be fixed properly, right now we can only match one dependency per line. Need multiple!
+ template = FakeTemplate.new("<%# render partial: 'messages/show', layout: 'messages/layout' %>", :erb)
+ tracker = make_tracker("multiple/_dependencies", template)
+
+ assert_equal ["messages/layout", "messages/show"], tracker.dependencies
+ end
+
+ def test_dependency_of_template_layout_standalone
+ template = FakeTemplate.new("<%# render layout: 'messages/layout' do %>", :erb)
+ tracker = make_tracker("messages/layout", template)
+
+ assert_equal ["messages/layout"], tracker.dependencies
+ end
+
def test_finds_dependency_in_correct_directory
template = FakeTemplate.new("<%# render(message.topic) %>", :erb)
- tracker = make_tracker('messages/_message', template)
+ tracker = make_tracker("messages/_message", template)
assert_equal ["topics/topic"], tracker.dependencies
end
def test_finds_dependency_in_correct_directory_with_underscore
template = FakeTemplate.new("<%# render(message_type.messages) %>", :erb)
- tracker = make_tracker('message_types/_message_type', template)
+ tracker = make_tracker("message_types/_message_type", template)
assert_equal ["messages/message"], tracker.dependencies
end
-end
+ def test_dependency_of_erb_template_with_no_spaces_after_render
+ template = FakeTemplate.new("<%# render'messages/message' %>", :erb)
+ tracker = make_tracker("messages/_message", template)
+
+ assert_equal ["messages/message"], tracker.dependencies
+ end
+
+ def test_finds_no_dependency_when_render_begins_the_name_of_an_identifier
+ template = FakeTemplate.new("<%# rendering 'it useless' %>", :erb)
+ tracker = make_tracker("resources/_resource", template)
+
+ assert_equal [], tracker.dependencies
+ end
+
+ def test_finds_no_dependency_when_render_ends_the_name_of_another_method
+ template = FakeTemplate.new("<%# surrender 'to reason' %>", :erb)
+ tracker = make_tracker("resources/_resource", template)
+
+ assert_equal [], tracker.dependencies
+ end
+
+ def test_finds_dependency_on_multiline_render_calls
+ template = FakeTemplate.new("<%#
+ render :object => @all_posts,
+ :partial => 'posts' %>", :erb)
+
+ tracker = make_tracker("some/_little_posts", template)
+
+ assert_equal ["some/posts"], tracker.dependencies
+ end
+
+ def test_finds_multiple_unrelated_odd_dependencies
+ template = FakeTemplate.new("
+ <%# render('shared/header', title: 'Title') %>
+ <h2>Section title</h2>
+ <%# render@section %>
+ ", :erb)
+
+ tracker = make_tracker("multiple/_dependencies", template)
+
+ assert_equal ["shared/header", "sections/section"], tracker.dependencies
+ end
+
+ def test_finds_dependencies_for_all_kinds_of_identifiers
+ template = FakeTemplate.new("
+ <%# render $globals %>
+ <%# render @instance_variables %>
+ <%# render @@class_variables %>
+ ", :erb)
+
+ tracker = make_tracker("identifiers/_all", template)
+
+ assert_equal [
+ "globals/global",
+ "instance_variables/instance_variable",
+ "class_variables/class_variable"
+ ], tracker.dependencies
+ end
+
+ def test_finds_dependencies_on_method_chains
+ template = FakeTemplate.new("<%# render @parent.child.grandchildren %>", :erb)
+ tracker = make_tracker("method/_chains", template)
+
+ assert_equal ["grandchildren/grandchild"], tracker.dependencies
+ end
+
+ def test_finds_dependencies_with_special_characters
+ template = FakeTemplate.new("<%# render @pokémon, partial: 'ピカチュウ' %>", :erb)
+ tracker = make_tracker("special/_characters", template)
+
+ assert_equal ["special/ピカチュウ"], tracker.dependencies
+ end
+
+ def test_finds_dependencies_with_quotes_within
+ template = FakeTemplate.new(%{
+ <%# render "single/quote's" %>
+ <%# render 'double/quote"s' %>
+ }, :erb)
+
+ tracker = make_tracker("quotes/_single_and_double", template)
+
+ assert_equal ["single/quote's", 'double/quote"s'], tracker.dependencies
+ end
+
+ def test_finds_dependencies_with_extra_spaces
+ template = FakeTemplate.new(%{
+ <%= render "header" %>
+ <%= render partial: "form" %>
+ <%= render @message %>
+ <%= render ( @message.events ) %>
+ <%= render :collection => @message.comments,
+ :partial => "comments/comment" %>
+ }, :erb)
+
+ tracker = make_tracker("spaces/_extra", template)
+
+ assert_equal [
+ "spaces/header",
+ "spaces/form",
+ "messages/message",
+ "events/event",
+ "comments/comment"
+ ], tracker.dependencies
+ end
+end
diff --git a/actionview/test/template/digestor_test.rb b/actionview/test/template/digestor_test.rb
index 779a7fb53c..c2b8439df3 100644
--- a/actionview/test/template/digestor_test.rb
+++ b/actionview/test/template/digestor_test.rb
@@ -15,18 +15,30 @@ end
class FixtureFinder
FIXTURES_DIR = "#{File.dirname(__FILE__)}/../fixtures/digestor"
- attr_reader :details
+ attr_reader :details
+ attr_accessor :formats
+ attr_accessor :variants
def initialize
- @details = {}
+ @details = {}
+ @formats = []
+ @variants = []
end
def details_key
details.hash
end
- def find(logical_name, keys, partial, options)
- FixtureTemplate.new("digestor/#{partial ? logical_name.gsub(%r|/([^/]+)$|, '/_\1') : logical_name}.#{options[:formats].first}.erb")
+ def find(name, prefixes = [], partial = false, keys = [], options = {})
+ partial_name = partial ? name.gsub(%r|/([^/]+)$|, '/_\1') : name
+ format = @formats.first.to_s
+ format += "+#{@variants.first}" if @variants.any?
+
+ FixtureTemplate.new("digestor/#{partial_name}.#{format}.erb")
+ end
+
+ def disable_cache(&block)
+ yield
end
end
@@ -88,13 +100,13 @@ class TemplateDigestorTest < ActionView::TestCase
end
def test_logging_of_missing_template
- assert_logged "Couldn't find template for digesting: messages/something_missing.html" do
+ assert_logged "Couldn't find template for digesting: messages/something_missing" do
digest("messages/show")
end
end
def test_logging_of_missing_template_ending_with_number
- assert_logged "Couldn't find template for digesting: messages/something_missing_1.html" do
+ assert_logged "Couldn't find template for digesting: messages/something_missing_1" do
digest("messages/show")
end
end
@@ -194,6 +206,13 @@ class TemplateDigestorTest < ActionView::TestCase
end
end
+ def test_variants
+ assert_digest_difference("messages/new", false, variants: [:iphone]) do
+ change_template("messages/new", :iphone)
+ change_template("messages/_header", :iphone)
+ end
+ end
+
def test_dependencies_via_options_results_in_different_digest
digest_plain = digest("comments/_comment")
digest_fridge = digest("comments/_comment", dependencies: ["fridge"])
@@ -214,6 +233,7 @@ class TemplateDigestorTest < ActionView::TestCase
assert_digest_difference("messages/edit", true) do
change_template("comments/_comment")
end
+ ensure
ActionView::Resolver.caching = resolver_before
end
@@ -242,6 +262,7 @@ class TemplateDigestorTest < ActionView::TestCase
ActionView::Resolver.caching = resolver_before
end
+
private
def assert_logged(message)
old_logger = ActionView::Base.logger
@@ -258,26 +279,33 @@ class TemplateDigestorTest < ActionView::TestCase
end
end
- def assert_digest_difference(template_name, persistent = false)
- previous_digest = digest(template_name)
+ def assert_digest_difference(template_name, persistent = false, options = {})
+ previous_digest = digest(template_name, options)
ActionView::Digestor.cache.clear unless persistent
yield
- assert previous_digest != digest(template_name), "digest didn't change"
+ assert previous_digest != digest(template_name, options), "digest didn't change"
ActionView::Digestor.cache.clear
end
- def digest(template_name, options={})
- ActionView::Digestor.digest(template_name, :html, finder, options)
+ def digest(template_name, options = {})
+ options = options.dup
+
+ finder.formats = [:html]
+ finder.variants = options.delete(:variants) || []
+
+ ActionView::Digestor.digest({ name: template_name, finder: finder }.merge(options))
end
def finder
@finder ||= FixtureFinder.new
end
- def change_template(template_name)
- File.open("digestor/#{template_name}.html.erb", "w") do |f|
+ def change_template(template_name, variant = nil)
+ variant = "+#{variant}" if variant.present?
+
+ File.open("digestor/#{template_name}.html#{variant}.erb", "w") do |f|
f.write "\nTHIS WAS CHANGED!"
end
end
diff --git a/actionview/test/template/erb_util_test.rb b/actionview/test/template/erb_util_test.rb
index 9bacbba908..3e72be31de 100644
--- a/actionview/test/template/erb_util_test.rb
+++ b/actionview/test/template/erb_util_test.rb
@@ -84,7 +84,7 @@ class ErbUtilTest < ActiveSupport::TestCase
end
def test_rest_in_ascii
- (0..127).to_a.map {|int| int.chr }.each do |chr|
+ (0..127).to_a.map(&:chr).each do |chr|
next if %('"&<>).include?(chr)
assert_equal chr, html_escape(chr)
end
@@ -92,6 +92,7 @@ class ErbUtilTest < ActiveSupport::TestCase
def test_html_escape_once
assert_equal '1 &lt;&gt;&amp;&quot;&#39; 2 &amp; 3', html_escape_once('1 <>&"\' 2 &amp; 3')
+ assert_equal " &#X27; &#x27; &#x03BB; &#X03bb; &quot; &#39; &lt; &gt; ", html_escape_once(" &#X27; &#x27; &#x03BB; &#X03bb; \" ' < > ")
end
def test_html_escape_once_returns_unsafe_strings_when_passed_unsafe_strings
diff --git a/actionview/test/template/form_collections_helper_test.rb b/actionview/test/template/form_collections_helper_test.rb
index 18632465db..b193d387c3 100644
--- a/actionview/test/template/form_collections_helper_test.rb
+++ b/actionview/test/template/form_collections_helper_test.rb
@@ -68,6 +68,23 @@ class FormCollectionsHelperTest < ActionView::TestCase
assert_no_select 'input[type=radio][value=false][disabled=disabled]'
end
+ test 'collection radio accepts multiple readonly items' do
+ collection = [[1, true], [0, false], [2, 'other']]
+ with_collection_radio_buttons :user, :active, collection, :last, :first, :readonly => [true, false]
+
+ assert_select 'input[type=radio][value=true][readonly=readonly]'
+ assert_select 'input[type=radio][value=false][readonly=readonly]'
+ assert_no_select 'input[type=radio][value=other][readonly=readonly]'
+ end
+
+ test 'collection radio accepts single readonly item' do
+ collection = [[1, true], [0, false]]
+ with_collection_radio_buttons :user, :active, collection, :last, :first, :readonly => true
+
+ assert_select 'input[type=radio][value=true][readonly=readonly]'
+ assert_no_select 'input[type=radio][value=false][readonly=readonly]'
+ end
+
test 'collection radio accepts html options as input' do
collection = [[1, true], [0, false]]
with_collection_radio_buttons :user, :active, collection, :last, :first, {}, :class => 'special-radio'
@@ -168,8 +185,8 @@ class FormCollectionsHelperTest < ActionView::TestCase
p.collection_radio_buttons :category_id, collection, :id, :name
end
- assert_select 'input#post_category_id_1[type=radio][value=1]'
- assert_select 'input#post_category_id_2[type=radio][value=2]'
+ assert_select 'input#post_category_id_1[type=radio][value="1"]'
+ assert_select 'input#post_category_id_2[type=radio][value="2"]'
assert_select 'label[for=post_category_id_1]', 'Category 1'
assert_select 'label[for=post_category_id_2]', 'Category 2'
@@ -186,22 +203,36 @@ class FormCollectionsHelperTest < ActionView::TestCase
collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')]
with_collection_check_boxes :user, :category_ids, collection, :id, :name
- assert_select 'input#user_category_ids_1[type=checkbox][value=1]'
- assert_select 'input#user_category_ids_2[type=checkbox][value=2]'
+ assert_select 'input#user_category_ids_1[type=checkbox][value="1"]'
+ assert_select 'input#user_category_ids_2[type=checkbox][value="2"]'
end
test 'collection check boxes generates only one hidden field for the entire collection, to ensure something will be sent back to the server when posting an empty collection' do
collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')]
with_collection_check_boxes :user, :category_ids, collection, :id, :name
- assert_select "input[type=hidden][name='user[category_ids][]'][value=]", :count => 1
+ assert_select "input[type=hidden][name='user[category_ids][]'][value='']", :count => 1
end
test 'collection check boxes generates a hidden field using the given :name in :html_options' do
collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')]
with_collection_check_boxes :user, :category_ids, collection, :id, :name, {}, {name: "user[other_category_ids][]"}
- assert_select "input[type=hidden][name='user[other_category_ids][]'][value=]", :count => 1
+ assert_select "input[type=hidden][name='user[other_category_ids][]'][value='']", :count => 1
+ end
+
+ test 'collection check boxes generates a hidden field with index if it was provided' do
+ collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')]
+ with_collection_check_boxes :user, :category_ids, collection, :id, :name, { index: 322 }
+
+ assert_select "input[type=hidden][name='user[322][category_ids][]'][value='']", count: 1
+ end
+
+ test 'collection check boxes does not generate a hidden field if include_hidden option is false' do
+ collection = [Category.new(1, 'Category 1'), Category.new(2, 'Category 2')]
+ with_collection_check_boxes :user, :category_ids, collection, :id, :name, include_hidden: false
+
+ assert_select "input[type=hidden][name='user[category_ids][]'][value='']", :count => 0
end
test 'collection check boxes accepts a collection and generate a series of checkboxes with labels for label method' do
@@ -229,8 +260,8 @@ class FormCollectionsHelperTest < ActionView::TestCase
collection = [[1, 'Category 1', {class: 'foo'}], [2, 'Category 2', {class: 'bar'}]]
with_collection_check_boxes :user, :active, collection, :first, :second
- assert_select 'input[type=checkbox][value=1].foo'
- assert_select 'input[type=checkbox][value=2].bar'
+ assert_select 'input[type=checkbox][value="1"].foo'
+ assert_select 'input[type=checkbox][value="2"].bar'
end
test 'collection check boxes sets the label class defined inside the block' do
@@ -255,27 +286,27 @@ class FormCollectionsHelperTest < ActionView::TestCase
collection = (1..3).map{|i| [i, "Category #{i}"] }
with_collection_check_boxes :user, :category_ids, collection, :first, :last, :checked => [1, 3]
- assert_select 'input[type=checkbox][value=1][checked=checked]'
- assert_select 'input[type=checkbox][value=3][checked=checked]'
- assert_no_select 'input[type=checkbox][value=2][checked=checked]'
+ assert_select 'input[type=checkbox][value="1"][checked=checked]'
+ assert_select 'input[type=checkbox][value="3"][checked=checked]'
+ assert_no_select 'input[type=checkbox][value="2"][checked=checked]'
end
test 'collection check boxes accepts selected string values as :checked option' do
collection = (1..3).map{|i| [i, "Category #{i}"] }
with_collection_check_boxes :user, :category_ids, collection, :first, :last, :checked => ['1', '3']
- assert_select 'input[type=checkbox][value=1][checked=checked]'
- assert_select 'input[type=checkbox][value=3][checked=checked]'
- assert_no_select 'input[type=checkbox][value=2][checked=checked]'
+ assert_select 'input[type=checkbox][value="1"][checked=checked]'
+ assert_select 'input[type=checkbox][value="3"][checked=checked]'
+ assert_no_select 'input[type=checkbox][value="2"][checked=checked]'
end
test 'collection check boxes accepts a single checked value' do
collection = (1..3).map{|i| [i, "Category #{i}"] }
with_collection_check_boxes :user, :category_ids, collection, :first, :last, :checked => 3
- assert_select 'input[type=checkbox][value=3][checked=checked]'
- assert_no_select 'input[type=checkbox][value=1][checked=checked]'
- assert_no_select 'input[type=checkbox][value=2][checked=checked]'
+ assert_select 'input[type=checkbox][value="3"][checked=checked]'
+ assert_no_select 'input[type=checkbox][value="1"][checked=checked]'
+ assert_no_select 'input[type=checkbox][value="2"][checked=checked]'
end
test 'collection check boxes accepts selected values as :checked option and override the model values' do
@@ -286,44 +317,71 @@ class FormCollectionsHelperTest < ActionView::TestCase
p.collection_check_boxes :category_ids, collection, :first, :last, :checked => [1, 3]
end
- assert_select 'input[type=checkbox][value=1][checked=checked]'
- assert_select 'input[type=checkbox][value=3][checked=checked]'
- assert_no_select 'input[type=checkbox][value=2][checked=checked]'
+ assert_select 'input[type=checkbox][value="1"][checked=checked]'
+ assert_select 'input[type=checkbox][value="3"][checked=checked]'
+ assert_no_select 'input[type=checkbox][value="2"][checked=checked]'
end
test 'collection check boxes accepts multiple disabled items' do
collection = (1..3).map{|i| [i, "Category #{i}"] }
with_collection_check_boxes :user, :category_ids, collection, :first, :last, :disabled => [1, 3]
- assert_select 'input[type=checkbox][value=1][disabled=disabled]'
- assert_select 'input[type=checkbox][value=3][disabled=disabled]'
- assert_no_select 'input[type=checkbox][value=2][disabled=disabled]'
+ assert_select 'input[type=checkbox][value="1"][disabled=disabled]'
+ assert_select 'input[type=checkbox][value="3"][disabled=disabled]'
+ assert_no_select 'input[type=checkbox][value="2"][disabled=disabled]'
end
test 'collection check boxes accepts single disabled item' do
collection = (1..3).map{|i| [i, "Category #{i}"] }
with_collection_check_boxes :user, :category_ids, collection, :first, :last, :disabled => 1
- assert_select 'input[type=checkbox][value=1][disabled=disabled]'
- assert_no_select 'input[type=checkbox][value=3][disabled=disabled]'
- assert_no_select 'input[type=checkbox][value=2][disabled=disabled]'
+ assert_select 'input[type=checkbox][value="1"][disabled=disabled]'
+ assert_no_select 'input[type=checkbox][value="3"][disabled=disabled]'
+ assert_no_select 'input[type=checkbox][value="2"][disabled=disabled]'
end
test 'collection check boxes accepts a proc to disabled items' do
collection = (1..3).map{|i| [i, "Category #{i}"] }
with_collection_check_boxes :user, :category_ids, collection, :first, :last, :disabled => proc { |i| i.first == 1 }
- assert_select 'input[type=checkbox][value=1][disabled=disabled]'
- assert_no_select 'input[type=checkbox][value=3][disabled=disabled]'
- assert_no_select 'input[type=checkbox][value=2][disabled=disabled]'
+ assert_select 'input[type=checkbox][value="1"][disabled=disabled]'
+ assert_no_select 'input[type=checkbox][value="3"][disabled=disabled]'
+ assert_no_select 'input[type=checkbox][value="2"][disabled=disabled]'
+ end
+
+ test 'collection check boxes accepts multiple readonly items' do
+ collection = (1..3).map{|i| [i, "Category #{i}"] }
+ with_collection_check_boxes :user, :category_ids, collection, :first, :last, :readonly => [1, 3]
+
+ assert_select 'input[type=checkbox][value="1"][readonly=readonly]'
+ assert_select 'input[type=checkbox][value="3"][readonly=readonly]'
+ assert_no_select 'input[type=checkbox][value="2"][readonly=readonly]'
+ end
+
+ test 'collection check boxes accepts single readonly item' do
+ collection = (1..3).map{|i| [i, "Category #{i}"] }
+ with_collection_check_boxes :user, :category_ids, collection, :first, :last, :readonly => 1
+
+ assert_select 'input[type=checkbox][value="1"][readonly=readonly]'
+ assert_no_select 'input[type=checkbox][value="3"][readonly=readonly]'
+ assert_no_select 'input[type=checkbox][value="2"][readonly=readonly]'
+ end
+
+ test 'collection check boxes accepts a proc to readonly items' do
+ collection = (1..3).map{|i| [i, "Category #{i}"] }
+ with_collection_check_boxes :user, :category_ids, collection, :first, :last, :readonly => proc { |i| i.first == 1 }
+
+ assert_select 'input[type=checkbox][value="1"][readonly=readonly]'
+ assert_no_select 'input[type=checkbox][value="3"][readonly=readonly]'
+ assert_no_select 'input[type=checkbox][value="2"][readonly=readonly]'
end
test 'collection check boxes accepts html options' do
collection = [[1, 'Category 1'], [2, 'Category 2']]
with_collection_check_boxes :user, :category_ids, collection, :first, :last, {}, :class => 'check'
- assert_select 'input.check[type=checkbox][value=1]'
- assert_select 'input.check[type=checkbox][value=2]'
+ assert_select 'input.check[type=checkbox][value="1"]'
+ assert_select 'input.check[type=checkbox][value="2"]'
end
test 'collection check boxes with fields for' do
@@ -332,8 +390,8 @@ class FormCollectionsHelperTest < ActionView::TestCase
p.collection_check_boxes :category_ids, collection, :id, :name
end
- assert_select 'input#post_category_ids_1[type=checkbox][value=1]'
- assert_select 'input#post_category_ids_2[type=checkbox][value=2]'
+ assert_select 'input#post_category_ids_1[type=checkbox][value="1"]'
+ assert_select 'input#post_category_ids_2[type=checkbox][value="2"]'
assert_select 'label[for=post_category_ids_1]', 'Category 1'
assert_select 'label[for=post_category_ids_2]', 'Category 2'
diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb
index fe82349265..fff1e1e572 100644
--- a/actionview/test/template/form_helper_test.rb
+++ b/actionview/test/template/form_helper_test.rb
@@ -10,15 +10,20 @@ class FormHelperTest < ActionView::TestCase
@output_buffer = super
end
- def setup
- super
+ teardown do
+ I18n.backend.reload!
+ end
+ setup do
# Create "label" locale for testing I18n label helpers
I18n.backend.store_translations 'label', {
activemodel: {
attributes: {
post: {
cost: "Total cost"
+ },
+ :"post/language" => {
+ spanish: "Espanol"
}
}
},
@@ -54,6 +59,35 @@ class FormHelperTest < ActionView::TestCase
}
}
+ I18n.backend.store_translations 'placeholder', {
+ activemodel: {
+ attributes: {
+ post: {
+ cost: "Total cost"
+ },
+ :"post/cost" => {
+ uk: "Pounds"
+ }
+ }
+ },
+ helpers: {
+ placeholder: {
+ post: {
+ title: "What is this about?",
+ written_on: {
+ spanish: "Escrito en"
+ },
+ comments: {
+ body: "Write body here"
+ }
+ },
+ tag: {
+ value: "Tag"
+ }
+ }
+ }
+ }
+
@post = Post.new
@comment = Comment.new
def @post.errors()
@@ -143,75 +177,74 @@ class FormHelperTest < ActionView::TestCase
end
def test_label_with_locales_strings
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_body">Write entire text here</label>', label("post", "body"))
- ensure
- I18n.locale = old_locale
+ with_locale :label do
+ assert_dom_equal('<label for="post_body">Write entire text here</label>', label("post", "body"))
+ end
end
def test_label_with_human_attribute_name
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_cost">Total cost</label>', label(:post, :cost))
- ensure
- I18n.locale = old_locale
+ with_locale :label do
+ assert_dom_equal('<label for="post_cost">Total cost</label>', label(:post, :cost))
+ end
+ end
+
+ def test_label_with_human_attribute_name_and_options
+ with_locale :label do
+ assert_dom_equal('<label for="post_language_spanish">Espanol</label>', label(:post, :language, value: "spanish"))
+ end
end
def test_label_with_locales_symbols
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_body">Write entire text here</label>', label(:post, :body))
- ensure
- I18n.locale = old_locale
+ with_locale :label do
+ assert_dom_equal('<label for="post_body">Write entire text here</label>', label(:post, :body))
+ end
end
def test_label_with_locales_and_options
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal(
- '<label for="post_body" class="post_body">Write entire text here</label>',
- label(:post, :body, class: "post_body")
- )
- ensure
- I18n.locale = old_locale
+ with_locale :label do
+ assert_dom_equal(
+ '<label for="post_body" class="post_body">Write entire text here</label>',
+ label(:post, :body, class: "post_body")
+ )
+ end
end
def test_label_with_locales_and_value
- old_locale, I18n.locale = I18n.locale, :label
- assert_dom_equal('<label for="post_color_red">Rojo</label>', label(:post, :color, value: "red"))
- ensure
- I18n.locale = old_locale
+ with_locale :label do
+ assert_dom_equal('<label for="post_color_red">Rojo</label>', label(:post, :color, value: "red"))
+ end
end
def test_label_with_locales_and_nested_attributes
- old_locale, I18n.locale = I18n.locale, :label
- form_for(@post, html: { id: 'create-post' }) do |f|
- f.fields_for(:comments) do |cf|
- concat cf.label(:body)
+ with_locale :label do
+ form_for(@post, html: { id: 'create-post' }) do |f|
+ f.fields_for(:comments) do |cf|
+ concat cf.label(:body)
+ end
end
- end
- expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
- '<label for="post_comments_attributes_0_body">Write body here</label>'
- end
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
+ '<label for="post_comments_attributes_0_body">Write body here</label>'
+ end
- assert_dom_equal expected, output_buffer
- ensure
- I18n.locale = old_locale
+ assert_dom_equal expected, output_buffer
+ end
end
def test_label_with_locales_fallback_and_nested_attributes
- old_locale, I18n.locale = I18n.locale, :label
- form_for(@post, html: { id: 'create-post' }) do |f|
- f.fields_for(:tags) do |cf|
- concat cf.label(:value)
+ with_locale :label do
+ form_for(@post, html: { id: 'create-post' }) do |f|
+ f.fields_for(:tags) do |cf|
+ concat cf.label(:value)
+ end
end
- end
- expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
- '<label for="post_tags_attributes_0_value">Tag</label>'
- end
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
+ '<label for="post_tags_attributes_0_value">Tag</label>'
+ end
- assert_dom_equal expected, output_buffer
- ensure
- I18n.locale = old_locale
+ assert_dom_equal expected, output_buffer
+ end
end
def test_label_with_for_attribute_as_symbol
@@ -272,6 +305,13 @@ class FormHelperTest < ActionView::TestCase
)
end
+ def test_label_with_block_and_html
+ assert_dom_equal(
+ '<label for="post_terms">Accept <a href="/terms">Terms</a>.</label>',
+ label(:post, :terms) { 'Accept <a href="/terms">Terms</a>.'.html_safe }
+ )
+ end
+
def test_label_with_block_and_options
assert_dom_equal(
'<label for="my_for">The title, please:</label>',
@@ -279,13 +319,90 @@ class FormHelperTest < ActionView::TestCase
)
end
+ def test_label_with_block_and_builder
+ with_locale :label do
+ assert_dom_equal(
+ '<label for="post_body"><b>Write entire text here</b></label>',
+ label(:post, :body) { |b| "<b>#{b.translation}</b>".html_safe }
+ )
+ end
+ end
+
def test_label_with_block_in_erb
- assert_equal(
+ assert_dom_equal(
%{<label for="post_message">\n Message\n <input id="post_message" name="post[message]" type="text" />\n</label>},
view.render("test/label_with_block")
)
end
+ def test_text_field_placeholder_without_locales
+ with_locale :placeholder do
+ assert_dom_equal('<input id="post_body" name="post[body]" placeholder="Body" type="text" value="Back to the hill and over it again!" />', text_field(:post, :body, placeholder: true))
+ end
+ end
+
+ def test_text_field_placeholder_with_locales
+ with_locale :placeholder do
+ assert_dom_equal('<input id="post_title" name="post[title]" placeholder="What is this about?" type="text" value="Hello World" />', text_field(:post, :title, placeholder: true))
+ end
+ end
+
+ def test_text_field_placeholder_with_human_attribute_name
+ with_locale :placeholder do
+ assert_dom_equal('<input id="post_cost" name="post[cost]" placeholder="Total cost" type="text" />', text_field(:post, :cost, placeholder: true))
+ end
+ end
+
+ def test_text_field_placeholder_with_string_value
+ with_locale :placeholder do
+ assert_dom_equal('<input id="post_cost" name="post[cost]" placeholder="HOW MUCH?" type="text" />', text_field(:post, :cost, placeholder: "HOW MUCH?"))
+ end
+ end
+
+ def test_text_field_placeholder_with_human_attribute_name_and_value
+ with_locale :placeholder do
+ assert_dom_equal('<input id="post_cost" name="post[cost]" placeholder="Pounds" type="text" />', text_field(:post, :cost, placeholder: :uk))
+ end
+ end
+
+ def test_text_field_placeholder_with_locales_and_value
+ with_locale :placeholder do
+ assert_dom_equal('<input id="post_written_on" name="post[written_on]" placeholder="Escrito en" type="text" value="2004-06-15" />', text_field(:post, :written_on, placeholder: :spanish))
+ end
+ end
+
+ def test_text_field_placeholder_with_locales_and_nested_attributes
+ with_locale :placeholder do
+ form_for(@post, html: { id: 'create-post' }) do |f|
+ f.fields_for(:comments) do |cf|
+ concat cf.text_field(:body, placeholder: true)
+ end
+ end
+
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
+ '<input id="post_comments_attributes_0_body" name="post[comments_attributes][0][body]" placeholder="Write body here" type="text" />'
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+ end
+
+ def test_text_field_placeholder_with_locales_fallback_and_nested_attributes
+ with_locale :placeholder do
+ form_for(@post, html: { id: 'create-post' }) do |f|
+ f.fields_for(:tags) do |cf|
+ concat cf.text_field(:value, placeholder: true)
+ end
+ end
+
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
+ '<input id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" placeholder="Tag" type="text" value="new tag" />'
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+ end
+
def test_text_field
assert_dom_equal(
'<input id="post_title" name="post[title]" type="text" value="Hello World" />',
@@ -352,22 +469,36 @@ class FormHelperTest < ActionView::TestCase
def test_text_field_doesnt_change_param_values
object_name = 'post[]'
expected = '<input id="post_123_title" name="post[123][title]" type="text" value="Hello World" />'
- assert_equal expected, text_field(object_name, "title")
- assert_equal object_name, "post[]"
+ assert_dom_equal expected, text_field(object_name, "title")
end
- def test_file_field_has_no_size
+ def test_file_field_does_generate_a_hidden_field
+ expected = '<input name="user[avatar]" type="hidden" value="" /><input id="user_avatar" name="user[avatar]" type="file" />'
+ assert_dom_equal expected, file_field("user", "avatar")
+ end
+
+ def test_file_field_does_not_generate_a_hidden_field_if_included_hidden_option_is_false
+ expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
+ assert_dom_equal expected, file_field("user", "avatar", include_hidden: false)
+ end
+
+ def test_file_field_does_not_generate_a_hidden_field_if_included_hidden_option_is_false_with_key_as_string
expected = '<input id="user_avatar" name="user[avatar]" type="file" />'
+ assert_dom_equal expected, file_field("user", "avatar", "include_hidden" => false)
+ end
+
+ def test_file_field_has_no_size
+ expected = '<input name="user[avatar]" type="hidden" value="" /><input id="user_avatar" name="user[avatar]" type="file" />'
assert_dom_equal expected, file_field("user", "avatar")
end
def test_file_field_with_multiple_behavior
- expected = '<input id="import_file" multiple="multiple" name="import[file][]" type="file" />'
+ expected = '<input name="import[file][]" type="hidden" value="" /><input id="import_file" multiple="multiple" name="import[file][]" type="file" />'
assert_dom_equal expected, file_field("import", "file", :multiple => true)
end
def test_file_field_with_multiple_behavior_and_explicit_name
- expected = '<input id="import_file" multiple="multiple" name="custom" type="file" />'
+ expected = '<input name="custom" type="hidden" value="" /><input id="import_file" multiple="multiple" name="custom" type="file" />'
assert_dom_equal expected, file_field("import", "file", :multiple => true, :name => "custom")
end
@@ -654,6 +785,92 @@ class FormHelperTest < ActionView::TestCase
)
end
+ def test_text_area_placeholder_without_locales
+ with_locale :placeholder do
+ assert_dom_equal(
+ %{<textarea id="post_body" name="post[body]" placeholder="Body">\nBack to the hill and over it again!</textarea>},
+ text_area(:post, :body, placeholder: true)
+ )
+ end
+ end
+
+ def test_text_area_placeholder_with_locales
+ with_locale :placeholder do
+ assert_dom_equal(
+ %{<textarea id="post_title" name="post[title]" placeholder="What is this about?">\nHello World</textarea>},
+ text_area(:post, :title, placeholder: true)
+ )
+ end
+ end
+
+ def test_text_area_placeholder_with_human_attribute_name
+ with_locale :placeholder do
+ assert_dom_equal(
+ %{<textarea id="post_cost" name="post[cost]" placeholder="Total cost">\n</textarea>},
+ text_area(:post, :cost, placeholder: true)
+ )
+ end
+ end
+
+ def test_text_area_placeholder_with_string_value
+ with_locale :placeholder do
+ assert_dom_equal(
+ %{<textarea id="post_cost" name="post[cost]" placeholder="HOW MUCH?">\n</textarea>},
+ text_area(:post, :cost, placeholder: "HOW MUCH?")
+ )
+ end
+ end
+
+ def test_text_area_placeholder_with_human_attribute_name_and_value
+ with_locale :placeholder do
+ assert_dom_equal(
+ %{<textarea id="post_cost" name="post[cost]" placeholder="Pounds">\n</textarea>},
+ text_area(:post, :cost, placeholder: :uk)
+ )
+ end
+ end
+
+ def test_text_area_placeholder_with_locales_and_value
+ with_locale :placeholder do
+ assert_dom_equal(
+ %{<textarea id="post_written_on" name="post[written_on]" placeholder="Escrito en">\n2004-06-15</textarea>},
+ text_area(:post, :written_on, placeholder: :spanish)
+ )
+ end
+ end
+
+ def test_text_area_placeholder_with_locales_and_nested_attributes
+ with_locale :placeholder do
+ form_for(@post, html: { id: 'create-post' }) do |f|
+ f.fields_for(:comments) do |cf|
+ concat cf.text_area(:body, placeholder: true)
+ end
+ end
+
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
+ %{<textarea id="post_comments_attributes_0_body" name="post[comments_attributes][0][body]" placeholder="Write body here">\n</textarea>}
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+ end
+
+ def test_text_area_placeholder_with_locales_fallback_and_nested_attributes
+ with_locale :placeholder do
+ form_for(@post, html: { id: 'create-post' }) do |f|
+ f.fields_for(:tags) do |cf|
+ concat cf.text_area(:value, placeholder: true)
+ end
+ end
+
+ expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch") do
+ %{<textarea id="post_tags_attributes_0_value" name="post[tags_attributes][0][value]" placeholder="Tag">\nnew tag</textarea>}
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+ end
+
def test_text_area
assert_dom_equal(
%{<textarea id="post_body" name="post[body]">\nBack to the hill and over it again!</textarea>},
@@ -683,6 +900,13 @@ class FormHelperTest < ActionView::TestCase
)
end
+ def test_text_area_with_value_before_type_cast
+ assert_dom_equal(
+ %{<textarea id="post_id" name="post[id]">\n123</textarea>},
+ text_area("post", "id")
+ )
+ end
+
def test_text_area_with_html_entities
@post.body = "The HTML Entity for & is &amp;"
assert_dom_equal(
@@ -719,6 +943,11 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal(expected, search_field("contact", "notes_query"))
end
+ def test_search_field_with_onsearch_value
+ expected = %{<input onsearch="true" type="search" name="contact[notes_query]" id="contact_notes_query" incremental="true" />}
+ assert_dom_equal(expected, search_field("contact", "notes_query", onsearch: true))
+ end
+
def test_telephone_field
expected = %{<input id="user_cell" name="user[cell]" type="tel" />}
assert_dom_equal(expected, telephone_field("user", "cell"))
@@ -765,6 +994,22 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal(expected, date_field("post", "written_on"))
end
+ def test_date_field_with_string_values_for_min_and_max
+ expected = %{<input id="post_written_on" max="2010-08-15" min="2000-06-15" name="post[written_on]" type="date" value="2004-06-15" />}
+ @post.written_on = DateTime.new(2004, 6, 15)
+ min_value = "2000-06-15"
+ max_value = "2010-08-15"
+ assert_dom_equal(expected, date_field("post", "written_on", min: min_value, max: max_value))
+ end
+
+ def test_date_field_with_invalid_string_values_for_min_and_max
+ expected = %{<input id="post_written_on" name="post[written_on]" type="date" value="2004-06-15" />}
+ @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
+ min_value = "foo"
+ max_value = "bar"
+ assert_dom_equal(expected, date_field("post", "written_on", min: min_value, max: max_value))
+ end
+
def test_time_field
expected = %{<input id="post_written_on" name="post[written_on]" type="time" value="00:00:00.000" />}
assert_dom_equal(expected, time_field("post", "written_on"))
@@ -800,6 +1045,22 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal(expected, time_field("post", "written_on"))
end
+ def test_time_field_with_string_values_for_min_and_max
+ expected = %{<input id="post_written_on" max="10:25:00.000" min="20:45:30.000" name="post[written_on]" type="time" value="01:02:03.000" />}
+ @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
+ min_value = "20:45:30.000"
+ max_value = "10:25:00.000"
+ assert_dom_equal(expected, time_field("post", "written_on", min: min_value, max: max_value))
+ end
+
+ def test_time_field_with_invalid_string_values_for_min_and_max
+ expected = %{<input id="post_written_on" name="post[written_on]" type="time" value="01:02:03.000" />}
+ @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
+ min_value = "foo"
+ max_value = "bar"
+ assert_dom_equal(expected, time_field("post", "written_on", min: min_value, max: max_value))
+ end
+
def test_datetime_field
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T00:00:00.000+0000" />}
assert_dom_equal(expected, datetime_field("post", "written_on"))
@@ -841,6 +1102,22 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal(expected, datetime_field("post", "written_on"))
end
+ def test_datetime_field_with_string_values_for_min_and_max
+ expected = %{<input id="post_written_on" max="2010-08-15T10:25:00.000+0000" min="2000-06-15T20:45:30.000+0000" name="post[written_on]" type="datetime" value="2004-06-15T01:02:03.000+0000" />}
+ @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
+ min_value = "2000-06-15T20:45:30.000+0000"
+ max_value = "2010-08-15T10:25:00.000+0000"
+ assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value))
+ end
+
+ def test_datetime_field_with_invalid_string_values_for_min_and_max
+ expected = %{<input id="post_written_on" name="post[written_on]" type="datetime" value="2004-06-15T01:02:03.000+0000" />}
+ @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
+ min_value = "foo"
+ max_value = "bar"
+ assert_dom_equal(expected, datetime_field("post", "written_on", min: min_value, max: max_value))
+ end
+
def test_datetime_local_field
expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T00:00:00" />}
assert_dom_equal(expected, datetime_local_field("post", "written_on"))
@@ -876,6 +1153,22 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal(expected, datetime_local_field("post", "written_on"))
end
+ def test_datetime_local_field_with_string_values_for_min_and_max
+ expected = %{<input id="post_written_on" max="2010-08-15T10:25:00" min="2000-06-15T20:45:30" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
+ @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
+ min_value = "2000-06-15T20:45:30"
+ max_value = "2010-08-15T10:25:00"
+ assert_dom_equal(expected, datetime_local_field("post", "written_on", min: min_value, max: max_value))
+ end
+
+ def test_datetime_local_field_with_invalid_string_values_for_min_and_max
+ expected = %{<input id="post_written_on" name="post[written_on]" type="datetime-local" value="2004-06-15T01:02:03" />}
+ @post.written_on = DateTime.new(2004, 6, 15, 1, 2, 3)
+ min_value = "foo"
+ max_value = "bar"
+ assert_dom_equal(expected, datetime_local_field("post", "written_on", min: min_value, max: max_value))
+ end
+
def test_month_field
expected = %{<input id="post_written_on" name="post[written_on]" type="month" value="2004-06" />}
assert_dom_equal(expected, month_field("post", "written_on"))
@@ -1427,7 +1720,7 @@ class FormHelperTest < ActionView::TestCase
expected = whole_form("/posts", "new_post", "new_post") do
"<input checked='checked' id='post_1_tag_ids_1' name='post[1][tag_ids][]' type='checkbox' value='1' />" +
"<label for='post_1_tag_ids_1'>Tag 1</label>" +
- "<input name='post[tag_ids][]' type='hidden' value='' />"
+ "<input name='post[1][tag_ids][]' type='hidden' value='' />"
end
assert_dom_equal expected, output_buffer
@@ -1441,7 +1734,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/posts/123", "create-post", "edit_post", method: "patch", multipart: true) do
- "<input name='post[file]' type='file' id='post_file' />"
+ "<input name='post[file]' type='hidden' value='' /><input name='post[file]' type='file' id='post_file' />"
end
assert_dom_equal expected, output_buffer
@@ -1457,7 +1750,7 @@ class FormHelperTest < ActionView::TestCase
end
expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch", multipart: true) do
- "<input name='post[comment][file]' type='file' id='post_comment_file' />"
+ "<input name='post[comment][file]' type='hidden' value='' /><input name='post[comment][file]' type='file' id='post_comment_file' />"
end
assert_dom_equal expected, output_buffer
@@ -1512,6 +1805,20 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_tags_do_not_call_private_properties_on_form_object
+ obj = Class.new do
+ private
+
+ def private_property
+ raise "This method should not be called."
+ end
+ end.new
+
+ form_for(obj, as: "other_name", url: '/', html: { id: "edit-other-name" }) do |f|
+ assert_raise(NoMethodError) { f.hidden_field(:private_property) }
+ end
+ end
+
def test_form_for_with_method_as_part_of_html_options
form_for(@post, url: '/', html: { id: 'create-post', method: :delete }) do |f|
concat f.text_field(:title)
@@ -1577,6 +1884,30 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_form_for_enforce_utf8_true
+ form_for(:post, enforce_utf8: true) do |f|
+ concat f.text_field(:title)
+ end
+
+ expected = whole_form("/", nil, nil, enforce_utf8: true) do
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
+ def test_form_for_enforce_utf8_false
+ form_for(:post, enforce_utf8: false) do |f|
+ concat f.text_field(:title)
+ end
+
+ expected = whole_form("/", nil, nil, enforce_utf8: false) do
+ "<input name='post[title]' type='text' id='post_title' value='Hello World' />"
+ end
+
+ assert_dom_equal expected, output_buffer
+ end
+
def test_form_for_with_remote_in_html
form_for(@post, url: '/', html: { remote: true, id: 'create-post', method: :patch }) do |f|
concat f.text_field(:title)
@@ -1811,69 +2142,61 @@ class FormHelperTest < ActionView::TestCase
end
def test_submit_with_object_as_new_record_and_locale_strings
- old_locale, I18n.locale = I18n.locale, :submit
+ with_locale :submit do
+ @post.persisted = false
+ @post.stubs(:to_key).returns(nil)
+ form_for(@post) do |f|
+ concat f.submit
+ end
- @post.persisted = false
- @post.stubs(:to_key).returns(nil)
- form_for(@post) do |f|
- concat f.submit
- end
+ expected = whole_form('/posts', 'new_post', 'new_post') do
+ "<input name='commit' type='submit' value='Create Post' />"
+ end
- expected = whole_form('/posts', 'new_post', 'new_post') do
- "<input name='commit' type='submit' value='Create Post' />"
+ assert_dom_equal expected, output_buffer
end
-
- assert_dom_equal expected, output_buffer
- ensure
- I18n.locale = old_locale
end
def test_submit_with_object_as_existing_record_and_locale_strings
- old_locale, I18n.locale = I18n.locale, :submit
+ with_locale :submit do
+ form_for(@post) do |f|
+ concat f.submit
+ end
- form_for(@post) do |f|
- concat f.submit
- end
+ expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
+ "<input name='commit' type='submit' value='Confirm Post changes' />"
+ end
- expected = whole_form('/posts/123', 'edit_post_123', 'edit_post', method: 'patch') do
- "<input name='commit' type='submit' value='Confirm Post changes' />"
+ assert_dom_equal expected, output_buffer
end
-
- assert_dom_equal expected, output_buffer
- ensure
- I18n.locale = old_locale
end
def test_submit_without_object_and_locale_strings
- old_locale, I18n.locale = I18n.locale, :submit
+ with_locale :submit do
+ form_for(:post) do |f|
+ concat f.submit class: "extra"
+ end
- form_for(:post) do |f|
- concat f.submit class: "extra"
- end
+ expected = whole_form do
+ "<input name='commit' class='extra' type='submit' value='Save changes' />"
+ end
- expected = whole_form do
- "<input name='commit' class='extra' type='submit' value='Save changes' />"
+ assert_dom_equal expected, output_buffer
end
-
- assert_dom_equal expected, output_buffer
- ensure
- I18n.locale = old_locale
end
def test_submit_with_object_and_nested_lookup
- old_locale, I18n.locale = I18n.locale, :submit
+ with_locale :submit do
+ form_for(@post, as: :another_post) do |f|
+ concat f.submit
+ end
- form_for(@post, as: :another_post) do |f|
- concat f.submit
- end
+ expected = whole_form('/posts/123', 'edit_another_post', 'edit_another_post', method: 'patch') do
+ "<input name='commit' type='submit' value='Update your Post' />"
+ end
- expected = whole_form('/posts/123', 'edit_another_post', 'edit_another_post', method: 'patch') do
- "<input name='commit' type='submit' value='Update your Post' />"
+ assert_dom_equal expected, output_buffer
end
-
- assert_dom_equal expected, output_buffer
- ensure
- I18n.locale = old_locale
end
def test_nested_fields_for
@@ -2405,6 +2728,18 @@ class FormHelperTest < ActionView::TestCase
assert_dom_equal expected, output_buffer
end
+ def test_nested_fields_label_translation_with_more_than_10_records
+ @post.comments = Array.new(11) { |id| Comment.new(id + 1) }
+
+ I18n.expects(:t).with('post.comments.body', default: [:"comment.body", ''], scope: "helpers.label").times(11).returns "Write body here"
+
+ form_for(@post) do |f|
+ f.fields_for(:comments) do |cf|
+ concat cf.label(:body)
+ end
+ end
+ end
+
def test_nested_fields_for_with_existing_records_on_a_supplied_nested_attributes_collection_different_from_record_one
comments = Array.new(2) { |id| Comment.new(id + 1) }
@post.comments = []
@@ -2918,7 +3253,7 @@ class FormHelperTest < ActionView::TestCase
def test_form_for_with_string_url_option
form_for(@post, url: 'http://www.otherdomain.com') do |f| end
- assert_equal whole_form("http://www.otherdomain.com", "edit_post_123", "edit_post", method: "patch"), output_buffer
+ assert_dom_equal whole_form("http://www.otherdomain.com", "edit_post_123", "edit_post", method: "patch"), output_buffer
end
def test_form_for_with_hash_url_option
@@ -2932,14 +3267,14 @@ class FormHelperTest < ActionView::TestCase
form_for(@post, url: @post) do |f| end
expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch")
- assert_equal expected, output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_existing_object
form_for(@post) do |f| end
expected = whole_form("/posts/123", "edit_post_123", "edit_post", method: "patch")
- assert_equal expected, output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_new_object
@@ -2950,7 +3285,7 @@ class FormHelperTest < ActionView::TestCase
form_for(post) do |f| end
expected = whole_form("/posts", "new_post", "new_post")
- assert_equal expected, output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_existing_object_in_list
@@ -2987,7 +3322,7 @@ class FormHelperTest < ActionView::TestCase
form_for(@post, url: "/super_posts") do |f| end
expected = whole_form("/super_posts", "edit_post_123", "edit_post", method: "patch")
- assert_equal expected, output_buffer
+ assert_dom_equal expected, output_buffer
end
def test_form_for_with_default_method_as_patch
@@ -3022,13 +3357,20 @@ class FormHelperTest < ActionView::TestCase
protected
- def hidden_fields(method = nil)
- txt = %{<div style="display:none">}
- txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
+ def hidden_fields(options = {})
+ method = options[:method]
+
+ if options.fetch(:enforce_utf8, true)
+ txt = %{<input name="utf8" type="hidden" value="&#x2713;" />}
+ else
+ txt = ''
+ end
+
if method && !%w(get post).include?(method.to_s)
txt << %{<input name="_method" type="hidden" value="#{method}" />}
end
- txt << %{</div>}
+
+ txt
end
def form_text(action = "/", id = nil, html_class = nil, remote = nil, multipart = nil, method = nil)
@@ -3046,10 +3388,17 @@ class FormHelperTest < ActionView::TestCase
method, remote, multipart = options.values_at(:method, :remote, :multipart)
- form_text(action, id, html_class, remote, multipart, method) + hidden_fields(method) + contents + "</form>"
+ form_text(action, id, html_class, remote, multipart, method) + hidden_fields(options.slice :method, :enforce_utf8) + contents + "</form>"
end
def protect_against_forgery?
false
end
+
+ def with_locale(testing_locale = :label)
+ old_locale, I18n.locale = I18n.locale, testing_locale
+ yield
+ ensure
+ I18n.locale = old_locale
+ end
end
diff --git a/actionview/test/template/form_options_helper_test.rb b/actionview/test/template/form_options_helper_test.rb
index 50e9d132a7..d25fa3706f 100644
--- a/actionview/test/template/form_options_helper_test.rb
+++ b/actionview/test/template/form_options_helper_test.rb
@@ -119,6 +119,26 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_array_options_for_select_with_custom_defined_selected
+ assert_dom_equal(
+ "<option selected=\"selected\" type=\"Coach\" value=\"1\">Richard Bandler</option>\n<option type=\"Coachee\" value=\"1\">Richard Bandler</option>",
+ options_for_select([
+ ['Richard Bandler', 1, { type: 'Coach', selected: 'selected' }],
+ ['Richard Bandler', 1, { type: 'Coachee' }]
+ ])
+ )
+ end
+
+ def test_array_options_for_select_with_custom_defined_disabled
+ assert_dom_equal(
+ "<option disabled=\"disabled\" type=\"Coach\" value=\"1\">Richard Bandler</option>\n<option type=\"Coachee\" value=\"1\">Richard Bandler</option>",
+ options_for_select([
+ ['Richard Bandler', 1, { type: 'Coach', disabled: 'disabled' }],
+ ['Richard Bandler', 1, { type: 'Coachee' }]
+ ])
+ )
+ end
+
def test_array_options_for_select_with_selection
assert_dom_equal(
"<option value=\"Denmark\">Denmark</option>\n<option value=\"&lt;USA&gt;\" selected=\"selected\">&lt;USA&gt;</option>\n<option value=\"Sweden\">Sweden</option>",
@@ -571,6 +591,19 @@ class FormOptionsHelperTest < ActionView::TestCase
)
end
+ def test_select_under_fields_for_with_block_without_options
+ @post = Post.new
+
+ output_buffer = fields_for :post, @post do |f|
+ concat(f.select(:category) {})
+ end
+
+ assert_dom_equal(
+ "<select id=\"post_category\" name=\"post[category]\"></select>",
+ output_buffer
+ )
+ end
+
def test_select_with_multiple_to_add_hidden_input
output_buffer = select(:post, :category, "", {}, :multiple => true)
assert_dom_equal(
@@ -813,7 +846,7 @@ class FormOptionsHelperTest < ActionView::TestCase
select("post", "category", %w( one two ), :selected => 'two', :prompt => true)
)
end
-
+
def test_select_with_disabled_array
@post = Post.new
@post.category = "<mus>"
diff --git a/actionview/test/template/form_tag_helper_test.rb b/actionview/test/template/form_tag_helper_test.rb
index 0d5831dc6f..84a581b107 100644
--- a/actionview/test/template/form_tag_helper_test.rb
+++ b/actionview/test/template/form_tag_helper_test.rb
@@ -14,12 +14,15 @@ class FormTagHelperTest < ActionView::TestCase
method = options[:method]
enforce_utf8 = options.fetch(:enforce_utf8, true)
- txt = %{<div style="display:none">}
- txt << %{<input name="utf8" type="hidden" value="&#x2713;" />} if enforce_utf8
- if method && !%w(get post).include?(method.to_s)
- txt << %{<input name="_method" type="hidden" value="#{method}" />}
+ ''.tap do |txt|
+ if enforce_utf8
+ txt << %{<input name="utf8" type="hidden" value="&#x2713;" />}
+ end
+
+ if method && !%w(get post).include?(method.to_s)
+ txt << %{<input name="_method" type="hidden" value="#{method}" />}
+ end
end
- txt << %{</div>}
end
def form_text(action = "http://www.example.com", options = {})
@@ -167,6 +170,13 @@ class FormTagHelperTest < ActionView::TestCase
assert_dom_equal expected, actual
end
+ def test_multiple_field_tags_with_same_options
+ options = {class: 'important'}
+ assert_dom_equal %(<input name="title" type="file" id="title" class="important"/>), file_field_tag("title", options)
+ assert_dom_equal %(<input type="password" name="title" id="title" value="Hello!" class="important" />), password_field_tag("title", "Hello!", options)
+ assert_dom_equal %(<input type="text" name="title" id="title" value="Hello!" class="important" />), text_field_tag("title", "Hello!", options)
+ end
+
def test_radio_button_tag
actual = radio_button_tag "people", "david"
expected = %(<input id="people_david" name="people" type="radio" value="david" />)
@@ -222,6 +232,18 @@ class FormTagHelperTest < ActionView::TestCase
assert_dom_equal expected, actual
end
+ def test_select_tag_with_include_blank_false
+ actual = select_tag "places", "<option>Home</option><option>Work</option><option>Pub</option>".html_safe, include_blank: false
+ expected = %(<select id="places" name="places"><option>Home</option><option>Work</option><option>Pub</option></select>)
+ assert_dom_equal expected, actual
+ end
+
+ def test_select_tag_with_include_blank_string
+ actual = select_tag "places", "<option>Home</option><option>Work</option><option>Pub</option>".html_safe, include_blank: 'Choose'
+ expected = %(<select id="places" name="places"><option value="">Choose</option><option>Home</option><option>Work</option><option>Pub</option></select>)
+ assert_dom_equal expected, actual
+ end
+
def test_select_tag_with_prompt
actual = select_tag "places", "<option>Home</option><option>Work</option><option>Pub</option>".html_safe, :prompt => "string"
expected = %(<select id="places" name="places"><option value="">string</option><option>Home</option><option>Work</option><option>Pub</option></select>)
@@ -476,6 +498,11 @@ class FormTagHelperTest < ActionView::TestCase
assert_dom_equal('<button name="temptation" type="button"><strong>Do not press me</strong></button>', output)
end
+ def test_button_tag_defaults_with_block_and_options
+ output = button_tag(:name => 'temptation', :value => 'within') { content_tag(:strong, 'Do not press me') }
+ assert_dom_equal('<button name="temptation" value="within" type="submit" ><strong>Do not press me</strong></button>', output)
+ end
+
def test_button_tag_with_confirmation
assert_dom_equal(
%(<button name="button" type="submit" data-confirm="Are you sure?">Save</button>),
@@ -624,6 +651,6 @@ class FormTagHelperTest < ActionView::TestCase
private
def root_elem(rendered_content)
- HTML::Document.new(rendered_content).root.children[0]
+ Nokogiri::HTML::DocumentFragment.parse(rendered_content).children.first # extract from nodeset
end
end
diff --git a/actionview/test/template/html-scanner/cdata_node_test.rb b/actionview/test/template/html-scanner/cdata_node_test.rb
deleted file mode 100644
index 9b58174641..0000000000
--- a/actionview/test/template/html-scanner/cdata_node_test.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-require 'abstract_unit'
-
-class CDATANodeTest < ActiveSupport::TestCase
- def setup
- @node = HTML::CDATA.new(nil, 0, 0, "<p>howdy</p>")
- end
-
- def test_to_s
- assert_equal "<![CDATA[<p>howdy</p>]]>", @node.to_s
- end
-
- def test_content
- assert_equal "<p>howdy</p>", @node.content
- end
-end
diff --git a/actionview/test/template/html-scanner/document_test.rb b/actionview/test/template/html-scanner/document_test.rb
deleted file mode 100644
index 17f045d549..0000000000
--- a/actionview/test/template/html-scanner/document_test.rb
+++ /dev/null
@@ -1,148 +0,0 @@
-require 'abstract_unit'
-
-class DocumentTest < ActiveSupport::TestCase
- def test_handle_doctype
- doc = nil
- assert_nothing_raised do
- doc = HTML::Document.new <<-HTML.strip
- <!DOCTYPE "blah" "blah" "blah">
- <html>
- </html>
- HTML
- end
- assert_equal 3, doc.root.children.length
- assert_equal %{<!DOCTYPE "blah" "blah" "blah">}, doc.root.children[0].content
- assert_match %r{\s+}m, doc.root.children[1].content
- assert_equal "html", doc.root.children[2].name
- end
-
- def test_find_img
- doc = HTML::Document.new <<-HTML.strip
- <html>
- <body>
- <p><img src="hello.gif"></p>
- </body>
- </html>
- HTML
- assert doc.find(:tag=>"img", :attributes=>{"src"=>"hello.gif"})
- end
-
- def test_find_all
- doc = HTML::Document.new <<-HTML.strip
- <html>
- <body>
- <p class="test"><img src="hello.gif"></p>
- <div class="foo">
- <p class="test">something</p>
- <p>here is <em class="test">more</em></p>
- </div>
- </body>
- </html>
- HTML
- all = doc.find_all :attributes => { :class => "test" }
- assert_equal 3, all.length
- assert_equal [ "p", "p", "em" ], all.map { |n| n.name }
- end
-
- def test_find_with_text
- doc = HTML::Document.new <<-HTML.strip
- <html>
- <body>
- <p>Some text</p>
- </body>
- </html>
- HTML
- assert doc.find(:content => "Some text")
- assert doc.find(:tag => "p", :child => { :content => "Some text" })
- assert doc.find(:tag => "p", :child => "Some text")
- assert doc.find(:tag => "p", :content => "Some text")
- end
-
- def test_parse_xml
- assert_nothing_raised { HTML::Document.new("<tags><tag/></tags>", true, true) }
- assert_nothing_raised { HTML::Document.new("<outer><link>something</link></outer>", true, true) }
- end
-
- def test_parse_document
- doc = HTML::Document.new(<<-HTML)
- <div>
- <h2>blah</h2>
- <table>
- </table>
- </div>
- HTML
- assert_not_nil doc.find(:tag => "div", :children => { :count => 1, :only => { :tag => "table" } })
- end
-
- def test_tag_nesting_nothing_to_s
- doc = HTML::Document.new("<tag></tag>")
- assert_equal "<tag></tag>", doc.root.to_s
- end
-
- def test_tag_nesting_space_to_s
- doc = HTML::Document.new("<tag> </tag>")
- assert_equal "<tag> </tag>", doc.root.to_s
- end
-
- def test_tag_nesting_text_to_s
- doc = HTML::Document.new("<tag>text</tag>")
- assert_equal "<tag>text</tag>", doc.root.to_s
- end
-
- def test_tag_nesting_tag_to_s
- doc = HTML::Document.new("<tag><nested /></tag>")
- assert_equal "<tag><nested /></tag>", doc.root.to_s
- end
-
- def test_parse_cdata
- doc = HTML::Document.new(<<-HTML)
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
- <head>
- <title><![CDATA[<br>]]></title>
- </head>
- <body>
- <p>this document has &lt;br&gt; for a title</p>
- </body>
-</html>
-HTML
-
- assert_nil doc.find(:tag => "title", :descendant => { :tag => "br" })
- assert doc.find(:tag => "title", :child => "<br>")
- end
-
- def test_find_empty_tag
- doc = HTML::Document.new("<div id='map'></div>")
- assert_nil doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /./)
- assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /\A\Z/)
- assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => /^$/)
- assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => "")
- assert doc.find(:tag => "div", :attributes => { :id => "map" }, :content => nil)
- end
-
- def test_parse_invalid_document
- assert_nothing_raised do
- HTML::Document.new("<html>
- <table>
- <tr>
- <td style=\"color: #FFFFFF; height: 17px; onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" style=\"cursor:pointer; height: 17px;\"; nowrap onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" onmouseout=\"this.bgColor='#0066cc'; this.style.color='#FFFFFF'\" onmouseover=\"this.bgColor='#ffffff'; this.style.color='#0033cc'\">About Us</td>
- </tr>
- </table>
- </html>")
- end
- end
-
- def test_invalid_document_raises_exception_when_strict
- assert_raise RuntimeError do
- HTML::Document.new("<html>
- <table>
- <tr>
- <td style=\"color: #FFFFFF; height: 17px; onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" style=\"cursor:pointer; height: 17px;\"; nowrap onclick=\"window.location.href='http://www.rmeinc.com/about_rme.aspx'\" onmouseout=\"this.bgColor='#0066cc'; this.style.color='#FFFFFF'\" onmouseover=\"this.bgColor='#ffffff'; this.style.color='#0033cc'\">About Us</td>
- </tr>
- </table>
- </html>", true)
- end
- end
-
-end
diff --git a/actionview/test/template/html-scanner/node_test.rb b/actionview/test/template/html-scanner/node_test.rb
deleted file mode 100644
index 5b5d092036..0000000000
--- a/actionview/test/template/html-scanner/node_test.rb
+++ /dev/null
@@ -1,89 +0,0 @@
-require 'abstract_unit'
-
-class NodeTest < ActiveSupport::TestCase
-
- class MockNode
- def initialize(matched, value)
- @matched = matched
- @value = value
- end
-
- def find(conditions)
- @matched && self
- end
-
- def to_s
- @value.to_s
- end
- end
-
- def setup
- @node = HTML::Node.new("parent")
- @node.children.concat [MockNode.new(false,1), MockNode.new(true,"two"), MockNode.new(false,:three)]
- end
-
- def test_match
- assert !@node.match("foo")
- end
-
- def test_tag
- assert !@node.tag?
- end
-
- def test_to_s
- assert_equal "1twothree", @node.to_s
- end
-
- def test_find
- assert_equal "two", @node.find('blah').to_s
- end
-
- def test_parse_strict
- s = "<b foo='hello'' bar='baz'>"
- assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) }
- end
-
- def test_parse_relaxed
- s = "<b foo='hello'' bar='baz'>"
- node = nil
- assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
- assert node.attributes.has_key?("foo")
- assert !node.attributes.has_key?("bar")
- end
-
- def test_to_s_with_boolean_attrs
- s = "<b foo bar>"
- node = HTML::Node.parse(nil,0,0,s)
- assert node.attributes.has_key?("foo")
- assert node.attributes.has_key?("bar")
- assert "<b foo bar>", node.to_s
- end
-
- def test_parse_with_unclosed_tag
- s = "<span onmouseover='bang'"
- node = nil
- assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
- assert node.attributes.has_key?("onmouseover")
- end
-
- def test_parse_with_valid_cdata_section
- s = "<![CDATA[<span>contents</span>]]>"
- node = nil
- assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
- assert_kind_of HTML::CDATA, node
- assert_equal '<span>contents</span>', node.content
- end
-
- def test_parse_strict_with_unterminated_cdata_section
- s = "<![CDATA[neverending..."
- assert_raise(RuntimeError) { HTML::Node.parse(nil,0,0,s) }
- end
-
- def test_parse_relaxed_with_unterminated_cdata_section
- s = "<![CDATA[neverending..."
- node = nil
- assert_nothing_raised { node = HTML::Node.parse(nil,0,0,s,false) }
- assert_kind_of HTML::CDATA, node
- assert_equal 'neverending...', node.content
- end
-end
diff --git a/actionview/test/template/html-scanner/sanitizer_test.rb b/actionview/test/template/html-scanner/sanitizer_test.rb
deleted file mode 100644
index b1c1b83807..0000000000
--- a/actionview/test/template/html-scanner/sanitizer_test.rb
+++ /dev/null
@@ -1,330 +0,0 @@
-require 'abstract_unit'
-
-class SanitizerTest < ActionController::TestCase
- def setup
- @sanitizer = nil # used by assert_sanitizer
- end
-
- def test_strip_tags_with_quote
- sanitizer = HTML::FullSanitizer.new
- string = '<" <img src="trollface.gif" onload="alert(1)"> hi'
-
- assert_equal ' hi', sanitizer.sanitize(string)
- end
-
- def test_strip_tags
- sanitizer = HTML::FullSanitizer.new
- assert_equal("<<<bad html", sanitizer.sanitize("<<<bad html"))
- assert_equal("<<", sanitizer.sanitize("<<<bad html>"))
- assert_equal("Dont touch me", sanitizer.sanitize("Dont touch me"))
- assert_equal("This is a test.", sanitizer.sanitize("<p>This <u>is<u> a <a href='test.html'><strong>test</strong></a>.</p>"))
- assert_equal("Weirdos", sanitizer.sanitize("Wei<<a>a onclick='alert(document.cookie);'</a>/>rdos"))
- assert_equal("This is a test.", sanitizer.sanitize("This is a test."))
- assert_equal(
- %{This is a test.\n\n\nIt no longer contains any HTML.\n}, sanitizer.sanitize(
- %{<title>This is <b>a <a href="" target="_blank">test</a></b>.</title>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n}))
- assert_equal "This has a here.", sanitizer.sanitize("This has a <!-- comment --> here.")
- assert_equal "This has a here.", sanitizer.sanitize("This has a <![CDATA[<section>]]> here.")
- assert_equal "This has an unclosed ", sanitizer.sanitize("This has an unclosed <![CDATA[<section>]] here...")
- [nil, '', ' '].each { |blank| assert_equal blank, sanitizer.sanitize(blank) }
- assert_nothing_raised { sanitizer.sanitize("This is a frozen string with no tags".freeze) }
- end
-
- def test_strip_links
- sanitizer = HTML::LinkSanitizer.new
- assert_equal "Dont touch me", sanitizer.sanitize("Dont touch me")
- assert_equal "on my mind\nall day long", sanitizer.sanitize("<a href='almost'>on my mind</a>\n<A href='almost'>all day long</A>")
- assert_equal "0wn3d", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'><a href='http://www.rubyonrails.com/' onlclick='steal()'>0wn3d</a></a>")
- assert_equal "Magic", sanitizer.sanitize("<a href='http://www.rubyonrails.com/'>Mag<a href='http://www.ruby-lang.org/'>ic")
- assert_equal "FrrFox", sanitizer.sanitize("<href onlclick='steal()'>FrrFox</a></href>")
- assert_equal "My mind\nall <b>day</b> long", sanitizer.sanitize("<a href='almost'>My mind</a>\n<A href='almost'>all <b>day</b> long</A>")
- assert_equal "all <b>day</b> long", sanitizer.sanitize("<<a>a href='hello'>all <b>day</b> long<</A>/a>")
-
- assert_equal "<a<a", sanitizer.sanitize("<a<a")
- end
-
- def test_sanitize_form
- assert_sanitized "<form action=\"/foo/bar\" method=\"post\"><input></form>", ''
- end
-
- def test_sanitize_plaintext
- raw = "<plaintext><span>foo</span></plaintext>"
- assert_sanitized raw, "<span>foo</span>"
- end
-
- def test_sanitize_script
- assert_sanitized "a b c<script language=\"Javascript\">blah blah blah</script>d e f", "a b cd e f"
- end
-
- def test_sanitize_js_handlers
- raw = %{onthis="do that" <a href="#" onclick="hello" name="foo" onbogus="remove me">hello</a>}
- assert_sanitized raw, %{onthis="do that" <a name="foo" href="#">hello</a>}
- end
-
- def test_sanitize_javascript_href
- raw = %{href="javascript:bang" <a href="javascript:bang" name="hello">foo</a>, <span href="javascript:bang">bar</span>}
- assert_sanitized raw, %{href="javascript:bang" <a name="hello">foo</a>, <span>bar</span>}
- end
-
- def test_sanitize_image_src
- raw = %{src="javascript:bang" <img src="javascript:bang" width="5">foo</img>, <span src="javascript:bang">bar</span>}
- assert_sanitized raw, %{src="javascript:bang" <img width="5">foo</img>, <span>bar</span>}
- end
-
- HTML::WhiteListSanitizer.allowed_tags.each do |tag_name|
- define_method "test_should_allow_#{tag_name}_tag" do
- assert_sanitized "start <#{tag_name} title=\"1\" onclick=\"foo\">foo <bad>bar</bad> baz</#{tag_name}> end", %(start <#{tag_name} title="1">foo bar baz</#{tag_name}> end)
- end
- end
-
- def test_should_allow_anchors
- assert_sanitized %(<a href="foo" onclick="bar"><script>baz</script></a>), %(<a href="foo"></a>)
- end
-
- # RFC 3986, sec 4.2
- def test_allow_colons_in_path_component
- assert_sanitized("<a href=\"./this:that\">foo</a>")
- end
-
- %w(src width height alt).each do |img_attr|
- define_method "test_should_allow_image_#{img_attr}_attribute" do
- assert_sanitized %(<img #{img_attr}="foo" onclick="bar" />), %(<img #{img_attr}="foo" />)
- end
- end
-
- def test_should_handle_non_html
- assert_sanitized 'abc'
- end
-
- def test_should_handle_blank_text
- assert_sanitized nil
- assert_sanitized ''
- end
-
- def test_should_allow_custom_tags
- text = "<u>foo</u>"
- sanitizer = HTML::WhiteListSanitizer.new
- assert_equal(text, sanitizer.sanitize(text, :tags => %w(u)))
- end
-
- def test_should_allow_only_custom_tags
- text = "<u>foo</u> with <i>bar</i>"
- sanitizer = HTML::WhiteListSanitizer.new
- assert_equal("<u>foo</u> with bar", sanitizer.sanitize(text, :tags => %w(u)))
- end
-
- def test_should_allow_custom_tags_with_attributes
- text = %(<blockquote cite="http://example.com/">foo</blockquote>)
- sanitizer = HTML::WhiteListSanitizer.new
- assert_equal(text, sanitizer.sanitize(text))
- end
-
- def test_should_allow_custom_tags_with_custom_attributes
- text = %(<blockquote foo="bar">Lorem ipsum</blockquote>)
- sanitizer = HTML::WhiteListSanitizer.new
- assert_equal(text, sanitizer.sanitize(text, :attributes => ['foo']))
- end
-
- def test_should_raise_argument_error_if_tags_is_not_enumerable
- sanitizer = HTML::WhiteListSanitizer.new
- e = assert_raise(ArgumentError) do
- sanitizer.sanitize('', :tags => 'foo')
- end
-
- assert_equal "You should pass :tags as an Enumerable", e.message
- end
-
- def test_should_raise_argument_error_if_attributes_is_not_enumerable
- sanitizer = HTML::WhiteListSanitizer.new
- e = assert_raise(ArgumentError) do
- sanitizer.sanitize('', :attributes => 'foo')
- end
-
- assert_equal "You should pass :attributes as an Enumerable", e.message
- end
-
- [%w(img src), %w(a href)].each do |(tag, attr)|
- define_method "test_should_strip_#{attr}_attribute_in_#{tag}_with_bad_protocols" do
- assert_sanitized %(<#{tag} #{attr}="javascript:bang" title="1">boo</#{tag}>), %(<#{tag} title="1">boo</#{tag}>)
- end
- end
-
- def test_should_flag_bad_protocols
- sanitizer = HTML::WhiteListSanitizer.new
- %w(about chrome data disk hcp help javascript livescript lynxcgi lynxexec ms-help ms-its mhtml mocha opera res resource shell vbscript view-source vnd.ms.radio wysiwyg).each do |proto|
- assert sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://bad")
- end
- end
-
- def test_should_accept_good_protocols_ignoring_case
- sanitizer = HTML::WhiteListSanitizer.new
- HTML::WhiteListSanitizer.allowed_protocols.each do |proto|
- assert !sanitizer.send(:contains_bad_protocols?, 'src', "#{proto.capitalize}://good")
- end
- end
-
- def test_should_accept_good_protocols_ignoring_space
- sanitizer = HTML::WhiteListSanitizer.new
- HTML::WhiteListSanitizer.allowed_protocols.each do |proto|
- assert !sanitizer.send(:contains_bad_protocols?, 'src', " #{proto}://good")
- end
- end
-
- def test_should_accept_good_protocols
- sanitizer = HTML::WhiteListSanitizer.new
- HTML::WhiteListSanitizer.allowed_protocols.each do |proto|
- assert !sanitizer.send(:contains_bad_protocols?, 'src', "#{proto}://good")
- end
- end
-
- def test_should_reject_hex_codes_in_protocol
- assert_sanitized %(<a href="&#37;6A&#37;61&#37;76&#37;61&#37;73&#37;63&#37;72&#37;69&#37;70&#37;74&#37;3A&#37;61&#37;6C&#37;65&#37;72&#37;74&#37;28&#37;22&#37;58&#37;53&#37;53&#37;22&#37;29">1</a>), "<a>1</a>"
- assert @sanitizer.send(:contains_bad_protocols?, 'src', "%6A%61%76%61%73%63%72%69%70%74%3A%61%6C%65%72%74%28%22%58%53%53%22%29")
- end
-
- def test_should_block_script_tag
- assert_sanitized %(<SCRIPT\nSRC=http://ha.ckers.org/xss.js></SCRIPT>), ""
- end
-
- [%(<IMG SRC="javascript:alert('XSS');">),
- %(<IMG SRC=javascript:alert('XSS')>),
- %(<IMG SRC=JaVaScRiPt:alert('XSS')>),
- %(<IMG """><SCRIPT>alert("XSS")</SCRIPT>">),
- %(<IMG SRC=javascript:alert(&quot;XSS&quot;)>),
- %(<IMG SRC=javascript:alert(String.fromCharCode(88,83,83))>),
- %(<IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114;&#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114;&#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;>),
- %(<IMG SRC=&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041>),
- %(<IMG SRC=&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>),
- %(<IMG SRC="jav\tascript:alert('XSS');">),
- %(<IMG SRC="jav&#x09;ascript:alert('XSS');">),
- %(<IMG SRC="jav&#x0A;ascript:alert('XSS');">),
- %(<IMG SRC="jav&#x0D;ascript:alert('XSS');">),
- %(<IMG SRC=" &#14; javascript:alert('XSS');">),
- %(<IMG SRC="javascript&#x3a;alert('XSS');">),
- %(<IMG SRC=`javascript:alert("RSnake says, 'XSS'")`>)].each_with_index do |img_hack, i|
- define_method "test_should_not_fall_for_xss_image_hack_#{i+1}" do
- assert_sanitized img_hack, "<img>"
- end
- end
-
- def test_should_sanitize_tag_broken_up_by_null
- assert_sanitized %(<SCR\0IPT>alert(\"XSS\")</SCR\0IPT>), "alert(\"XSS\")"
- end
-
- def test_should_sanitize_invalid_script_tag
- assert_sanitized %(<SCRIPT/XSS SRC="http://ha.ckers.org/xss.js"></SCRIPT>), ""
- end
-
- def test_should_sanitize_script_tag_with_multiple_open_brackets
- assert_sanitized %(<<SCRIPT>alert("XSS");//<</SCRIPT>), "&lt;"
- assert_sanitized %(<iframe src=http://ha.ckers.org/scriptlet.html\n<a), %(&lt;a)
- end
-
- def test_should_sanitize_unclosed_script
- assert_sanitized %(<SCRIPT SRC=http://ha.ckers.org/xss.js?<B>), "<b>"
- end
-
- def test_should_sanitize_half_open_scripts
- assert_sanitized %(<IMG SRC="javascript:alert('XSS')"), "<img>"
- end
-
- def test_should_not_fall_for_ridiculous_hack
- img_hack = %(<IMG\nSRC\n=\n"\nj\na\nv\na\ns\nc\nr\ni\np\nt\n:\na\nl\ne\nr\nt\n(\n'\nX\nS\nS\n'\n)\n"\n>)
- assert_sanitized img_hack, "<img>"
- end
-
- def test_should_sanitize_attributes
- assert_sanitized %(<SPAN title="'><script>alert()</script>">blah</SPAN>), %(<span title="#{CGI.escapeHTML "'><script>alert()</script>"}">blah</span>)
- end
-
- def test_should_sanitize_illegal_style_properties
- raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;)
- expected = %(display: block; width: 100%; height: 100%; background-color: black; background-image: ; background-x: center; background-y: center;)
- assert_equal expected, sanitize_css(raw)
- end
-
- def test_should_sanitize_with_trailing_space
- raw = "display:block; "
- expected = "display: block;"
- assert_equal expected, sanitize_css(raw)
- end
-
- def test_should_sanitize_xul_style_attributes
- raw = %(-moz-binding:url('http://ha.ckers.org/xssmoz.xml#xss'))
- assert_equal '', sanitize_css(raw)
- end
-
- def test_should_sanitize_invalid_tag_names
- assert_sanitized(%(a b c<script/XSS src="http://ha.ckers.org/xss.js"></script>d e f), "a b cd e f")
- end
-
- def test_should_sanitize_non_alpha_and_non_digit_characters_in_tags
- assert_sanitized('<a onclick!#$%&()*~+-_.,:;?@[/|\]^`=alert("XSS")>foo</a>', "<a>foo</a>")
- end
-
- def test_should_sanitize_invalid_tag_names_in_single_tags
- assert_sanitized('<img/src="http://ha.ckers.org/xss.js"/>', "<img />")
- end
-
- def test_should_sanitize_img_dynsrc_lowsrc
- assert_sanitized(%(<img lowsrc="javascript:alert('XSS')" />), "<img />")
- end
-
- def test_should_sanitize_div_background_image_unicode_encoded
- raw = %(background-image:\0075\0072\006C\0028'\006a\0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061\006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029)
- assert_equal '', sanitize_css(raw)
- end
-
- def test_should_sanitize_div_style_expression
- raw = %(width: expression(alert('XSS'));)
- assert_equal '', sanitize_css(raw)
- end
-
- def test_should_sanitize_across_newlines
- raw = %(\nwidth:\nexpression(alert('XSS'));\n)
- assert_equal '', sanitize_css(raw)
- end
-
- def test_should_sanitize_img_vbscript
- assert_sanitized %(<img src='vbscript:msgbox("XSS")' />), '<img />'
- end
-
- def test_should_sanitize_cdata_section
- assert_sanitized "<![CDATA[<span>section</span>]]>", "&lt;![CDATA[&lt;span>section&lt;/span>]]>"
- end
-
- def test_should_sanitize_unterminated_cdata_section
- assert_sanitized "<![CDATA[<span>neverending...", "&lt;![CDATA[&lt;span>neverending...]]>"
- end
-
- def test_should_not_mangle_urls_with_ampersand
- assert_sanitized %{<a href=\"http://www.domain.com?var1=1&amp;var2=2\">my link</a>}
- end
-
- def test_should_sanitize_neverending_attribute
- assert_sanitized "<span class=\"\\", "<span class=\"\\\">"
- end
-
- def test_x03a
- assert_sanitized %(<a href="javascript&#x3a;alert('XSS');">), "<a>"
- assert_sanitized %(<a href="javascript&#x003a;alert('XSS');">), "<a>"
- assert_sanitized %(<a href="http&#x3a;//legit">), %(<a href="http://legit">)
- assert_sanitized %(<a href="javascript&#x3A;alert('XSS');">), "<a>"
- assert_sanitized %(<a href="javascript&#x003A;alert('XSS');">), "<a>"
- assert_sanitized %(<a href="http&#x3A;//legit">), %(<a href="http://legit">)
- end
-
-protected
- def assert_sanitized(input, expected = nil)
- @sanitizer ||= HTML::WhiteListSanitizer.new
- if input
- assert_dom_equal expected || input, @sanitizer.sanitize(input)
- else
- assert_nil @sanitizer.sanitize(input)
- end
- end
-
- def sanitize_css(input)
- (@sanitizer ||= HTML::WhiteListSanitizer.new).sanitize_css(input)
- end
-end
diff --git a/actionview/test/template/html-scanner/tag_node_test.rb b/actionview/test/template/html-scanner/tag_node_test.rb
deleted file mode 100644
index a29d2d43d7..0000000000
--- a/actionview/test/template/html-scanner/tag_node_test.rb
+++ /dev/null
@@ -1,243 +0,0 @@
-require 'abstract_unit'
-
-class TagNodeTest < ActiveSupport::TestCase
- def test_open_without_attributes
- node = tag("<tag>")
- assert_equal "tag", node.name
- assert_equal Hash.new, node.attributes
- assert_nil node.closing
- end
-
- def test_open_with_attributes
- node = tag("<TAG1 foo=hey_ho x:bar=\"blah blah\" BAZ='blah blah blah' >")
- assert_equal "tag1", node.name
- assert_equal "hey_ho", node["foo"]
- assert_equal "blah blah", node["x:bar"]
- assert_equal "blah blah blah", node["baz"]
- end
-
- def test_self_closing_without_attributes
- node = tag("<tag/>")
- assert_equal "tag", node.name
- assert_equal Hash.new, node.attributes
- assert_equal :self, node.closing
- end
-
- def test_self_closing_with_attributes
- node = tag("<tag a=b/>")
- assert_equal "tag", node.name
- assert_equal( { "a" => "b" }, node.attributes )
- assert_equal :self, node.closing
- end
-
- def test_closing_without_attributes
- node = tag("</tag>")
- assert_equal "tag", node.name
- assert_nil node.attributes
- assert_equal :close, node.closing
- end
-
- def test_bracket_op_when_no_attributes
- node = tag("</tag>")
- assert_nil node["foo"]
- end
-
- def test_bracket_op_when_attributes
- node = tag("<tag a=b/>")
- assert_equal "b", node["a"]
- end
-
- def test_attributes_with_escaped_quotes
- node = tag("<tag a='b\\'c' b=\"bob \\\"float\\\"\">")
- assert_equal "b\\'c", node["a"]
- assert_equal "bob \\\"float\\\"", node["b"]
- end
-
- def test_to_s
- node = tag("<a b=c d='f' g=\"h 'i'\" />")
- node = node.to_s
- assert node.include?('a')
- assert node.include?('b="c"')
- assert node.include?('d="f"')
- assert node.include?('g="h')
- assert node.include?('i')
- end
-
- def test_tag
- assert tag("<tag>").tag?
- end
-
- def test_match_tag_as_string
- assert tag("<tag>").match(:tag => "tag")
- assert !tag("<tag>").match(:tag => "b")
- end
-
- def test_match_tag_as_regexp
- assert tag("<tag>").match(:tag => /t.g/)
- assert !tag("<tag>").match(:tag => /t[bqs]g/)
- end
-
- def test_match_attributes_as_string
- t = tag("<tag a=something b=else />")
- assert t.match(:attributes => {"a" => "something"})
- assert t.match(:attributes => {"b" => "else"})
- end
-
- def test_match_attributes_as_regexp
- t = tag("<tag a=something b=else />")
- assert t.match(:attributes => {"a" => /^something$/})
- assert t.match(:attributes => {"b" => /e.*e/})
- assert t.match(:attributes => {"a" => /me..i/, "b" => /.ls.$/})
- end
-
- def test_match_attributes_as_number
- t = tag("<tag a=15 b=3.1415 />")
- assert t.match(:attributes => {"a" => 15})
- assert t.match(:attributes => {"b" => 3.1415})
- assert t.match(:attributes => {"a" => 15, "b" => 3.1415})
- end
-
- def test_match_attributes_exist
- t = tag("<tag a=15 b=3.1415 />")
- assert t.match(:attributes => {"a" => true})
- assert t.match(:attributes => {"b" => true})
- assert t.match(:attributes => {"a" => true, "b" => true})
- end
-
- def test_match_attributes_not_exist
- t = tag("<tag a=15 b=3.1415 />")
- assert t.match(:attributes => {"c" => false})
- assert t.match(:attributes => {"c" => nil})
- assert t.match(:attributes => {"a" => true, "c" => false})
- end
-
- def test_match_parent_success
- t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>"))
- assert t.match(:parent => {:tag => "foo", :attributes => {"k" => /v.l/, "j" => false}})
- end
-
- def test_match_parent_fail
- t = tag("<tag a=15 b='hello'>", tag("<foo k='value'>"))
- assert !t.match(:parent => {:tag => /kafka/})
- end
-
- def test_match_child_success
- t = tag("<tag x:k='something'>")
- tag("<child v=john a=kelly>", t)
- tag("<sib m=vaughn v=james>", t)
- assert t.match(:child => { :tag => "sib", :attributes => {"v" => /j/}})
- assert t.match(:child => { :attributes => {"a" => "kelly"}})
- end
-
- def test_match_child_fail
- t = tag("<tag x:k='something'>")
- tag("<child v=john a=kelly>", t)
- tag("<sib m=vaughn v=james>", t)
- assert !t.match(:child => { :tag => "sib", :attributes => {"v" => /r/}})
- assert !t.match(:child => { :attributes => {"v" => false}})
- end
-
- def test_match_ancestor_success
- t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>")))
- assert t.match(:ancestor => {:tag => "parent", :attributes => {"a" => /ll/}})
- assert t.match(:ancestor => {:attributes => {"m" => "vaughn"}})
- end
-
- def test_match_ancestor_fail
- t = tag("<tag x:k='something'>", tag("<parent v=john a=kelly>", tag("<grandparent m=vaughn v=james>")))
- assert !t.match(:ancestor => {:tag => /^parent/, :attributes => {"v" => /m/}})
- assert !t.match(:ancestor => {:attributes => {"v" => false}})
- end
-
- def test_match_descendant_success
- tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>")))
- assert t.match(:descendant => {:tag => "child", :attributes => {"a" => /ll/}})
- assert t.match(:descendant => {:attributes => {"m" => "vaughn"}})
- end
-
- def test_match_descendant_fail
- tag("<grandchild m=vaughn v=james>", tag("<child v=john a=kelly>", t = tag("<tag x:k='something'>")))
- assert !t.match(:descendant => {:tag => /^child/, :attributes => {"v" => /m/}})
- assert !t.match(:descendant => {:attributes => {"v" => false}})
- end
-
- def test_match_child_count
- t = tag("<tag x:k='something'>")
- tag("hello", t)
- tag("<child v=john a=kelly>", t)
- tag("<sib m=vaughn v=james>", t)
- assert t.match(:children => { :count => 2 })
- assert t.match(:children => { :count => 2..4 })
- assert t.match(:children => { :less_than => 4 })
- assert t.match(:children => { :greater_than => 1 })
- assert !t.match(:children => { :count => 3 })
- end
-
- def test_conditions_as_strings
- t = tag("<tag x:k='something'>")
- assert t.match("tag" => "tag")
- assert t.match("attributes" => { "x:k" => "something" })
- assert !t.match("tag" => "gat")
- assert !t.match("attributes" => { "x:j" => "something" })
- end
-
- def test_attributes_as_symbols
- t = tag("<child v=john a=kelly>")
- assert t.match(:attributes => { :v => /oh/ })
- assert t.match(:attributes => { :a => /ll/ })
- end
-
- def test_match_sibling
- t = tag("<tag x:k='something'>")
- tag("hello", t)
- tag("<span a=b>", t)
- tag("world", t)
- m = tag("<span k=r>", t)
- tag("<span m=l>", t)
-
- assert m.match(:sibling => {:tag => "span", :attributes => {:a => true}})
- assert m.match(:sibling => {:tag => "span", :attributes => {:m => true}})
- assert !m.match(:sibling => {:tag => "span", :attributes => {:k => true}})
- end
-
- def test_match_sibling_before
- t = tag("<tag x:k='something'>")
- tag("hello", t)
- tag("<span a=b>", t)
- tag("world", t)
- m = tag("<span k=r>", t)
- tag("<span m=l>", t)
-
- assert m.match(:before => {:tag => "span", :attributes => {:m => true}})
- assert !m.match(:before => {:tag => "span", :attributes => {:a => true}})
- assert !m.match(:before => {:tag => "span", :attributes => {:k => true}})
- end
-
- def test_match_sibling_after
- t = tag("<tag x:k='something'>")
- tag("hello", t)
- tag("<span a=b>", t)
- tag("world", t)
- m = tag("<span k=r>", t)
- tag("<span m=l>", t)
-
- assert m.match(:after => {:tag => "span", :attributes => {:a => true}})
- assert !m.match(:after => {:tag => "span", :attributes => {:m => true}})
- assert !m.match(:after => {:tag => "span", :attributes => {:k => true}})
- end
-
- def test_tag_to_s
- t = tag("<b x='foo'>")
- tag("hello", t)
- tag("<hr />", t)
- assert_equal %(<b x="foo">hello<hr /></b>), t.to_s
- end
-
- private
-
- def tag(content, parent=nil)
- node = HTML::Node.parse(parent,0,0,content)
- parent.children << node if parent
- node
- end
-end
diff --git a/actionview/test/template/html-scanner/text_node_test.rb b/actionview/test/template/html-scanner/text_node_test.rb
deleted file mode 100644
index cbcb9e78f0..0000000000
--- a/actionview/test/template/html-scanner/text_node_test.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-require 'abstract_unit'
-
-class TextNodeTest < ActiveSupport::TestCase
- def setup
- @node = HTML::Text.new(nil, 0, 0, "hello, howdy, aloha, annyeong")
- end
-
- def test_to_s
- assert_equal "hello, howdy, aloha, annyeong", @node.to_s
- end
-
- def test_find_string
- assert_equal @node, @node.find("hello, howdy, aloha, annyeong")
- assert_equal false, @node.find("bogus")
- end
-
- def test_find_regexp
- assert_equal @node, @node.find(/an+y/)
- assert_nil @node.find(/b/)
- end
-
- def test_find_hash
- assert_equal @node, @node.find(:content => /howdy/)
- assert_nil @node.find(:content => /^howdy$/)
- assert_equal false, @node.find(:content => "howdy")
- end
-
- def test_find_other
- assert_nil @node.find(:hello)
- end
-
- def test_match_string
- assert @node.match("hello, howdy, aloha, annyeong")
- assert_equal false, @node.match("bogus")
- end
-
- def test_match_regexp
- assert_not_nil @node, @node.match(/an+y/)
- assert_nil @node.match(/b/)
- end
-
- def test_match_hash
- assert_not_nil @node, @node.match(:content => "howdy")
- assert_nil @node.match(:content => /^howdy$/)
- end
-
- def test_match_other
- assert_nil @node.match(:hello)
- end
-end
diff --git a/actionview/test/template/html-scanner/tokenizer_test.rb b/actionview/test/template/html-scanner/tokenizer_test.rb
deleted file mode 100644
index 1d59de23b6..0000000000
--- a/actionview/test/template/html-scanner/tokenizer_test.rb
+++ /dev/null
@@ -1,131 +0,0 @@
-require 'abstract_unit'
-
-class TokenizerTest < ActiveSupport::TestCase
-
- def test_blank
- tokenize ""
- assert_end
- end
-
- def test_space
- tokenize " "
- assert_next " "
- assert_end
- end
-
- def test_tag_simple_open
- tokenize "<tag>"
- assert_next "<tag>"
- assert_end
- end
-
- def test_tag_simple_self_closing
- tokenize "<tag />"
- assert_next "<tag />"
- assert_end
- end
-
- def test_tag_simple_closing
- tokenize "</tag>"
- assert_next "</tag>"
- end
-
- def test_tag_with_single_quoted_attribute
- tokenize %{<tag a='hello'>x}
- assert_next %{<tag a='hello'>}
- end
-
- def test_tag_with_single_quoted_attribute_with_escape
- tokenize %{<tag a='hello\\''>x}
- assert_next %{<tag a='hello\\''>}
- end
-
- def test_tag_with_double_quoted_attribute
- tokenize %{<tag a="hello">x}
- assert_next %{<tag a="hello">}
- end
-
- def test_tag_with_double_quoted_attribute_with_escape
- tokenize %{<tag a="hello\\"">x}
- assert_next %{<tag a="hello\\"">}
- end
-
- def test_tag_with_unquoted_attribute
- tokenize %{<tag a=hello>x}
- assert_next %{<tag a=hello>}
- end
-
- def test_tag_with_lt_char_in_attribute
- tokenize %{<tag a="x < y">x}
- assert_next %{<tag a="x < y">}
- end
-
- def test_tag_with_gt_char_in_attribute
- tokenize %{<tag a="x > y">x}
- assert_next %{<tag a="x > y">}
- end
-
- def test_doctype_tag
- tokenize %{<!DOCTYPE "blah" "blah" "blah">\n <html>}
- assert_next %{<!DOCTYPE "blah" "blah" "blah">}
- assert_next %{\n }
- assert_next %{<html>}
- end
-
- def test_cdata_tag
- tokenize %{<![CDATA[<br>]]>}
- assert_next %{<![CDATA[<br>]]>}
- assert_end
- end
-
- def test_unterminated_cdata_tag
- tokenize %{<content:encoded><![CDATA[ neverending...}
- assert_next %{<content:encoded>}
- assert_next %{<![CDATA[ neverending...}
- assert_end
- end
-
- def test_less_than_with_space
- tokenize %{original < hello > world}
- assert_next %{original }
- assert_next %{< hello > world}
- end
-
- def test_less_than_without_matching_greater_than
- tokenize %{hello <span onmouseover="gotcha"\n<b>foo</b>\nbar</span>}
- assert_next %{hello }
- assert_next %{<span onmouseover="gotcha"\n}
- assert_next %{<b>}
- assert_next %{foo}
- assert_next %{</b>}
- assert_next %{\nbar}
- assert_next %{</span>}
- assert_end
- end
-
- def test_unterminated_comment
- tokenize %{hello <!-- neverending...}
- assert_next %{hello }
- assert_next %{<!-- neverending...}
- assert_end
- end
-
- private
-
- def tokenize(text)
- @tokenizer = HTML::Tokenizer.new(text)
- end
-
- def assert_next(expected, message=nil)
- token = @tokenizer.next
- assert_equal expected, token, message
- end
-
- def assert_sequence(*expected)
- assert_next expected.shift until expected.empty?
- end
-
- def assert_end(message=nil)
- assert_nil @tokenizer.next, message
- end
-end
diff --git a/actionview/test/template/html_test.rb b/actionview/test/template/html_test.rb
new file mode 100644
index 0000000000..549c12c88c
--- /dev/null
+++ b/actionview/test/template/html_test.rb
@@ -0,0 +1,17 @@
+require 'abstract_unit'
+
+class HTMLTest < ActiveSupport::TestCase
+ test 'formats returns symbol for recognized MIME type' do
+ assert_equal [:html], ActionView::Template::HTML.new('', :html).formats
+ end
+
+ test 'formats returns string for recognized MIME type when MIME does not have symbol' do
+ foo = Mime::Type.lookup("foo")
+ assert_nil foo.to_sym
+ assert_equal ['foo'], ActionView::Template::HTML.new('', foo).formats
+ end
+
+ test 'formats returns string for unknown MIME type' do
+ assert_equal ['foo'], ActionView::Template::HTML.new('', 'foo').formats
+ end
+end
diff --git a/actionview/test/template/javascript_helper_test.rb b/actionview/test/template/javascript_helper_test.rb
index 4703111741..9ba7f64ad1 100644
--- a/actionview/test/template/javascript_helper_test.rb
+++ b/actionview/test/template/javascript_helper_test.rb
@@ -12,14 +12,14 @@ class JavaScriptHelperTest < ActionView::TestCase
yield if block_given?
end
- def setup
- super
+ setup do
+ @old_escape_html_entities_in_json = ActiveSupport.escape_html_entities_in_json
ActiveSupport.escape_html_entities_in_json = true
@template = self
end
def teardown
- ActiveSupport.escape_html_entities_in_json = false
+ ActiveSupport.escape_html_entities_in_json = @old_escape_html_entities_in_json
end
def test_escape_javascript
diff --git a/actionview/test/template/lookup_context_test.rb b/actionview/test/template/lookup_context_test.rb
index ce9485e146..4f7823045e 100644
--- a/actionview/test/template/lookup_context_test.rb
+++ b/actionview/test/template/lookup_context_test.rb
@@ -93,6 +93,20 @@ class LookupContextTest < ActiveSupport::TestCase
assert_equal "Hey verden", template.source
end
+ test "find templates with given variants" do
+ @lookup_context.formats = [:html]
+ @lookup_context.variants = [:phone]
+
+ template = @lookup_context.find("hello_world", %w(test))
+ assert_equal "Hello phone!", template.source
+
+ @lookup_context.variants = [:phone]
+ @lookup_context.formats = [:text]
+
+ template = @lookup_context.find("hello_world", %w(test))
+ assert_equal "Hello texty phone!", template.source
+ end
+
test "found templates respects given formats if one cannot be found from template or handler" do
ActionView::Template::Handlers::Builder.expects(:default_format).returns(nil)
@lookup_context.formats = [:text]
diff --git a/actionview/test/template/number_helper_test.rb b/actionview/test/template/number_helper_test.rb
index be336ea3fb..b59883b760 100644
--- a/actionview/test/template/number_helper_test.rb
+++ b/actionview/test/template/number_helper_test.rb
@@ -8,6 +8,8 @@ class NumberHelperTest < ActionView::TestCase
assert_equal "555-1234", number_to_phone(5551234)
assert_equal "(800) 555-1212 x 123", number_to_phone(8005551212, area_code: true, extension: 123)
assert_equal "+18005551212", number_to_phone(8005551212, country_code: 1, delimiter: "")
+ assert_equal "+&lt;script&gt;&lt;/script&gt;8005551212", number_to_phone(8005551212, country_code: "<script></script>", delimiter: "")
+ assert_equal "8005551212 x &lt;script&gt;&lt;/script&gt;", number_to_phone(8005551212, extension: "<script></script>", delimiter: "")
end
def test_number_to_currency
@@ -16,14 +18,23 @@ class NumberHelperTest < ActionView::TestCase
assert_equal "$1,234,567,892", number_to_currency(1234567891.50, precision: 0)
assert_equal "1,234,567,890.50 - K&#269;", number_to_currency("-1234567890.50", unit: raw("K&#269;"), format: "%n %u", negative_format: "%n - %u")
assert_equal "&amp;pound;1,234,567,890.50", number_to_currency("1234567890.50", unit: "&pound;")
+ assert_equal "&lt;b&gt;1,234,567,890.50&lt;/b&gt; $", number_to_currency("1234567890.50", format: "<b>%n</b> %u")
+ assert_equal "&lt;b&gt;1,234,567,890.50&lt;/b&gt; $", number_to_currency("-1234567890.50", negative_format: "<b>%n</b> %u")
+ assert_equal "&lt;b&gt;1,234,567,890.50&lt;/b&gt; $", number_to_currency("-1234567890.50", 'negative_format' => "<b>%n</b> %u")
end
def test_number_to_percentage
assert_equal nil, number_to_percentage(nil)
assert_equal "100.000%", number_to_percentage(100)
+ assert_equal "100.000 %", number_to_percentage(100, format: '%n %')
+ assert_equal "&lt;b&gt;100.000&lt;/b&gt; %", number_to_percentage(100, format: '<b>%n</b> %')
+ assert_equal "<b>100.000</b> %", number_to_percentage(100, format: raw('<b>%n</b> %'))
assert_equal "100%", number_to_percentage(100, precision: 0)
assert_equal "123.4%", number_to_percentage(123.400, precision: 3, strip_insignificant_zeros: true)
assert_equal "1.000,000%", number_to_percentage(1000, delimiter: ".", separator: ",")
+ assert_equal "98a%", number_to_percentage("98a")
+ assert_equal "NaN%", number_to_percentage(Float::NAN)
+ assert_equal "Inf%", number_to_percentage(Float::INFINITY)
end
def test_number_with_delimiter
@@ -37,6 +48,7 @@ class NumberHelperTest < ActionView::TestCase
assert_equal "-111.235", number_with_precision(-111.2346)
assert_equal "111.00", number_with_precision(111, precision: 2)
assert_equal "0.00100", number_with_precision(0.001, precision: 5)
+ assert_equal "3.33", number_with_precision(Rational(10, 3), precision: 2)
end
def test_number_to_human_size
@@ -52,6 +64,31 @@ class NumberHelperTest < ActionView::TestCase
assert_equal "489.0 Thousand", number_to_human(489000, precision: 4, strip_insignificant_zeros: false)
end
+ def test_number_to_human_escape_units
+ volume = { unit: "<b>ml</b>", thousand: "<b>lt</b>", million: "<b>m3</b>", trillion: "<b>km3</b>", quadrillion: "<b>Pl</b>" }
+ assert_equal '123 &lt;b&gt;lt&lt;/b&gt;', number_to_human(123456, :units => volume)
+ assert_equal '12 &lt;b&gt;ml&lt;/b&gt;', number_to_human(12, :units => volume)
+ assert_equal '1.23 &lt;b&gt;m3&lt;/b&gt;', number_to_human(1234567, :units => volume)
+ assert_equal '1.23 &lt;b&gt;km3&lt;/b&gt;', number_to_human(1_234_567_000_000, :units => volume)
+ assert_equal '1.23 &lt;b&gt;Pl&lt;/b&gt;', number_to_human(1_234_567_000_000_000, :units => volume)
+
+ #Including fractionals
+ distance = { mili: "<b>mm</b>", centi: "<b>cm</b>", deci: "<b>dm</b>", unit: "<b>m</b>",
+ ten: "<b>dam</b>", hundred: "<b>hm</b>", thousand: "<b>km</b>",
+ micro: "<b>um</b>", nano: "<b>nm</b>", pico: "<b>pm</b>", femto: "<b>fm</b>"}
+ assert_equal '1.23 &lt;b&gt;mm&lt;/b&gt;', number_to_human(0.00123, :units => distance)
+ assert_equal '1.23 &lt;b&gt;cm&lt;/b&gt;', number_to_human(0.0123, :units => distance)
+ assert_equal '1.23 &lt;b&gt;dm&lt;/b&gt;', number_to_human(0.123, :units => distance)
+ assert_equal '1.23 &lt;b&gt;m&lt;/b&gt;', number_to_human(1.23, :units => distance)
+ assert_equal '1.23 &lt;b&gt;dam&lt;/b&gt;', number_to_human(12.3, :units => distance)
+ assert_equal '1.23 &lt;b&gt;hm&lt;/b&gt;', number_to_human(123, :units => distance)
+ assert_equal '1.23 &lt;b&gt;km&lt;/b&gt;', number_to_human(1230, :units => distance)
+ assert_equal '1.23 &lt;b&gt;um&lt;/b&gt;', number_to_human(0.00000123, :units => distance)
+ assert_equal '1.23 &lt;b&gt;nm&lt;/b&gt;', number_to_human(0.00000000123, :units => distance)
+ assert_equal '1.23 &lt;b&gt;pm&lt;/b&gt;', number_to_human(0.00000000000123, :units => distance)
+ assert_equal '1.23 &lt;b&gt;fm&lt;/b&gt;', number_to_human(0.00000000000000123, :units => distance)
+ end
+
def test_number_helpers_escape_delimiter_and_separator
assert_equal "111&lt;script&gt;&lt;/script&gt;111&lt;script&gt;&lt;/script&gt;1111", number_to_phone(1111111111, delimiter: "<script></script>")
@@ -73,6 +110,14 @@ class NumberHelperTest < ActionView::TestCase
assert_equal "100&lt;script&gt;&lt;/script&gt;000 Quadrillion", number_to_human(10**20, delimiter: "<script></script>")
end
+ def test_number_to_human_with_custom_translation_scope
+ I18n.backend.store_translations 'ts',
+ :custom_units_for_number_to_human => {:mili => "mm", :centi => "cm", :deci => "dm", :unit => "m", :ten => "dam", :hundred => "hm", :thousand => "km"}
+ assert_equal "1.01 cm", number_to_human(0.0101, :locale => 'ts', :units => :custom_units_for_number_to_human)
+ ensure
+ I18n.reload!
+ end
+
def test_number_helpers_outputs_are_html_safe
assert number_to_human(1).html_safe?
assert !number_to_human("<script></script>").html_safe?
diff --git a/actionview/test/template/output_buffer_test.rb b/actionview/test/template/output_buffer_test.rb
deleted file mode 100644
index eb0df3d1ab..0000000000
--- a/actionview/test/template/output_buffer_test.rb
+++ /dev/null
@@ -1,59 +0,0 @@
-require 'abstract_unit'
-
-class OutputBufferTest < ActionController::TestCase
- class TestController < ActionController::Base
- def index
- render :text => 'foo'
- end
- end
-
- tests TestController
-
- def setup
- @vc = @controller.view_context
- get :index
- assert_equal ['foo'], body_parts
- end
-
- test 'output buffer is nil after rendering' do
- assert_nil output_buffer
- end
-
- test 'flushing ignores nil output buffer' do
- @controller.view_context.flush_output_buffer
- assert_nil output_buffer
- assert_equal ['foo'], body_parts
- end
-
- test 'flushing ignores empty output buffer' do
- @vc.output_buffer = ''
- @vc.flush_output_buffer
- assert_equal '', output_buffer
- assert_equal ['foo'], body_parts
- end
-
- test 'flushing appends the output buffer to the body parts' do
- @vc.output_buffer = 'bar'
- @vc.flush_output_buffer
- assert_equal '', output_buffer
- assert_equal ['foo', 'bar'], body_parts
- end
-
- test 'flushing preserves output buffer encoding' do
- original_buffer = ' '.force_encoding(Encoding::EUC_JP)
- @vc.output_buffer = original_buffer
- @vc.flush_output_buffer
- assert_equal ['foo', original_buffer], body_parts
- assert_not_equal original_buffer, output_buffer
- assert_equal Encoding::EUC_JP, output_buffer.encoding
- end
-
- protected
- def output_buffer
- @vc.output_buffer
- end
-
- def body_parts
- @controller.response.body_parts
- end
-end
diff --git a/actionview/test/template/output_safety_helper_test.rb b/actionview/test/template/output_safety_helper_test.rb
index 76c71c9e6d..a1bf0e1a5f 100644
--- a/actionview/test/template/output_safety_helper_test.rb
+++ b/actionview/test/template/output_safety_helper_test.rb
@@ -25,4 +25,11 @@ class OutputSafetyHelperTest < ActionView::TestCase
assert_equal "<p>foo</p><br /><p>bar</p>", joined
end
-end \ No newline at end of file
+ test "safe_join should work recursively similarly to Array.join" do
+ joined = safe_join(['a',['b','c']], ':')
+ assert_equal 'a:b:c', joined
+
+ joined = safe_join(['"a"',['<b>','<c>']], ' <br/> ')
+ assert_equal '&quot;a&quot; &lt;br/&gt; &lt;b&gt; &lt;br/&gt; &lt;c&gt;', joined
+ end
+end
diff --git a/actionview/test/template/partial_iteration_test.rb b/actionview/test/template/partial_iteration_test.rb
new file mode 100644
index 0000000000..695f9f1bef
--- /dev/null
+++ b/actionview/test/template/partial_iteration_test.rb
@@ -0,0 +1,33 @@
+require 'abstract_unit'
+require 'action_view/renderer/partial_renderer'
+
+class PartialIterationTest < ActiveSupport::TestCase
+ def test_has_size_and_index
+ iteration = ActionView::PartialIteration.new 3
+ assert_equal 0, iteration.index, "should be at the first index"
+ assert_equal 3, iteration.size, "should have the size"
+ end
+
+ def test_first_is_true_when_current_is_at_the_first_index
+ iteration = ActionView::PartialIteration.new 3
+ assert iteration.first?, "first when current is 0"
+ end
+
+ def test_first_is_false_unless_current_is_at_the_first_index
+ iteration = ActionView::PartialIteration.new 3
+ iteration.iterate!
+ assert !iteration.first?, "not first when current is 1"
+ end
+
+ def test_last_is_true_when_current_is_at_the_last_index
+ iteration = ActionView::PartialIteration.new 3
+ iteration.iterate!
+ iteration.iterate!
+ assert iteration.last?, "last when current is 2"
+ end
+
+ def test_last_is_false_unless_current_is_at_the_last_index
+ iteration = ActionView::PartialIteration.new 3
+ assert !iteration.last?, "not last when current is 0"
+ end
+end
diff --git a/actionview/test/template/record_identifier_test.rb b/actionview/test/template/record_identifier_test.rb
index 22038110a5..04898c0b0e 100644
--- a/actionview/test/template/record_identifier_test.rb
+++ b/actionview/test/template/record_identifier_test.rb
@@ -9,7 +9,6 @@ class RecordIdentifierTest < ActiveSupport::TestCase
@record = @klass.new
@singular = 'comment'
@plural = 'comments'
- @uncountable = Sheep
end
def test_dom_id_with_new_record
@@ -47,3 +46,46 @@ class RecordIdentifierTest < ActiveSupport::TestCase
assert_equal @singular, ActionView::RecordIdentifier.dom_class(@record)
end
end
+
+class RecordIdentifierWithoutActiveModelTest < ActiveSupport::TestCase
+ include ActionView::RecordIdentifier
+
+ def setup
+ @record = Plane.new
+ end
+
+ def test_dom_id_with_new_record
+ assert_equal "new_airplane", dom_id(@record)
+ end
+
+ def test_dom_id_with_new_record_and_prefix
+ assert_equal "custom_prefix_airplane", dom_id(@record, :custom_prefix)
+ end
+
+ def test_dom_id_with_saved_record
+ @record.save
+ assert_equal "airplane_1", dom_id(@record)
+ end
+
+ def test_dom_id_with_prefix
+ @record.save
+ assert_equal "edit_airplane_1", dom_id(@record, :edit)
+ end
+
+ def test_dom_class
+ assert_equal 'airplane', dom_class(@record)
+ end
+
+ def test_dom_class_with_prefix
+ assert_equal "custom_prefix_airplane", dom_class(@record, :custom_prefix)
+ end
+
+ def test_dom_id_as_singleton_method
+ @record.save
+ assert_equal "airplane_1", ActionView::RecordIdentifier.dom_id(@record)
+ end
+
+ def test_dom_class_as_singleton_method
+ assert_equal 'airplane', ActionView::RecordIdentifier.dom_class(@record)
+ end
+end
diff --git a/actionview/test/template/render_test.rb b/actionview/test/template/render_test.rb
index 055a273cc3..dc4abca048 100644
--- a/actionview/test/template/render_test.rb
+++ b/actionview/test/template/render_test.rb
@@ -12,17 +12,16 @@ module RenderTestCases
@controller_view = TestController.new.view_context
# Reload and register danish language for testing
- I18n.reload!
I18n.backend.store_translations 'da', {}
I18n.backend.store_translations 'pt-BR', {}
# Ensure original are still the same since we are reindexing view paths
- assert_equal ORIGINAL_LOCALES, I18n.available_locales.map {|l| l.to_s }.sort
+ assert_equal ORIGINAL_LOCALES, I18n.available_locales.map(&:to_s).sort
end
def test_render_without_options
e = assert_raises(ArgumentError) { @view.render() }
- assert_match "You invoked render but did not give any of :partial, :template, :inline, :file or :text option.", e.message
+ assert_match(/You invoked render but did not give any of (.+) option./, e.message)
end
def test_render_file
@@ -176,14 +175,14 @@ module RenderTestCases
def test_render_partial_with_invalid_name
e = assert_raises(ArgumentError) { @view.render(:partial => "test/200") }
assert_equal "The partial name (test/200) is not a valid Ruby identifier; " +
- "make sure your partial name starts with a lowercase letter or underscore, " +
+ "make sure your partial name starts with underscore, " +
"and is followed by any combination of letters, numbers and underscores.", e.message
end
def test_render_partial_with_missing_filename
e = assert_raises(ArgumentError) { @view.render(:partial => "test/") }
assert_equal "The partial name (test/) is not a valid Ruby identifier; " +
- "make sure your partial name starts with a lowercase letter or underscore, " +
+ "make sure your partial name starts with underscore, " +
"and is followed by any combination of letters, numbers and underscores.", e.message
end
@@ -195,7 +194,21 @@ module RenderTestCases
def test_render_partial_with_hyphen
e = assert_raises(ArgumentError) { @view.render(:partial => "test/a-in") }
assert_equal "The partial name (test/a-in) is not a valid Ruby identifier; " +
- "make sure your partial name starts with a lowercase letter or underscore, " +
+ "make sure your partial name starts with underscore, " +
+ "and is followed by any combination of letters, numbers and underscores.", e.message
+ end
+
+ def test_render_partial_with_invalid_option_as
+ e = assert_raises(ArgumentError) { @view.render(:partial => "test/partial_only", :as => 'a-in') }
+ assert_equal "The value (a-in) of the option `as` is not a valid Ruby identifier; " +
+ "make sure it starts with lowercase letter, " +
+ "and is followed by any combination of letters, numbers and underscores.", e.message
+ end
+
+ def test_render_partial_with_hyphen_and_invalid_option_as
+ e = assert_raises(ArgumentError) { @view.render(:partial => "test/a-in", :as => 'a-in') }
+ assert_equal "The value (a-in) of the option `as` is not a valid Ruby identifier; " +
+ "make sure it starts with lowercase letter, " +
"and is followed by any combination of letters, numbers and underscores.", e.message
end
@@ -257,7 +270,7 @@ module RenderTestCases
end
def test_render_partial_collection_without_as
- assert_equal "local_inspector,local_inspector_counter",
+ assert_equal "local_inspector,local_inspector_counter,local_inspector_iteration",
@view.render(:partial => "test/local_inspector", :collection => [ Customer.new("mary") ])
end
@@ -304,6 +317,16 @@ module RenderTestCases
assert_equal "Hola: david", @controller_view.render('customer_greeting', :greeting => 'Hola', :customer_greeting => Customer.new("david"))
end
+ def test_render_partial_with_object_uses_render_partial_path
+ assert_equal "Hello: lifo",
+ @controller_view.render(:partial => Customer.new("lifo"), :locals => {:greeting => "Hello"})
+ end
+
+ def test_render_partial_with_object_and_format_uses_render_partial_path
+ assert_equal "<greeting>Hello</greeting><name>lifo</name>",
+ @controller_view.render(:partial => Customer.new("lifo"), :formats => :xml, :locals => {:greeting => "Hello"})
+ end
+
def test_render_partial_using_object
assert_equal "Hello: lifo",
@controller_view.render(Customer.new("lifo"), :greeting => "Hello")
@@ -315,11 +338,16 @@ module RenderTestCases
@controller_view.render(customers, :greeting => "Hello")
end
+ def test_render_partial_using_collection_without_path
+ assert_equal "hi good customer: david0", @controller_view.render([ GoodCustomer.new("david") ], greeting: "hi")
+ end
+
def test_render_partial_without_object_or_collection_does_not_generate_partial_name_local_variable
exception = assert_raises ActionView::Template::Error do
@controller_view.render("partial_name_local_variable")
end
- assert_match "undefined local variable or method `partial_name_local_variable'", exception.message
+ assert_instance_of NameError, exception.original_exception
+ assert_equal :partial_name_local_variable, exception.original_exception.name
end
# TODO: The reason for this test is unclear, improve documentation
@@ -359,23 +387,48 @@ module RenderTestCases
def test_render_inline_with_render_from_to_proc
ActionView::Template.register_template_handler :ruby_handler, :source.to_proc
- assert_equal '3', @view.render(:inline => "(1 + 2).to_s", :type => :ruby_handler)
+ assert_equal '3', @view.render(inline: "(1 + 2).to_s", type: :ruby_handler)
+ ensure
+ ActionView::Template.unregister_template_handler :ruby_handler
end
def test_render_inline_with_compilable_custom_type
ActionView::Template.register_template_handler :foo, CustomHandler
- assert_equal 'source: "Hello, World!"', @view.render(:inline => "Hello, World!", :type => :foo)
+ assert_equal 'source: "Hello, World!"', @view.render(inline: "Hello, World!", type: :foo)
+ ensure
+ ActionView::Template.unregister_template_handler :foo
end
def test_render_inline_with_locals_and_compilable_custom_type
ActionView::Template.register_template_handler :foo, CustomHandler
- assert_equal 'source: "Hello, <%= name %>!"', @view.render(:inline => "Hello, <%= name %>!", :locals => { :name => "Josh" }, :type => :foo)
+ assert_equal 'source: "Hello, <%= name %>!"', @view.render(inline: "Hello, <%= name %>!", locals: { name: "Josh" }, type: :foo)
+ ensure
+ ActionView::Template.unregister_template_handler :foo
+ end
+
+ def test_render_body
+ assert_equal 'some body', @view.render(body: 'some body')
+ end
+
+ def test_render_plain
+ assert_equal 'some plaintext', @view.render(plain: 'some plaintext')
end
def test_render_knows_about_types_registered_when_extensions_are_checked_earlier_in_initialization
ActionView::Template::Handlers.extensions
ActionView::Template.register_template_handler :foo, CustomHandler
assert ActionView::Template::Handlers.extensions.include?(:foo)
+ ensure
+ ActionView::Template.unregister_template_handler :foo
+ end
+
+ def test_render_does_not_use_unregistered_extension_and_template_handler
+ ActionView::Template.register_template_handler :foo, CustomHandler
+ ActionView::Template.unregister_template_handler :foo
+ assert_not ActionView::Template::Handlers.extensions.include?(:foo)
+ assert_equal "Hello, World!", @view.render(inline: "Hello, World!", type: :foo)
+ ensure
+ ActionView::Template::Handlers.class_variable_get(:@@template_handlers).delete(:foo)
end
def test_render_ignores_templates_with_malformed_template_handlers
@@ -427,6 +480,11 @@ module RenderTestCases
@view.render(:partial => 'test/partial_with_partial', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
end
+ def test_render_partial_shortcut_with_block_content
+ assert_equal %(Before (shortcut test)\nBefore\n\n Yielded: arg1/arg2\n\nAfter\nAfter),
+ @view.render(partial: "test/partial_shortcut_with_block_content", layout: "test/layout_for_partial", locals: { name: "shortcut test" })
+ end
+
def test_render_layout_with_a_nested_render_layout_call
assert_equal %(Before (Foo!)\nBefore (Bar!)\npartial html\nAfter\npartial with layout\n\nAfter),
@view.render(:partial => 'test/partial_with_layout', :layout => 'test/layout_for_partial', :locals => { :name => 'Foo!'})
@@ -464,7 +522,9 @@ module RenderTestCases
def test_render_with_passing_couple_extensions_to_one_register_template_handler_function_call
ActionView::Template.register_template_handler :foo1, :foo2, CustomHandler
- assert_equal @view.render(:inline => "Hello, World!", :type => :foo1), @view.render(:inline => "Hello, World!", :type => :foo2)
+ assert_equal @view.render(inline: "Hello, World!", type: :foo1), @view.render(inline: "Hello, World!", type: :foo2)
+ ensure
+ ActionView::Template.unregister_template_handler :foo1, :foo2
end
def test_render_throws_exception_when_no_extensions_passed_to_register_template_handler_function_call
@@ -484,6 +544,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase
def teardown
GC.start
+ I18n.reload!
end
end
@@ -501,6 +562,7 @@ class LazyViewRenderTest < ActiveSupport::TestCase
def teardown
GC.start
+ I18n.reload!
end
def test_render_utf8_template_with_magic_comment
diff --git a/actionview/test/template/sanitize_helper_test.rb b/actionview/test/template/sanitize_helper_test.rb
index 12d5260a9d..e4be21be2c 100644
--- a/actionview/test/template/sanitize_helper_test.rb
+++ b/actionview/test/template/sanitize_helper_test.rb
@@ -1,19 +1,15 @@
require 'abstract_unit'
# The exhaustive tests are in test/controller/html/sanitizer_test.rb.
-# This tests the that the helpers hook up correctly to the sanitizer classes.
+# This tests that the helpers hook up correctly to the sanitizer classes.
class SanitizeHelperTest < ActionView::TestCase
tests ActionView::Helpers::SanitizeHelper
def test_strip_links
assert_equal "Dont touch me", strip_links("Dont touch me")
- assert_equal "<a<a", strip_links("<a<a")
assert_equal "on my mind\nall day long", strip_links("<a href='almost'>on my mind</a>\n<A href='almost'>all day long</A>")
- assert_equal "0wn3d", strip_links("<a href='http://www.rubyonrails.com/'><a href='http://www.rubyonrails.com/' onlclick='steal()'>0wn3d</a></a>")
assert_equal "Magic", strip_links("<a href='http://www.rubyonrails.com/'>Mag<a href='http://www.ruby-lang.org/'>ic")
- assert_equal "FrrFox", strip_links("<href onlclick='steal()'>FrrFox</a></href>")
assert_equal "My mind\nall <b>day</b> long", strip_links("<a href='almost'>My mind</a>\n<A href='almost'>all <b>day</b> long</A>")
- assert_equal "all <b>day</b> long", strip_links("<<a>a href='hello'>all <b>day</b> long<</A>/a>")
end
def test_sanitize_form
@@ -22,27 +18,15 @@ class SanitizeHelperTest < ActionView::TestCase
def test_should_sanitize_illegal_style_properties
raw = %(display:block; position:absolute; left:0; top:0; width:100%; height:100%; z-index:1; background-color:black; background-image:url(http://www.ragingplatypus.com/i/cam-full.jpg); background-x:center; background-y:center; background-repeat:repeat;)
- expected = %(display: block; width: 100%; height: 100%; background-color: black; background-image: ; background-x: center; background-y: center;)
+ expected = %(display: block; width: 100%; height: 100%; background-color: black; background-x: center; background-y: center;)
assert_equal expected, sanitize_css(raw)
end
def test_strip_tags
- assert_equal("<<<bad html", strip_tags("<<<bad html"))
- assert_equal("<<", strip_tags("<<<bad html>"))
assert_equal("Dont touch me", strip_tags("Dont touch me"))
assert_equal("This is a test.", strip_tags("<p>This <u>is<u> a <a href='test.html'><strong>test</strong></a>.</p>"))
- assert_equal("Weirdos", strip_tags("Wei<<a>a onclick='alert(document.cookie);'</a>/>rdos"))
- assert_equal("This is a test.", strip_tags("This is a test."))
- assert_equal(
- %{This is a test.\n\n\nIt no longer contains any HTML.\n}, strip_tags(
- %{<title>This is <b>a <a href="" target="_blank">test</a></b>.</title>\n\n<!-- it has a comment -->\n\n<p>It no <b>longer <strong>contains <em>any <strike>HTML</strike></em>.</strong></b></p>\n}))
assert_equal "This has a here.", strip_tags("This has a <!-- comment --> here.")
- [nil, '', ' '].each do |blank|
- stripped = strip_tags(blank)
- assert_equal blank, stripped
- end
assert_equal "", strip_tags("<script>")
- assert_equal "something &lt;img onerror=alert(1337)", ERB::Util.html_escape(strip_tags("something <img onerror=alert(1337)"))
end
def test_sanitize_is_marked_safe
diff --git a/actionview/test/template/tag_helper_test.rb b/actionview/test/template/tag_helper_test.rb
index fb016a52de..d037447567 100644
--- a/actionview/test/template/tag_helper_test.rb
+++ b/actionview/test/template/tag_helper_test.rb
@@ -50,6 +50,11 @@ class TagHelperTest < ActionView::TestCase
assert_dom_equal "<div>Hello world!</div>", buffer
end
+ def test_content_tag_with_block_in_erb_containing_non_displayed_erb
+ buffer = render_erb("<%= content_tag(:p) do %><% 1 %><% end %>")
+ assert_dom_equal "<p></p>", buffer
+ end
+
def test_content_tag_with_block_and_options_in_erb
buffer = render_erb("<%= content_tag(:div, :class => 'green') do %>Hello world!<% end %>")
assert_dom_equal %(<div class="green">Hello world!</div>), buffer
@@ -64,6 +69,11 @@ class TagHelperTest < ActionView::TestCase
content_tag("a", "href" => "create") { "Create" }
end
+ def test_content_tag_with_block_and_non_string_outside_out_of_erb
+ assert_equal content_tag("p"),
+ content_tag("p") { 3.times { "do_something" } }
+ end
+
def test_content_tag_nested_in_content_tag_out_of_erb
assert_equal content_tag("p", content_tag("b", "Hello")),
content_tag("p") { content_tag("b", "Hello") },
@@ -80,11 +90,27 @@ class TagHelperTest < ActionView::TestCase
str = content_tag('p', "limelight", :class => ["song", "play"])
assert_equal "<p class=\"song play\">limelight</p>", str
+
+ str = content_tag('p', "limelight", :class => ["song", ["play"]])
+ assert_equal "<p class=\"song play\">limelight</p>", str
end
def test_content_tag_with_unescaped_array_class
str = content_tag('p', "limelight", {:class => ["song", "play>"]}, false)
assert_equal "<p class=\"song play>\">limelight</p>", str
+
+ str = content_tag('p', "limelight", {:class => ["song", ["play>"]]}, false)
+ assert_equal "<p class=\"song play>\">limelight</p>", str
+ end
+
+ def test_content_tag_with_empty_array_class
+ str = content_tag('p', 'limelight', {:class => []})
+ assert_equal '<p class="">limelight</p>', str
+ end
+
+ def test_content_tag_with_unescaped_empty_array_class
+ str = content_tag('p', 'limelight', {:class => []}, false)
+ assert_equal '<p class="">limelight</p>', str
end
def test_content_tag_with_data_attributes
@@ -107,6 +133,7 @@ class TagHelperTest < ActionView::TestCase
def test_escape_once
assert_equal '1 &lt; 2 &amp; 3', escape_once('1 < 2 &amp; 3')
+ assert_equal " &#X27; &#x27; &#x03BB; &#X03bb; &quot; &#39; &lt; &gt; ", escape_once(" &#X27; &#x27; &#x03BB; &#X03bb; \" ' < > ")
end
def test_tag_honors_html_safe_for_param_values
@@ -115,6 +142,14 @@ class TagHelperTest < ActionView::TestCase
end
end
+ def test_tag_honors_html_safe_with_escaped_array_class
+ str = tag('p', :class => ['song>', 'play>'.html_safe])
+ assert_equal '<p class="song&gt; play>" />', str
+
+ str = tag('p', :class => ['song>'.html_safe, 'play>'])
+ assert_equal '<p class="song> play&gt;" />', str
+ end
+
def test_skip_invalid_escaped_attributes
['&1;', '&#1dfa3;', '& #123;'].each do |escaped|
assert_equal %(<a href="#{escaped.gsub(/&/, '&amp;')}" />), tag('a', :href => escaped)
@@ -131,4 +166,11 @@ class TagHelperTest < ActionView::TestCase
tag('a', { data => { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: 'hello', symbol: :foo, array: [1, 2, 3], hash: { key: 'value'}, string_with_quotes: 'double"quote"party"' } })
}
end
+
+ def test_aria_attributes
+ ['aria', :aria].each { |aria|
+ assert_dom_equal '<a aria-a-float="3.14" aria-a-big-decimal="-123.456" aria-a-number="1" aria-array="[1,2,3]" aria-hash="{&quot;key&quot;:&quot;value&quot;}" aria-string-with-quotes="double&quot;quote&quot;party&quot;" aria-string="hello" aria-symbol="foo" />',
+ tag('a', { aria => { a_float: 3.14, a_big_decimal: BigDecimal.new("-123.456"), a_number: 1, string: 'hello', symbol: :foo, array: [1, 2, 3], hash: { key: 'value'}, string_with_quotes: 'double"quote"party"' } })
+ }
+ end
end
diff --git a/actionview/test/template/test_case_test.rb b/actionview/test/template/test_case_test.rb
index 4ee0930341..5ad1938b61 100644
--- a/actionview/test/template/test_case_test.rb
+++ b/actionview/test/template/test_case_test.rb
@@ -1,4 +1,5 @@
require 'abstract_unit'
+require 'rails/engine'
module ActionView
@@ -154,7 +155,7 @@ module ActionView
test "view_assigns excludes internal ivars" do
INTERNAL_IVARS.each do |ivar|
assert defined?(ivar), "expected #{ivar} to be defined"
- assert !view_assigns.keys.include?(ivar.to_s.sub('@', '').to_sym), "expected #{ivar} to be excluded from view_assigns"
+ assert !view_assigns.keys.include?(ivar.to_s.tr('@', '').to_sym), "expected #{ivar} to be excluded from view_assigns"
end
end
end
@@ -223,7 +224,7 @@ module ActionView
test "is able to use mounted routes" do
with_routing do |set|
- app = Class.new do
+ app = Class.new(Rails::Engine) do
def self.routes
@routes ||= ActionDispatch::Routing::RouteSet.new
end
@@ -292,6 +293,17 @@ module ActionView
assert_select 'li', :text => 'foo'
end
end
+
+ test "do not memoize the document_root_element in view tests" do
+ concat form_tag('/foo')
+
+ assert_select 'form'
+
+ concat content_tag(:b, 'Strong', class: 'foo')
+
+ assert_select 'form'
+ assert_select 'b.foo'
+ end
end
class RenderTemplateTest < ActionView::TestCase
diff --git a/actionview/test/template/test_test.rb b/actionview/test/template/test_test.rb
index 108a674d95..88bac85039 100644
--- a/actionview/test/template/test_test.rb
+++ b/actionview/test/template/test_test.rb
@@ -37,10 +37,22 @@ class PeopleHelperTest < ActionView::TestCase
def test_link_to_person
with_test_route_set do
- person = mock(:name => "David")
- person.class.extend ActiveModel::Naming
- expects(:mocha_mock_path).with(person).returns("/people/1")
+ person = Struct.new(:name) {
+ extend ActiveModel::Naming
+ def to_model; self; end
+ def persisted?; true; end
+ def self.name; 'Mocha::Mock'; end
+ }.new "David"
+
+ the_model = nil
+ extend Module.new {
+ define_method(:mocha_mock_path) { |model, *args|
+ the_model = model
+ "/people/1"
+ }
+ }
assert_equal '<a href="/people/1">David</a>', link_to_person(person)
+ assert_equal person, the_model
end
end
diff --git a/actionview/test/template/text_helper_test.rb b/actionview/test/template/text_helper_test.rb
index a514bba83d..f05b845e46 100644
--- a/actionview/test/template/text_helper_test.rb
+++ b/actionview/test/template/text_helper_test.rb
@@ -187,10 +187,16 @@ class TextHelperTest < ActionView::TestCase
"This text is not changed because we supplied an empty phrase",
highlight("This text is not changed because we supplied an empty phrase", nil)
)
+ end
+ def test_highlight_pending
assert_equal ' ', highlight(' ', 'blank text is returned verbatim')
end
+ def test_highlight_should_return_blank_string_for_nil
+ assert_equal '', highlight(nil, 'blank string is returned for nil')
+ end
+
def test_highlight_should_sanitize_input
assert_equal(
"This is a <mark>beautiful</mark> morning",
@@ -222,6 +228,11 @@ class TextHelperTest < ActionView::TestCase
)
end
+ def test_highlight_accepts_regexp
+ assert_equal("This day was challenging for judge <mark>Allen</mark> and his colleagues.",
+ highlight("This day was challenging for judge Allen and his colleagues.", /\ballen\b/i))
+ end
+
def test_highlight_with_multiple_phrases_in_one_pass
assert_equal %(<em>wow</em> <em>em</em>), highlight('wow em', %w(wow em), :highlighter => '<em>\1</em>')
end
@@ -260,6 +271,13 @@ class TextHelperTest < ActionView::TestCase
assert_equal options, passed_options
end
+ def test_highlight_with_block
+ assert_equal(
+ "<b>one</b> <b>two</b> <b>three</b>",
+ highlight("one two three", ["one", "two", "three"]) { |word| "<b>#{word}</b>" }
+ )
+ end
+
def test_excerpt
assert_equal("...is a beautiful morn...", excerpt("This is a beautiful morning", "beautiful", :radius => 5))
assert_equal("This is a...", excerpt("This is a beautiful morning", "this", :radius => 5))
@@ -267,6 +285,16 @@ class TextHelperTest < ActionView::TestCase
assert_nil excerpt("This is a beautiful morning", "day")
end
+ def test_excerpt_with_regex
+ assert_equal('...is a beautiful! mor...', excerpt('This is a beautiful! morning', 'beautiful', :radius => 5))
+ assert_equal('...is a beautiful? mor...', excerpt('This is a beautiful? morning', 'beautiful', :radius => 5))
+ assert_equal('...is a beautiful? mor...', excerpt('This is a beautiful? morning', /\bbeau\w*\b/i, :radius => 5))
+ assert_equal('...is a beautiful? mor...', excerpt('This is a beautiful? morning', /\b(beau\w*)\b/i, :radius => 5))
+ assert_equal("...udge Allen and...", excerpt("This day was challenging for judge Allen and his colleagues.", /\ballen\b/i, :radius => 5))
+ assert_equal("...judge Allen and...", excerpt("This day was challenging for judge Allen and his colleagues.", /\ballen\b/i, :radius => 1, :separator => ' '))
+ assert_equal("...was challenging for...", excerpt("This day was challenging for judge Allen and his colleagues.", /\b(\w*allen\w*)\b/i, :radius => 5))
+ end
+
def test_excerpt_should_not_be_html_safe
assert !excerpt('This is a beautiful! morning', 'beautiful', :radius => 5).html_safe?
end
@@ -288,11 +316,6 @@ class TextHelperTest < ActionView::TestCase
assert_equal("...abc...", excerpt("z abc d", "b", :radius => 1))
end
- def test_excerpt_with_regex
- assert_equal('...is a beautiful! mor...', excerpt('This is a beautiful! morning', 'beautiful', :radius => 5))
- assert_equal('...is a beautiful? mor...', excerpt('This is a beautiful? morning', 'beautiful', :radius => 5))
- end
-
def test_excerpt_with_omission
assert_equal("[...]is a beautiful morn[...]", excerpt("This is a beautiful morning", "beautiful", :omission => "[...]",:radius => 5))
assert_equal(
diff --git a/actionview/test/template/text_test.rb b/actionview/test/template/text_test.rb
new file mode 100644
index 0000000000..d899d54589
--- /dev/null
+++ b/actionview/test/template/text_test.rb
@@ -0,0 +1,17 @@
+require 'abstract_unit'
+
+class TextTest < ActiveSupport::TestCase
+ test 'formats returns symbol for recognized MIME type' do
+ assert_equal [:text], ActionView::Template::Text.new('', :text).formats
+ end
+
+ test 'formats returns string for recognized MIME type when MIME does not have symbol' do
+ foo = Mime::Type.lookup("foo")
+ assert_nil foo.to_sym
+ assert_equal ['foo'], ActionView::Template::Text.new('', foo).formats
+ end
+
+ test 'formats returns string for unknown MIME type' do
+ assert_equal ['foo'], ActionView::Template::Text.new('', 'foo').formats
+ end
+end
diff --git a/actionview/test/template/translation_helper_test.rb b/actionview/test/template/translation_helper_test.rb
index 269714fad0..8fde478ac9 100644
--- a/actionview/test/template/translation_helper_test.rb
+++ b/actionview/test/template/translation_helper_test.rb
@@ -1,12 +1,19 @@
require 'abstract_unit'
+module I18n
+ class CustomExceptionHandler
+ def self.call(exception, locale, key, options)
+ 'from CustomExceptionHandler'
+ end
+ end
+end
+
class TranslationHelperTest < ActiveSupport::TestCase
- include ActionView::Helpers::TagHelper
include ActionView::Helpers::TranslationHelper
attr_reader :request, :view
- def setup
+ setup do
I18n.backend.store_translations(:en,
:translations => {
:templates => {
@@ -30,6 +37,10 @@ class TranslationHelperTest < ActiveSupport::TestCase
@view = ::ActionView::Base.new(ActionController::Base.view_paths, {})
end
+ teardown do
+ I18n.backend.reload!
+ end
+
def test_delegates_to_i18n_setting_the_rescue_format_option_to_html
I18n.expects(:translate).with(:foo, :locale => 'en', :raise=>true).returns("")
translate :foo, :locale => 'en'
@@ -53,12 +64,38 @@ class TranslationHelperTest < ActiveSupport::TestCase
assert_equal false, translate(:"translations.missing", :rescue_format => nil).html_safe?
end
+ def test_raises_missing_translation_message_with_raise_config_option
+ ActionView::Base.raise_on_missing_translations = true
+
+ assert_raise(I18n::MissingTranslationData) do
+ translate("translations.missing")
+ end
+ ensure
+ ActionView::Base.raise_on_missing_translations = false
+ end
+
def test_raises_missing_translation_message_with_raise_option
assert_raise(I18n::MissingTranslationData) do
translate(:"translations.missing", :raise => true)
end
end
+ def test_uses_custom_exception_handler_when_specified
+ old_exception_handler = I18n.exception_handler
+ I18n.exception_handler = I18n::CustomExceptionHandler
+ assert_equal 'from CustomExceptionHandler', translate(:"translations.missing", raise: false)
+ ensure
+ I18n.exception_handler = old_exception_handler
+ end
+
+ def test_uses_custom_exception_handler_when_specified_for_html
+ old_exception_handler = I18n.exception_handler
+ I18n.exception_handler = I18n::CustomExceptionHandler
+ assert_equal 'from CustomExceptionHandler', translate(:"translations.missing_html", raise: false)
+ ensure
+ I18n.exception_handler = old_exception_handler
+ end
+
def test_i18n_translate_defaults_to_nil_rescue_format
expected = 'translation missing: en.translations.missing'
assert_equal expected, I18n.translate(:"translations.missing")
@@ -132,6 +169,12 @@ class TranslationHelperTest < ActiveSupport::TestCase
assert_equal true, translation.html_safe?
end
+ def test_translate_with_last_default_not_named_html
+ translation = translate(:'translations.missing', :default => [:'translations.missing_html', :'translations.foo'])
+ assert_equal 'Foo', translation
+ assert_equal false, translation.html_safe?
+ end
+
def test_translate_with_string_default
translation = translate(:'translations.missing', default: 'A Generic String')
assert_equal 'A Generic String', translation
@@ -141,4 +184,10 @@ class TranslationHelperTest < ActiveSupport::TestCase
translation = translate(:'translations.missing', default: ['A Generic String', 'Second generic string'])
assert_equal 'A Generic String', translation
end
+
+ def test_translate_does_not_change_options
+ options = {}
+ translate(:'translations.missing', options)
+ assert_equal({}, options)
+ end
end
diff --git a/actionview/test/template/url_helper_test.rb b/actionview/test/template/url_helper_test.rb
index deba33510a..0d6f31af9b 100644
--- a/actionview/test/template/url_helper_test.rb
+++ b/actionview/test/template/url_helper_test.rb
@@ -25,7 +25,7 @@ class UrlHelperTest < ActiveSupport::TestCase
include routes.url_helpers
include ActionView::Helpers::JavaScriptHelper
- include ActionDispatch::Assertions::DomAssertions
+ include Rails::Dom::Testing::Assertions::DomAssertions
include ActionView::Context
include RenderERBUtils
@@ -53,14 +53,21 @@ class UrlHelperTest < ActiveSupport::TestCase
end
def test_button_to_with_straight_url
- assert_dom_equal %{<form method="post" action="http://www.example.com" class="button_to"><div><input type="submit" value="Hello" /></div></form>}, button_to("Hello", "http://www.example.com")
+ assert_dom_equal %{<form method="post" action="http://www.example.com" class="button_to"><input type="submit" value="Hello" /></form>}, button_to("Hello", "http://www.example.com")
+ end
+
+ def test_button_to_with_path
+ assert_dom_equal(
+ %{<form method="post" action="/article/Hello" class="button_to"><input type="submit" value="Hello" /></form>},
+ button_to("Hello", article_path("Hello".html_safe))
+ )
end
def test_button_to_with_straight_url_and_request_forgery
self.request_forgery = true
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to"><div><input type="submit" value="Hello" /><input name="form_token" type="hidden" value="secret" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to"><input type="submit" value="Hello" /><input name="form_token" type="hidden" value="secret" /></form>},
button_to("Hello", "http://www.example.com")
)
ensure
@@ -68,102 +75,102 @@ class UrlHelperTest < ActiveSupport::TestCase
end
def test_button_to_with_form_class
- assert_dom_equal %{<form method="post" action="http://www.example.com" class="custom-class"><div><input type="submit" value="Hello" /></div></form>}, button_to("Hello", "http://www.example.com", form_class: 'custom-class')
+ assert_dom_equal %{<form method="post" action="http://www.example.com" class="custom-class"><input type="submit" value="Hello" /></form>}, button_to("Hello", "http://www.example.com", form_class: 'custom-class')
end
def test_button_to_with_form_class_escapes
- assert_dom_equal %{<form method="post" action="http://www.example.com" class="&lt;script&gt;evil_js&lt;/script&gt;"><div><input type="submit" value="Hello" /></div></form>}, button_to("Hello", "http://www.example.com", form_class: '<script>evil_js</script>')
+ assert_dom_equal %{<form method="post" action="http://www.example.com" class="&lt;script&gt;evil_js&lt;/script&gt;"><input type="submit" value="Hello" /></form>}, button_to("Hello", "http://www.example.com", form_class: '<script>evil_js</script>')
end
def test_button_to_with_query
- assert_dom_equal %{<form method="post" action="http://www.example.com/q1=v1&amp;q2=v2" class="button_to"><div><input type="submit" value="Hello" /></div></form>}, button_to("Hello", "http://www.example.com/q1=v1&q2=v2")
+ assert_dom_equal %{<form method="post" action="http://www.example.com/q1=v1&amp;q2=v2" class="button_to"><input type="submit" value="Hello" /></form>}, button_to("Hello", "http://www.example.com/q1=v1&q2=v2")
end
def test_button_to_with_html_safe_URL
- assert_dom_equal %{<form method="post" action="http://www.example.com/q1=v1&amp;q2=v2" class="button_to"><div><input type="submit" value="Hello" /></div></form>}, button_to("Hello", "http://www.example.com/q1=v1&amp;q2=v2".html_safe)
+ assert_dom_equal %{<form method="post" action="http://www.example.com/q1=v1&amp;q2=v2" class="button_to"><input type="submit" value="Hello" /></form>}, button_to("Hello", "http://www.example.com/q1=v1&amp;q2=v2".html_safe)
end
def test_button_to_with_query_and_no_name
- assert_dom_equal %{<form method="post" action="http://www.example.com?q1=v1&amp;q2=v2" class="button_to"><div><input type="submit" value="http://www.example.com?q1=v1&amp;q2=v2" /></div></form>}, button_to(nil, "http://www.example.com?q1=v1&q2=v2")
+ assert_dom_equal %{<form method="post" action="http://www.example.com?q1=v1&amp;q2=v2" class="button_to"><input type="submit" value="http://www.example.com?q1=v1&amp;q2=v2" /></form>}, button_to(nil, "http://www.example.com?q1=v1&q2=v2")
end
def test_button_to_with_javascript_confirm
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to"><div><input data-confirm="Are you sure?" type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to"><input data-confirm="Are you sure?" type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", data: { confirm: "Are you sure?" })
)
end
def test_button_to_with_javascript_disable_with
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to"><div><input data-disable-with="Greeting..." type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to"><input data-disable-with="Greeting..." type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", data: { disable_with: "Greeting..." })
)
end
def test_button_to_with_remote_and_form_options
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="custom-class" data-remote="true" data-type="json"><div><input type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="custom-class" data-remote="true" data-type="json"><input type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", remote: true, form: { class: "custom-class", "data-type" => "json" })
)
end
def test_button_to_with_remote_and_javascript_confirm
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to" data-remote="true"><div><input data-confirm="Are you sure?" type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to" data-remote="true"><input data-confirm="Are you sure?" type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", remote: true, data: { confirm: "Are you sure?" })
)
end
def test_button_to_with_remote_and_javascript_disable_with
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to" data-remote="true"><div><input data-disable-with="Greeting..." type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to" data-remote="true"><input data-disable-with="Greeting..." type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", remote: true, data: { disable_with: "Greeting..." })
)
end
def test_button_to_with_remote_false
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to"><div><input type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to"><input type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", remote: false)
)
end
def test_button_to_enabled_disabled
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to"><div><input type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to"><input type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", disabled: false)
)
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to"><div><input disabled="disabled" type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to"><input disabled="disabled" type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", disabled: true)
)
end
def test_button_to_with_method_delete
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to"><div><input type="hidden" name="_method" value="delete" /><input type="submit" value="Hello" /></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to"><input type="hidden" name="_method" value="delete" /><input type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", method: :delete)
)
end
def test_button_to_with_method_get
assert_dom_equal(
- %{<form method="get" action="http://www.example.com" class="button_to"><div><input type="submit" value="Hello" /></div></form>},
+ %{<form method="get" action="http://www.example.com" class="button_to"><input type="submit" value="Hello" /></form>},
button_to("Hello", "http://www.example.com", method: :get)
)
end
def test_button_to_with_block
assert_dom_equal(
- %{<form method="post" action="http://www.example.com" class="button_to"><div><button type="submit"><span>Hello</span></button></div></form>},
+ %{<form method="post" action="http://www.example.com" class="button_to"><button type="submit"><span>Hello</span></button></form>},
button_to("http://www.example.com") { content_tag(:span, 'Hello') }
)
end
def test_button_to_with_params
assert_dom_equal(
- %{<form action="http://www.example.com" class="button_to" method="post"><div><input type="submit" value="Hello" /><input type="hidden" name="foo" value="bar" /><input type="hidden" name="baz" value="quux" /></div></form>},
+ %{<form action="http://www.example.com" class="button_to" method="post"><input type="submit" value="Hello" /><input type="hidden" name="foo" value="bar" /><input type="hidden" name="baz" value="quux" /></form>},
button_to("Hello", "http://www.example.com", params: {foo: :bar, baz: "quux"})
)
end
@@ -486,8 +493,8 @@ class UrlHelperTest < ActiveSupport::TestCase
def test_mail_with_options
assert_dom_equal(
- %{<a href="mailto:me@example.com?cc=ccaddress%40example.com&amp;bcc=bccaddress%40example.com&amp;body=This%20is%20the%20body%20of%20the%20message.&amp;subject=This%20is%20an%20example%20email">My email</a>},
- mail_to("me@example.com", "My email", cc: "ccaddress@example.com", bcc: "bccaddress@example.com", subject: "This is an example email", body: "This is the body of the message.")
+ %{<a href="mailto:me@example.com?cc=ccaddress%40example.com&amp;bcc=bccaddress%40example.com&amp;body=This%20is%20the%20body%20of%20the%20message.&amp;subject=This%20is%20an%20example%20email&amp;reply-to=foo%40bar.com">My email</a>},
+ mail_to("me@example.com", "My email", cc: "ccaddress@example.com", bcc: "bccaddress@example.com", subject: "This is an example email", body: "This is the body of the message.", reply_to: "foo@bar.com")
)
end