html-pipeline 2.4.1 → 2.4.2
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.
- checksums.yaml +4 -4
- data/.travis.yml +15 -4
- data/Appraisals +13 -0
- data/CHANGELOG.md +4 -0
- data/Gemfile +2 -1
- data/Rakefile +4 -1
- data/html-pipeline.gemspec +2 -3
- data/lib/html/pipeline/emoji_filter.rb +22 -1
- data/lib/html/pipeline/version.rb +1 -1
- metadata +4 -46
- data/script/changelog +0 -47
- data/script/package +0 -7
- data/script/release +0 -16
- data/test/helpers/mocked_instrumentation_service.rb +0 -17
- data/test/html/pipeline/absolute_source_filter_test.rb +0 -55
- data/test/html/pipeline/autolink_filter_test.rb +0 -35
- data/test/html/pipeline/camo_filter_test.rb +0 -77
- data/test/html/pipeline/email_reply_filter_test.rb +0 -66
- data/test/html/pipeline/emoji_filter_test.rb +0 -65
- data/test/html/pipeline/https_filter_test.rb +0 -53
- data/test/html/pipeline/image_filter_test.rb +0 -39
- data/test/html/pipeline/image_max_width_filter_test.rb +0 -50
- data/test/html/pipeline/markdown_filter_test.rb +0 -101
- data/test/html/pipeline/mention_filter_test.rb +0 -212
- data/test/html/pipeline/plain_text_input_filter_test.rb +0 -22
- data/test/html/pipeline/sanitization_filter_test.rb +0 -166
- data/test/html/pipeline/syntax_highlight_filter_test.rb +0 -22
- data/test/html/pipeline/toc_filter_test.rb +0 -134
- data/test/html/pipeline_test.rb +0 -74
- data/test/test_helper.rb +0 -16
@@ -1,212 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class HTML::Pipeline::MentionFilterTest < Minitest::Test
|
4
|
-
def filter(html, base_url='/', info_url=nil, username_pattern=nil)
|
5
|
-
HTML::Pipeline::MentionFilter.call(html, :base_url => base_url, :info_url => info_url, :username_pattern => username_pattern)
|
6
|
-
end
|
7
|
-
|
8
|
-
def test_filtering_a_documentfragment
|
9
|
-
body = "<p>@kneath: check it out.</p>"
|
10
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(body)
|
11
|
-
|
12
|
-
res = filter(doc, '/')
|
13
|
-
assert_same doc, res
|
14
|
-
|
15
|
-
link = "<a href=\"/kneath\" class=\"user-mention\">@kneath</a>"
|
16
|
-
assert_equal "<p>#{link}: check it out.</p>",
|
17
|
-
res.to_html
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_filtering_plain_text
|
21
|
-
body = "<p>@kneath: check it out.</p>"
|
22
|
-
res = filter(body, '/')
|
23
|
-
|
24
|
-
link = "<a href=\"/kneath\" class=\"user-mention\">@kneath</a>"
|
25
|
-
assert_equal "<p>#{link}: check it out.</p>",
|
26
|
-
res.to_html
|
27
|
-
end
|
28
|
-
|
29
|
-
def test_not_replacing_mentions_in_pre_tags
|
30
|
-
body = "<pre>@kneath: okay</pre>"
|
31
|
-
assert_equal body, filter(body).to_html
|
32
|
-
end
|
33
|
-
|
34
|
-
def test_not_replacing_mentions_in_code_tags
|
35
|
-
body = "<p><code>@kneath:</code> okay</p>"
|
36
|
-
assert_equal body, filter(body).to_html
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_not_replacing_mentions_in_style_tags
|
40
|
-
body = "<style>@media (min-width: 768px) { color: red; }</style>"
|
41
|
-
assert_equal body, filter(body).to_html
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_not_replacing_mentions_in_links
|
45
|
-
body = "<p><a>@kneath</a> okay</p>"
|
46
|
-
assert_equal body, filter(body).to_html
|
47
|
-
end
|
48
|
-
|
49
|
-
def test_entity_encoding_and_whatnot
|
50
|
-
body = "<p>@kneath what's up</p>"
|
51
|
-
link = "<a href=\"/kneath\" class=\"user-mention\">@kneath</a>"
|
52
|
-
assert_equal "<p>#{link} what's up</p>", filter(body, '/').to_html
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_html_injection
|
56
|
-
body = "<p>@kneath <script>alert(0)</script></p>"
|
57
|
-
link = "<a href=\"/kneath\" class=\"user-mention\">@kneath</a>"
|
58
|
-
assert_equal "<p>#{link} <script>alert(0)</script></p>",
|
59
|
-
filter(body, '/').to_html
|
60
|
-
end
|
61
|
-
|
62
|
-
def test_links_to_nothing_when_no_info_url_given
|
63
|
-
body = "<p>How do I @mention someone?</p>"
|
64
|
-
assert_equal "<p>How do I @mention someone?</p>",
|
65
|
-
filter(body, '/').to_html
|
66
|
-
end
|
67
|
-
|
68
|
-
def test_links_to_more_info_when_info_url_given
|
69
|
-
body = "<p>How do I @mention someone?</p>"
|
70
|
-
link = "<a href=\"https://github.com/blog/821\" class=\"user-mention\">@mention</a>"
|
71
|
-
assert_equal "<p>How do I #{link} someone?</p>",
|
72
|
-
filter(body, '/', 'https://github.com/blog/821').to_html
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_base_url_slash
|
76
|
-
body = "<p>Hi, @jch!</p>"
|
77
|
-
link = "<a href=\"/jch\" class=\"user-mention\">@jch</a>"
|
78
|
-
assert_equal "<p>Hi, #{link}!</p>",
|
79
|
-
filter(body, '/').to_html
|
80
|
-
end
|
81
|
-
|
82
|
-
def test_base_url_under_custom_route
|
83
|
-
body = "<p>Hi, @jch!</p>"
|
84
|
-
link = "<a href=\"/userprofile/jch\" class=\"user-mention\">@jch</a>"
|
85
|
-
assert_equal "<p>Hi, #{link}!</p>",
|
86
|
-
filter(body, '/userprofile').to_html
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_base_url_slash_with_tilde
|
90
|
-
body = "<p>Hi, @jch!</p>"
|
91
|
-
link = "<a href=\"/~jch\" class=\"user-mention\">@jch</a>"
|
92
|
-
assert_equal "<p>Hi, #{link}!</p>",
|
93
|
-
filter(body, '/~').to_html
|
94
|
-
end
|
95
|
-
|
96
|
-
MarkdownPipeline =
|
97
|
-
HTML::Pipeline.new [
|
98
|
-
HTML::Pipeline::MarkdownFilter,
|
99
|
-
HTML::Pipeline::MentionFilter
|
100
|
-
]
|
101
|
-
|
102
|
-
def mentioned_usernames
|
103
|
-
result = {}
|
104
|
-
MarkdownPipeline.call(@body, {}, result)
|
105
|
-
result[:mentioned_usernames]
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_matches_usernames_in_body
|
109
|
-
@body = "@test how are you?"
|
110
|
-
assert_equal %w[test], mentioned_usernames
|
111
|
-
end
|
112
|
-
|
113
|
-
def test_matches_usernames_with_dashes
|
114
|
-
@body = "hi @some-user"
|
115
|
-
assert_equal %w[some-user], mentioned_usernames
|
116
|
-
end
|
117
|
-
|
118
|
-
def test_matches_usernames_followed_by_a_single_dot
|
119
|
-
@body = "okay @some-user."
|
120
|
-
assert_equal %w[some-user], mentioned_usernames
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_matches_usernames_followed_by_multiple_dots
|
124
|
-
@body = "okay @some-user..."
|
125
|
-
assert_equal %w[some-user], mentioned_usernames
|
126
|
-
end
|
127
|
-
|
128
|
-
def test_does_not_match_email_addresses
|
129
|
-
@body = "aman@tmm1.net"
|
130
|
-
assert_equal [], mentioned_usernames
|
131
|
-
end
|
132
|
-
|
133
|
-
def test_does_not_match_domain_name_looking_things
|
134
|
-
@body = "we need a @github.com email"
|
135
|
-
assert_equal [], mentioned_usernames
|
136
|
-
end
|
137
|
-
|
138
|
-
def test_does_not_match_organization_team_mentions
|
139
|
-
@body = "we need to @github/enterprise know"
|
140
|
-
assert_equal [], mentioned_usernames
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_matches_colon_suffixed_names
|
144
|
-
@body = "@tmm1: what do you think?"
|
145
|
-
assert_equal %w[tmm1], mentioned_usernames
|
146
|
-
end
|
147
|
-
|
148
|
-
def test_matches_list_of_names
|
149
|
-
@body = "@defunkt @atmos @kneath"
|
150
|
-
assert_equal %w[defunkt atmos kneath], mentioned_usernames
|
151
|
-
end
|
152
|
-
|
153
|
-
def test_matches_list_of_names_with_commas
|
154
|
-
@body = "/cc @defunkt, @atmos, @kneath"
|
155
|
-
assert_equal %w[defunkt atmos kneath], mentioned_usernames
|
156
|
-
end
|
157
|
-
|
158
|
-
def test_matches_inside_brackets
|
159
|
-
@body = "(@mislav) and [@rtomayko]"
|
160
|
-
assert_equal %w[mislav rtomayko], mentioned_usernames
|
161
|
-
end
|
162
|
-
|
163
|
-
def test_doesnt_ignore_invalid_users
|
164
|
-
@body = "@defunkt @mojombo and @somedude"
|
165
|
-
assert_equal ['defunkt', 'mojombo', 'somedude'], mentioned_usernames
|
166
|
-
end
|
167
|
-
|
168
|
-
def test_returns_distinct_set
|
169
|
-
@body = "/cc @defunkt, @atmos, @kneath, @defunkt, @defunkt"
|
170
|
-
assert_equal %w[defunkt atmos kneath], mentioned_usernames
|
171
|
-
end
|
172
|
-
|
173
|
-
def test_does_not_match_inline_code_block_with_multiple_code_blocks
|
174
|
-
@body = "something\n\n`/cc @defunkt @atmos @kneath` `/cc @atmos/atmos`"
|
175
|
-
assert_equal %w[], mentioned_usernames
|
176
|
-
end
|
177
|
-
|
178
|
-
def test_mention_at_end_of_parenthetical_sentence
|
179
|
-
@body = "(We're talking 'bout @ymendel.)"
|
180
|
-
assert_equal %w[ymendel], mentioned_usernames
|
181
|
-
end
|
182
|
-
|
183
|
-
def test_username_pattern_can_be_customized
|
184
|
-
body = "<p>@_abc: test.</p>"
|
185
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(body)
|
186
|
-
|
187
|
-
res = filter(doc, '/', nil, /(_[a-z]{3})/)
|
188
|
-
|
189
|
-
link = "<a href=\"/_abc\" class=\"user-mention\">@_abc</a>"
|
190
|
-
assert_equal "<p>#{link}: test.</p>",
|
191
|
-
res.to_html
|
192
|
-
end
|
193
|
-
|
194
|
-
def test_filter_does_not_create_a_new_object_for_default_username_pattern
|
195
|
-
body = "<div>@test</div>"
|
196
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(body)
|
197
|
-
|
198
|
-
filter(doc.clone, '/', nil)
|
199
|
-
pattern_count = HTML::Pipeline::MentionFilter::MentionPatterns.length
|
200
|
-
filter(doc.clone, '/', nil)
|
201
|
-
|
202
|
-
assert_equal pattern_count, HTML::Pipeline::MentionFilter::MentionPatterns.length
|
203
|
-
filter(doc.clone, '/', nil, /test/)
|
204
|
-
assert_equal pattern_count + 1, HTML::Pipeline::MentionFilter::MentionPatterns.length
|
205
|
-
end
|
206
|
-
|
207
|
-
def test_mention_link_filter
|
208
|
-
filter = HTML::Pipeline::MentionFilter.new nil
|
209
|
-
expected = "<a href='/hubot' class='user-mention'>@hubot</a>"
|
210
|
-
assert_equal expected, filter.mention_link_filter("@hubot")
|
211
|
-
end
|
212
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class HTML::Pipeline::PlainTextInputFilterTest < Minitest::Test
|
4
|
-
PlainTextInputFilter = HTML::Pipeline::PlainTextInputFilter
|
5
|
-
|
6
|
-
def test_fails_when_given_a_documentfragment
|
7
|
-
body = "<p>heyo</p>"
|
8
|
-
doc = Nokogiri::HTML::DocumentFragment.parse(body)
|
9
|
-
assert_raises(TypeError) { PlainTextInputFilter.call(doc, {}) }
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_wraps_input_in_a_div_element
|
13
|
-
doc = PlainTextInputFilter.call("howdy pahtner", {})
|
14
|
-
assert_equal "<div>howdy pahtner</div>", doc.to_s
|
15
|
-
end
|
16
|
-
|
17
|
-
def test_html_escapes_plain_text_input
|
18
|
-
doc = PlainTextInputFilter.call("See: <http://example.org>", {})
|
19
|
-
assert_equal "<div>See: <http://example.org></div>",
|
20
|
-
doc.to_s
|
21
|
-
end
|
22
|
-
end
|
@@ -1,166 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
class HTML::Pipeline::SanitizationFilterTest < Minitest::Test
|
4
|
-
SanitizationFilter = HTML::Pipeline::SanitizationFilter
|
5
|
-
|
6
|
-
def test_removing_script_tags
|
7
|
-
orig = %(<p><img src="http://github.com/img.png" /><script></script></p>)
|
8
|
-
html = SanitizationFilter.call(orig).to_s
|
9
|
-
refute_match /script/, html
|
10
|
-
end
|
11
|
-
|
12
|
-
def test_removing_style_tags
|
13
|
-
orig = %(<p><style>hey now</style></p>)
|
14
|
-
html = SanitizationFilter.call(orig).to_s
|
15
|
-
refute_match /style/, html
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_removing_style_attributes
|
19
|
-
orig = %(<p style='font-size:1000%'>YO DAWG</p>)
|
20
|
-
html = SanitizationFilter.call(orig).to_s
|
21
|
-
refute_match /font-size/, html
|
22
|
-
refute_match /style/, html
|
23
|
-
end
|
24
|
-
|
25
|
-
def test_removing_script_event_handler_attributes
|
26
|
-
orig = %(<a onclick='javascript:alert(0)'>YO DAWG</a>)
|
27
|
-
html = SanitizationFilter.call(orig).to_s
|
28
|
-
refute_match /javscript/, html
|
29
|
-
refute_match /onclick/, html
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_sanitizes_li_elements_not_contained_in_ul_or_ol
|
33
|
-
stuff = "a\n<li>b</li>\nc"
|
34
|
-
html = SanitizationFilter.call(stuff).to_s
|
35
|
-
assert_equal "a\nb\nc", html
|
36
|
-
end
|
37
|
-
|
38
|
-
def test_does_not_sanitize_li_elements_contained_in_ul_or_ol
|
39
|
-
stuff = "a\n<ul><li>b</li></ul>\nc"
|
40
|
-
assert_equal stuff, SanitizationFilter.call(stuff).to_s
|
41
|
-
end
|
42
|
-
|
43
|
-
def test_github_specific_protocols_are_not_removed
|
44
|
-
stuff = '<a href="github-windows://spillthelog">Spill this yo</a> and so on'
|
45
|
-
assert_equal stuff, SanitizationFilter.call(stuff).to_s
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_unknown_schemes_are_removed
|
49
|
-
stuff = '<a href="something-weird://heyyy">Wat</a> is this'
|
50
|
-
html = SanitizationFilter.call(stuff).to_s
|
51
|
-
assert_equal '<a>Wat</a> is this', html
|
52
|
-
end
|
53
|
-
|
54
|
-
def test_whitelisted_longdesc_schemes_are_allowed
|
55
|
-
stuff = '<img src="./foo.jpg" longdesc="http://longdesc.com">'
|
56
|
-
html = SanitizationFilter.call(stuff).to_s
|
57
|
-
assert_equal '<img src="./foo.jpg" longdesc="http://longdesc.com">', html
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_weird_longdesc_schemes_are_removed
|
61
|
-
stuff = '<img src="./foo.jpg" longdesc="javascript:alert(1)">'
|
62
|
-
html = SanitizationFilter.call(stuff).to_s
|
63
|
-
assert_equal '<img src="./foo.jpg">', html
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_standard_schemes_are_removed_if_not_specified_in_anchor_schemes
|
67
|
-
stuff = '<a href="http://www.example.com/">No href for you</a>'
|
68
|
-
filter = SanitizationFilter.new(stuff, {:anchor_schemes => []})
|
69
|
-
html = filter.call.to_s
|
70
|
-
assert_equal '<a>No href for you</a>', html
|
71
|
-
end
|
72
|
-
|
73
|
-
def test_custom_anchor_schemes_are_not_removed
|
74
|
-
stuff = '<a href="something-weird://heyyy">Wat</a> is this'
|
75
|
-
filter = SanitizationFilter.new(stuff, {:anchor_schemes => ['something-weird']})
|
76
|
-
html = filter.call.to_s
|
77
|
-
assert_equal stuff, html
|
78
|
-
end
|
79
|
-
|
80
|
-
def test_anchor_schemes_are_merged_with_other_anchor_restrictions
|
81
|
-
stuff = '<a href="something-weird://heyyy" ping="more-weird://hiii">Wat</a> is this'
|
82
|
-
whitelist = {
|
83
|
-
:elements => ['a'],
|
84
|
-
:attributes => {'a' => ['href', 'ping']},
|
85
|
-
:protocols => {'a' => {'ping' => ['http']}}
|
86
|
-
}
|
87
|
-
filter = SanitizationFilter.new(stuff, {:whitelist => whitelist, :anchor_schemes => ['something-weird']})
|
88
|
-
html = filter.call.to_s
|
89
|
-
assert_equal '<a href="something-weird://heyyy">Wat</a> is this', html
|
90
|
-
end
|
91
|
-
|
92
|
-
def test_uses_anchor_schemes_from_whitelist_when_not_separately_specified
|
93
|
-
stuff = '<a href="something-weird://heyyy">Wat</a> is this'
|
94
|
-
whitelist = {
|
95
|
-
:elements => ['a'],
|
96
|
-
:attributes => {'a' => ['href']},
|
97
|
-
:protocols => {'a' => {'href' => ['something-weird']}}
|
98
|
-
}
|
99
|
-
filter = SanitizationFilter.new(stuff, {:whitelist => whitelist})
|
100
|
-
html = filter.call.to_s
|
101
|
-
assert_equal stuff, html
|
102
|
-
end
|
103
|
-
|
104
|
-
def test_whitelist_contains_default_anchor_schemes
|
105
|
-
assert_equal SanitizationFilter::WHITELIST[:protocols]['a']['href'], ['http', 'https', 'mailto', :relative, 'github-windows', 'github-mac']
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_whitelist_from_full_constant
|
109
|
-
stuff = '<a href="something-weird://heyyy" ping="more-weird://hiii">Wat</a> is this'
|
110
|
-
filter = SanitizationFilter.new(stuff, :whitelist => SanitizationFilter::FULL)
|
111
|
-
html = filter.call.to_s
|
112
|
-
assert_equal 'Wat is this', html
|
113
|
-
end
|
114
|
-
|
115
|
-
def test_exports_default_anchor_schemes
|
116
|
-
assert_equal SanitizationFilter::ANCHOR_SCHEMES, ['http', 'https', 'mailto', :relative, 'github-windows', 'github-mac']
|
117
|
-
end
|
118
|
-
|
119
|
-
def test_script_contents_are_removed
|
120
|
-
orig = '<script>JavaScript!</script>'
|
121
|
-
assert_equal "", SanitizationFilter.call(orig).to_s
|
122
|
-
end
|
123
|
-
|
124
|
-
def test_table_rows_and_cells_removed_if_not_in_table
|
125
|
-
orig = %(<tr><td>Foo</td></tr><td>Bar</td>)
|
126
|
-
assert_equal 'FooBar', SanitizationFilter.call(orig).to_s
|
127
|
-
end
|
128
|
-
|
129
|
-
def test_table_sections_removed_if_not_in_table
|
130
|
-
orig = %(<thead><tr><td>Foo</td></tr></thead>)
|
131
|
-
assert_equal 'Foo', SanitizationFilter.call(orig).to_s
|
132
|
-
end
|
133
|
-
|
134
|
-
def test_table_sections_are_not_removed
|
135
|
-
orig = %(<table>
|
136
|
-
<thead><tr><th>Column 1</th></tr></thead>
|
137
|
-
<tfoot><tr><td>Sum</td></tr></tfoot>
|
138
|
-
<tbody><tr><td>1</td></tr></tbody>
|
139
|
-
</table>)
|
140
|
-
assert_equal orig, SanitizationFilter.call(orig).to_s
|
141
|
-
end
|
142
|
-
|
143
|
-
def test_summary_tag_are_not_removed
|
144
|
-
orig = %(<summary>Foo</summary>)
|
145
|
-
assert_equal orig, SanitizationFilter.call(orig).to_s
|
146
|
-
end
|
147
|
-
|
148
|
-
def test_details_tag_and_open_attribute_are_not_removed
|
149
|
-
orig = %(<details open>Foo</details>)
|
150
|
-
assert_equal orig, SanitizationFilter.call(orig).to_s
|
151
|
-
end
|
152
|
-
|
153
|
-
def test_nested_details_tag_are_not_removed
|
154
|
-
orig = <<-NESTED
|
155
|
-
<details>
|
156
|
-
<summary>Foo</summary>
|
157
|
-
<details>
|
158
|
-
Bar
|
159
|
-
<summary>Baz</summary>
|
160
|
-
</details>
|
161
|
-
Qux
|
162
|
-
</details>
|
163
|
-
NESTED
|
164
|
-
assert_equal orig, SanitizationFilter.call(orig).to_s
|
165
|
-
end
|
166
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
require "test_helper"
|
2
|
-
|
3
|
-
SyntaxHighlightFilter = HTML::Pipeline::SyntaxHighlightFilter
|
4
|
-
|
5
|
-
class HTML::Pipeline::SyntaxHighlightFilterTest < Minitest::Test
|
6
|
-
def test_highlight_default
|
7
|
-
filter = SyntaxHighlightFilter.new \
|
8
|
-
"<pre>hello</pre>", :highlight => "coffeescript"
|
9
|
-
|
10
|
-
doc = filter.call
|
11
|
-
assert !doc.css(".highlight-coffeescript").empty?
|
12
|
-
end
|
13
|
-
|
14
|
-
def test_highlight_default_will_not_override
|
15
|
-
filter = SyntaxHighlightFilter.new \
|
16
|
-
"<pre lang='c'>hello</pre>", :highlight => "coffeescript"
|
17
|
-
|
18
|
-
doc = filter.call
|
19
|
-
assert doc.css(".highlight-coffeescript").empty?
|
20
|
-
assert !doc.css(".highlight-c").empty?
|
21
|
-
end
|
22
|
-
end
|
@@ -1,134 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
require "test_helper"
|
3
|
-
|
4
|
-
class HTML::Pipeline::TableOfContentsFilterTest < Minitest::Test
|
5
|
-
TocFilter = HTML::Pipeline::TableOfContentsFilter
|
6
|
-
|
7
|
-
TocPipeline =
|
8
|
-
HTML::Pipeline.new [
|
9
|
-
HTML::Pipeline::TableOfContentsFilter
|
10
|
-
]
|
11
|
-
|
12
|
-
def toc
|
13
|
-
result = {}
|
14
|
-
TocPipeline.call(@orig, {}, result)
|
15
|
-
result[:toc]
|
16
|
-
end
|
17
|
-
|
18
|
-
def test_anchors_are_added_properly
|
19
|
-
orig = %(<h1>Ice cube</h1><p>Will swarm on any motherfucker in a blue uniform</p>)
|
20
|
-
assert_includes TocFilter.call(orig).to_s, '<a id='
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_custom_anchor_icons_added_properly
|
24
|
-
orig = %(<h1>Ice cube</h1>)
|
25
|
-
expected = %Q{<h1>\n<a id="ice-cube" class="anchor" href="#ice-cube" aria-hidden="true">#</a>Ice cube</h1>}
|
26
|
-
|
27
|
-
assert_equal expected, TocFilter.call(orig, {:anchor_icon => "#"}).to_s
|
28
|
-
end
|
29
|
-
|
30
|
-
def test_toc_list_added_properly
|
31
|
-
@orig = %(<h1>Ice cube</h1><p>Will swarm on any motherfucker in a blue uniform</p>)
|
32
|
-
assert_includes toc, %Q{<ul class="section-nav">\n<li><a href="}
|
33
|
-
end
|
34
|
-
|
35
|
-
def test_anchors_have_sane_names
|
36
|
-
orig = %(<h1>Dr Dre</h1><h1>Ice Cube</h1><h1>Eazy-E</h1><h1>MC Ren</h1>)
|
37
|
-
result = TocFilter.call(orig).to_s
|
38
|
-
|
39
|
-
assert_includes result, '"dr-dre"'
|
40
|
-
assert_includes result, '"ice-cube"'
|
41
|
-
assert_includes result, '"eazy-e"'
|
42
|
-
assert_includes result, '"mc-ren"'
|
43
|
-
end
|
44
|
-
|
45
|
-
def test_anchors_have_aria_hidden
|
46
|
-
orig = "<h1>Straight Outta Compton</h1>"
|
47
|
-
result = TocFilter.call(orig).to_s
|
48
|
-
assert_includes result, 'aria-hidden="true"'
|
49
|
-
end
|
50
|
-
|
51
|
-
def test_toc_hrefs_have_sane_values
|
52
|
-
@orig = %(<h1>Dr Dre</h1><h1>Ice Cube</h1><h1>Eazy-E</h1><h1>MC Ren</h1>)
|
53
|
-
assert_includes toc, '"#dr-dre"'
|
54
|
-
assert_includes toc, '"#ice-cube"'
|
55
|
-
assert_includes toc, '"#eazy-e"'
|
56
|
-
assert_includes toc, '"#mc-ren"'
|
57
|
-
end
|
58
|
-
|
59
|
-
def test_dupe_headers_have_unique_trailing_identifiers
|
60
|
-
orig = %(<h1>Straight Outta Compton</h1>
|
61
|
-
<h2>Dopeman</h2>
|
62
|
-
<h3>Express Yourself</h3>
|
63
|
-
<h1>Dopeman</h1>)
|
64
|
-
|
65
|
-
result = TocFilter.call(orig).to_s
|
66
|
-
|
67
|
-
assert_includes result, '"dopeman"'
|
68
|
-
assert_includes result, '"dopeman-1"'
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_dupe_headers_have_unique_toc_anchors
|
72
|
-
@orig = %(<h1>Straight Outta Compton</h1>
|
73
|
-
<h2>Dopeman</h2>
|
74
|
-
<h3>Express Yourself</h3>
|
75
|
-
<h1>Dopeman</h1>)
|
76
|
-
|
77
|
-
assert_includes toc, '"#dopeman"'
|
78
|
-
assert_includes toc, '"#dopeman-1"'
|
79
|
-
end
|
80
|
-
|
81
|
-
def test_all_header_tags_are_found_when_adding_anchors
|
82
|
-
orig = %(<h1>"Funky President" by James Brown</h1>
|
83
|
-
<h2>"It's My Thing" by Marva Whitney</h2>
|
84
|
-
<h3>"Boogie Back" by Roy Ayers</h3>
|
85
|
-
<h4>"Feel Good" by Fancy</h4>
|
86
|
-
<h5>"Funky Drummer" by James Brown</h5>
|
87
|
-
<h6>"Ruthless Villain" by Eazy-E</h6>
|
88
|
-
<h7>"Be Thankful for What You Got" by William DeVaughn</h7>)
|
89
|
-
|
90
|
-
doc = TocFilter.call(orig)
|
91
|
-
|
92
|
-
assert_equal 6, doc.search('a').size
|
93
|
-
end
|
94
|
-
|
95
|
-
def test_toc_is_complete
|
96
|
-
@orig = %(<h1>"Funky President" by James Brown</h1>
|
97
|
-
<h2>"It's My Thing" by Marva Whitney</h2>
|
98
|
-
<h3>"Boogie Back" by Roy Ayers</h3>
|
99
|
-
<h4>"Feel Good" by Fancy</h4>
|
100
|
-
<h5>"Funky Drummer" by James Brown</h5>
|
101
|
-
<h6>"Ruthless Villain" by Eazy-E</h6>
|
102
|
-
<h7>"Be Thankful for What You Got" by William DeVaughn</h7>)
|
103
|
-
|
104
|
-
expected = %Q{<ul class="section-nav">\n<li><a href="#funky-president-by-james-brown">"Funky President" by James Brown</a></li>\n<li><a href="#its-my-thing-by-marva-whitney">"It's My Thing" by Marva Whitney</a></li>\n<li><a href="#boogie-back-by-roy-ayers">"Boogie Back" by Roy Ayers</a></li>\n<li><a href="#feel-good-by-fancy">"Feel Good" by Fancy</a></li>\n<li><a href="#funky-drummer-by-james-brown">"Funky Drummer" by James Brown</a></li>\n<li><a href="#ruthless-villain-by-eazy-e">"Ruthless Villain" by Eazy-E</a></li>\n</ul>}
|
105
|
-
|
106
|
-
assert_equal expected, toc
|
107
|
-
end
|
108
|
-
|
109
|
-
if RUBY_VERSION > "1.9" # not sure how to make this work on 1.8.7
|
110
|
-
|
111
|
-
def test_anchors_with_utf8_characters
|
112
|
-
orig = %(<h1>日本語</h1>
|
113
|
-
<h1>Русский</h1)
|
114
|
-
|
115
|
-
rendered_h1s = TocFilter.call(orig).search('h1').map(&:to_s)
|
116
|
-
|
117
|
-
assert_equal "<h1>\n<a id=\"日本語\" class=\"anchor\" href=\"#%E6%97%A5%E6%9C%AC%E8%AA%9E\" aria-hidden=\"true\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"></span></a>日本語</h1>",
|
118
|
-
rendered_h1s[0]
|
119
|
-
assert_equal "<h1>\n<a id=\"Русский\" class=\"anchor\" href=\"#%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9\" aria-hidden=\"true\"><span aria-hidden=\"true\" class=\"octicon octicon-link\"></span></a>Русский</h1>",
|
120
|
-
rendered_h1s[1]
|
121
|
-
end
|
122
|
-
|
123
|
-
def test_toc_with_utf8_characters
|
124
|
-
@orig = %(<h1>日本語</h1>
|
125
|
-
<h1>Русский</h1)
|
126
|
-
|
127
|
-
rendered_toc = Nokogiri::HTML::DocumentFragment.parse(toc).to_s
|
128
|
-
|
129
|
-
expected = %Q{<ul class="section-nav">\n<li><a href="#%E6%97%A5%E6%9C%AC%E8%AA%9E">日本語</a></li>\n<li><a href="#%D0%A0%D1%83%D1%81%D1%81%D0%BA%D0%B8%D0%B9">Русский</a></li>\n</ul>}
|
130
|
-
|
131
|
-
assert_equal expected, rendered_toc
|
132
|
-
end
|
133
|
-
end
|
134
|
-
end
|