Mercurial > hg > soundsoftware-site
diff .svn/pristine/8e/8e4c7afc7109386dd42e0a86c04a6247a9bd537e.svn-base @ 909:cbb26bc654de redmine-1.3
Update to Redmine 1.3-stable branch (Redmine SVN rev 8964)
author | Chris Cannam |
---|---|
date | Fri, 24 Feb 2012 19:09:32 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.svn/pristine/8e/8e4c7afc7109386dd42e0a86c04a6247a9bd537e.svn-base Fri Feb 24 19:09:32 2012 +0000 @@ -0,0 +1,343 @@ +# Redmine - project management software +# Copyright (C) 2006-2011 Jean-Philippe Lang +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +require File.expand_path('../../../../../test_helper', __FILE__) +require 'digest/md5' + +class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase + + def setup + @formatter = Redmine::WikiFormatting::Textile::Formatter + end + + MODIFIERS = { + "*" => 'strong', # bold + "_" => 'em', # italic + "+" => 'ins', # underline + "-" => 'del', # deleted + "^" => 'sup', # superscript + "~" => 'sub' # subscript + } + + def test_modifiers + assert_html_output( + '*bold*' => '<strong>bold</strong>', + 'before *bold*' => 'before <strong>bold</strong>', + '*bold* after' => '<strong>bold</strong> after', + '*two words*' => '<strong>two words</strong>', + '*two*words*' => '<strong>two*words</strong>', + '*two * words*' => '<strong>two * words</strong>', + '*two* *words*' => '<strong>two</strong> <strong>words</strong>', + '*(two)* *(words)*' => '<strong>(two)</strong> <strong>(words)</strong>', + # with class + '*(foo)two words*' => '<strong class="foo">two words</strong>' + ) + end + + def test_modifiers_combination + MODIFIERS.each do |m1, tag1| + MODIFIERS.each do |m2, tag2| + next if m1 == m2 + text = "#{m2}#{m1}Phrase modifiers#{m1}#{m2}" + html = "<#{tag2}><#{tag1}>Phrase modifiers</#{tag1}></#{tag2}>" + assert_html_output text => html + end + end + end + + def test_inline_code + assert_html_output( + 'this is @some code@' => 'this is <code>some code</code>', + '@<Location /redmine>@' => '<code><Location /redmine></code>' + ) + end + + def test_escaping + assert_html_output( + 'this is a <script>' => 'this is a <script>' + ) + end + + def test_use_of_backslashes_followed_by_numbers_in_headers + assert_html_output({ + 'h1. 2009\02\09' => '<h1>2009\02\09</h1>' + }, false) + end + + def test_double_dashes_should_not_strikethrough + assert_html_output( + 'double -- dashes -- test' => 'double -- dashes -- test', + 'double -- *dashes* -- test' => 'double -- <strong>dashes</strong> -- test' + ) + end + + def test_acronyms + assert_html_output( + 'this is an acronym: GPL(General Public License)' => 'this is an acronym: <acronym title="General Public License">GPL</acronym>', + '2 letters JP(Jean-Philippe) acronym' => '2 letters <acronym title="Jean-Philippe">JP</acronym> acronym', + 'GPL(This is a double-quoted "title")' => '<acronym title="This is a double-quoted "title"">GPL</acronym>' + ) + end + + def test_blockquote + # orig raw text + raw = <<-RAW +John said: +> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero. +> Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor. +> * Donec odio lorem, +> * sagittis ac, +> * malesuada in, +> * adipiscing eu, dolor. +> +> >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus. +> Proin a tellus. Nam vel neque. + +He's right. +RAW + + # expected html + expected = <<-EXPECTED +<p>John said:</p> +<blockquote> +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.<br /> +Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor. +<ul> + <li>Donec odio lorem,</li> + <li>sagittis ac,</li> + <li>malesuada in,</li> + <li>adipiscing eu, dolor.</li> +</ul> +<blockquote> +<p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p> +</blockquote> +<p>Proin a tellus. Nam vel neque.</p> +</blockquote> +<p>He's right.</p> +EXPECTED + + assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '') + end + + def test_table + raw = <<-RAW +This is a table with empty cells: + +|cell11|cell12|| +|cell21||cell23| +|cell31|cell32|cell33| +RAW + + expected = <<-EXPECTED +<p>This is a table with empty cells:</p> + +<table> + <tr><td>cell11</td><td>cell12</td><td></td></tr> + <tr><td>cell21</td><td></td><td>cell23</td></tr> + <tr><td>cell31</td><td>cell32</td><td>cell33</td></tr> +</table> +EXPECTED + + assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '') + end + + def test_table_with_line_breaks + raw = <<-RAW +This is a table with line breaks: + +|cell11 +continued|cell12|| +|-cell21-||cell23 +cell23 line2 +cell23 *line3*| +|cell31|cell32 +cell32 line2|cell33| + +RAW + + expected = <<-EXPECTED +<p>This is a table with line breaks:</p> + +<table> + <tr> + <td>cell11<br />continued</td> + <td>cell12</td> + <td></td> + </tr> + <tr> + <td><del>cell21</del></td> + <td></td> + <td>cell23<br/>cell23 line2<br/>cell23 <strong>line3</strong></td> + </tr> + <tr> + <td>cell31</td> + <td>cell32<br/>cell32 line2</td> + <td>cell33</td> + </tr> +</table> +EXPECTED + + assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '') + end + + def test_textile_should_not_mangle_brackets + assert_equal '<p>[msg1][msg2]</p>', to_html('[msg1][msg2]') + end + + def test_textile_should_escape_image_urls + # this is onclick="alert('XSS');" in encoded form + raw = '!/images/comment.png"onclick=alert('XSS');"!' + expected = '<p><img src="/images/comment.png"onclick=&#x61;&#x6c;&#x65;&#x72;&#x74;&#x28;&#x27;&#x58;&#x53;&#x53;&#x27;&#x29;;&#x22;" alt="" /></p>' + assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '') + end + + + STR_WITHOUT_PRE = [ + # 0 +"h1. Title + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.", + # 1 +"h2. Heading 2 + +Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in. + +Cras ipsum felis, ultrices at porttitor vel, faucibus eu nunc.", + # 2 +"h2. Heading 2 + +Morbi facilisis accumsan orci non pharetra. + +h3. Heading 3 + +Nulla nunc nisi, egestas in ornare vel, posuere ac libero.", + # 3 +"h3. Heading 3 + +Praesent eget turpis nibh, a lacinia nulla.", + # 4 +"h2. Heading 2 + +Ut rhoncus elementum adipiscing."] + + TEXT_WITHOUT_PRE = STR_WITHOUT_PRE.join("\n\n").freeze + + def test_get_section_should_return_the_requested_section_and_its_hash + assert_section_with_hash STR_WITHOUT_PRE[1], TEXT_WITHOUT_PRE, 2 + assert_section_with_hash STR_WITHOUT_PRE[2..3].join("\n\n"), TEXT_WITHOUT_PRE, 3 + assert_section_with_hash STR_WITHOUT_PRE[3], TEXT_WITHOUT_PRE, 5 + assert_section_with_hash STR_WITHOUT_PRE[4], TEXT_WITHOUT_PRE, 6 + + assert_section_with_hash '', TEXT_WITHOUT_PRE, 0 + assert_section_with_hash '', TEXT_WITHOUT_PRE, 10 + end + + def test_update_section_should_update_the_requested_section + replacement = "New text" + + assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement) + assert_equal [STR_WITHOUT_PRE[0..1], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(3, replacement) + assert_equal [STR_WITHOUT_PRE[0..2], replacement, STR_WITHOUT_PRE[4]].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(5, replacement) + assert_equal [STR_WITHOUT_PRE[0..3], replacement].flatten.join("\n\n"), @formatter.new(TEXT_WITHOUT_PRE).update_section(6, replacement) + + assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(0, replacement) + assert_equal TEXT_WITHOUT_PRE, @formatter.new(TEXT_WITHOUT_PRE).update_section(10, replacement) + end + + def test_update_section_with_hash_should_update_the_requested_section + replacement = "New text" + + assert_equal [STR_WITHOUT_PRE[0], replacement, STR_WITHOUT_PRE[2..4]].flatten.join("\n\n"), + @formatter.new(TEXT_WITHOUT_PRE).update_section(2, replacement, Digest::MD5.hexdigest(STR_WITHOUT_PRE[1])) + end + + def test_update_section_with_wrong_hash_should_raise_an_error + assert_raise Redmine::WikiFormatting::StaleSectionError do + @formatter.new(TEXT_WITHOUT_PRE).update_section(2, "New text", Digest::MD5.hexdigest("Old text")) + end + end + + STR_WITH_PRE = [ + # 0 +"h1. Title + +Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.", + # 1 +"h2. Heading 2 + +<pre><code class=\"ruby\"> + def foo + end +</code></pre> + +<pre><code><pre><code class=\"ruby\"> + Place your code here. +</code></pre> +</code></pre> + +Morbi facilisis accumsan orci non pharetra. + +<pre> +Pre Content: + +h2. Inside pre + +<tag> inside pre block + +Morbi facilisis accumsan orci non pharetra. +</pre>", + # 2 +"h3. Heading 3 + +Nulla nunc nisi, egestas in ornare vel, posuere ac libero."] + + def test_get_section_should_ignore_pre_content + text = STR_WITH_PRE.join("\n\n") + + assert_section_with_hash STR_WITH_PRE[1..2].join("\n\n"), text, 2 + assert_section_with_hash STR_WITH_PRE[2], text, 3 + end + + def test_update_section_should_not_escape_pre_content_outside_section + text = STR_WITH_PRE.join("\n\n") + replacement = "New text" + + assert_equal [STR_WITH_PRE[0..1], "New text"].flatten.join("\n\n"), + @formatter.new(text).update_section(3, replacement) + end + + private + + def assert_html_output(to_test, expect_paragraph = true) + to_test.each do |text, expected| + assert_equal(( expect_paragraph ? "<p>#{expected}</p>" : expected ), @formatter.new(text).to_html, "Formatting the following text failed:\n===\n#{text}\n===\n") + end + end + + def to_html(text) + @formatter.new(text).to_html + end + + def assert_section_with_hash(expected, text, index) + result = @formatter.new(text).get_section(index) + + assert_kind_of Array, result + assert_equal 2, result.size + assert_equal expected, result.first, "section content did not match" + assert_equal Digest::MD5.hexdigest(expected), result.last, "section hash did not match" + end +end