Redmine 4.1.1
This commit is contained in:
parent
33e7b881a5
commit
3d976f1b3b
1593 changed files with 36180 additions and 19489 deletions
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2006-2019 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
|
||||
|
@ -32,4 +34,34 @@ class Redmine::WikiFormatting::HtmlParserTest < ActiveSupport::TestCase
|
|||
assert_equal "Text",
|
||||
@parser.to_text('<html><body><style>body {font-size: 0.8em;}</style>Text</body></html>')
|
||||
end
|
||||
|
||||
def test_should_remove_preceding_whitespaces
|
||||
to_test = {
|
||||
"<div> blocks with</div>\n<p>\n preceding whitespaces\n</p>" => "blocks with\n\npreceding whitespaces",
|
||||
"<div>blocks without</div>\n<p>\npreceding whitespaces\n</p>" => "blocks without\n\npreceding whitespaces",
|
||||
"<span> span with</span>\n<span> preceding whitespaces</span>" => "span with preceding whitespaces",
|
||||
"<span>span without</span>\n<span>preceding whitespaces</span>" => "span without preceding whitespaces"
|
||||
}
|
||||
to_test.each do |html, expected|
|
||||
assert_equal expected, @parser.to_text(html)
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_remove_space_of_beginning_of_line
|
||||
str = <<~HTML
|
||||
<table>
|
||||
<tr>
|
||||
<th>th1</th>
|
||||
<th>th2</th>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>td1</td>
|
||||
<td>td2</td>
|
||||
</tr>
|
||||
</table>
|
||||
HTML
|
||||
|
||||
assert_equal "th1\n\nth2\n\ntd1\n\ntd2",
|
||||
@parser.to_text(str)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2006-2019 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
|
||||
|
@ -26,12 +28,12 @@ class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest
|
|||
extend ActionView::Helpers::SanitizeHelper::ClassMethods
|
||||
|
||||
fixtures :projects, :roles, :enabled_modules, :users,
|
||||
:repositories, :changesets,
|
||||
:trackers, :issue_statuses, :issues,
|
||||
:versions, :documents,
|
||||
:wikis, :wiki_pages, :wiki_contents,
|
||||
:boards, :messages,
|
||||
:attachments
|
||||
:repositories, :changesets,
|
||||
:trackers, :issue_statuses, :issues,
|
||||
:versions, :documents,
|
||||
:wikis, :wiki_pages, :wiki_contents,
|
||||
:boards, :messages,
|
||||
:attachments, :enumerations
|
||||
|
||||
def setup
|
||||
super
|
||||
|
@ -87,7 +89,7 @@ class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest
|
|||
|
||||
def test_multiple_macros_on_the_same_line
|
||||
Redmine::WikiFormatting::Macros.macro :foo do |obj, args|
|
||||
args.any? ? "args: #{args.join(',')}" : "no args"
|
||||
args.any? ? "args: #{args.join(',')}" : "no args"
|
||||
end
|
||||
|
||||
assert_equal '<p>no args no args</p>', textilizable("{{foo}} {{foo}}")
|
||||
|
@ -210,11 +212,11 @@ class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest
|
|||
text = "{{collapse\n*Collapsed* block of text\n}}"
|
||||
with_locale 'en' do
|
||||
result = textilizable(text)
|
||||
|
||||
|
||||
assert_select_in result, 'div.collapsed-text'
|
||||
assert_select_in result, 'strong', :text => 'Collapsed'
|
||||
assert_select_in result, 'a.collapsible.collapsed', :text => 'Show'
|
||||
assert_select_in result, 'a.collapsible', :text => 'Hide'
|
||||
assert_select_in result, 'a.collapsible.icon-collapsed', :text => 'Show'
|
||||
assert_select_in result, 'a.collapsible.icon-expended', :text => 'Hide'
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -224,8 +226,8 @@ class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest
|
|||
|
||||
assert_select_in result, 'div.collapsed-text'
|
||||
assert_select_in result, 'strong', :text => 'Collapsed'
|
||||
assert_select_in result, 'a.collapsible.collapsed', :text => 'Example'
|
||||
assert_select_in result, 'a.collapsible', :text => 'Example'
|
||||
assert_select_in result, 'a.collapsible.icon-collapsed', :text => 'Example'
|
||||
assert_select_in result, 'a.collapsible.icon-expended', :text => 'Example'
|
||||
end
|
||||
|
||||
def test_macro_collapse_with_two_args
|
||||
|
@ -234,22 +236,22 @@ class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest
|
|||
|
||||
assert_select_in result, 'div.collapsed-text'
|
||||
assert_select_in result, 'strong', :text => 'Collapsed'
|
||||
assert_select_in result, 'a.collapsible.collapsed', :text => 'Show example'
|
||||
assert_select_in result, 'a.collapsible', :text => 'Hide example'
|
||||
assert_select_in result, 'a.collapsible.icon-collapsed', :text => 'Show example'
|
||||
assert_select_in result, 'a.collapsible.icon-expended', :text => 'Hide example'
|
||||
end
|
||||
|
||||
def test_macro_collapse_should_not_break_toc
|
||||
set_language_if_valid 'en'
|
||||
|
||||
text = <<-RAW
|
||||
{{toc}}
|
||||
text = <<~RAW
|
||||
{{toc}}
|
||||
|
||||
h1. Title
|
||||
h1. Title
|
||||
|
||||
{{collapse(Show example, Hide example)
|
||||
h2. Heading
|
||||
}}"
|
||||
RAW
|
||||
{{collapse(Show example, Hide example)
|
||||
h2. Heading
|
||||
}}"
|
||||
RAW
|
||||
|
||||
expected_toc = '<ul class="toc"><li><strong>Table of contents</strong></li><li><a href="#Title">Title</a><ul><li><a href="#Heading">Heading</a></li></ul></li></ul>'
|
||||
|
||||
|
@ -307,7 +309,7 @@ RAW
|
|||
end
|
||||
|
||||
def test_macro_thumbnail
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17" />'.html_safe,
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17/200" />'.html_safe,
|
||||
"/attachments/17",
|
||||
:class => "thumbnail",
|
||||
:title => "testfile.PNG")
|
||||
|
@ -316,7 +318,7 @@ RAW
|
|||
end
|
||||
|
||||
def test_macro_thumbnail_with_full_path
|
||||
link = link_to('<img alt="testfile.PNG" src="http://test.host/attachments/thumbnail/17" />'.html_safe,
|
||||
link = link_to('<img alt="testfile.PNG" src="http://test.host/attachments/thumbnail/17/200" />'.html_safe,
|
||||
"http://test.host/attachments/17",
|
||||
:class => "thumbnail",
|
||||
:title => "testfile.PNG")
|
||||
|
@ -325,16 +327,16 @@ RAW
|
|||
end
|
||||
|
||||
def test_macro_thumbnail_with_size
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17/200" />'.html_safe,
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17/400" />'.html_safe,
|
||||
"/attachments/17",
|
||||
:class => "thumbnail",
|
||||
:title => "testfile.PNG")
|
||||
assert_equal "<p>#{link}</p>",
|
||||
textilizable("{{thumbnail(testfile.png, size=200)}}", :object => Issue.find(14))
|
||||
textilizable("{{thumbnail(testfile.png, size=400)}}", :object => Issue.find(14))
|
||||
end
|
||||
|
||||
def test_macro_thumbnail_with_title
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17" />'.html_safe,
|
||||
link = link_to('<img alt="testfile.PNG" src="/attachments/thumbnail/17/200" />'.html_safe,
|
||||
"/attachments/17",
|
||||
:class => "thumbnail",
|
||||
:title => "Cool image")
|
||||
|
@ -344,32 +346,30 @@ RAW
|
|||
|
||||
def test_macro_thumbnail_with_invalid_filename_should_fail
|
||||
assert_include 'test.png not found',
|
||||
textilizable("{{thumbnail(test.png)}}", :object => Issue.find(14))
|
||||
textilizable("{{thumbnail(test.png)}}", :object => Issue.find(14))
|
||||
end
|
||||
|
||||
def test_macros_should_not_be_executed_in_pre_tags
|
||||
text = <<-RAW
|
||||
{{hello_world(foo)}}
|
||||
text = <<~RAW
|
||||
{{hello_world(foo)}}
|
||||
|
||||
<pre>
|
||||
{{hello_world(pre)}}
|
||||
!{{hello_world(pre)}}
|
||||
</pre>
|
||||
<pre>
|
||||
{{hello_world(pre)}}
|
||||
!{{hello_world(pre)}}
|
||||
</pre>
|
||||
|
||||
{{hello_world(bar)}}
|
||||
RAW
|
||||
{{hello_world(bar)}}
|
||||
RAW
|
||||
expected = <<~EXPECTED
|
||||
<p>Hello world! Object: NilClass, Arguments: foo and no block of text.</p>
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>Hello world! Object: NilClass, Arguments: foo and no block of text.</p>
|
||||
|
||||
<pre>
|
||||
{{hello_world(pre)}}
|
||||
!{{hello_world(pre)}}
|
||||
</pre>
|
||||
|
||||
<p>Hello world! Object: NilClass, Arguments: bar and no block of text.</p>
|
||||
EXPECTED
|
||||
<pre>
|
||||
{{hello_world(pre)}}
|
||||
!{{hello_world(pre)}}
|
||||
</pre>
|
||||
|
||||
<p>Hello world! Object: NilClass, Arguments: bar and no block of text.</p>
|
||||
EXPECTED
|
||||
assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
|
||||
end
|
||||
|
||||
|
@ -384,21 +384,19 @@ EXPECTED
|
|||
end
|
||||
|
||||
def test_macros_with_text_should_not_mangle_following_macros
|
||||
text = <<-RAW
|
||||
{{hello_world
|
||||
Line of text
|
||||
}}
|
||||
|
||||
{{hello_world
|
||||
Another line of text
|
||||
}}
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>Hello world! Object: NilClass, Called with no argument and a 12 bytes long block of text.</p>
|
||||
<p>Hello world! Object: NilClass, Called with no argument and a 20 bytes long block of text.</p>
|
||||
EXPECTED
|
||||
text = <<~RAW
|
||||
{{hello_world
|
||||
Line of text
|
||||
}}
|
||||
|
||||
{{hello_world
|
||||
Another line of text
|
||||
}}
|
||||
RAW
|
||||
expected = <<~EXPECTED
|
||||
<p>Hello world! Object: NilClass, Called with no argument and a 12 bytes long block of text.</p>
|
||||
<p>Hello world! Object: NilClass, Called with no argument and a 20 bytes long block of text.</p>
|
||||
EXPECTED
|
||||
assert_equal expected.gsub(%r{[\r\n\t]}, ''), textilizable(text).gsub(%r{[\r\n\t]}, '')
|
||||
end
|
||||
|
||||
|
@ -406,4 +404,14 @@ EXPECTED
|
|||
text = "*{{hello_world}}*"
|
||||
assert_match %r|\A<p><strong>Hello world!.*</strong></p>\z|, textilizable(text)
|
||||
end
|
||||
|
||||
def test_issue_macro_should_not_render_link_if_not_visible
|
||||
assert_equal "<p>#123</p>", textilizable('{{issue(123)}}')
|
||||
end
|
||||
|
||||
def test_issue_macro_should_render_link_to_issue
|
||||
issue = Issue.find 1
|
||||
assert_equal %{<p><a class="issue tracker-1 status-1 priority-4 priority-lowest" href="/issues/1">Bug #1</a>: #{issue.subject}</p>}, textilizable("{{issue(1)}}")
|
||||
assert_equal %{<p>eCookbook - <a class="issue tracker-1 status-1 priority-4 priority-lowest" href="/issues/1">Bug #1</a>: #{issue.subject}</p>}, textilizable("{{issue(1, project=true)}}")
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2006-2019 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
|
||||
|
@ -58,24 +60,24 @@ class Redmine::WikiFormatting::MarkdownFormatterTest < ActionView::TestCase
|
|||
assert_include 'version:"1.0"', @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
def test_should_support_syntax_highligth
|
||||
text = <<-STR
|
||||
~~~ruby
|
||||
def foo
|
||||
end
|
||||
~~~
|
||||
STR
|
||||
def test_should_support_syntax_highlight
|
||||
text = <<~STR
|
||||
~~~ruby
|
||||
def foo
|
||||
end
|
||||
~~~
|
||||
STR
|
||||
assert_select_in @formatter.new(text).to_html, 'pre code.ruby.syntaxhl' do
|
||||
assert_select 'span.keyword', :text => 'def'
|
||||
assert_select 'span.k', :text => 'def'
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_not_allow_invalid_language_for_code_blocks
|
||||
text = <<-STR
|
||||
~~~foo
|
||||
test
|
||||
~~~
|
||||
STR
|
||||
text = <<~STR
|
||||
~~~foo
|
||||
test
|
||||
~~~
|
||||
STR
|
||||
assert_equal "<pre>test\n</pre>", @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
|
@ -90,43 +92,76 @@ STR
|
|||
end
|
||||
|
||||
def test_markdown_should_not_require_surrounded_empty_line
|
||||
text = <<-STR
|
||||
This is a list:
|
||||
* One
|
||||
* Two
|
||||
STR
|
||||
text = <<~STR
|
||||
This is a list:
|
||||
* One
|
||||
* Two
|
||||
STR
|
||||
assert_equal "<p>This is a list:</p>\n\n<ul>\n<li>One</li>\n<li>Two</li>\n</ul>", @formatter.new(text).to_html.strip
|
||||
end
|
||||
|
||||
STR_WITH_PRE = [
|
||||
# 0
|
||||
"# Title
|
||||
def test_footnotes
|
||||
text = <<~STR
|
||||
This is some text[^1].
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
|
||||
# 1
|
||||
"## Heading 2
|
||||
[^1]: This is the foot note
|
||||
STR
|
||||
expected = <<~EXPECTED
|
||||
<p>This is some text<sup id="fnref1"><a href="#fn1">1</a></sup>.</p>
|
||||
<div class="footnotes">
|
||||
<hr>
|
||||
<ol>
|
||||
|
||||
~~~ruby
|
||||
def foo
|
||||
<li id="fn1">
|
||||
<p>This is the foot note <a href="#fnref1">↩</a></p>
|
||||
</li>
|
||||
|
||||
</ol>
|
||||
</div>
|
||||
EXPECTED
|
||||
assert_equal expected.gsub(%r{[\r\n\t]}, ''), @formatter.new(text).to_html.gsub(%r{[\r\n\t]}, '')
|
||||
end
|
||||
>>>>>>> .merge-right.r17266
|
||||
~~~
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
STR_WITH_PRE = [
|
||||
# 0
|
||||
<<~STR.chomp,
|
||||
# Title
|
||||
|
||||
```
|
||||
Pre Content:
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
STR
|
||||
# 1
|
||||
<<~STR.chomp,
|
||||
## Heading 2
|
||||
|
||||
## Inside pre
|
||||
~~~ruby
|
||||
def foo
|
||||
end
|
||||
~~~
|
||||
|
||||
<tag> inside pre block
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
```",
|
||||
# 2
|
||||
"### Heading 3
|
||||
~~~ ruby
|
||||
def foo
|
||||
end
|
||||
~~~
|
||||
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
|
||||
```
|
||||
Pre Content:
|
||||
|
||||
## Inside pre
|
||||
|
||||
<tag> inside pre block
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
```
|
||||
STR
|
||||
# 2
|
||||
<<~STR.chomp,
|
||||
### Heading 3
|
||||
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero.
|
||||
STR
|
||||
]
|
||||
|
||||
def test_get_section_should_ignore_pre_content
|
||||
text = STR_WITH_PRE.join("\n\n")
|
||||
|
@ -143,6 +178,11 @@ Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
|
|||
@formatter.new(text).update_section(3, replacement)
|
||||
end
|
||||
|
||||
def test_should_support_underlined_text
|
||||
text = 'This _text_ should be underlined'
|
||||
assert_equal '<p>This <u>text</u> should be underlined</p>', @formatter.new(text).to_html.strip
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def assert_section_with_hash(expected, text, index)
|
||||
|
@ -153,6 +193,5 @@ Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
|
|||
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
|
||||
end
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2006-2019 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
|
||||
|
@ -26,5 +28,22 @@ class Redmine::WikiFormatting::MarkdownHtmlParserTest < ActiveSupport::TestCase
|
|||
def test_should_convert_tags
|
||||
assert_equal 'A **simple** html snippet.',
|
||||
@parser.to_text('<p>A <b>simple</b> html snippet.</p>')
|
||||
|
||||
assert_equal 'foo [bar](http://example.com/) baz',
|
||||
@parser.to_text('foo<a href="http://example.com/">bar</a>baz')
|
||||
|
||||
assert_equal 'foo http://example.com/ baz',
|
||||
@parser.to_text('foo<a href="http://example.com/"></a>baz')
|
||||
|
||||
assert_equal 'foobarbaz',
|
||||
@parser.to_text('foo<a name="Header-one">bar</a>baz')
|
||||
|
||||
assert_equal 'foobaz',
|
||||
@parser.to_text('foo<a name="Header-one"/>baz')
|
||||
end
|
||||
|
||||
def test_html_tables_conversion
|
||||
assert_equal "*th1*\n*th2*\n\ntd1\ntd2",
|
||||
@parser.to_text('<table><tr><th>th1</th><th>th2</th></tr><tr><td>td1</td><td>td2</td></tr></table>')
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#encoding: utf-8
|
||||
# frozen_string_literal: true
|
||||
|
||||
#
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2006-2019 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
|
||||
|
@ -80,6 +81,10 @@ class Redmine::WikiFormatting::TextileFormatterTest < ActionView::TestCase
|
|||
'p{border-right:1px}. text' => '<p style="border-right:1px;">text</p>',
|
||||
'p{border-top:1px}. text' => '<p style="border-top:1px;">text</p>',
|
||||
'p{border-bottom:1px}. text' => '<p style="border-bottom:1px;">text</p>',
|
||||
'p{width:50px}. text' => '<p style="width:50px;">text</p>',
|
||||
'p{max-width:100px}. text' => '<p style="max-width:100px;">text</p>',
|
||||
'p{height:40px}. text' => '<p style="height:40px;">text</p>',
|
||||
'p{max-height:80px}. text' => '<p style="max-height:80px;">text</p>',
|
||||
}, false)
|
||||
|
||||
# multiple styles
|
||||
|
@ -156,6 +161,24 @@ RAW
|
|||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
|
||||
raw = <<~RAW
|
||||
* Item-1
|
||||
|
||||
* Item-1a
|
||||
* Item-1b
|
||||
RAW
|
||||
expected = <<~EXPECTED
|
||||
<ul>
|
||||
<li>Item-1
|
||||
<ul>
|
||||
<li>Item-1a</li>
|
||||
<li>Item-1b</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
EXPECTED
|
||||
assert_equal expected.gsub(%r{\s+}, ''), to_html(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_escaping
|
||||
|
@ -276,7 +299,7 @@ EXPECTED
|
|||
This is a table with trailing whitespace in one row:
|
||||
|
||||
|cell11|cell12|
|
||||
|cell21|cell22|
|
||||
|cell21|cell22|
|
||||
|cell31|cell32|
|
||||
RAW
|
||||
|
||||
|
@ -378,67 +401,76 @@ EXPECTED
|
|||
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
|
||||
# 0
|
||||
<<~STR.chomp,
|
||||
h1. Title
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
|
||||
# 1
|
||||
"h2. Heading 2
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
STR
|
||||
# 1
|
||||
<<~STR.chomp,
|
||||
h2. Heading 2
|
||||
|
||||
Maecenas sed elit sit amet mi accumsan vestibulum non nec velit. Proin porta tincidunt lorem, consequat rhoncus dolor fermentum in.
|
||||
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
|
||||
Cras ipsum felis, ultrices at porttitor vel, faucibus eu nunc.
|
||||
STR
|
||||
# 2
|
||||
<<~STR.chomp,
|
||||
h2. Heading 2
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
|
||||
h3. Heading 3
|
||||
h3. Heading 3
|
||||
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero.",
|
||||
# 3
|
||||
"h3. Heading 3
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero.
|
||||
STR
|
||||
# 3
|
||||
<<~STR.chomp,
|
||||
h3. Heading 3
|
||||
|
||||
Praesent eget turpis nibh, a lacinia nulla.",
|
||||
# 4
|
||||
"h2. Heading 2
|
||||
|
||||
Ut rhoncus elementum adipiscing."]
|
||||
Praesent eget turpis nibh, a lacinia nulla.
|
||||
STR
|
||||
# 4
|
||||
<<~STR.chomp,
|
||||
h2. Heading 2
|
||||
|
||||
Ut rhoncus elementum adipiscing.
|
||||
STR
|
||||
]
|
||||
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"))
|
||||
|
@ -446,38 +478,45 @@ Ut rhoncus elementum adipiscing."]
|
|||
end
|
||||
|
||||
STR_WITH_PRE = [
|
||||
# 0
|
||||
"h1. Title
|
||||
# 0
|
||||
<<~STR.chomp,
|
||||
h1. Title
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.",
|
||||
# 1
|
||||
"h2. Heading 2
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
STR
|
||||
# 1
|
||||
<<~STR.chomp,
|
||||
h2. Heading 2
|
||||
|
||||
<pre><code class=\"ruby\">
|
||||
def foo
|
||||
end
|
||||
</code></pre>
|
||||
<pre><code class=\"ruby\">
|
||||
def foo
|
||||
end
|
||||
</code></pre>
|
||||
|
||||
<pre><code><pre><code class=\"ruby\">
|
||||
Place your code here.
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
<pre><code><pre><code class=\"ruby\">
|
||||
Place your code here.
|
||||
</code></pre>
|
||||
</code></pre>
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
|
||||
<pre>
|
||||
Pre Content:
|
||||
<pre>
|
||||
Pre Content:
|
||||
|
||||
h2. Inside pre
|
||||
h2. Inside pre
|
||||
|
||||
<tag> inside pre block
|
||||
<tag> inside pre block
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
</pre>",
|
||||
# 2
|
||||
"h3. Heading 3
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
</pre>
|
||||
STR
|
||||
# 2
|
||||
<<~STR.chomp,
|
||||
h3. Heading 3
|
||||
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero.
|
||||
STR
|
||||
]
|
||||
|
||||
def test_get_section_should_ignore_pre_content
|
||||
text = STR_WITH_PRE.join("\n\n")
|
||||
|
@ -489,7 +528,7 @@ Nulla nunc nisi, egestas in ornare vel, posuere ac libero."]
|
|||
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
|
||||
|
@ -504,13 +543,13 @@ Content 1
|
|||
h1. Heading 2
|
||||
|
||||
Content 2
|
||||
|
||||
|
||||
h1. Heading 3
|
||||
|
||||
Content 3
|
||||
|
||||
h1. Heading 4
|
||||
|
||||
|
||||
Content 4
|
||||
STR
|
||||
|
||||
|
@ -551,9 +590,9 @@ STR
|
|||
|
||||
def test_should_allow_valid_language_class_attribute_on_code_tags
|
||||
# language name is double-quoted
|
||||
assert_html_output({"<code class=\"ruby\">test</code>" => "<code class=\"ruby syntaxhl\"><span class=\"CodeRay\">test</span></code>"}, false)
|
||||
assert_html_output({"<code class=\"ruby\">test</code>" => "<code class=\"ruby syntaxhl\"><span class=\"nb\">test</span></code>"}, false)
|
||||
# language name is single-quoted
|
||||
assert_html_output({"<code class='ruby'>test</code>" => "<code class=\"ruby syntaxhl\"><span class=\"CodeRay\">test</span></code>"}, false)
|
||||
assert_html_output({"<code class='ruby'>test</code>" => "<code class=\"ruby syntaxhl\"><span class=\"nb\">test</span></code>"}, false)
|
||||
end
|
||||
|
||||
def test_should_not_allow_valid_language_class_attribute_on_non_code_offtags
|
||||
|
@ -588,6 +627,21 @@ STR
|
|||
}, false)
|
||||
end
|
||||
|
||||
def test_footnotes
|
||||
text = <<-STR
|
||||
This is some text[1].
|
||||
|
||||
fn1. This is the foot note
|
||||
STR
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>This is some text<sup><a href=\"#fn1\">1</a></sup>.</p>
|
||||
<p id="fn1" class="footnote"><sup>1</sup> This is the foot note</p>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{[\r\n\t]}, ''), to_html(text).gsub(%r{[\r\n\t]}, '')
|
||||
end
|
||||
|
||||
# TODO: Remove this test after migrating to RedCloth 4
|
||||
def test_should_not_crash_with_special_input
|
||||
assert_nothing_raised { to_html(" \f") }
|
||||
|
@ -621,10 +675,10 @@ EXPECTED
|
|||
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"
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2017 Jean-Philippe Lang
|
||||
# Copyright (C) 2006-2019 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
|
||||
|
@ -26,5 +28,22 @@ class Redmine::WikiFormatting::TextileHtmlParserTest < ActiveSupport::TestCase
|
|||
def test_should_convert_tags
|
||||
assert_equal 'A *simple* html snippet.',
|
||||
@parser.to_text('<p>A <b>simple</b> html snippet.</p>')
|
||||
|
||||
assert_equal 'foo "bar":http://example.com/ baz',
|
||||
@parser.to_text('foo<a href="http://example.com/">bar</a>baz')
|
||||
|
||||
assert_equal 'foo http://example.com/ baz',
|
||||
@parser.to_text('foo<a href="http://example.com/"></a>baz')
|
||||
|
||||
assert_equal 'foobarbaz',
|
||||
@parser.to_text('foo<a name="Header-one">bar</a>baz')
|
||||
|
||||
assert_equal 'foobaz',
|
||||
@parser.to_text('foo<a name="Header-one"/>baz')
|
||||
end
|
||||
|
||||
def test_html_tables_conversion
|
||||
assert_equal "*th1*\n*th2*\n\ntd1\ntd2",
|
||||
@parser.to_text('<table><tr><th>th1</th><th>th2</th></tr><tr><td>td1</td><td>td2</td></tr></table>')
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue