mirror of
https://github.com/redmine/redmine.git
synced 2026-07-11 01:03:11 +02:00
Drop deprecated Redcarpet based Markdown formatter (#40149).
Patch by Go MAEDA (user:maeda). git-svn-id: https://svn.redmine.org/redmine/trunk@23153 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
@@ -113,7 +113,7 @@ class Redmine::Acts::MentionableTest < ActiveSupport::TestCase
|
||||
```
|
||||
STR
|
||||
|
||||
with_settings text_formatting: 'markdown' do
|
||||
with_settings text_formatting: 'common_mark' do
|
||||
issue = Issue.generate!(project_id: 1, description: description)
|
||||
|
||||
assert_equal [], issue.mentioned_users
|
||||
|
||||
@@ -1,354 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006- 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_relative '../../../../test_helper'
|
||||
|
||||
class Redmine::WikiFormatting::MarkdownFormatterTest < ActionView::TestCase
|
||||
def setup
|
||||
unless Object.const_defined?(:Redcarpet)
|
||||
skip "Redcarpet is not installed"
|
||||
end
|
||||
@formatter = Redmine::WikiFormatting::Markdown::Formatter
|
||||
end
|
||||
|
||||
def test_syntax_error_in_image_reference_should_not_raise_exception
|
||||
assert @formatter.new("!>[](foo.png)").to_html
|
||||
end
|
||||
|
||||
def test_empty_image_should_not_raise_exception
|
||||
assert @formatter.new("![]()").to_html
|
||||
end
|
||||
|
||||
# re-using the formatter after getting above error crashes the
|
||||
# ruby interpreter. This seems to be related to
|
||||
# https://github.com/vmg/redcarpet/issues/318
|
||||
def test_should_not_crash_redcarpet_after_syntax_error
|
||||
@formatter.new("!>[](foo.png)").to_html rescue nil
|
||||
assert @formatter.new("").to_html.present?
|
||||
end
|
||||
|
||||
def test_inline_style
|
||||
assert_equal "<p><strong>foo</strong></p>", @formatter.new("**foo**").to_html.strip
|
||||
end
|
||||
|
||||
def test_not_set_intra_emphasis
|
||||
assert_equal "<p>foo_bar_baz</p>", @formatter.new("foo_bar_baz").to_html.strip
|
||||
end
|
||||
|
||||
def test_wiki_links_should_be_preserved
|
||||
text = 'This is a wiki link: [[Foo]]'
|
||||
assert_include '[[Foo]]', @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
def test_redmine_links_with_double_quotes_should_be_preserved
|
||||
text = 'This is a redmine link: version:"1.0"'
|
||||
assert_include 'version:"1.0"', @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
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.k', :text => 'def'
|
||||
assert_select "[data-language='ruby']"
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_not_allow_invalid_language_for_code_blocks
|
||||
text = <<~STR
|
||||
~~~foo
|
||||
test
|
||||
~~~
|
||||
STR
|
||||
assert_equal "<pre><code data-language=\"foo\">test\n</code></pre>", @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
def test_should_preserve_code_block_language_in_data_language
|
||||
text = <<~STR
|
||||
~~~c-k&r
|
||||
test
|
||||
~~~
|
||||
STR
|
||||
assert_equal "<pre><code data-language=\"c-k&r\">test\n</code></pre>", @formatter.new(text).to_html
|
||||
end
|
||||
|
||||
def test_external_links_should_have_external_css_class
|
||||
text = 'This is a [link](http://example.net/)'
|
||||
assert_equal '<p>This is a <a href="http://example.net/" class="external">link</a></p>', @formatter.new(text).to_html.strip
|
||||
end
|
||||
|
||||
def test_locals_links_should_not_have_external_css_class
|
||||
text = 'This is a [link](/issues)'
|
||||
assert_equal '<p>This is a <a href="/issues">link</a></p>', @formatter.new(text).to_html.strip
|
||||
end
|
||||
|
||||
def test_markdown_should_not_require_surrounded_empty_line
|
||||
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
|
||||
|
||||
def test_footnotes
|
||||
text = <<~STR
|
||||
This is some text[^1].
|
||||
|
||||
[^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>
|
||||
|
||||
<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
|
||||
|
||||
STR_WITH_PRE = [
|
||||
# 0
|
||||
<<~STR.chomp,
|
||||
# Title
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
STR
|
||||
# 1
|
||||
<<~STR.chomp,
|
||||
## Heading 2
|
||||
|
||||
~~~ruby
|
||||
def foo
|
||||
end
|
||||
~~~
|
||||
|
||||
Morbi facilisis accumsan orci non pharetra.
|
||||
|
||||
~~~ ruby
|
||||
def foo
|
||||
end
|
||||
~~~
|
||||
|
||||
```
|
||||
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")
|
||||
|
||||
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
|
||||
|
||||
STR_SETEXT_LIKE = [
|
||||
# 0
|
||||
<<~STR.chomp,
|
||||
# Title
|
||||
STR
|
||||
# 1
|
||||
<<~STR.chomp,
|
||||
## Heading 2
|
||||
|
||||
Thematic breaks - not be confused with setext headings.
|
||||
|
||||
---
|
||||
|
||||
Preceding CRLF is the default for web-submitted data.
|
||||
\r
|
||||
---\r
|
||||
\r
|
||||
|
||||
A space-only line does not mean much.
|
||||
\s
|
||||
---
|
||||
|
||||
End of thematic breaks.
|
||||
STR
|
||||
# 2
|
||||
<<~STR.chomp,
|
||||
## Heading 2
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero.
|
||||
STR
|
||||
]
|
||||
|
||||
STR_RARE_SETEXT_LIKE = [
|
||||
# 0
|
||||
<<~STR.chomp,
|
||||
# Title
|
||||
STR
|
||||
# 1
|
||||
<<~STR.chomp,
|
||||
## Heading 2
|
||||
|
||||
- item
|
||||
one
|
||||
-
|
||||
not a heading
|
||||
STR
|
||||
# 2
|
||||
<<~STR.chomp,
|
||||
## Heading 2
|
||||
Nulla nunc nisi, egestas in ornare vel, posuere ac libero.
|
||||
STR
|
||||
]
|
||||
|
||||
def test_get_section_should_ignore_setext_like_text
|
||||
text = STR_SETEXT_LIKE.join("\n\n")
|
||||
assert_section_with_hash STR_SETEXT_LIKE[1], text, 2
|
||||
assert_section_with_hash STR_SETEXT_LIKE[2], text, 3
|
||||
end
|
||||
|
||||
def test_get_section_should_ignore_rare_setext_like_text
|
||||
begin
|
||||
text = STR_RARE_SETEXT_LIKE.join("\n\n")
|
||||
assert_section_with_hash STR_RARE_SETEXT_LIKE[1], text, 2
|
||||
assert_section_with_hash STR_RARE_SETEXT_LIKE[2], text, 3
|
||||
rescue Minitest::Assertion => e
|
||||
skip "Section extraction is currently limited, see #35037. Known error: #{e.message}"
|
||||
end
|
||||
assert_not "This test should be adjusted when fixing the known error."
|
||||
end
|
||||
|
||||
def test_should_support_underlined_text
|
||||
text = 'This _text_ should be underlined'
|
||||
assert_equal '<p>This <u>text</u> should be underlined</p>', format(text)
|
||||
end
|
||||
|
||||
def test_should_autolink_mails
|
||||
input = "foo@example.org"
|
||||
assert_equal %(<p><a href="mailto:foo@example.org">foo@example.org</a></p>), format(input)
|
||||
|
||||
# The redcloth autolinker parses "plain" mailto links a bit unfortunately.
|
||||
# We do the best we can here...
|
||||
input = "mailto:foo@example.org"
|
||||
assert_equal %(<p>mailto:<a href="mailto:foo@example.org">foo@example.org</a></p>), format(input)
|
||||
end
|
||||
|
||||
def test_should_fixup_mailto_links
|
||||
input = "<mailto:foo@example.org>"
|
||||
assert_equal %(<p><a href="mailto:foo@example.org">foo@example.org</a></p>), format(input)
|
||||
end
|
||||
|
||||
def test_should_fixup_autolinked_user_references
|
||||
text = "user:user@example.org"
|
||||
assert_equal "<p>#{text}</p>", format(text)
|
||||
|
||||
text = "@user@example.org"
|
||||
assert_equal "<p>#{text}</p>", format(text)
|
||||
end
|
||||
|
||||
def test_should_fixup_autolinked_hires_files
|
||||
text = "printscreen@2x.png"
|
||||
assert_equal "<p>#{text}</p>", format(text).strip
|
||||
end
|
||||
|
||||
def test_should_allow_links_with_safe_url_schemes
|
||||
safe_schemes = %w(http https ftp)
|
||||
link_safe_schemes = %w(ssh foo)
|
||||
|
||||
(safe_schemes + link_safe_schemes).each do |scheme|
|
||||
input = "[#{scheme}](#{scheme}://example.com)"
|
||||
expected = %(<p><a href="#{scheme}://example.com" class="external">#{scheme}</a></p>)
|
||||
|
||||
assert_equal expected, format(input)
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_not_allow_links_with_unsafe_url_schemes
|
||||
unsafe_schemes = %w(data javascript vbscript)
|
||||
|
||||
unsafe_schemes.each do |scheme|
|
||||
input = "[#{scheme}](#{scheme}:something)"
|
||||
assert_equal "<p>#{input}</p>", format(input)
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_allow_autolinks_with_safe_url_schemes
|
||||
safe_schemes = %w(http https ftp)
|
||||
link_safe_schemes = %w(ssh foo)
|
||||
|
||||
(safe_schemes + link_safe_schemes).each do |scheme|
|
||||
input = "#{scheme}://example.org"
|
||||
expected = %(<p><a href="#{input}" class="external">#{input}</a></p>)
|
||||
|
||||
assert_equal expected, format(input) if safe_schemes.include?(scheme)
|
||||
assert_equal expected, format("<#{input}>")
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_not_autolink_unsafe_schemes
|
||||
unsafe_schemes = %w(data javascript vbscript)
|
||||
|
||||
unsafe_schemes.each do |scheme|
|
||||
link = "#{scheme}:something"
|
||||
|
||||
assert_equal "<p>#{link}</p>", format(link)
|
||||
assert_equal "<p>#{link}</p>", format("<#{link}>")
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def format(text)
|
||||
@formatter.new(text).to_html.strip
|
||||
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 ActiveSupport::Digest.hexdigest(expected), result.last, "section hash did not match"
|
||||
end
|
||||
end
|
||||
@@ -1,56 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006- 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_relative '../../../../test_helper'
|
||||
|
||||
class Redmine::WikiFormatting::MarkdownHtmlParserTest < ActiveSupport::TestCase
|
||||
def setup
|
||||
@parser = Redmine::WikiFormatting::Markdown::HtmlParser
|
||||
end
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user