greenmat 3.2.2.4 → 3.5.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -3,79 +3,81 @@ require 'test_helper'
3
3
 
4
4
  class HTMLRenderTest < Greenmat::TestCase
5
5
  def setup
6
- @markdown = Greenmat::Markdown.new(Greenmat::Render::HTML)
7
- @rndr = {
8
- :no_html => Greenmat::Render::HTML.new(:filter_html => true),
9
- :no_images => Greenmat::Render::HTML.new(:no_images => true),
10
- :no_links => Greenmat::Render::HTML.new(:no_links => true),
11
- :safe_links => Greenmat::Render::HTML.new(:safe_links_only => true),
12
- :escape_html => Greenmat::Render::HTML.new(:escape_html => true),
13
- :hard_wrap => Greenmat::Render::HTML.new(:hard_wrap => true),
14
- :toc_data => Greenmat::Render::HTML.new(:with_toc_data => true),
15
- :prettify => Greenmat::Render::HTML.new(:prettify => true)
16
- }
17
- end
18
-
19
- def render_with(rndr, text)
20
- Greenmat::Markdown.new(rndr).render(text)
6
+ @renderer = Greenmat::Render::HTML
21
7
  end
22
8
 
23
9
  # Hint: overrides filter_html, no_images and no_links
24
10
  def test_that_escape_html_works
25
- source = <<EOS
26
- Through <em>NO</em> <script>DOUBLE NO</script>
11
+ source = <<-HTML.strip_heredoc
12
+ Through <em>NO</em> <script>DOUBLE NO</script>
27
13
 
28
- <script>BAD</script>
14
+ <script>BAD</script>
29
15
 
30
- <img src="/favicon.ico" />
31
- EOS
32
- expected = <<EOE
33
- <p>Through &lt;em&gt;NO&lt;/em&gt; &lt;script&gt;DOUBLE NO&lt;/script&gt;</p>
16
+ <img src="/favicon.ico" />
17
+ HTML
18
+ expected = <<-HTML.chomp.strip_heredoc
19
+ <p>Through &lt;em&gt;NO&lt;/em&gt; &lt;script&gt;DOUBLE NO&lt;/script&gt;</p>
34
20
 
35
- <p>&lt;script&gt;BAD&lt;/script&gt;</p>
21
+ <p>&lt;script&gt;BAD&lt;/script&gt;</p>
36
22
 
37
- <p>&lt;img src=&quot;/favicon.ico&quot; /&gt;</p>
38
- EOE
23
+ <p>&lt;img src=&quot;/favicon.ico&quot; /&gt;</p>
24
+ HTML
39
25
 
40
- markdown = render_with(@rndr[:escape_html], source)
41
- html_equal expected, markdown
26
+ assert_equal expected, render(source, with: [:escape_html])
42
27
  end
43
28
 
44
29
  def test_that_filter_html_works
45
- markdown = render_with(@rndr[:no_html], 'Through <em>NO</em> <script>DOUBLE NO</script>')
46
- html_equal "<p>Through NO DOUBLE NO</p>\n", markdown
30
+ markdown = 'Through <em>NO</em> <script>DOUBLE NO</script>'
31
+ output = render(markdown, with: [:filter_html])
32
+
33
+ assert_equal "<p>Through NO DOUBLE NO</p>", output
47
34
  end
48
35
 
49
36
  def test_filter_html_doesnt_break_two_space_hard_break
50
- markdown = render_with(@rndr[:no_html], "Lorem, \nipsum\n")
51
- html_equal "<p>Lorem,<br/>\nipsum</p>\n", markdown
37
+ markdown = "Lorem, \nipsum\n"
38
+ output = render(markdown, with: [:filter_html])
39
+
40
+ assert_equal "<p>Lorem,<br>\nipsum</p>", output
52
41
  end
53
42
 
54
43
  def test_that_no_image_flag_works
55
- rd = render_with(@rndr[:no_images], %(![dust mite](http://dust.mite/image.png) <img src="image.png" />))
56
- assert rd !~ /<img/
44
+ markdown = %(![dust mite](http://dust.mite/image.png) <img src="image.png" />)
45
+ output = render(markdown, with: [:no_images])
46
+
47
+ assert_no_match %r{<img}, output
48
+ end
49
+
50
+ def test_that_links_with_ampersands_work
51
+ markdown = %([/?a=b&c=d](/?a=b&c=d))
52
+ output = render(markdown)
53
+ assert_equal "<p><a href=\"/?a=b&c=d\">/?a=b&amp;c=d</a></p>", output
57
54
  end
58
55
 
59
56
  def test_that_no_links_flag_works
60
- rd = render_with(@rndr[:no_links], %([This link](http://example.net/) <a href="links.html">links</a>))
61
- assert rd !~ /<a /
57
+ markdown = %([This link](http://example.net/) <a href="links.html">links</a>)
58
+ output = render(markdown, with: [:no_links])
59
+
60
+ assert_no_match %r{<a }, output
62
61
  end
63
62
 
64
63
  def test_that_safelink_flag_works
65
- rd = render_with(@rndr[:safe_links], "[IRC](irc://chat.freenode.org/#freenode)")
66
- html_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>\n", rd
64
+ markdown = "[IRC](irc://chat.freenode.org/#freenode)"
65
+ output = render(markdown, with: [:safe_links_only])
66
+
67
+ assert_equal "<p>[IRC](irc://chat.freenode.org/#freenode)</p>", output
67
68
  end
68
69
 
69
70
  def test_that_hard_wrap_works
70
- rd = render_with(@rndr[:hard_wrap], <<EOE)
71
- Hello world,
72
- this is just a simple test
71
+ markdown = <<-Markdown.strip_heredoc
72
+ Hello world,
73
+ this is just a simple test
73
74
 
74
- With hard wraps
75
- and other *things*.
76
- EOE
75
+ With hard wraps
76
+ and other *things*.
77
+ Markdown
78
+ output = render(markdown, with: [:hard_wrap])
77
79
 
78
- assert rd =~ /<br>/
80
+ assert_match %r{<br>}, output
79
81
  end
80
82
 
81
83
  def test_that_link_attributes_work
@@ -85,48 +87,45 @@ EOE
85
87
  end
86
88
 
87
89
  def test_that_link_works_with_quotes
88
- rd = render_with(Greenmat::Render::HTML.new, %([This'link"is](http://example.net/)))
89
- assert_equal "<p><a href=\"http://example.net/\">This&#39;link&quot;is</a></p>\n", rd
90
+ markdown = %([This'link"is](http://example.net/))
91
+ expected = %(<p><a href="http://example.net/">This&#39;link&quot;is</a></p>)
90
92
 
91
- rd = render_with(@rndr[:escape_html], %([This'link"is](http://example.net/)))
92
- assert_equal "<p><a href=\"http://example.net/\">This&#39;link&quot;is</a></p>\n", rd
93
+ assert_equal expected, render(markdown)
94
+ assert_equal expected, render(markdown, with: [:escape_html])
93
95
  end
94
96
 
95
97
  def test_that_code_emphasis_work
96
- markdown = <<-MD
97
- This should be **`a bold codespan`**
98
- However, this should be *`an emphasised codespan`*
98
+ markdown = <<-Markdown.strip_heredoc
99
+ This should be **`a bold codespan`**
100
+ However, this should be *`an emphasised codespan`*
99
101
 
100
- * **`ABC`** or **`DEF`**
101
- * Foo bar
102
- MD
102
+ * **`ABC`** or **`DEF`**
103
+ * Foo bar
104
+ Markdown
103
105
 
104
- html = <<HTML
105
- <p>This should be <strong><code>a bold codespan</code></strong>
106
- However, this should be <em><code>an emphasised codespan</code></em></p>
106
+ html = <<-HTML.chomp.strip_heredoc
107
+ <p>This should be <strong><code>a bold codespan</code></strong>
108
+ However, this should be <em><code>an emphasised codespan</code></em></p>
107
109
 
108
- <ul>
109
- <li><strong><code>ABC</code></strong> or <strong><code>DEF</code></strong></li>
110
- <li>Foo bar</li>
111
- </ul>
112
- HTML
110
+ <ul>
111
+ <li><strong><code>ABC</code></strong> or <strong><code>DEF</code></strong></li>
112
+ <li>Foo bar</li>
113
+ </ul>
114
+ HTML
113
115
 
114
- output = render_with(Greenmat::Render::HTML.new, markdown)
115
- assert_equal html, output
116
+ assert_equal html, render(markdown)
116
117
  end
117
118
 
118
119
  def test_that_parenthesis_are_handled_into_links
119
- markdown = "Hey have a look at the [bash man page](man:bash(1))!"
120
- html = "<p>Hey have a look at the <a href=\"man:bash(1)\">bash man page</a>!</p>\n"
121
- output = render_with(Greenmat::Render::HTML.new, markdown)
120
+ markdown = %(The [bash man page](man:bash(1))!)
121
+ expected = %(<p>The <a href="man:bash(1)">bash man page</a>!</p>)
122
122
 
123
- assert_equal html, output
123
+ assert_equal expected, render(markdown)
124
124
  end
125
125
 
126
126
  def test_autolinking_works_as_expected
127
- markdown = "Example of uri ftp://user:pass@example.com/. Email foo@bar.com and link http://bar.com"
128
- renderer = Greenmat::Markdown.new(Greenmat::Render::HTML, :autolink => true)
129
- output = renderer.render(markdown)
127
+ markdown = "Uri ftp://user:pass@example.com/. Email foo@bar.com and link http://bar.com"
128
+ output = render(markdown, with: [:autolink])
130
129
 
131
130
  assert output.include? '<a href="ftp://user:pass@example.com/">ftp://user:pass@example.com/</a>'
132
131
  assert output.include? 'mailto:foo@bar.com'
@@ -134,107 +133,142 @@ HTML
134
133
  end
135
134
 
136
135
  def test_that_footnotes_work
137
- markdown = <<-MD
138
- This is a footnote.[^1]
136
+ markdown = <<-Markdown.strip_heredoc
137
+ This is a footnote.[^1]
139
138
 
140
- [^1]: It provides additional information.
141
- MD
139
+ [^1]: It provides additional information.
140
+ Markdown
142
141
 
143
- html = <<HTML
144
- <p>This is a footnote.<sup id="fnref1"><a href="#fn1" rel="footnote">1</a></sup></p>
142
+ html = <<-HTML.chomp.strip_heredoc
143
+ <p>This is a footnote.<sup id="fnref1"><a href="#fn1">1</a></sup></p>
145
144
 
146
- <div class="footnotes">
147
- <hr>
148
- <ol>
145
+ <div class="footnotes">
146
+ <hr>
147
+ <ol>
149
148
 
150
- <li id="fn1">
151
- <p>It provides additional information.&nbsp;<a href="#fnref1" rev="footnote">&#8617;</a></p>
152
- </li>
149
+ <li id="fn1">
150
+ <p>It provides additional information.&nbsp;<a href="#fnref1">&#8617;</a></p>
151
+ </li>
153
152
 
154
- </ol>
155
- </div>
156
- HTML
153
+ </ol>
154
+ </div>
155
+ HTML
157
156
 
158
- renderer = Greenmat::Markdown.new(Greenmat::Render::HTML, :footnotes => true)
159
- output = renderer.render(markdown)
157
+ output = render(markdown, with: [:footnotes])
160
158
  assert_equal html, output
161
159
  end
162
160
 
163
161
  def test_footnotes_enabled_but_missing_marker
164
- markdown = <<MD
165
- Some text without a marker
162
+ markdown = <<-Markdown.strip_heredoc
163
+ Some text without a marker
166
164
 
167
- [^1] And a trailing definition
168
- MD
169
- html = <<HTML
170
- <p>Some text without a marker</p>
165
+ [^1] And a trailing definition
166
+ Markdown
167
+ html = <<-HTML.chomp.strip_heredoc
168
+ <p>Some text without a marker</p>
171
169
 
172
- <p>[^1] And a trailing definition</p>
173
- HTML
170
+ <p>[^1] And a trailing definition</p>
171
+ HTML
174
172
 
175
- renderer = Greenmat::Markdown.new(Greenmat::Render::HTML, :footnotes => true)
176
- output = renderer.render(markdown)
173
+ output = render(markdown, with: [:footnotes])
177
174
  assert_equal html, output
178
175
  end
179
176
 
180
177
  def test_footnotes_enabled_but_missing_definition
181
178
  markdown = "Some text with a marker[^1] but no definition."
182
- html = "<p>Some text with a marker[^1] but no definition.</p>\n"
179
+ expected = "<p>Some text with a marker[^1] but no definition.</p>"
183
180
 
184
- renderer = Greenmat::Markdown.new(Greenmat::Render::HTML, :footnotes => true)
185
- output = renderer.render(markdown)
186
- assert_equal html, output
181
+ output = render(markdown, with: [:footnotes])
182
+ assert_equal expected, output
187
183
  end
188
184
 
189
185
  def test_autolink_short_domains
190
186
  markdown = "Example of uri ftp://auto/short/domains. Email auto@l.n and link http://a/u/t/o/s/h/o/r/t"
191
- renderer = Greenmat::Markdown.new(Greenmat::Render::HTML, :autolink => true)
192
- output = renderer.render(markdown)
187
+ output = render(markdown, with: [:autolink])
193
188
 
194
189
  assert output.include? '<a href="ftp://auto/short/domains">ftp://auto/short/domains</a>'
195
190
  assert output.include? 'mailto:auto@l.n'
196
191
  assert output.include? '<a href="http://a/u/t/o/s/h/o/r/t">http://a/u/t/o/s/h/o/r/t</a>'
197
192
  end
198
193
 
199
- def test_toc_heading_id
200
- markdown = "# First level heading\n## Second level heading"
201
- output = render_with(@rndr[:toc_data], markdown)
202
- assert_match /<h1 id="first-level-heading">/, output
203
- assert_match /<h2 id="second-level-heading">/, output
204
- end
205
-
206
194
  def test_that_prettify_works
207
- text = <<-Markdown
208
- Foo
195
+ markdown = "\tclass Foo\nend"
196
+ output = render(markdown, with: [:prettify])
197
+
198
+ assert output.include?("<pre><code class=\"prettyprint\">")
209
199
 
210
- ~~~ruby
211
- some
212
- code
213
- ~~~
200
+ markdown = "`class`"
201
+ output = render(markdown, with: [:prettify])
214
202
 
215
- Bar
216
- Markdown
203
+ assert output.include?("<code class=\"prettyprint\">")
204
+ end
217
205
 
218
- renderer = Greenmat::Markdown.new(@rndr[:prettify], fenced_code_blocks: true)
219
- output = renderer.render(text)
206
+ def test_prettify_with_fenced_code_blocks
207
+ markdown = "~~~ruby\ncode\n~~~"
208
+ output = render(markdown, with: [:fenced_code_blocks, :prettify])
220
209
 
221
210
  assert output.include?("<code class=\"prettyprint\" data-metadata=\"ruby\">")
222
211
  end
223
212
 
224
213
  def test_safe_links_only_with_anchors
225
214
  markdown = "An [anchor link](#anchor) on a page."
226
-
227
- renderer = Greenmat::Markdown.new(@rndr[:safe_links])
228
- output = renderer.render(markdown)
215
+ output = render(markdown, with: [:safe_links_only])
229
216
 
230
217
  assert_match %r{<a href="#anchor">anchor link</a>}, output
231
218
  end
232
219
 
233
220
  def test_autolink_with_link_attributes
234
- render = Greenmat::Render::HTML.new(link_attributes: {rel: "nofollow"})
235
- parser = Greenmat::Markdown.new(render, autolink: true)
221
+ options = { autolink: true, link_attributes: {rel: "nofollow"} }
222
+ output = render("https://github.com/", with: options)
236
223
 
237
- output = parser.render("https://github.com/")
238
224
  assert_match %r{rel="nofollow"}, output
239
225
  end
226
+
227
+ def test_image_unsafe_src_with_safe_links_only
228
+ markdown = "![foo](javascript:while(1);)"
229
+ output = render(markdown, with: [:safe_links_only])
230
+
231
+ assert_not_match %r{img src}, output
232
+ end
233
+
234
+ def test_no_styles_option_inside_a_paragraph
235
+ markdown = "Hello <style> foo { bar: baz; } </style> !"
236
+ output = render(markdown, with: [:no_styles])
237
+
238
+ assert_no_match %r{<style>}, output
239
+ end
240
+
241
+ def test_no_styles_inside_html_block_rendering
242
+ markdown = "<style> foo { bar: baz; } </style>"
243
+ output = render(markdown, with: [:no_styles])
244
+
245
+ assert_no_match %r{<style>}, output
246
+ end
247
+
248
+ def test_non_ascii_removal_in_header_anchors
249
+ markdown = "# Glühlampe"
250
+ html = "<h1 id=\"gl-hlampe\">Glühlampe</h1>"
251
+
252
+ assert_equal html, render(markdown, with: [:with_toc_data])
253
+ end
254
+
255
+ def test_utf8_only_header_anchors
256
+ markdown = "# 見出し"
257
+ if 1.size == 4 # 32-bit architecture
258
+ html = "<h1 id=\"part-a194139f\">見出し</h1>"
259
+ elsif 1.size == 8 # 64-bit architecture
260
+ html = "<h1 id=\"part-37870bfa194139f\">見出し</h1>"
261
+ else
262
+ raise "unknown integer size"
263
+ end
264
+
265
+ assert_equal html, render(markdown, with: [:with_toc_data])
266
+ end
267
+
268
+ def test_escape_entities_removal_from_anchor
269
+ output = render("# Foo's & Bar's", with: [:with_toc_data])
270
+ result = %(<h1 id="foos-bars">Foo&#39;s &amp; Bar&#39;s</h1>)
271
+
272
+ assert_equal result, output
273
+ end
240
274
  end
@@ -3,24 +3,28 @@ require 'test_helper'
3
3
 
4
4
  class HTMLTOCRenderTest < Greenmat::TestCase
5
5
  def setup
6
- @render = Greenmat::Render::HTML_TOC
7
- @markdown = "# A title \n## A __nice__ subtitle\n## Another one \n### A sub-sub-title"
6
+ @renderer = Greenmat::Render::HTML_TOC
7
+ @markdown = <<-Markdown.strip_heredoc
8
+ # A title
9
+ ## A __nice__ subtitle
10
+ ## Another one
11
+ ### A sub-sub-title
12
+ ### 見出し
13
+ Markdown
8
14
  end
9
15
 
10
16
  def test_simple_toc_render
11
- renderer = Greenmat::Markdown.new(@render)
12
- output = renderer.render(@markdown).strip
17
+ output = render(@markdown)
13
18
 
14
19
  assert output.start_with?("<ul>")
15
20
  assert output.end_with?("</ul>")
16
21
 
17
22
  assert_equal 3, output.scan("<ul>").length
18
- assert_equal 4, output.scan("<li>").length
23
+ assert_equal 5, output.scan("<li>").length
19
24
  end
20
25
 
21
26
  def test_granular_toc_render
22
- renderer = Greenmat::Markdown.new(@render.new(nesting_level: 2))
23
- output = renderer.render(@markdown).strip
27
+ output = render(@markdown, with: { nesting_level: 2 })
24
28
 
25
29
  assert output.start_with?("<ul>")
26
30
  assert output.end_with?("</ul>")
@@ -29,21 +33,80 @@ class HTMLTOCRenderTest < Greenmat::TestCase
29
33
  assert !output.include?("A sub-sub title")
30
34
  end
31
35
 
36
+ def test_granular_toc_render_with_range
37
+ output = render(@markdown, with: { nesting_level: 2..5 }).strip
38
+
39
+ assert output.start_with?("<ul>")
40
+ assert output.end_with?("</ul>")
41
+
42
+ assert output.match("Another one")
43
+ assert output.match("A sub-sub-title")
44
+ assert output.match("見出し")
45
+
46
+ refute output.match("A title")
47
+ refute output.match("A really tiny title")
48
+ end
49
+
32
50
  def test_toc_heading_id
33
- renderer = Greenmat::Markdown.new(@render)
34
- output = renderer.render(@markdown)
51
+ output = render(@markdown)
35
52
 
36
53
  assert_match /a-title/, output
37
54
  assert_match /a-nice-subtitle/, output
38
55
  assert_match /another-one/, output
39
56
  assert_match /a-sub-sub-title/, output
57
+ # the part number length varies depending on architecture (32b or 64b)
58
+ assert_match /part-(37870bf)?a194139f/, output
40
59
  end
41
60
 
42
61
  def test_toc_heading_with_hyphen_and_equal
43
- renderer = Greenmat::Markdown.new(@render)
44
- output = renderer.render("# Hello World\n\n-\n\n=")
62
+ output = render("# Hello World\n\n-\n\n=")
45
63
 
46
64
  assert_equal 1, output.scan("<li>").length
47
65
  assert !output.include?('<a href=\"#\"></a>')
48
66
  end
67
+
68
+ def test_anchor_generation_with_edge_cases
69
+ # Imported from ActiveSupport::Inflector#parameterize's tests
70
+ titles = {
71
+ "Donald E. Knuth" => "donald-e-knuth",
72
+ "Random text with *(bad)* characters" => "random-text-with-bad-characters",
73
+ "!@#Surrounding bad characters!@#" => "surrounding-bad-characters",
74
+ "Squeeze separators" => "squeeze-separators",
75
+ "Test with + sign" => "test-with-sign",
76
+ "Test with a Namespaced::Class" => "test-with-a-namespaced-class"
77
+ }
78
+
79
+ titles.each do |title, anchor|
80
+ assert_match %("##{anchor}"), render("# #{title}")
81
+ end
82
+ end
83
+
84
+ def test_inline_markup_is_not_escaped
85
+ output = render(@markdown)
86
+
87
+ assert_match "A <strong>nice</strong> subtitle", output
88
+ assert_no_match %r{&lt;}, output
89
+ end
90
+
91
+ def test_inline_markup_escaping
92
+ output = render(@markdown, with: [:escape_html])
93
+
94
+ assert_match "&lt;strong&gt;", output
95
+ assert_no_match %r{<strong>}, output
96
+ end
97
+
98
+ def test_ignoring_fenced_code_blocks_comments
99
+ markdown = <<-Markdown.strip_heredoc
100
+ # Hello world !
101
+
102
+ ~~~ruby
103
+ # This is a comment
104
+ ~~~
105
+ Markdown
106
+
107
+ output = render(markdown)
108
+
109
+ assert output.match("Hello world")
110
+ refute output.match("This is a comment")
111
+ end
49
112
  end