greenmat 3.2.2.4 → 3.5.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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