qiita_marker 0.23.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE.txt +21 -0
  3. data/README.md +50 -0
  4. data/Rakefile +113 -0
  5. data/bin/qiita_marker +123 -0
  6. data/ext/qiita_marker/arena.c +103 -0
  7. data/ext/qiita_marker/autolink.c +425 -0
  8. data/ext/qiita_marker/autolink.h +8 -0
  9. data/ext/qiita_marker/blocks.c +1596 -0
  10. data/ext/qiita_marker/buffer.c +278 -0
  11. data/ext/qiita_marker/buffer.h +116 -0
  12. data/ext/qiita_marker/case_fold_switch.inc +4327 -0
  13. data/ext/qiita_marker/chunk.h +135 -0
  14. data/ext/qiita_marker/cmark-gfm-core-extensions.h +54 -0
  15. data/ext/qiita_marker/cmark-gfm-extension_api.h +736 -0
  16. data/ext/qiita_marker/cmark-gfm-extensions_export.h +42 -0
  17. data/ext/qiita_marker/cmark-gfm.h +817 -0
  18. data/ext/qiita_marker/cmark-gfm_export.h +42 -0
  19. data/ext/qiita_marker/cmark-gfm_version.h +7 -0
  20. data/ext/qiita_marker/cmark.c +55 -0
  21. data/ext/qiita_marker/cmark_ctype.c +44 -0
  22. data/ext/qiita_marker/cmark_ctype.h +33 -0
  23. data/ext/qiita_marker/commonmark.c +529 -0
  24. data/ext/qiita_marker/config.h +76 -0
  25. data/ext/qiita_marker/core-extensions.c +27 -0
  26. data/ext/qiita_marker/entities.inc +2138 -0
  27. data/ext/qiita_marker/ext_scanners.c +879 -0
  28. data/ext/qiita_marker/ext_scanners.h +24 -0
  29. data/ext/qiita_marker/extconf.rb +7 -0
  30. data/ext/qiita_marker/footnotes.c +63 -0
  31. data/ext/qiita_marker/footnotes.h +27 -0
  32. data/ext/qiita_marker/houdini.h +57 -0
  33. data/ext/qiita_marker/houdini_href_e.c +100 -0
  34. data/ext/qiita_marker/houdini_html_e.c +66 -0
  35. data/ext/qiita_marker/houdini_html_u.c +149 -0
  36. data/ext/qiita_marker/html.c +486 -0
  37. data/ext/qiita_marker/html.h +27 -0
  38. data/ext/qiita_marker/inlines.c +1691 -0
  39. data/ext/qiita_marker/inlines.h +29 -0
  40. data/ext/qiita_marker/iterator.c +159 -0
  41. data/ext/qiita_marker/iterator.h +26 -0
  42. data/ext/qiita_marker/latex.c +466 -0
  43. data/ext/qiita_marker/linked_list.c +37 -0
  44. data/ext/qiita_marker/man.c +278 -0
  45. data/ext/qiita_marker/map.c +122 -0
  46. data/ext/qiita_marker/map.h +41 -0
  47. data/ext/qiita_marker/node.c +979 -0
  48. data/ext/qiita_marker/node.h +125 -0
  49. data/ext/qiita_marker/parser.h +58 -0
  50. data/ext/qiita_marker/plaintext.c +235 -0
  51. data/ext/qiita_marker/plugin.c +36 -0
  52. data/ext/qiita_marker/plugin.h +34 -0
  53. data/ext/qiita_marker/qiita_marker.c +1321 -0
  54. data/ext/qiita_marker/qiita_marker.h +16 -0
  55. data/ext/qiita_marker/references.c +42 -0
  56. data/ext/qiita_marker/references.h +26 -0
  57. data/ext/qiita_marker/registry.c +63 -0
  58. data/ext/qiita_marker/registry.h +24 -0
  59. data/ext/qiita_marker/render.c +205 -0
  60. data/ext/qiita_marker/render.h +62 -0
  61. data/ext/qiita_marker/scanners.c +10520 -0
  62. data/ext/qiita_marker/scanners.h +62 -0
  63. data/ext/qiita_marker/scanners.re +341 -0
  64. data/ext/qiita_marker/strikethrough.c +167 -0
  65. data/ext/qiita_marker/strikethrough.h +9 -0
  66. data/ext/qiita_marker/syntax_extension.c +149 -0
  67. data/ext/qiita_marker/syntax_extension.h +34 -0
  68. data/ext/qiita_marker/table.c +822 -0
  69. data/ext/qiita_marker/table.h +12 -0
  70. data/ext/qiita_marker/tagfilter.c +60 -0
  71. data/ext/qiita_marker/tagfilter.h +8 -0
  72. data/ext/qiita_marker/tasklist.c +156 -0
  73. data/ext/qiita_marker/tasklist.h +8 -0
  74. data/ext/qiita_marker/utf8.c +317 -0
  75. data/ext/qiita_marker/utf8.h +35 -0
  76. data/ext/qiita_marker/xml.c +181 -0
  77. data/lib/qiita_marker/config.rb +52 -0
  78. data/lib/qiita_marker/node/inspect.rb +57 -0
  79. data/lib/qiita_marker/node.rb +83 -0
  80. data/lib/qiita_marker/renderer/html_renderer.rb +252 -0
  81. data/lib/qiita_marker/renderer.rb +135 -0
  82. data/lib/qiita_marker/version.rb +5 -0
  83. data/lib/qiita_marker.rb +45 -0
  84. data/qiita_marker.gemspec +40 -0
  85. data/test/benchmark.rb +32 -0
  86. data/test/fixtures/curly.md +1 -0
  87. data/test/fixtures/dingus.md +10 -0
  88. data/test/fixtures/strong.md +1 -0
  89. data/test/fixtures/table.md +10 -0
  90. data/test/test_attributes.rb +24 -0
  91. data/test/test_basics.rb +35 -0
  92. data/test/test_commands.rb +72 -0
  93. data/test/test_commonmark.rb +36 -0
  94. data/test/test_doc.rb +130 -0
  95. data/test/test_encoding.rb +23 -0
  96. data/test/test_extensions.rb +116 -0
  97. data/test/test_footnotes.rb +60 -0
  98. data/test/test_gc.rb +47 -0
  99. data/test/test_helper.rb +71 -0
  100. data/test/test_linebreaks.rb +15 -0
  101. data/test/test_maliciousness.rb +262 -0
  102. data/test/test_node.rb +89 -0
  103. data/test/test_options.rb +37 -0
  104. data/test/test_pathological_inputs.rb +94 -0
  105. data/test/test_plaintext.rb +46 -0
  106. data/test/test_renderer.rb +47 -0
  107. data/test/test_smartpunct.rb +27 -0
  108. data/test/test_spec.rb +30 -0
  109. data/test/test_tasklists.rb +43 -0
  110. data/test/test_xml.rb +107 -0
  111. metadata +313 -0
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestExtensions < Minitest::Test
6
+ def setup
7
+ @markdown = fixtures_file('table.md')
8
+ end
9
+
10
+ def test_uses_specified_extensions
11
+ QiitaMarker.render_html(@markdown, :DEFAULT, %i[]).tap do |out|
12
+ assert_includes out, '| a'
13
+ assert_includes out, '| <strong>x</strong>'
14
+ assert_includes out, '~~hi~~'
15
+ end
16
+
17
+ QiitaMarker.render_html(@markdown, :DEFAULT, %i[table]).tap do |out|
18
+ refute_includes out, '| a'
19
+ %w[<table> <tr> <th> a </th> <td> c </td> <strong>x</strong>].each { |html| assert_includes out, html }
20
+ assert_includes out, '~~hi~~'
21
+ end
22
+
23
+ QiitaMarker.render_html(@markdown, :DEFAULT, %i[strikethrough]).tap do |out|
24
+ assert_includes out, '| a'
25
+ refute_includes out, '~~hi~~'
26
+ assert_includes out, '<del>hi</del>'
27
+ end
28
+
29
+ doc = QiitaMarker.render_doc('~a~ ~~b~~ ~~~c~~~', :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
30
+ assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", doc.to_html)
31
+
32
+ html = QiitaMarker.render_html('~a~ ~~b~~ ~~~c~~~', :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
33
+ assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", html)
34
+
35
+ QiitaMarker.render_html(@markdown, :DEFAULT, %i[table strikethrough]).tap do |out|
36
+ refute_includes out, '| a'
37
+ refute_includes out, '| <strong>x</strong>'
38
+ refute_includes out, '~~hi~~'
39
+ end
40
+ end
41
+
42
+ def test_extensions_with_renderers
43
+ doc = QiitaMarker.render_doc(@markdown, :DEFAULT, %i[table])
44
+
45
+ doc.to_html.tap do |out|
46
+ refute_includes out, '| a'
47
+ %w[<table> <tr> <th> a </th> <td> c </td> <strong>x</strong>].each { |html| assert_includes out, html }
48
+ assert_includes out, '~~hi~~'
49
+ end
50
+
51
+ HtmlRenderer.new.render(doc).tap do |out|
52
+ refute_includes out, '| a'
53
+ %w[<table> <tr> <th> a </th> <td> c </td> <strong>x</strong>].each { |html| assert_includes out, html }
54
+ assert_includes out, '~~hi~~'
55
+ end
56
+
57
+ doc = QiitaMarker.render_doc('~a~ ~~b~~ ~~~c~~~', :STRIKETHROUGH_DOUBLE_TILDE, [:strikethrough])
58
+ assert_equal("<p>~a~ <del>b</del> ~~~c~~~</p>\n", HtmlRenderer.new.render(doc))
59
+ end
60
+
61
+ def test_bad_extension_specifications
62
+ assert_raises(TypeError) { QiitaMarker.render_html(@markdown, :DEFAULT, 'nope') }
63
+ assert_raises(TypeError) { QiitaMarker.render_html(@markdown, :DEFAULT, ['table']) }
64
+ assert_raises(ArgumentError) { QiitaMarker.render_html(@markdown, :DEFAULT, %i[table bad]) }
65
+ end
66
+
67
+ def test_comments_are_kept_as_expected
68
+ assert_equal "<!--hello--> <blah> &lt;xmp>\n",
69
+ QiitaMarker.render_html("<!--hello--> <blah> <xmp>\n", :UNSAFE, %i[tagfilter])
70
+ end
71
+
72
+ def test_table_prefer_style_attributes
73
+ assert_equal(<<~HTML, QiitaMarker.render_html(<<~MD, :TABLE_PREFER_STYLE_ATTRIBUTES, %i[table]))
74
+ <table>
75
+ <thead>
76
+ <tr>
77
+ <th style="text-align: left">aaa</th>
78
+ <th>bbb</th>
79
+ <th style="text-align: center">ccc</th>
80
+ <th>ddd</th>
81
+ <th style="text-align: right">eee</th>
82
+ </tr>
83
+ </thead>
84
+ <tbody>
85
+ <tr>
86
+ <td style="text-align: left">fff</td>
87
+ <td>ggg</td>
88
+ <td style="text-align: center">hhh</td>
89
+ <td>iii</td>
90
+ <td style="text-align: right">jjj</td>
91
+ </tr>
92
+ </tbody>
93
+ </table>
94
+ HTML
95
+ aaa | bbb | ccc | ddd | eee
96
+ :-- | --- | :-: | --- | --:
97
+ fff | ggg | hhh | iii | jjj
98
+ MD
99
+ end
100
+
101
+ def test_plaintext
102
+ assert_equal(<<~HTML, QiitaMarker.render_doc(<<~MD, :DEFAULT, %i[table strikethrough]).to_plaintext)
103
+ Hello ~there~.
104
+
105
+ | a |
106
+ | --- |
107
+ | b |
108
+ HTML
109
+ Hello ~~there~~.
110
+
111
+ | a |
112
+ | - |
113
+ | b |
114
+ MD
115
+ end
116
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestFootnotes < Minitest::Test
6
+ def setup
7
+ @doc = QiitaMarker.render_doc("Hello[^hi].\n\n[^hi]: Hey!\n", :FOOTNOTES)
8
+ end
9
+
10
+ def test_to_html
11
+ expected = <<~HTML
12
+ <p>Hello<sup class="footnote-ref"><a href="#fn-hi" id="fnref-hi" data-footnote-ref>1</a></sup>.</p>
13
+ <section class="footnotes" data-footnotes>
14
+ <ol>
15
+ <li id="fn-hi">
16
+ <p>Hey! <a href="#fnref-hi" class="footnote-backref" data-footnote-backref aria-label="Back to content">↩</a></p>
17
+ </li>
18
+ </ol>
19
+ </section>
20
+ HTML
21
+
22
+ assert_equal expected, @doc.to_html
23
+ end
24
+
25
+ def test_html_renderer
26
+ expected = <<~HTML
27
+ <p>Hello<sup class="footnote-ref"><a href="#fn1" id="fnref1">1</a></sup>.</p>
28
+ <section class="footnotes">
29
+ <ol>
30
+ <li id="fn1">
31
+ <p>Hey! <a href="#fnref1" class="footnote-backref">↩</a></p>
32
+ </li>
33
+ </ol>
34
+ </section>
35
+ HTML
36
+
37
+ assert_equal expected, QiitaMarker::HtmlRenderer.new.render(@doc)
38
+ end
39
+
40
+ def test_render_html
41
+ md = <<~MARKDOWN
42
+ # footnotes
43
+ Let's render some footnotes[^1]
44
+
45
+ [^1]: This is a footnote
46
+ MARKDOWN
47
+ expected = <<~HTML
48
+ <h1>footnotes</h1>
49
+ <p>Let's render some footnotes<sup class="footnote-ref"><a href="#fn-1" id="fnref-1" data-footnote-ref>1</a></sup></p>
50
+ <section class="footnotes" data-footnotes>
51
+ <ol>
52
+ <li id="fn-1">
53
+ <p>This is a footnote <a href="#fnref-1" class="footnote-backref" data-footnote-backref aria-label="Back to content">↩</a></p>
54
+ </li>
55
+ </ol>
56
+ </section>
57
+ HTML
58
+ assert_equal expected, QiitaMarker.render_html(md, :FOOTNOTES)
59
+ end
60
+ end
data/test/test_gc.rb ADDED
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ # rubocop:disable Lint/UselessAssignment
4
+ require 'test_helper'
5
+
6
+ class TestNode < Minitest::Test
7
+ # These tests are somewhat fragile. It would be better to allocate lots
8
+ # of memory after a GC run to make sure that potentially freed memory
9
+ # isn't valid by accident.
10
+
11
+ def test_drop_parent_reference
12
+ doc = QiitaMarker.render_doc('Hi *there*')
13
+ text = doc.first_child.last_child.first_child
14
+ doc = nil
15
+ GC.start
16
+ # Test that doc has not been freed.
17
+ assert_equal 'there', text.string_content
18
+ end
19
+
20
+ def test_drop_child_reference
21
+ doc = QiitaMarker.render_doc('Hi *there*')
22
+ text = doc.first_child.last_child.first_child
23
+ text = nil
24
+ GC.start
25
+ # Test that the cached child object is still valid.
26
+ text = doc.first_child.last_child.first_child
27
+ assert_equal 'there', text.string_content
28
+ end
29
+
30
+ def test_remove_parent
31
+ doc = QiitaMarker.render_doc('Hi *there*')
32
+ para = doc.first_child
33
+ para.delete
34
+ doc = nil
35
+ para = nil
36
+ # TODO: Test that the `para` node was actually freed after unlinking.
37
+ end
38
+
39
+ def test_add_parent
40
+ doc = Node.new(:document)
41
+ hrule = Node.new(:hrule)
42
+ doc.append_child(hrule)
43
+ # If the hrule node was erroneously freed, this would result in a double
44
+ # free.
45
+ end
46
+ end
47
+ # rubocop:enable Lint/UselessAssignment
@@ -0,0 +1,71 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'qiita_marker'
4
+ require 'minitest/autorun'
5
+ require 'minitest/pride'
6
+ require 'minitest/focus'
7
+
8
+ include QiitaMarker # rubocop:disable Style/MixinUsage
9
+
10
+ FIXTURES_DIR = File.join(File.dirname(__FILE__), 'fixtures')
11
+
12
+ def fixtures_file(file)
13
+ File.read(File.join(FIXTURES_DIR, file), encoding: 'utf-8')
14
+ end
15
+
16
+ def make_bin(file, args = '')
17
+ `ruby bin/qiita_marker #{File.join(FIXTURES_DIR, file)} #{args}`.chomp
18
+ end
19
+
20
+ def open_spec_file(filename)
21
+ line_number = 0
22
+ start_line = 0
23
+ end_line = 0
24
+ example_number = 0
25
+ markdown_lines = []
26
+ html_lines = []
27
+ state = 0 # 0 regular text, 1 markdown example, 2 html output
28
+ headertext = ''
29
+ tests = []
30
+ extensions = []
31
+
32
+ header_re = Regexp.new('#+ ')
33
+ filepath = File.join('ext', 'qiita_marker', 'cmark-upstream', 'test', filename)
34
+
35
+ File.readlines(filepath, encoding: 'utf-8').each do |line|
36
+ line_number += 1
37
+
38
+ l = line.strip
39
+ if l =~ /^`{32} example(.*)$/
40
+ state = 1
41
+ extensions = Regexp.last_match(1).split
42
+ elsif l == '`' * 32
43
+ state = 0
44
+ example_number += 1
45
+ end_line = line_number
46
+ tests << {
47
+ markdown: markdown_lines.join.tr('→', "\t"),
48
+ html: html_lines.join.tr('→', "\t").rstrip,
49
+ example: example_number,
50
+ start_line: start_line,
51
+ end_line: end_line,
52
+ section: headertext,
53
+ extensions: extensions.map(&:to_sym)
54
+ }
55
+ start_line = 0
56
+ markdown_lines = []
57
+ html_lines = []
58
+ elsif l == '.'
59
+ state = 2
60
+ elsif state == 1
61
+ start_line = line_number - 1 if start_line.zero?
62
+ markdown_lines << line.to_s
63
+ elsif state == 2
64
+ html_lines << line.to_s
65
+ elsif state.zero? && header_re.match(line)
66
+ headertext = line.sub(header_re, '').strip
67
+ end
68
+ end
69
+
70
+ tests
71
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestLinebreaks < Minitest::Test
6
+ def test_hardbreak_no_spaces
7
+ doc = QiitaMarker.render_doc("foo\nbaz")
8
+ assert_equal "<p>foo<br />\nbaz</p>\n", doc.to_html(:HARDBREAKS)
9
+ end
10
+
11
+ def test_hardbreak_with_spaces
12
+ doc = QiitaMarker.render_doc("foo \nbaz")
13
+ assert_equal "<p>foo<br />\nbaz</p>\n", doc.to_html(:HARDBREAKS)
14
+ end
15
+ end
@@ -0,0 +1,262 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ module QiitaMarker
6
+ class TestMaliciousness < Minitest::Test
7
+ def setup
8
+ @doc = QiitaMarker.render_doc('Hi *there*')
9
+ end
10
+
11
+ def test_init_with_bad_type
12
+ assert_raises TypeError do
13
+ Node.new(123)
14
+ end
15
+
16
+ assert_raises NodeError do
17
+ Node.new(:totes_fake)
18
+ end
19
+
20
+ assert_raises TypeError do
21
+ Node.new([])
22
+ end
23
+
24
+ assert_raises TypeError do
25
+ Node.new([23])
26
+ end
27
+
28
+ assert_raises TypeError do
29
+ Node.new(nil)
30
+ end
31
+ end
32
+
33
+ def test_rendering_with_bad_type
34
+ assert_raises TypeError do
35
+ QiitaMarker.render_html("foo \n baz", 123)
36
+ end
37
+
38
+ assert_raises TypeError do
39
+ QiitaMarker.render_html("foo \n baz", :totes_fake)
40
+ end
41
+
42
+ assert_raises TypeError do
43
+ QiitaMarker.render_html("foo \n baz", [])
44
+ end
45
+
46
+ assert_raises TypeError do
47
+ QiitaMarker.render_html("foo \n baz", [23])
48
+ end
49
+
50
+ assert_raises TypeError do
51
+ QiitaMarker.render_html("foo \n baz", nil)
52
+ end
53
+
54
+ assert_raises TypeError do
55
+ QiitaMarker.render_html("foo \n baz", [:SMART, 'totes_fake'])
56
+ end
57
+
58
+ assert_raises TypeError do
59
+ QiitaMarker.render_html(123)
60
+ end
61
+
62
+ assert_raises TypeError do
63
+ QiitaMarker.render_html([123])
64
+ end
65
+
66
+ assert_raises TypeError do
67
+ QiitaMarker.render_html(nil)
68
+ end
69
+
70
+ assert_raises TypeError do
71
+ QiitaMarker.render_doc("foo \n baz", 123)
72
+ end
73
+
74
+ err = assert_raises TypeError do
75
+ QiitaMarker.render_doc("foo \n baz", :safe)
76
+ end
77
+ assert_equal('option \':safe\' does not exist for QiitaMarker::Config::OPTS[:parse]', err.message)
78
+
79
+ assert_raises TypeError do
80
+ QiitaMarker.render_doc("foo \n baz", :totes_fake)
81
+ end
82
+
83
+ assert_raises TypeError do
84
+ QiitaMarker.render_doc("foo \n baz", [])
85
+ end
86
+
87
+ assert_raises TypeError do
88
+ QiitaMarker.render_doc("foo \n baz", [23])
89
+ end
90
+
91
+ assert_raises TypeError do
92
+ QiitaMarker.render_doc("foo \n baz", nil)
93
+ end
94
+
95
+ assert_raises TypeError do
96
+ QiitaMarker.render_doc("foo \n baz", [:SMART, 'totes_fake'])
97
+ end
98
+
99
+ assert_raises TypeError do
100
+ QiitaMarker.render_doc(123)
101
+ end
102
+
103
+ assert_raises TypeError do
104
+ QiitaMarker.render_doc([123])
105
+ end
106
+
107
+ assert_raises TypeError do
108
+ QiitaMarker.render_doc(nil)
109
+ end
110
+ end
111
+
112
+ def test_bad_set_string_content
113
+ assert_raises TypeError do
114
+ @doc.string_content = 123
115
+ end
116
+ end
117
+
118
+ def test_bad_walking
119
+ assert_nil @doc.parent
120
+ assert_nil @doc.previous
121
+ end
122
+
123
+ def test_bad_insertion
124
+ code = Node.new(:code)
125
+ assert_raises NodeError do
126
+ @doc.insert_before(code)
127
+ end
128
+
129
+ paragraph = Node.new(:paragraph)
130
+ assert_raises NodeError do
131
+ @doc.insert_after(paragraph)
132
+ end
133
+
134
+ document = Node.new(:document)
135
+ assert_raises NodeError do
136
+ @doc.prepend_child(document)
137
+ end
138
+
139
+ assert_raises NodeError do
140
+ @doc.append_child(document)
141
+ end
142
+ end
143
+
144
+ def test_bad_url_get
145
+ assert_raises NodeError do
146
+ @doc.url
147
+ end
148
+ end
149
+
150
+ def test_bad_url_set
151
+ assert_raises NodeError do
152
+ @doc.url = '123'
153
+ end
154
+
155
+ link = QiitaMarker.render_doc('[GitHub](https://www.github.com)').first_child.first_child
156
+ assert_raises TypeError do
157
+ link.url = 123
158
+ end
159
+ end
160
+
161
+ def test_bad_title_get
162
+ assert_raises NodeError do
163
+ @doc.title
164
+ end
165
+ end
166
+
167
+ def test_bad_title_set
168
+ assert_raises NodeError do
169
+ @doc.title = '123'
170
+ end
171
+
172
+ image = QiitaMarker.render_doc('![alt text](https://github.com/favicon.ico "Favicon")')
173
+ image = image.first_child.first_child
174
+ assert_raises TypeError do
175
+ image.title = 123
176
+ end
177
+ end
178
+
179
+ def test_bad_header_level_get
180
+ assert_raises NodeError do
181
+ @doc.header_level
182
+ end
183
+ end
184
+
185
+ def test_bad_header_level_set
186
+ assert_raises NodeError do
187
+ @doc.header_level = 1
188
+ end
189
+
190
+ header = QiitaMarker.render_doc('### Header Three').first_child
191
+ assert_raises TypeError do
192
+ header.header_level = '123'
193
+ end
194
+ end
195
+
196
+ def test_bad_list_type_get
197
+ assert_raises NodeError do
198
+ @doc.list_type
199
+ end
200
+ end
201
+
202
+ def test_bad_list_type_set
203
+ assert_raises NodeError do
204
+ @doc.list_type = :bullet_list
205
+ end
206
+
207
+ ul_list = QiitaMarker.render_doc("* Bullet\n*Bullet").first_child
208
+ assert_raises NodeError do
209
+ ul_list.list_type = :fake
210
+ end
211
+ assert_raises TypeError do
212
+ ul_list.list_type = 1234
213
+ end
214
+ end
215
+
216
+ def test_bad_list_start_get
217
+ assert_raises NodeError do
218
+ @doc.list_start
219
+ end
220
+ end
221
+
222
+ def test_bad_list_start_set
223
+ assert_raises NodeError do
224
+ @doc.list_start = 12
225
+ end
226
+
227
+ ol_list = QiitaMarker.render_doc("1. One\n2. Two").first_child
228
+ assert_raises TypeError do
229
+ ol_list.list_start = :fake
230
+ end
231
+ end
232
+
233
+ def test_bad_list_tight_get
234
+ assert_raises NodeError do
235
+ @doc.list_tight
236
+ end
237
+ end
238
+
239
+ def test_bad_list_tight_set
240
+ assert_raises NodeError do
241
+ @doc.list_tight = false
242
+ end
243
+ end
244
+
245
+ def test_bad_fence_info_get
246
+ assert_raises NodeError do
247
+ @doc.fence_info
248
+ end
249
+ end
250
+
251
+ def test_bad_fence_info_set
252
+ assert_raises NodeError do
253
+ @doc.fence_info = 'ruby'
254
+ end
255
+
256
+ fence = QiitaMarker.render_doc("``` ruby\nputs 'wow'\n```").first_child
257
+ assert_raises TypeError do
258
+ fence.fence_info = 123
259
+ end
260
+ end
261
+ end
262
+ end
data/test/test_node.rb ADDED
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestNode < Minitest::Test
6
+ def setup
7
+ @doc = QiitaMarker.render_doc('Hi *there*, I am mostly text!')
8
+ end
9
+
10
+ def test_walk
11
+ nodes = []
12
+ @doc.walk do |node|
13
+ nodes << node.type
14
+ end
15
+ assert_equal %i[document paragraph text emph text text], nodes
16
+ end
17
+
18
+ def test_each
19
+ nodes = []
20
+ @doc.first_child.each do |node|
21
+ nodes << node.type
22
+ end
23
+ assert_equal %i[text emph text], nodes
24
+ end
25
+
26
+ def test_deprecated_each_child
27
+ nodes = []
28
+ _, err = capture_io do
29
+ @doc.first_child.each_child do |node|
30
+ nodes << node.type
31
+ end
32
+ end
33
+ assert_equal %i[text emph text], nodes
34
+ assert_match(/`each_child` is deprecated/, err)
35
+ end
36
+
37
+ def test_select
38
+ nodes = @doc.first_child.select { |node| node.type == :text }
39
+ assert_equal QiitaMarker::Node, nodes.first.class
40
+ assert_equal %i[text text], nodes.map(&:type)
41
+ end
42
+
43
+ def test_map
44
+ nodes = @doc.first_child.map(&:type)
45
+ assert_equal %i[text emph text], nodes
46
+ end
47
+
48
+ def test_insert_illegal
49
+ assert_raises NodeError do
50
+ @doc.insert_before(@doc)
51
+ end
52
+ end
53
+
54
+ def test_to_html
55
+ assert_equal "<p>Hi <em>there</em>, I am mostly text!</p>\n", @doc.to_html
56
+ end
57
+
58
+ def test_html_renderer
59
+ renderer = HtmlRenderer.new
60
+ result = renderer.render(@doc)
61
+ assert_equal "<p>Hi <em>there</em>, I am mostly text!</p>\n", result
62
+ end
63
+
64
+ def test_walk_and_set_string_content
65
+ @doc.walk do |node|
66
+ node.string_content = 'world' if node.type == :text && node.string_content == 'there'
67
+ end
68
+ result = HtmlRenderer.new.render(@doc)
69
+ assert_equal "<p>Hi <em>world</em>, I am mostly text!</p>\n", result
70
+ end
71
+
72
+ def test_walk_and_delete_node
73
+ @doc.walk do |node|
74
+ if node.type == :emph
75
+ node.insert_before(node.first_child)
76
+ node.delete
77
+ end
78
+ end
79
+ assert_equal "<p>Hi there, I am mostly text!</p>\n", @doc.to_html
80
+ end
81
+
82
+ def test_inspect
83
+ assert_match(/#<QiitaMarker::Node\(document\):/, @doc.inspect)
84
+ end
85
+
86
+ def test_pretty_print
87
+ assert_match(/#<QiitaMarker::Node\(document\):/, PP.pp(@doc, +''))
88
+ end
89
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
4
+
5
+ class TestExtensions < Minitest::Test
6
+ def test_full_info_string
7
+ md = <<~MD
8
+ ```ruby
9
+ module Foo
10
+ ```
11
+ MD
12
+
13
+ QiitaMarker.render_html(md, :FULL_INFO_STRING).tap do |out|
14
+ assert_includes out, '<pre><code class="language-ruby">'
15
+ end
16
+
17
+ md = <<~MD
18
+ ```ruby my info string
19
+ module Foo
20
+ ```
21
+ MD
22
+
23
+ QiitaMarker.render_html(md, :FULL_INFO_STRING).tap do |out|
24
+ assert_includes out, '<pre><code class="language-ruby" data-meta="my info string">'
25
+ end
26
+
27
+ md = <<~MD
28
+ ```ruby my \x00 string
29
+ module Foo
30
+ ```
31
+ MD
32
+
33
+ QiitaMarker.render_html(md, :FULL_INFO_STRING).tap do |out|
34
+ assert_includes out, %(<pre><code class="language-ruby" data-meta="my � string">)
35
+ end
36
+ end
37
+ end