summaryrefslogtreecommitdiff
path: root/test/rdoc
diff options
context:
space:
mode:
Diffstat (limited to 'test/rdoc')
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Amps and angle encoding.text21
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Auto links.text13
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Backslash escapes.text120
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Blockquotes with code blocks.text11
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Code Blocks.text14
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Code Spans.text6
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Hard-wrapped paragraphs with list-like lines.text8
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Horizontal rules.text67
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Inline HTML (Advanced).text15
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Inline HTML (Simple).text69
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Inline HTML comments.text13
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Links, inline style.text12
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Links, reference style.text71
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Links, shortcut references.text20
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Literal quotes in titles.text7
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Basics.text306
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Syntax.text888
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Nested blockquotes.text5
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Ordered and unordered lists.text131
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Strong and em together.text7
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Tabs.text21
-rw-r--r--test/rdoc/MarkdownTest_1.0.3/Tidyness.text5
-rw-r--r--test/rdoc/test.ja.large.rdoc (renamed from test/rdoc/test.ja.largedoc)0
-rw-r--r--test/rdoc/test_attribute_manager.rb66
-rw-r--r--test/rdoc/test_rdoc_any_method.rb134
-rw-r--r--test/rdoc/test_rdoc_attr.rb85
-rw-r--r--test/rdoc/test_rdoc_class_module.rb855
-rw-r--r--test/rdoc/test_rdoc_code_object.rb35
-rw-r--r--test/rdoc/test_rdoc_comment.rb504
-rw-r--r--test/rdoc/test_rdoc_constant.rb132
-rw-r--r--test/rdoc/test_rdoc_context.rb230
-rw-r--r--test/rdoc/test_rdoc_context_section.rb123
-rw-r--r--test/rdoc/test_rdoc_cross_reference.rb28
-rw-r--r--test/rdoc/test_rdoc_encoding.rb27
-rw-r--r--test/rdoc/test_rdoc_extend.rb94
-rw-r--r--test/rdoc/test_rdoc_generator_darkfish.rb110
-rw-r--r--test/rdoc/test_rdoc_generator_json_index.rb275
-rw-r--r--test/rdoc/test_rdoc_generator_markup.rb56
-rw-r--r--test/rdoc/test_rdoc_generator_ri.rb39
-rw-r--r--test/rdoc/test_rdoc_include.rb12
-rw-r--r--test/rdoc/test_rdoc_markdown.rb977
-rw-r--r--test/rdoc/test_rdoc_markdown_test.rb1891
-rw-r--r--test/rdoc/test_rdoc_markup.rb16
-rw-r--r--test/rdoc/test_rdoc_markup_attribute_manager.rb17
-rw-r--r--test/rdoc/test_rdoc_markup_attributes.rb39
-rw-r--r--test/rdoc/test_rdoc_markup_document.rb55
-rw-r--r--test/rdoc/test_rdoc_markup_formatter.rb29
-rw-r--r--test/rdoc/test_rdoc_markup_hard_break.rb31
-rw-r--r--test/rdoc/test_rdoc_markup_heading.rb20
-rw-r--r--test/rdoc/test_rdoc_markup_include.rb19
-rw-r--r--test/rdoc/test_rdoc_markup_indented_paragraph.rb23
-rw-r--r--test/rdoc/test_rdoc_markup_paragraph.rb23
-rw-r--r--test/rdoc/test_rdoc_markup_parser.rb381
-rw-r--r--test/rdoc/test_rdoc_markup_pre_process.rb69
-rw-r--r--test/rdoc/test_rdoc_markup_raw.rb14
-rw-r--r--test/rdoc/test_rdoc_markup_to_ansi.rb49
-rw-r--r--test/rdoc/test_rdoc_markup_to_bs.rb33
-rw-r--r--test/rdoc/test_rdoc_markup_to_html.rb259
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_crossref.rb142
-rw-r--r--test/rdoc/test_rdoc_markup_to_html_snippet.rb710
-rw-r--r--test/rdoc/test_rdoc_markup_to_joined_paragraph.rb32
-rw-r--r--test/rdoc/test_rdoc_markup_to_label.rb112
-rw-r--r--test/rdoc/test_rdoc_markup_to_markdown.rb352
-rw-r--r--test/rdoc/test_rdoc_markup_to_rdoc.rb48
-rw-r--r--test/rdoc/test_rdoc_markup_to_table_of_contents.rb95
-rw-r--r--test/rdoc/test_rdoc_markup_to_tt_only.rb25
-rw-r--r--test/rdoc/test_rdoc_markup_verbatim.rb29
-rw-r--r--test/rdoc/test_rdoc_method_attr.rb35
-rw-r--r--test/rdoc/test_rdoc_normal_class.rb29
-rw-r--r--test/rdoc/test_rdoc_normal_module.rb2
-rw-r--r--test/rdoc/test_rdoc_options.rb232
-rw-r--r--test/rdoc/test_rdoc_parser.rb121
-rw-r--r--test/rdoc/test_rdoc_parser_c.rb377
-rw-r--r--test/rdoc/test_rdoc_parser_markdown.rb55
-rw-r--r--test/rdoc/test_rdoc_parser_rd.rb52
-rw-r--r--test/rdoc/test_rdoc_parser_ruby.rb1152
-rw-r--r--test/rdoc/test_rdoc_parser_simple.rb54
-rw-r--r--test/rdoc/test_rdoc_rd.rb30
-rw-r--r--test/rdoc/test_rdoc_rd_block_parser.rb523
-rw-r--r--test/rdoc/test_rdoc_rd_inline.rb63
-rw-r--r--test/rdoc/test_rdoc_rd_inline_parser.rb173
-rw-r--r--test/rdoc/test_rdoc_rdoc.rb203
-rw-r--r--test/rdoc/test_rdoc_ri_driver.rb489
-rw-r--r--test/rdoc/test_rdoc_ri_paths.rb150
-rw-r--r--test/rdoc/test_rdoc_ruby_lex.rb222
-rw-r--r--test/rdoc/test_rdoc_ruby_token.rb19
-rw-r--r--test/rdoc/test_rdoc_rubygems_hook.rb7
-rw-r--r--test/rdoc/test_rdoc_servlet.rb408
-rw-r--r--test/rdoc/test_rdoc_stats.rb352
-rw-r--r--test/rdoc/test_rdoc_store.rb (renamed from test/rdoc/test_rdoc_ri_store.rb)415
-rw-r--r--test/rdoc/test_rdoc_task.rb17
-rw-r--r--test/rdoc/test_rdoc_text.rb193
-rw-r--r--test/rdoc/test_rdoc_token_stream.rb42
-rw-r--r--test/rdoc/test_rdoc_tom_doc.rb455
-rw-r--r--test/rdoc/test_rdoc_top_level.rb227
-rw-r--r--test/rdoc/xref_test_case.rb24
96 files changed, 14695 insertions, 1551 deletions
diff --git a/test/rdoc/MarkdownTest_1.0.3/Amps and angle encoding.text b/test/rdoc/MarkdownTest_1.0.3/Amps and angle encoding.text
new file mode 100644
index 0000000000..0e9527f931
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Amps and angle encoding.text
@@ -0,0 +1,21 @@
+AT&T has an ampersand in their name.
+
+AT&T is another way to write it.
+
+This & that.
+
+4 < 5.
+
+6 > 5.
+
+Here's a [link] [1] with an ampersand in the URL.
+
+Here's a link with an amersand in the link text: [AT&T] [2].
+
+Here's an inline [link](/script?foo=1&bar=2).
+
+Here's an inline [link](</script?foo=1&bar=2>).
+
+
+[1]: http://example.com/?foo=1&bar=2
+[2]: http://att.com/ "AT&T" \ No newline at end of file
diff --git a/test/rdoc/MarkdownTest_1.0.3/Auto links.text b/test/rdoc/MarkdownTest_1.0.3/Auto links.text
new file mode 100644
index 0000000000..abbc48869d
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Auto links.text
@@ -0,0 +1,13 @@
+Link: <http://example.com/>.
+
+With an ampersand: <http://example.com/?foo=1&bar=2>
+
+* In a list?
+* <http://example.com/>
+* It should.
+
+> Blockquoted: <http://example.com/>
+
+Auto-links should not occur here: `<http://example.com/>`
+
+ or here: <http://example.com/> \ No newline at end of file
diff --git a/test/rdoc/MarkdownTest_1.0.3/Backslash escapes.text b/test/rdoc/MarkdownTest_1.0.3/Backslash escapes.text
new file mode 100644
index 0000000000..5b014cb33d
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Backslash escapes.text
@@ -0,0 +1,120 @@
+These should all get escaped:
+
+Backslash: \\
+
+Backtick: \`
+
+Asterisk: \*
+
+Underscore: \_
+
+Left brace: \{
+
+Right brace: \}
+
+Left bracket: \[
+
+Right bracket: \]
+
+Left paren: \(
+
+Right paren: \)
+
+Greater-than: \>
+
+Hash: \#
+
+Period: \.
+
+Bang: \!
+
+Plus: \+
+
+Minus: \-
+
+
+
+These should not, because they occur within a code block:
+
+ Backslash: \\
+
+ Backtick: \`
+
+ Asterisk: \*
+
+ Underscore: \_
+
+ Left brace: \{
+
+ Right brace: \}
+
+ Left bracket: \[
+
+ Right bracket: \]
+
+ Left paren: \(
+
+ Right paren: \)
+
+ Greater-than: \>
+
+ Hash: \#
+
+ Period: \.
+
+ Bang: \!
+
+ Plus: \+
+
+ Minus: \-
+
+
+Nor should these, which occur in code spans:
+
+Backslash: `\\`
+
+Backtick: `` \` ``
+
+Asterisk: `\*`
+
+Underscore: `\_`
+
+Left brace: `\{`
+
+Right brace: `\}`
+
+Left bracket: `\[`
+
+Right bracket: `\]`
+
+Left paren: `\(`
+
+Right paren: `\)`
+
+Greater-than: `\>`
+
+Hash: `\#`
+
+Period: `\.`
+
+Bang: `\!`
+
+Plus: `\+`
+
+Minus: `\-`
+
+
+These should get escaped, even though they're matching pairs for
+other Markdown constructs:
+
+\*asterisks\*
+
+\_underscores\_
+
+\`backticks\`
+
+This is a code span with a literal backslash-backtick sequence: `` \` ``
+
+This is a tag with unescaped backticks <span attr='`ticks`'>bar</span>.
+
+This is a tag with backslashes <span attr='\\backslashes\\'>bar</span>.
diff --git a/test/rdoc/MarkdownTest_1.0.3/Blockquotes with code blocks.text b/test/rdoc/MarkdownTest_1.0.3/Blockquotes with code blocks.text
new file mode 100644
index 0000000000..c31d171049
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Blockquotes with code blocks.text
@@ -0,0 +1,11 @@
+> Example:
+>
+> sub status {
+> print "working";
+> }
+>
+> Or:
+>
+> sub status {
+> return "working";
+> }
diff --git a/test/rdoc/MarkdownTest_1.0.3/Code Blocks.text b/test/rdoc/MarkdownTest_1.0.3/Code Blocks.text
new file mode 100644
index 0000000000..b54b09285a
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Code Blocks.text
@@ -0,0 +1,14 @@
+ code block on the first line
+
+Regular text.
+
+ code block indented by spaces
+
+Regular text.
+
+ the lines in this block
+ all contain trailing spaces
+
+Regular Text.
+
+ code block on the last line \ No newline at end of file
diff --git a/test/rdoc/MarkdownTest_1.0.3/Code Spans.text b/test/rdoc/MarkdownTest_1.0.3/Code Spans.text
new file mode 100644
index 0000000000..750a1973df
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Code Spans.text
@@ -0,0 +1,6 @@
+`<test a="` content of attribute `">`
+
+Fix for backticks within HTML tag: <span attr='`ticks`'>like this</span>
+
+Here's how you put `` `backticks` `` in a code span.
+
diff --git a/test/rdoc/MarkdownTest_1.0.3/Hard-wrapped paragraphs with list-like lines.text b/test/rdoc/MarkdownTest_1.0.3/Hard-wrapped paragraphs with list-like lines.text
new file mode 100644
index 0000000000..f8a5b27bf4
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Hard-wrapped paragraphs with list-like lines.text
@@ -0,0 +1,8 @@
+In Markdown 1.0.0 and earlier. Version
+8. This line turns into a list item.
+Because a hard-wrapped line in the
+middle of a paragraph looked like a
+list item.
+
+Here's one with a bullet.
+* criminey.
diff --git a/test/rdoc/MarkdownTest_1.0.3/Horizontal rules.text b/test/rdoc/MarkdownTest_1.0.3/Horizontal rules.text
new file mode 100644
index 0000000000..1594bda27b
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Horizontal rules.text
@@ -0,0 +1,67 @@
+Dashes:
+
+---
+
+ ---
+
+ ---
+
+ ---
+
+ ---
+
+- - -
+
+ - - -
+
+ - - -
+
+ - - -
+
+ - - -
+
+
+Asterisks:
+
+***
+
+ ***
+
+ ***
+
+ ***
+
+ ***
+
+* * *
+
+ * * *
+
+ * * *
+
+ * * *
+
+ * * *
+
+
+Underscores:
+
+___
+
+ ___
+
+ ___
+
+ ___
+
+ ___
+
+_ _ _
+
+ _ _ _
+
+ _ _ _
+
+ _ _ _
+
+ _ _ _
diff --git a/test/rdoc/MarkdownTest_1.0.3/Inline HTML (Advanced).text b/test/rdoc/MarkdownTest_1.0.3/Inline HTML (Advanced).text
new file mode 100644
index 0000000000..86b7206d2a
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Inline HTML (Advanced).text
@@ -0,0 +1,15 @@
+Simple block on one line:
+
+<div>foo</div>
+
+And nested without indentation:
+
+<div>
+<div>
+<div>
+foo
+</div>
+<div style=">"/>
+</div>
+<div>bar</div>
+</div>
diff --git a/test/rdoc/MarkdownTest_1.0.3/Inline HTML (Simple).text b/test/rdoc/MarkdownTest_1.0.3/Inline HTML (Simple).text
new file mode 100644
index 0000000000..14aa2dc272
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Inline HTML (Simple).text
@@ -0,0 +1,69 @@
+Here's a simple block:
+
+<div>
+ foo
+</div>
+
+This should be a code block, though:
+
+ <div>
+ foo
+ </div>
+
+As should this:
+
+ <div>foo</div>
+
+Now, nested:
+
+<div>
+ <div>
+ <div>
+ foo
+ </div>
+ </div>
+</div>
+
+This should just be an HTML comment:
+
+<!-- Comment -->
+
+Multiline:
+
+<!--
+Blah
+Blah
+-->
+
+Code block:
+
+ <!-- Comment -->
+
+Just plain comment, with trailing spaces on the line:
+
+<!-- foo -->
+
+Code:
+
+ <hr />
+
+Hr's:
+
+<hr>
+
+<hr/>
+
+<hr />
+
+<hr>
+
+<hr/>
+
+<hr />
+
+<hr class="foo" id="bar" />
+
+<hr class="foo" id="bar"/>
+
+<hr class="foo" id="bar" >
+
diff --git a/test/rdoc/MarkdownTest_1.0.3/Inline HTML comments.text b/test/rdoc/MarkdownTest_1.0.3/Inline HTML comments.text
new file mode 100644
index 0000000000..41d830d038
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Inline HTML comments.text
@@ -0,0 +1,13 @@
+Paragraph one.
+
+<!-- This is a simple comment -->
+
+<!--
+ This is another comment.
+-->
+
+Paragraph two.
+
+<!-- one comment block -- -- with two comments -->
+
+The end.
diff --git a/test/rdoc/MarkdownTest_1.0.3/Links, inline style.text b/test/rdoc/MarkdownTest_1.0.3/Links, inline style.text
new file mode 100644
index 0000000000..09017a90c7
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Links, inline style.text
@@ -0,0 +1,12 @@
+Just a [URL](/url/).
+
+[URL and title](/url/ "title").
+
+[URL and title](/url/ "title preceded by two spaces").
+
+[URL and title](/url/ "title preceded by a tab").
+
+[URL and title](/url/ "title has spaces afterward" ).
+
+
+[Empty]().
diff --git a/test/rdoc/MarkdownTest_1.0.3/Links, reference style.text b/test/rdoc/MarkdownTest_1.0.3/Links, reference style.text
new file mode 100644
index 0000000000..341ec88e3d
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Links, reference style.text
@@ -0,0 +1,71 @@
+Foo [bar] [1].
+
+Foo [bar][1].
+
+Foo [bar]
+[1].
+
+[1]: /url/ "Title"
+
+
+With [embedded [brackets]] [b].
+
+
+Indented [once][].
+
+Indented [twice][].
+
+Indented [thrice][].
+
+Indented [four][] times.
+
+ [once]: /url
+
+ [twice]: /url
+
+ [thrice]: /url
+
+ [four]: /url
+
+
+[b]: /url/
+
+* * *
+
+[this] [this] should work
+
+So should [this][this].
+
+And [this] [].
+
+And [this][].
+
+And [this].
+
+But not [that] [].
+
+Nor [that][].
+
+Nor [that].
+
+[Something in brackets like [this][] should work]
+
+[Same with [this].]
+
+In this case, [this](/somethingelse/) points to something else.
+
+Backslashing should suppress \[this] and [this\].
+
+[this]: foo
+
+
+* * *
+
+Here's one where the [link
+breaks] across lines.
+
+Here's another where the [link
+breaks] across lines, but with a line-ending space.
+
+
+[link breaks]: /url/
diff --git a/test/rdoc/MarkdownTest_1.0.3/Links, shortcut references.text b/test/rdoc/MarkdownTest_1.0.3/Links, shortcut references.text
new file mode 100644
index 0000000000..8c44c98fee
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Links, shortcut references.text
@@ -0,0 +1,20 @@
+This is the [simple case].
+
+[simple case]: /simple
+
+
+
+This one has a [line
+break].
+
+This one has a [line
+break] with a line-ending space.
+
+[line break]: /foo
+
+
+[this] [that] and the [other]
+
+[this]: /this
+[that]: /that
+[other]: /other
diff --git a/test/rdoc/MarkdownTest_1.0.3/Literal quotes in titles.text b/test/rdoc/MarkdownTest_1.0.3/Literal quotes in titles.text
new file mode 100644
index 0000000000..29d0e4235b
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Literal quotes in titles.text
@@ -0,0 +1,7 @@
+Foo [bar][].
+
+Foo [bar](/url/ "Title with "quotes" inside").
+
+
+ [bar]: /url/ "Title with "quotes" inside"
+
diff --git a/test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Basics.text b/test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Basics.text
new file mode 100644
index 0000000000..486055ca7f
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Basics.text
@@ -0,0 +1,306 @@
+Markdown: Basics
+================
+
+<ul id="ProjectSubmenu">
+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+ <li><a class="selected" title="Markdown Basics">Basics</a></li>
+ <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+
+Getting the Gist of Markdown's Formatting Syntax
+------------------------------------------------
+
+This page offers a brief overview of what it's like to use Markdown.
+The [syntax page] [s] provides complete, detailed documentation for
+every feature, but Markdown should be very easy to pick up simply by
+looking at a few examples of it in action. The examples on this page
+are written in a before/after style, showing example syntax and the
+HTML output produced by Markdown.
+
+It's also helpful to simply try Markdown out; the [Dingus] [d] is a
+web application that allows you type your own Markdown-formatted text
+and translate it to XHTML.
+
+**Note:** This document is itself written using Markdown; you
+can [see the source for it by adding '.text' to the URL] [src].
+
+ [s]: /projects/markdown/syntax "Markdown Syntax"
+ [d]: /projects/markdown/dingus "Markdown Dingus"
+ [src]: /projects/markdown/basics.text
+
+
+## Paragraphs, Headers, Blockquotes ##
+
+A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing spaces or tabs is considered
+blank.) Normal paragraphs should not be intended with spaces or tabs.
+
+Markdown offers two styles of headers: *Setext* and *atx*.
+Setext-style headers for `<h1>` and `<h2>` are created by
+"underlining" with equal signs (`=`) and hyphens (`-`), respectively.
+To create an atx-style header, you put 1-6 hash marks (`#`) at the
+beginning of the line -- the number of hashes equals the resulting
+HTML header level.
+
+Blockquotes are indicated using email-style '`>`' angle brackets.
+
+Markdown:
+
+ A First Level Header
+ ====================
+
+ A Second Level Header
+ ---------------------
+
+ Now is the time for all good men to come to
+ the aid of their country. This is just a
+ regular paragraph.
+
+ The quick brown fox jumped over the lazy
+ dog's back.
+
+ ### Header 3
+
+ > This is a blockquote.
+ >
+ > This is the second paragraph in the blockquote.
+ >
+ > ## This is an H2 in a blockquote
+
+
+Output:
+
+ <h1>A First Level Header</h1>
+
+ <h2>A Second Level Header</h2>
+
+ <p>Now is the time for all good men to come to
+ the aid of their country. This is just a
+ regular paragraph.</p>
+
+ <p>The quick brown fox jumped over the lazy
+ dog's back.</p>
+
+ <h3>Header 3</h3>
+
+ <blockquote>
+ <p>This is a blockquote.</p>
+
+ <p>This is the second paragraph in the blockquote.</p>
+
+ <h2>This is an H2 in a blockquote</h2>
+ </blockquote>
+
+
+
+### Phrase Emphasis ###
+
+Markdown uses asterisks and underscores to indicate spans of emphasis.
+
+Markdown:
+
+ Some of these words *are emphasized*.
+ Some of these words _are emphasized also_.
+
+ Use two asterisks for **strong emphasis**.
+ Or, if you prefer, __use two underscores instead__.
+
+Output:
+
+ <p>Some of these words <em>are emphasized</em>.
+ Some of these words <em>are emphasized also</em>.</p>
+
+ <p>Use two asterisks for <strong>strong emphasis</strong>.
+ Or, if you prefer, <strong>use two underscores instead</strong>.</p>
+
+
+
+## Lists ##
+
+Unordered (bulleted) lists use asterisks, pluses, and hyphens (`*`,
+`+`, and `-`) as list markers. These three markers are
+interchangable; this:
+
+ * Candy.
+ * Gum.
+ * Booze.
+
+this:
+
+ + Candy.
+ + Gum.
+ + Booze.
+
+and this:
+
+ - Candy.
+ - Gum.
+ - Booze.
+
+all produce the same output:
+
+ <ul>
+ <li>Candy.</li>
+ <li>Gum.</li>
+ <li>Booze.</li>
+ </ul>
+
+Ordered (numbered) lists use regular numbers, followed by periods, as
+list markers:
+
+ 1. Red
+ 2. Green
+ 3. Blue
+
+Output:
+
+ <ol>
+ <li>Red</li>
+ <li>Green</li>
+ <li>Blue</li>
+ </ol>
+
+If you put blank lines between items, you'll get `<p>` tags for the
+list item text. You can create multi-paragraph list items by indenting
+the paragraphs by 4 spaces or 1 tab:
+
+ * A list item.
+
+ With multiple paragraphs.
+
+ * Another item in the list.
+
+Output:
+
+ <ul>
+ <li><p>A list item.</p>
+ <p>With multiple paragraphs.</p></li>
+ <li><p>Another item in the list.</p></li>
+ </ul>
+
+
+
+### Links ###
+
+Markdown supports two styles for creating links: *inline* and
+*reference*. With both styles, you use square brackets to delimit the
+text you want to turn into a link.
+
+Inline-style links use parentheses immediately after the link text.
+For example:
+
+ This is an [example link](http://example.com/).
+
+Output:
+
+ <p>This is an <a href="http://example.com/">
+ example link</a>.</p>
+
+Optionally, you may include a title attribute in the parentheses:
+
+ This is an [example link](http://example.com/ "With a Title").
+
+Output:
+
+ <p>This is an <a href="http://example.com/" title="With a Title">
+ example link</a>.</p>
+
+Reference-style links allow you to refer to your links by names, which
+you define elsewhere in your document:
+
+ I get 10 times more traffic from [Google][1] than from
+ [Yahoo][2] or [MSN][3].
+
+ [1]: http://google.com/ "Google"
+ [2]: http://search.yahoo.com/ "Yahoo Search"
+ [3]: http://search.msn.com/ "MSN Search"
+
+Output:
+
+ <p>I get 10 times more traffic from <a href="http://google.com/"
+ title="Google">Google</a> than from <a href="http://search.yahoo.com/"
+ title="Yahoo Search">Yahoo</a> or <a href="http://search.msn.com/"
+ title="MSN Search">MSN</a>.</p>
+
+The title attribute is optional. Link names may contain letters,
+numbers and spaces, but are *not* case sensitive:
+
+ I start my morning with a cup of coffee and
+ [The New York Times][NY Times].
+
+ [ny times]: http://www.nytimes.com/
+
+Output:
+
+ <p>I start my morning with a cup of coffee and
+ <a href="http://www.nytimes.com/">The New York Times</a>.</p>
+
+
+### Images ###
+
+Image syntax is very much like link syntax.
+
+Inline (titles are optional):
+
+ ![alt text](/path/to/img.jpg "Title")
+
+Reference-style:
+
+ ![alt text][id]
+
+ [id]: /path/to/img.jpg "Title"
+
+Both of the above examples produce the same output:
+
+ <img src="/path/to/img.jpg" alt="alt text" title="Title" />
+
+
+
+### Code ###
+
+In a regular paragraph, you can create code span by wrapping text in
+backtick quotes. Any ampersands (`&`) and angle brackets (`<` or
+`>`) will automatically be translated into HTML entities. This makes
+it easy to use Markdown to write about HTML example code:
+
+ I strongly recommend against using any `<blink>` tags.
+
+ I wish SmartyPants used named entities like `&mdash;`
+ instead of decimal-encoded entites like `&#8212;`.
+
+Output:
+
+ <p>I strongly recommend against using any
+ <code>&lt;blink&gt;</code> tags.</p>
+
+ <p>I wish SmartyPants used named entities like
+ <code>&amp;mdash;</code> instead of decimal-encoded
+ entites like <code>&amp;#8212;</code>.</p>
+
+
+To specify an entire block of pre-formatted code, indent every line of
+the block by 4 spaces or 1 tab. Just like with code spans, `&`, `<`,
+and `>` characters will be escaped automatically.
+
+Markdown:
+
+ If you want your page to validate under XHTML 1.0 Strict,
+ you've got to put paragraph tags in your blockquotes:
+
+ <blockquote>
+ <p>For example.</p>
+ </blockquote>
+
+Output:
+
+ <p>If you want your page to validate under XHTML 1.0 Strict,
+ you've got to put paragraph tags in your blockquotes:</p>
+
+ <pre><code>&lt;blockquote&gt;
+ &lt;p&gt;For example.&lt;/p&gt;
+ &lt;/blockquote&gt;
+ </code></pre>
diff --git a/test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Syntax.text b/test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Syntax.text
new file mode 100644
index 0000000000..57360a16c8
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Markdown Documentation - Syntax.text
@@ -0,0 +1,888 @@
+Markdown: Syntax
+================
+
+<ul id="ProjectSubmenu">
+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+ <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
+ <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+
+
+* [Overview](#overview)
+ * [Philosophy](#philosophy)
+ * [Inline HTML](#html)
+ * [Automatic Escaping for Special Characters](#autoescape)
+* [Block Elements](#block)
+ * [Paragraphs and Line Breaks](#p)
+ * [Headers](#header)
+ * [Blockquotes](#blockquote)
+ * [Lists](#list)
+ * [Code Blocks](#precode)
+ * [Horizontal Rules](#hr)
+* [Span Elements](#span)
+ * [Links](#link)
+ * [Emphasis](#em)
+ * [Code](#code)
+ * [Images](#img)
+* [Miscellaneous](#misc)
+ * [Backslash Escapes](#backslash)
+ * [Automatic Links](#autolink)
+
+
+**Note:** This document is itself written using Markdown; you
+can [see the source for it by adding '.text' to the URL][src].
+
+ [src]: /projects/markdown/syntax.text
+
+* * *
+
+<h2 id="overview">Overview</h2>
+
+<h3 id="philosophy">Philosophy</h3>
+
+Markdown is intended to be as easy-to-read and easy-to-write as is feasible.
+
+Readability, however, is emphasized above all else. A Markdown-formatted
+document should be publishable as-is, as plain text, without looking
+like it's been marked up with tags or formatting instructions. While
+Markdown's syntax has been influenced by several existing text-to-HTML
+filters -- including [Setext] [1], [atx] [2], [Textile] [3], [reStructuredText] [4],
+[Grutatext] [5], and [EtText] [6] -- the single biggest source of
+inspiration for Markdown's syntax is the format of plain text email.
+
+ [1]: http://docutils.sourceforge.net/mirror/setext.html
+ [2]: http://www.aaronsw.com/2002/atx/
+ [3]: http://textism.com/tools/textile/
+ [4]: http://docutils.sourceforge.net/rst.html
+ [5]: http://www.triptico.com/software/grutatxt.html
+ [6]: http://ettext.taint.org/doc/
+
+To this end, Markdown's syntax is comprised entirely of punctuation
+characters, which punctuation characters have been carefully chosen so
+as to look like what they mean. E.g., asterisks around a word actually
+look like \*emphasis\*. Markdown lists look like, well, lists. Even
+blockquotes look like quoted passages of text, assuming you've ever
+used email.
+
+
+
+<h3 id="html">Inline HTML</h3>
+
+Markdown's syntax is intended for one purpose: to be used as a
+format for *writing* for the web.
+
+Markdown is not a replacement for HTML, or even close to it. Its
+syntax is very small, corresponding only to a very small subset of
+HTML tags. The idea is *not* to create a syntax that makes it easier
+to insert HTML tags. In my opinion, HTML tags are already easy to
+insert. The idea for Markdown is to make it easy to read, write, and
+edit prose. HTML is a *publishing* format; Markdown is a *writing*
+format. Thus, Markdown's formatting syntax only addresses issues that
+can be conveyed in plain text.
+
+For any markup that is not covered by Markdown's syntax, you simply
+use HTML itself. There's no need to preface it or delimit it to
+indicate that you're switching from Markdown to HTML; you just use
+the tags.
+
+The only restrictions are that block-level HTML elements -- e.g. `<div>`,
+`<table>`, `<pre>`, `<p>`, etc. -- must be separated from surrounding
+content by blank lines, and the start and end tags of the block should
+not be indented with tabs or spaces. Markdown is smart enough not
+to add extra (unwanted) `<p>` tags around HTML block-level tags.
+
+For example, to add an HTML table to a Markdown article:
+
+ This is a regular paragraph.
+
+ <table>
+ <tr>
+ <td>Foo</td>
+ </tr>
+ </table>
+
+ This is another regular paragraph.
+
+Note that Markdown formatting syntax is not processed within block-level
+HTML tags. E.g., you can't use Markdown-style `*emphasis*` inside an
+HTML block.
+
+Span-level HTML tags -- e.g. `<span>`, `<cite>`, or `<del>` -- can be
+used anywhere in a Markdown paragraph, list item, or header. If you
+want, you can even use HTML tags instead of Markdown formatting; e.g. if
+you'd prefer to use HTML `<a>` or `<img>` tags instead of Markdown's
+link or image syntax, go right ahead.
+
+Unlike block-level HTML tags, Markdown syntax *is* processed within
+span-level tags.
+
+
+<h3 id="autoescape">Automatic Escaping for Special Characters</h3>
+
+In HTML, there are two characters that demand special treatment: `<`
+and `&`. Left angle brackets are used to start tags; ampersands are
+used to denote HTML entities. If you want to use them as literal
+characters, you must escape them as entities, e.g. `&lt;`, and
+`&amp;`.
+
+Ampersands in particular are bedeviling for web writers. If you want to
+write about 'AT&T', you need to write '`AT&amp;T`'. You even need to
+escape ampersands within URLs. Thus, if you want to link to:
+
+ http://images.google.com/images?num=30&q=larry+bird
+
+you need to encode the URL as:
+
+ http://images.google.com/images?num=30&amp;q=larry+bird
+
+in your anchor tag `href` attribute. Needless to say, this is easy to
+forget, and is probably the single most common source of HTML validation
+errors in otherwise well-marked-up web sites.
+
+Markdown allows you to use these characters naturally, taking care of
+all the necessary escaping for you. If you use an ampersand as part of
+an HTML entity, it remains unchanged; otherwise it will be translated
+into `&amp;`.
+
+So, if you want to include a copyright symbol in your article, you can write:
+
+ &copy;
+
+and Markdown will leave it alone. But if you write:
+
+ AT&T
+
+Markdown will translate it to:
+
+ AT&amp;T
+
+Similarly, because Markdown supports [inline HTML](#html), if you use
+angle brackets as delimiters for HTML tags, Markdown will treat them as
+such. But if you write:
+
+ 4 < 5
+
+Markdown will translate it to:
+
+ 4 &lt; 5
+
+However, inside Markdown code spans and blocks, angle brackets and
+ampersands are *always* encoded automatically. This makes it easy to use
+Markdown to write about HTML code. (As opposed to raw HTML, which is a
+terrible format for writing about HTML syntax, because every single `<`
+and `&` in your example code needs to be escaped.)
+
+
+* * *
+
+
+<h2 id="block">Block Elements</h2>
+
+
+<h3 id="p">Paragraphs and Line Breaks</h3>
+
+A paragraph is simply one or more consecutive lines of text, separated
+by one or more blank lines. (A blank line is any line that looks like a
+blank line -- a line containing nothing but spaces or tabs is considered
+blank.) Normal paragraphs should not be intended with spaces or tabs.
+
+The implication of the "one or more consecutive lines of text" rule is
+that Markdown supports "hard-wrapped" text paragraphs. This differs
+significantly from most other text-to-HTML formatters (including Movable
+Type's "Convert Line Breaks" option) which translate every line break
+character in a paragraph into a `<br />` tag.
+
+When you *do* want to insert a `<br />` break tag using Markdown, you
+end a line with two or more spaces, then type return.
+
+Yes, this takes a tad more effort to create a `<br />`, but a simplistic
+"every line break is a `<br />`" rule wouldn't work for Markdown.
+Markdown's email-style [blockquoting][bq] and multi-paragraph [list items][l]
+work best -- and look better -- when you format them with hard breaks.
+
+ [bq]: #blockquote
+ [l]: #list
+
+
+
+<h3 id="header">Headers</h3>
+
+Markdown supports two styles of headers, [Setext] [1] and [atx] [2].
+
+Setext-style headers are "underlined" using equal signs (for first-level
+headers) and dashes (for second-level headers). For example:
+
+ This is an H1
+ =============
+
+ This is an H2
+ -------------
+
+Any number of underlining `=`'s or `-`'s will work.
+
+Atx-style headers use 1-6 hash characters at the start of the line,
+corresponding to header levels 1-6. For example:
+
+ # This is an H1
+
+ ## This is an H2
+
+ ###### This is an H6
+
+Optionally, you may "close" atx-style headers. This is purely
+cosmetic -- you can use this if you think it looks better. The
+closing hashes don't even need to match the number of hashes
+used to open the header. (The number of opening hashes
+determines the header level.) :
+
+ # This is an H1 #
+
+ ## This is an H2 ##
+
+ ### This is an H3 ######
+
+
+<h3 id="blockquote">Blockquotes</h3>
+
+Markdown uses email-style `>` characters for blockquoting. If you're
+familiar with quoting passages of text in an email message, then you
+know how to create a blockquote in Markdown. It looks best if you hard
+wrap the text and put a `>` before every line:
+
+ > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+ > consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+ > Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+ >
+ > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+ > id sem consectetuer libero luctus adipiscing.
+
+Markdown allows you to be lazy and only put the `>` before the first
+line of a hard-wrapped paragraph:
+
+ > This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,
+ consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.
+ Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.
+
+ > Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse
+ id sem consectetuer libero luctus adipiscing.
+
+Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by
+adding additional levels of `>`:
+
+ > This is the first level of quoting.
+ >
+ > > This is nested blockquote.
+ >
+ > Back to the first level.
+
+Blockquotes can contain other Markdown elements, including headers, lists,
+and code blocks:
+
+ > ## This is a header.
+ >
+ > 1. This is the first list item.
+ > 2. This is the second list item.
+ >
+ > Here's some example code:
+ >
+ > return shell_exec("echo $input | $markdown_script");
+
+Any decent text editor should make email-style quoting easy. For
+example, with BBEdit, you can make a selection and choose Increase
+Quote Level from the Text menu.
+
+
+<h3 id="list">Lists</h3>
+
+Markdown supports ordered (numbered) and unordered (bulleted) lists.
+
+Unordered lists use asterisks, pluses, and hyphens -- interchangably
+-- as list markers:
+
+ * Red
+ * Green
+ * Blue
+
+is equivalent to:
+
+ + Red
+ + Green
+ + Blue
+
+and:
+
+ - Red
+ - Green
+ - Blue
+
+Ordered lists use numbers followed by periods:
+
+ 1. Bird
+ 2. McHale
+ 3. Parish
+
+It's important to note that the actual numbers you use to mark the
+list have no effect on the HTML output Markdown produces. The HTML
+Markdown produces from the above list is:
+
+ <ol>
+ <li>Bird</li>
+ <li>McHale</li>
+ <li>Parish</li>
+ </ol>
+
+If you instead wrote the list in Markdown like this:
+
+ 1. Bird
+ 1. McHale
+ 1. Parish
+
+or even:
+
+ 3. Bird
+ 1. McHale
+ 8. Parish
+
+you'd get the exact same HTML output. The point is, if you want to,
+you can use ordinal numbers in your ordered Markdown lists, so that
+the numbers in your source match the numbers in your published HTML.
+But if you want to be lazy, you don't have to.
+
+If you do use lazy list numbering, however, you should still start the
+list with the number 1. At some point in the future, Markdown may support
+starting ordered lists at an arbitrary number.
+
+List markers typically start at the left margin, but may be indented by
+up to three spaces. List markers must be followed by one or more spaces
+or a tab.
+
+To make lists look nice, you can wrap items with hanging indents:
+
+ * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+ Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+ viverra nec, fringilla in, laoreet vitae, risus.
+ * Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+ Suspendisse id sem consectetuer libero luctus adipiscing.
+
+But if you want to be lazy, you don't have to:
+
+ * Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
+ Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,
+ viverra nec, fringilla in, laoreet vitae, risus.
+ * Donec sit amet nisl. Aliquam semper ipsum sit amet velit.
+ Suspendisse id sem consectetuer libero luctus adipiscing.
+
+If list items are separated by blank lines, Markdown will wrap the
+items in `<p>` tags in the HTML output. For example, this input:
+
+ * Bird
+ * Magic
+
+will turn into:
+
+ <ul>
+ <li>Bird</li>
+ <li>Magic</li>
+ </ul>
+
+But this:
+
+ * Bird
+
+ * Magic
+
+will turn into:
+
+ <ul>
+ <li><p>Bird</p></li>
+ <li><p>Magic</p></li>
+ </ul>
+
+List items may consist of multiple paragraphs. Each subsequent
+paragraph in a list item must be intended by either 4 spaces
+or one tab:
+
+ 1. This is a list item with two paragraphs. Lorem ipsum dolor
+ sit amet, consectetuer adipiscing elit. Aliquam hendrerit
+ mi posuere lectus.
+
+ Vestibulum enim wisi, viverra nec, fringilla in, laoreet
+ vitae, risus. Donec sit amet nisl. Aliquam semper ipsum
+ sit amet velit.
+
+ 2. Suspendisse id sem consectetuer libero luctus adipiscing.
+
+It looks nice if you indent every line of the subsequent
+paragraphs, but here again, Markdown will allow you to be
+lazy:
+
+ * This is a list item with two paragraphs.
+
+ This is the second paragraph in the list item. You're
+ only required to indent the first line. Lorem ipsum dolor
+ sit amet, consectetuer adipiscing elit.
+
+ * Another item in the same list.
+
+To put a blockquote within a list item, the blockquote's `>`
+delimiters need to be indented:
+
+ * A list item with a blockquote:
+
+ > This is a blockquote
+ > inside a list item.
+
+To put a code block within a list item, the code block needs
+to be indented *twice* -- 8 spaces or two tabs:
+
+ * A list item with a code block:
+
+ <code goes here>
+
+
+It's worth noting that it's possible to trigger an ordered list by
+accident, by writing something like this:
+
+ 1986. What a great season.
+
+In other words, a *number-period-space* sequence at the beginning of a
+line. To avoid this, you can backslash-escape the period:
+
+ 1986\. What a great season.
+
+
+
+<h3 id="precode">Code Blocks</h3>
+
+Pre-formatted code blocks are used for writing about programming or
+markup source code. Rather than forming normal paragraphs, the lines
+of a code block are interpreted literally. Markdown wraps a code block
+in both `<pre>` and `<code>` tags.
+
+To produce a code block in Markdown, simply indent every line of the
+block by at least 4 spaces or 1 tab. For example, given this input:
+
+ This is a normal paragraph:
+
+ This is a code block.
+
+Markdown will generate:
+
+ <p>This is a normal paragraph:</p>
+
+ <pre><code>This is a code block.
+ </code></pre>
+
+One level of indentation -- 4 spaces or 1 tab -- is removed from each
+line of the code block. For example, this:
+
+ Here is an example of AppleScript:
+
+ tell application "Foo"
+ beep
+ end tell
+
+will turn into:
+
+ <p>Here is an example of AppleScript:</p>
+
+ <pre><code>tell application "Foo"
+ beep
+ end tell
+ </code></pre>
+
+A code block continues until it reaches a line that is not indented
+(or the end of the article).
+
+Within a code block, ampersands (`&`) and angle brackets (`<` and `>`)
+are automatically converted into HTML entities. This makes it very
+easy to include example HTML source code using Markdown -- just paste
+it and indent it, and Markdown will handle the hassle of encoding the
+ampersands and angle brackets. For example, this:
+
+ <div class="footer">
+ &copy; 2004 Foo Corporation
+ </div>
+
+will turn into:
+
+ <pre><code>&lt;div class="footer"&gt;
+ &amp;copy; 2004 Foo Corporation
+ &lt;/div&gt;
+ </code></pre>
+
+Regular Markdown syntax is not processed within code blocks. E.g.,
+asterisks are just literal asterisks within a code block. This means
+it's also easy to use Markdown to write about Markdown's own syntax.
+
+
+
+<h3 id="hr">Horizontal Rules</h3>
+
+You can produce a horizontal rule tag (`<hr />`) by placing three or
+more hyphens, asterisks, or underscores on a line by themselves. If you
+wish, you may use spaces between the hyphens or asterisks. Each of the
+following lines will produce a horizontal rule:
+
+ * * *
+
+ ***
+
+ *****
+
+ - - -
+
+ ---------------------------------------
+
+ _ _ _
+
+
+* * *
+
+<h2 id="span">Span Elements</h2>
+
+<h3 id="link">Links</h3>
+
+Markdown supports two style of links: *inline* and *reference*.
+
+In both styles, the link text is delimited by [square brackets].
+
+To create an inline link, use a set of regular parentheses immediately
+after the link text's closing square bracket. Inside the parentheses,
+put the URL where you want the link to point, along with an *optional*
+title for the link, surrounded in quotes. For example:
+
+ This is [an example](http://example.com/ "Title") inline link.
+
+ [This link](http://example.net/) has no title attribute.
+
+Will produce:
+
+ <p>This is <a href="http://example.com/" title="Title">
+ an example</a> inline link.</p>
+
+ <p><a href="http://example.net/">This link</a> has no
+ title attribute.</p>
+
+If you're referring to a local resource on the same server, you can
+use relative paths:
+
+ See my [About](/about/) page for details.
+
+Reference-style links use a second set of square brackets, inside
+which you place a label of your choosing to identify the link:
+
+ This is [an example][id] reference-style link.
+
+You can optionally use a space to separate the sets of brackets:
+
+ This is [an example] [id] reference-style link.
+
+Then, anywhere in the document, you define your link label like this,
+on a line by itself:
+
+ [id]: http://example.com/ "Optional Title Here"
+
+That is:
+
+* Square brackets containing the link identifier (optionally
+ indented from the left margin using up to three spaces);
+* followed by a colon;
+* followed by one or more spaces (or tabs);
+* followed by the URL for the link;
+* optionally followed by a title attribute for the link, enclosed
+ in double or single quotes.
+
+The link URL may, optionally, be surrounded by angle brackets:
+
+ [id]: <http://example.com/> "Optional Title Here"
+
+You can put the title attribute on the next line and use extra spaces
+or tabs for padding, which tends to look better with longer URLs:
+
+ [id]: http://example.com/longish/path/to/resource/here
+ "Optional Title Here"
+
+Link definitions are only used for creating links during Markdown
+processing, and are stripped from your document in the HTML output.
+
+Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are *not* case sensitive. E.g. these two links:
+
+ [link text][a]
+ [link text][A]
+
+are equivalent.
+
+The *implicit link name* shortcut allows you to omit the name of the
+link, in which case the link text itself is used as the name.
+Just use an empty set of square brackets -- e.g., to link the word
+"Google" to the google.com web site, you could simply write:
+
+ [Google][]
+
+And then define the link:
+
+ [Google]: http://google.com/
+
+Because link names may contain spaces, this shortcut even works for
+multiple words in the link text:
+
+ Visit [Daring Fireball][] for more information.
+
+And then define the link:
+
+ [Daring Fireball]: http://daringfireball.net/
+
+Link definitions can be placed anywhere in your Markdown document. I
+tend to put them immediately after each paragraph in which they're
+used, but if you want, you can put them all at the end of your
+document, sort of like footnotes.
+
+Here's an example of reference links in action:
+
+ I get 10 times more traffic from [Google] [1] than from
+ [Yahoo] [2] or [MSN] [3].
+
+ [1]: http://google.com/ "Google"
+ [2]: http://search.yahoo.com/ "Yahoo Search"
+ [3]: http://search.msn.com/ "MSN Search"
+
+Using the implicit link name shortcut, you could instead write:
+
+ I get 10 times more traffic from [Google][] than from
+ [Yahoo][] or [MSN][].
+
+ [google]: http://google.com/ "Google"
+ [yahoo]: http://search.yahoo.com/ "Yahoo Search"
+ [msn]: http://search.msn.com/ "MSN Search"
+
+Both of the above examples will produce the following HTML output:
+
+ <p>I get 10 times more traffic from <a href="http://google.com/"
+ title="Google">Google</a> than from
+ <a href="http://search.yahoo.com/" title="Yahoo Search">Yahoo</a>
+ or <a href="http://search.msn.com/" title="MSN Search">MSN</a>.</p>
+
+For comparison, here is the same paragraph written using
+Markdown's inline link style:
+
+ I get 10 times more traffic from [Google](http://google.com/ "Google")
+ than from [Yahoo](http://search.yahoo.com/ "Yahoo Search") or
+ [MSN](http://search.msn.com/ "MSN Search").
+
+The point of reference-style links is not that they're easier to
+write. The point is that with reference-style links, your document
+source is vastly more readable. Compare the above examples: using
+reference-style links, the paragraph itself is only 81 characters
+long; with inline-style links, it's 176 characters; and as raw HTML,
+it's 234 characters. In the raw HTML, there's more markup than there
+is text.
+
+With Markdown's reference-style links, a source document much more
+closely resembles the final output, as rendered in a browser. By
+allowing you to move the markup-related metadata out of the paragraph,
+you can add links without interrupting the narrative flow of your
+prose.
+
+
+<h3 id="em">Emphasis</h3>
+
+Markdown treats asterisks (`*`) and underscores (`_`) as indicators of
+emphasis. Text wrapped with one `*` or `_` will be wrapped with an
+HTML `<em>` tag; double `*`'s or `_`'s will be wrapped with an HTML
+`<strong>` tag. E.g., this input:
+
+ *single asterisks*
+
+ _single underscores_
+
+ **double asterisks**
+
+ __double underscores__
+
+will produce:
+
+ <em>single asterisks</em>
+
+ <em>single underscores</em>
+
+ <strong>double asterisks</strong>
+
+ <strong>double underscores</strong>
+
+You can use whichever style you prefer; the lone restriction is that
+the same character must be used to open and close an emphasis span.
+
+Emphasis can be used in the middle of a word:
+
+ un*fucking*believable
+
+But if you surround an `*` or `_` with spaces, it'll be treated as a
+literal asterisk or underscore.
+
+To produce a literal asterisk or underscore at a position where it
+would otherwise be used as an emphasis delimiter, you can backslash
+escape it:
+
+ \*this text is surrounded by literal asterisks\*
+
+
+
+<h3 id="code">Code</h3>
+
+To indicate a span of code, wrap it with backtick quotes (`` ` ``).
+Unlike a pre-formatted code block, a code span indicates code within a
+normal paragraph. For example:
+
+ Use the `printf()` function.
+
+will produce:
+
+ <p>Use the <code>printf()</code> function.</p>
+
+To include a literal backtick character within a code span, you can use
+multiple backticks as the opening and closing delimiters:
+
+ ``There is a literal backtick (`) here.``
+
+which will produce this:
+
+ <p><code>There is a literal backtick (`) here.</code></p>
+
+The backtick delimiters surrounding a code span may include spaces --
+one after the opening, one before the closing. This allows you to place
+literal backtick characters at the beginning or end of a code span:
+
+ A single backtick in a code span: `` ` ``
+
+ A backtick-delimited string in a code span: `` `foo` ``
+
+will produce:
+
+ <p>A single backtick in a code span: <code>`</code></p>
+
+ <p>A backtick-delimited string in a code span: <code>`foo`</code></p>
+
+With a code span, ampersands and angle brackets are encoded as HTML
+entities automatically, which makes it easy to include example HTML
+tags. Markdown will turn this:
+
+ Please don't use any `<blink>` tags.
+
+into:
+
+ <p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>
+
+You can write this:
+
+ `&#8212;` is the decimal-encoded equivalent of `&mdash;`.
+
+to produce:
+
+ <p><code>&amp;#8212;</code> is the decimal-encoded
+ equivalent of <code>&amp;mdash;</code>.</p>
+
+
+
+<h3 id="img">Images</h3>
+
+Admittedly, it's fairly difficult to devise a "natural" syntax for
+placing images into a plain text document format.
+
+Markdown uses an image syntax that is intended to resemble the syntax
+for links, allowing for two styles: *inline* and *reference*.
+
+Inline image syntax looks like this:
+
+ ![Alt text](/path/to/img.jpg)
+
+ ![Alt text](/path/to/img.jpg "Optional title")
+
+That is:
+
+* An exclamation mark: `!`;
+* followed by a set of square brackets, containing the `alt`
+ attribute text for the image;
+* followed by a set of parentheses, containing the URL or path to
+ the image, and an optional `title` attribute enclosed in double
+ or single quotes.
+
+Reference-style image syntax looks like this:
+
+ ![Alt text][id]
+
+Where "id" is the name of a defined image reference. Image references
+are defined using syntax identical to link references:
+
+ [id]: url/to/image "Optional title attribute"
+
+As of this writing, Markdown has no syntax for specifying the
+dimensions of an image; if this is important to you, you can simply
+use regular HTML `<img>` tags.
+
+
+* * *
+
+
+<h2 id="misc">Miscellaneous</h2>
+
+<h3 id="autolink">Automatic Links</h3>
+
+Markdown supports a shortcut style for creating "automatic" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:
+
+ <http://example.com/>
+
+Markdown will turn this into:
+
+ <a href="http://example.com/">http://example.com/</a>
+
+Automatic links for email addresses work similarly, except that
+Markdown will also perform a bit of randomized decimal and hex
+entity-encoding to help obscure your address from address-harvesting
+spambots. For example, Markdown will turn this:
+
+ <address@example.com>
+
+into something like this:
+
+ <a href="&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;
+ &#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;
+ &#109;">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;
+ &#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>
+
+which will render in a browser as a clickable link to "address@example.com".
+
+(This sort of entity-encoding trick will indeed fool many, if not
+most, address-harvesting bots, but it definitely won't fool all of
+them. It's better than nothing, but an address published in this way
+will probably eventually start receiving spam.)
+
+
+
+<h3 id="backslash">Backslash Escapes</h3>
+
+Markdown allows you to use backslash escapes to generate literal
+characters which would otherwise have special meaning in Markdown's
+formatting syntax. For example, if you wanted to surround a word with
+literal asterisks (instead of an HTML `<em>` tag), you can backslashes
+before the asterisks, like this:
+
+ \*literal asterisks\*
+
+Markdown provides backslash escapes for the following characters:
+
+ \ backslash
+ ` backtick
+ * asterisk
+ _ underscore
+ {} curly braces
+ [] square brackets
+ () parentheses
+ # hash mark
+ + plus sign
+ - minus sign (hyphen)
+ . dot
+ ! exclamation mark
+
diff --git a/test/rdoc/MarkdownTest_1.0.3/Nested blockquotes.text b/test/rdoc/MarkdownTest_1.0.3/Nested blockquotes.text
new file mode 100644
index 0000000000..ed3c624ffb
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Nested blockquotes.text
@@ -0,0 +1,5 @@
+> foo
+>
+> > bar
+>
+> foo
diff --git a/test/rdoc/MarkdownTest_1.0.3/Ordered and unordered lists.text b/test/rdoc/MarkdownTest_1.0.3/Ordered and unordered lists.text
new file mode 100644
index 0000000000..7f3b49777f
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Ordered and unordered lists.text
@@ -0,0 +1,131 @@
+## Unordered
+
+Asterisks tight:
+
+* asterisk 1
+* asterisk 2
+* asterisk 3
+
+
+Asterisks loose:
+
+* asterisk 1
+
+* asterisk 2
+
+* asterisk 3
+
+* * *
+
+Pluses tight:
+
++ Plus 1
++ Plus 2
++ Plus 3
+
+
+Pluses loose:
+
++ Plus 1
+
++ Plus 2
+
++ Plus 3
+
+* * *
+
+
+Minuses tight:
+
+- Minus 1
+- Minus 2
+- Minus 3
+
+
+Minuses loose:
+
+- Minus 1
+
+- Minus 2
+
+- Minus 3
+
+
+## Ordered
+
+Tight:
+
+1. First
+2. Second
+3. Third
+
+and:
+
+1. One
+2. Two
+3. Three
+
+
+Loose using tabs:
+
+1. First
+
+2. Second
+
+3. Third
+
+and using spaces:
+
+1. One
+
+2. Two
+
+3. Three
+
+Multiple paragraphs:
+
+1. Item 1, graf one.
+
+ Item 2. graf two. The quick brown fox jumped over the lazy dog's
+ back.
+
+2. Item 2.
+
+3. Item 3.
+
+
+
+## Nested
+
+* Tab
+ * Tab
+ * Tab
+
+Here's another:
+
+1. First
+2. Second:
+ * Fee
+ * Fie
+ * Foe
+3. Third
+
+Same thing but with paragraphs:
+
+1. First
+
+2. Second:
+ * Fee
+ * Fie
+ * Foe
+
+3. Third
+
+
+This was an error in Markdown 1.0.1:
+
+* this
+
+ * sub
+
+ that
diff --git a/test/rdoc/MarkdownTest_1.0.3/Strong and em together.text b/test/rdoc/MarkdownTest_1.0.3/Strong and em together.text
new file mode 100644
index 0000000000..95ee690dbe
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Strong and em together.text
@@ -0,0 +1,7 @@
+***This is strong and em.***
+
+So is ***this*** word.
+
+___This is strong and em.___
+
+So is ___this___ word.
diff --git a/test/rdoc/MarkdownTest_1.0.3/Tabs.text b/test/rdoc/MarkdownTest_1.0.3/Tabs.text
new file mode 100644
index 0000000000..589d1136e1
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Tabs.text
@@ -0,0 +1,21 @@
++ this is a list item
+ indented with tabs
+
++ this is a list item
+ indented with spaces
+
+Code:
+
+ this code block is indented by one tab
+
+And:
+
+ this code block is indented by two tabs
+
+And:
+
+ + this is an example list item
+ indented with tabs
+
+ + this is an example list item
+ indented with spaces
diff --git a/test/rdoc/MarkdownTest_1.0.3/Tidyness.text b/test/rdoc/MarkdownTest_1.0.3/Tidyness.text
new file mode 100644
index 0000000000..5f18b8da21
--- /dev/null
+++ b/test/rdoc/MarkdownTest_1.0.3/Tidyness.text
@@ -0,0 +1,5 @@
+> A list within a blockquote:
+>
+> * asterisk 1
+> * asterisk 2
+> * asterisk 3
diff --git a/test/rdoc/test.ja.largedoc b/test/rdoc/test.ja.large.rdoc
index a9c6c4691c..a9c6c4691c 100644
--- a/test/rdoc/test.ja.largedoc
+++ b/test/rdoc/test.ja.large.rdoc
diff --git a/test/rdoc/test_attribute_manager.rb b/test/rdoc/test_attribute_manager.rb
index 25e8ca5e04..8832a5d515 100644
--- a/test/rdoc/test_attribute_manager.rb
+++ b/test/rdoc/test_attribute_manager.rb
@@ -1,27 +1,26 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc'
-require 'rdoc/markup'
-require 'rdoc/markup/formatter'
-require 'rdoc/markup/attribute_manager'
+require 'rdoc/test_case'
-class TestAttributeManager < MiniTest::Unit::TestCase # HACK fix test name
+class TestAttributeManager < RDoc::TestCase # HACK fix test name
def setup
+ super
+
+ @options = RDoc::Options.new
+
@am = RDoc::Markup::AttributeManager.new
@klass = RDoc::Markup::AttributeManager
- @formatter = RDoc::Markup::Formatter.new
+ @formatter = RDoc::Markup::Formatter.new @options
@formatter.add_tag :BOLD, '<B>', '</B>'
@formatter.add_tag :EM, '<EM>', '</EM>'
- @formatter.add_tag :TT, '<TT>', '</TT>'
+ @formatter.add_tag :TT, '<CODE>', '</CODE>'
end
def test_convert_attrs_ignores_code
- assert_equal 'foo <TT>__send__</TT> bar', output('foo <code>__send__</code> bar')
+ assert_equal 'foo <CODE>__send__</CODE> bar', output('foo <code>__send__</code> bar')
end
def test_convert_attrs_ignores_tt
- assert_equal 'foo <TT>__send__</TT> bar', output('foo <tt>__send__</tt> bar')
+ assert_equal 'foo <CODE>__send__</CODE> bar', output('foo <tt>__send__</tt> bar')
end
def test_convert_attrs_preserves_double
@@ -30,7 +29,7 @@ class TestAttributeManager < MiniTest::Unit::TestCase # HACK fix test name
end
def test_convert_attrs_does_not_ignore_after_tt
- assert_equal 'the <TT>IF:</TT><EM>key</EM> directive', output('the <tt>IF:</tt>_key_ directive')
+ assert_equal 'the <CODE>IF:</CODE><EM>key</EM> directive', output('the <tt>IF:</tt>_key_ directive')
end
def test_initial_word_pairs
@@ -73,38 +72,39 @@ class TestAttributeManager < MiniTest::Unit::TestCase # HACK fix test name
end
def test_add_special
- @am.add_special("WikiWord", :WIKIWORD)
+ @am.add_special "WikiWord", :WIKIWORD
specials = @am.special
- assert_equal(1,specials.size)
- assert(specials.has_key?("WikiWord"))
+
+ assert_equal 1, specials.size
+ assert specials.assoc "WikiWord"
end
def test_escapes
- assert_equal '<TT>text</TT>', output('<tt>text</tt>')
- assert_equal '<tt>text</tt>', output('\\<tt>text</tt>')
- assert_equal '<tt>', output('\\<tt>')
- assert_equal '<TT><tt></TT>', output('<tt>\\<tt></tt>')
- assert_equal '<TT>\\<tt></TT>', output('<tt>\\\\<tt></tt>')
- assert_equal '<B>text</B>', output('*text*')
- assert_equal '*text*', output('\\*text*')
- assert_equal '\\', output('\\')
- assert_equal '\\text', output('\\text')
- assert_equal '\\\\text', output('\\\\text')
- assert_equal 'text \\ text', output('text \\ text')
-
- assert_equal 'and <TT>\\s</TT> matches space',
+ assert_equal '<CODE>text</CODE>', output('<tt>text</tt>')
+ assert_equal '<tt>text</tt>', output('\\<tt>text</tt>')
+ assert_equal '<tt>', output('\\<tt>')
+ assert_equal '<CODE><tt></CODE>', output('<tt>\\<tt></tt>')
+ assert_equal '<CODE>\\<tt></CODE>', output('<tt>\\\\<tt></tt>')
+ assert_equal '<B>text</B>', output('*text*')
+ assert_equal '*text*', output('\\*text*')
+ assert_equal '\\', output('\\')
+ assert_equal '\\text', output('\\text')
+ assert_equal '\\\\text', output('\\\\text')
+ assert_equal 'text \\ text', output('text \\ text')
+
+ assert_equal 'and <CODE>\\s</CODE> matches space',
output('and <tt>\\s</tt> matches space')
- assert_equal 'use <TT><tt>text</TT></tt> for code',
+ assert_equal 'use <CODE><tt>text</CODE></tt> for code',
output('use <tt>\\<tt>text</tt></tt> for code')
- assert_equal 'use <TT><tt>text</tt></TT> for code',
+ assert_equal 'use <CODE><tt>text</tt></CODE> for code',
output('use <tt>\\<tt>text\\</tt></tt> for code')
assert_equal 'use <tt><tt>text</tt></tt> for code',
output('use \\<tt>\\<tt>text</tt></tt> for code')
- assert_equal 'use <tt><TT>text</TT></tt> for code',
+ assert_equal 'use <tt><CODE>text</CODE></tt> for code',
output('use \\<tt><tt>text</tt></tt> for code')
- assert_equal 'use <TT>+text+</TT> for code',
+ assert_equal 'use <CODE>+text+</CODE> for code',
output('use <tt>\\+text+</tt> for code')
- assert_equal 'use <tt><TT>text</TT></tt> for code',
+ assert_equal 'use <tt><CODE>text</CODE></tt> for code',
output('use \\<tt>+text+</tt> for code')
assert_equal 'illegal <tag>not</tag> changed',
output('illegal <tag>not</tag> changed')
diff --git a/test/rdoc/test_rdoc_any_method.rb b/test/rdoc/test_rdoc_any_method.rb
index c0feccef95..abf749c4c9 100644
--- a/test/rdoc/test_rdoc_any_method.rb
+++ b/test/rdoc/test_rdoc_any_method.rb
@@ -1,8 +1,6 @@
require File.expand_path '../xref_test_case', __FILE__
-require 'rdoc/code_objects'
-require 'rdoc/generator/markup'
-class RDocAnyMethodTest < XrefTestCase
+class TestRDocAnyMethod < XrefTestCase
def test_aref
m = RDoc::AnyMethod.new nil, 'method?'
@@ -47,34 +45,12 @@ method(a, b) { |c, d| ... }
def test_markup_code
tokens = [
RDoc::RubyToken::TkCONSTANT. new(0, 0, 0, 'CONSTANT'),
- RDoc::RubyToken::TkDEF. new(0, 0, 0, 'KW'),
- RDoc::RubyToken::TkIVAR. new(0, 0, 0, 'IVAR'),
- RDoc::RubyToken::TkOp. new(0, 0, 0, 'Op'),
- RDoc::RubyToken::TkId. new(0, 0, 0, 'Id'),
- RDoc::RubyToken::TkNode. new(0, 0, 0, 'Node'),
- RDoc::RubyToken::TkCOMMENT. new(0, 0, 0, 'COMMENT'),
- RDoc::RubyToken::TkREGEXP. new(0, 0, 0, 'REGEXP'),
- RDoc::RubyToken::TkSTRING. new(0, 0, 0, 'STRING'),
- RDoc::RubyToken::TkVal. new(0, 0, 0, 'Val'),
- RDoc::RubyToken::TkBACKSLASH.new(0, 0, 0, '\\'),
]
@c2_a.collect_tokens
@c2_a.add_tokens(*tokens)
- expected = [
- '<span class="ruby-constant">CONSTANT</span>',
- '<span class="ruby-keyword">KW</span>',
- '<span class="ruby-ivar">IVAR</span>',
- '<span class="ruby-operator">Op</span>',
- '<span class="ruby-identifier">Id</span>',
- '<span class="ruby-node">Node</span>',
- '<span class="ruby-comment">COMMENT</span>',
- '<span class="ruby-regexp">REGEXP</span>',
- '<span class="ruby-string">STRING</span>',
- '<span class="ruby-value">Val</span>',
- '\\'
- ].join
+ expected = '<span class="ruby-constant">CONSTANT</span>'
assert_equal expected, @c2_a.markup_code
end
@@ -84,7 +60,9 @@ method(a, b) { |c, d| ... }
end
def test_marshal_dump
- top_level = RDoc::TopLevel.new 'file.rb'
+ @store.path = Dir.tmpdir
+ top_level = @store.add_file 'file.rb'
+
m = RDoc::AnyMethod.new nil, 'method'
m.block_params = 'some_block'
m.call_seq = 'call_seq'
@@ -92,20 +70,23 @@ method(a, b) { |c, d| ... }
m.params = 'param'
m.record_location top_level
- cm = RDoc::ClassModule.new 'Klass'
+ cm = top_level.add_class RDoc::ClassModule, 'Klass'
cm.add_method m
+ section = cm.sections.first
+
al = RDoc::Alias.new nil, 'method', 'aliased', 'alias comment'
al_m = m.add_alias al, cm
loaded = Marshal.load Marshal.dump m
+ loaded.store = @store
comment = RDoc::Markup::Document.new(
RDoc::Markup::Paragraph.new('this is a comment'))
assert_equal m, loaded
- assert_equal [al_m], loaded.aliases
+ assert_equal [al_m.name], loaded.aliases.map { |alas| alas.name }
assert_equal 'some_block', loaded.block_params
assert_equal 'call_seq', loaded.call_seq
assert_equal comment, loaded.comment
@@ -115,6 +96,8 @@ method(a, b) { |c, d| ... }
assert_equal 'param', loaded.params
assert_equal nil, loaded.singleton # defaults to nil
assert_equal :public, loaded.visibility
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
end
def test_marshal_load
@@ -138,28 +121,37 @@ method(a, b) { |c, d| ... }
end
def test_marshal_load_version_0
+ @store.path = Dir.tmpdir
+ top_level = @store.add_file 'file.rb'
+
m = RDoc::AnyMethod.new nil, 'method'
- cm = RDoc::ClassModule.new 'Klass'
+
+ cm = top_level.add_class RDoc::ClassModule, 'Klass'
cm.add_method m
+
+ section = cm.sections.first
+
al = RDoc::Alias.new nil, 'method', 'aliased', 'alias comment'
al_m = m.add_alias al, cm
- loaded = Marshal.load "\x04\bU:\x14RDoc::AnyMethod[\x0Fi\x00I" \
- "\"\vmethod\x06:\x06EF\"\x11Klass#method0:\vpublic" \
- "o:\eRDoc::Markup::Document\x06:\v@parts[\x06" \
- "o:\x1CRDoc::Markup::Paragraph\x06;\t[\x06I" \
- "\"\x16this is a comment\x06;\x06FI" \
- "\"\rcall_seq\x06;\x06FI\"\x0Fsome_block\x06;\x06F" \
- "[\x06[\aI\"\faliased\x06;\x06Fo;\b\x06;\t[\x06" \
- "o;\n\x06;\t[\x06I\"\x12alias comment\x06;\x06FI" \
+ loaded = Marshal.load "\x04\bU:\x14RDoc::AnyMethod[\x0Fi\x00I" +
+ "\"\vmethod\x06:\x06EF\"\x11Klass#method0:\vpublic" +
+ "o:\eRDoc::Markup::Document\x06:\v@parts[\x06" +
+ "o:\x1CRDoc::Markup::Paragraph\x06;\t[\x06I" +
+ "\"\x16this is a comment\x06;\x06FI" +
+ "\"\rcall_seq\x06;\x06FI\"\x0Fsome_block\x06;\x06F" +
+ "[\x06[\aI\"\faliased\x06;\x06Fo;\b\x06;\t[\x06" +
+ "o;\n\x06;\t[\x06I\"\x12alias comment\x06;\x06FI" +
"\"\nparam\x06;\x06F"
+ loaded.store = @store
+
comment = RDoc::Markup::Document.new(
RDoc::Markup::Paragraph.new('this is a comment'))
assert_equal m, loaded
- assert_equal [al_m], loaded.aliases
+ assert_equal [al_m.name], loaded.aliases.map { |alas| alas.name }
assert_equal 'some_block', loaded.block_params
assert_equal 'call_seq', loaded.call_seq
assert_equal comment, loaded.comment
@@ -169,6 +161,8 @@ method(a, b) { |c, d| ... }
assert_equal nil, loaded.singleton # defaults to nil
assert_equal :public, loaded.visibility
assert_equal nil, loaded.file
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
end
def test_name
@@ -200,6 +194,15 @@ method(a, b) { |c, d| ... }
assert_equal %w[a b c d], m.param_list
end
+ def test_param_list_default
+ m = RDoc::AnyMethod.new nil, 'method'
+ m.parent = @c1
+
+ m.params = '(b = default)'
+
+ assert_equal %w[b], m.param_list
+ end
+
def test_param_list_params
m = RDoc::AnyMethod.new nil, 'method'
m.parent = @c1
@@ -259,5 +262,58 @@ method(a, b) { |c, d| ... }
assert_equal 'C1', @c1.method_list.last.parent_name
end
+ def test_store_equals
+ loaded = Marshal.load Marshal.dump(@c1.method_list.last)
+
+ loaded.store = @store
+
+ assert_equal @store, loaded.file.store
+ end
+
+ def test_superclass_method
+ m3 = RDoc::AnyMethod.new '', 'no_super'
+
+ m2 = RDoc::AnyMethod.new '', 'supers'
+ m2.calls_super = true
+
+ m1 = RDoc::AnyMethod.new '', 'supers'
+
+ c1 = RDoc::NormalClass.new 'Outer'
+ c1.store = @store
+ c1.add_method m1
+
+ c2 = RDoc::NormalClass.new 'Inner', c1
+ c2.store = @store
+ c2.add_method m2
+ c2.add_method m3
+
+ assert_nil m3.superclass_method,
+ 'no superclass method for no_super'
+
+ assert_equal m1, m2.superclass_method,
+ 'superclass method missing for supers'
+ end
+
+ def test_superclass_method_multilevel
+ m2 = RDoc::AnyMethod.new '', 'supers'
+ m2.calls_super = true
+
+ m1 = RDoc::AnyMethod.new '', 'supers'
+
+ c1 = RDoc::NormalClass.new 'Outer'
+ c1.store = @store
+ c1.add_method m1
+
+ c2 = RDoc::NormalClass.new 'Middle', c1
+ c2.store = @store
+
+ c3 = RDoc::NormalClass.new 'Inner', c2
+ c3.store = @store
+ c3.add_method m2
+
+ assert_equal m1, m2.superclass_method,
+ 'superclass method missing for supers'
+ end
+
end
diff --git a/test/rdoc/test_rdoc_attr.rb b/test/rdoc/test_rdoc_attr.rb
index b69d8c6499..92ff1b9856 100644
--- a/test/rdoc/test_rdoc_attr.rb
+++ b/test/rdoc/test_rdoc_attr.rb
@@ -1,10 +1,10 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/rdoc'
+require 'rdoc/test_case'
-class TestRDocAttr < MiniTest::Unit::TestCase
+class TestRDocAttr < RDoc::TestCase
def setup
+ super
+
@a = RDoc::Attr.new nil, 'attr', 'RW', ''
end
@@ -43,15 +43,18 @@ class TestRDocAttr < MiniTest::Unit::TestCase
end
def test_marshal_dump
- tl = RDoc::TopLevel.new 'file.rb'
+ tl = @store.add_file 'file.rb'
@a.comment = 'this is a comment'
@a.record_location tl
- cm = RDoc::ClassModule.new 'Klass'
+ cm = tl.add_class RDoc::NormalClass, 'Klass'
cm.add_attribute @a
+ section = cm.sections.first
+
loaded = Marshal.load Marshal.dump @a
+ loaded.store = @store
assert_equal @a, loaded
@@ -65,31 +68,58 @@ class TestRDocAttr < MiniTest::Unit::TestCase
assert_equal 'RW', loaded.rw
assert_equal false, loaded.singleton
assert_equal :public, loaded.visibility
+ assert_equal tl, loaded.file
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
+ end
+
+ def test_marshal_dump_singleton
+ tl = @store.add_file 'file.rb'
+
+ @a.comment = 'this is a comment'
+ @a.record_location tl
+
+ cm = tl.add_class RDoc::NormalClass, 'Klass'
+ cm.add_attribute @a
+
+ section = cm.sections.first
@a.rw = 'R'
@a.singleton = true
@a.visibility = :protected
loaded = Marshal.load Marshal.dump @a
+ loaded.store = @store
assert_equal @a, loaded
+ comment = RDoc::Markup::Document.new(
+ RDoc::Markup::Paragraph.new('this is a comment'))
+
assert_equal comment, loaded.comment
assert_equal 'Klass::attr', loaded.full_name
assert_equal 'attr', loaded.name
assert_equal 'R', loaded.rw
assert_equal true, loaded.singleton
assert_equal :protected, loaded.visibility
+ assert_equal tl, loaded.file
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
end
def test_marshal_load_version_1
- data = "\x04\bU:\x0FRDoc::Attr[\fi\x06I\"\tattr\x06:\x06EF" \
- "\"\x0FKlass#attrI\"\aRW\x06;\x06F:\vpublic" \
- "o:\eRDoc::Markup::Document\x06:\v@parts[\x06" \
- "o:\x1CRDoc::Markup::Paragraph\x06;\t[\x06I" \
+ tl = @store.add_file 'file.rb'
+ cm = tl.add_class RDoc::NormalClass, 'Klass'
+ section = cm.sections.first
+
+ data = "\x04\bU:\x0FRDoc::Attr[\fi\x06I\"\tattr\x06:\x06EF" +
+ "\"\x0FKlass#attrI\"\aRW\x06;\x06F:\vpublic" +
+ "o:\eRDoc::Markup::Document\x06:\v@parts[\x06" +
+ "o:\x1CRDoc::Markup::Paragraph\x06;\t[\x06I" +
"\"\x16this is a comment\x06;\x06FF"
loaded = Marshal.load data
+ loaded.store = @store
comment = RDoc::Markup::Document.new(
RDoc::Markup::Paragraph.new('this is a comment'))
@@ -101,7 +131,40 @@ class TestRDocAttr < MiniTest::Unit::TestCase
assert_equal false, loaded.singleton
assert_equal :public, loaded.visibility
- assert_equal nil, loaded.file # version 2
+ # version 2
+ assert_nil loaded.file
+
+ # version 3
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
+ end
+
+ def test_marshal_load_version_2
+ tl = @store.add_file 'file.rb'
+ cm = tl.add_class RDoc::NormalClass, 'Klass'
+ section = cm.sections.first
+
+ loaded = Marshal.load "\x04\bU:\x0FRDoc::Attr[\ri\aI\"\tattr\x06" +
+ ":\x06ETI\"\x0FKlass#attr\x06;\x06TI\"\aRW\x06" +
+ ";\x06T:\vpublico:\eRDoc::Markup::Document\a" +
+ ":\v@parts[\x06o:\x1CRDoc::Markup::Paragraph\x06;" +
+ "\t[\x06I\"\x16this is a comment\x06;\x06T:\n" +
+ "@file0FI\"\ffile.rb\x06;\x06T"
+ loaded.store = @store
+
+ comment = doc(para('this is a comment'))
+
+ assert_equal comment, loaded.comment
+ assert_equal 'Klass#attr', loaded.full_name
+ assert_equal 'attr', loaded.name
+ assert_equal 'RW', loaded.rw
+ assert_equal false, loaded.singleton
+ assert_equal :public, loaded.visibility
+ assert_equal tl, loaded.file
+
+ # version 3
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
end
def test_params
diff --git a/test/rdoc/test_rdoc_class_module.rb b/test/rdoc/test_rdoc_class_module.rb
index 7d32a91580..a6aa1e9472 100644
--- a/test/rdoc/test_rdoc_class_module.rb
+++ b/test/rdoc/test_rdoc_class_module.rb
@@ -1,14 +1,7 @@
-require 'pp'
require File.expand_path '../xref_test_case', __FILE__
class TestRDocClassModule < XrefTestCase
- def setup
- super
-
- @RM = RDoc::Markup
- end
-
def mu_pp obj
s = ''
s = PP.pp obj, s
@@ -17,9 +10,9 @@ class TestRDocClassModule < XrefTestCase
end
def test_add_comment
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
- tl3 = RDoc::TopLevel.new 'three.rb'
+ tl1 = @store.add_file 'one.rb'
+ tl2 = @store.add_file 'two.rb'
+ tl3 = @store.add_file 'three.rb'
cm = RDoc::ClassModule.new 'Klass'
cm.add_comment '# comment 1', tl1
@@ -40,8 +33,16 @@ class TestRDocClassModule < XrefTestCase
assert_equal "comment 1\n---\ncomment 2\n---\n* comment 3", cm.comment
end
+ def test_add_comment_comment
+ cm = RDoc::ClassModule.new 'Klass'
+
+ cm.add_comment comment('comment'), @top_level
+
+ assert_equal 'comment', cm.comment.text
+ end
+
def test_add_comment_stopdoc
- tl = RDoc::TopLevel.new 'file.rb'
+ tl = @store.add_file 'file.rb'
cm = RDoc::ClassModule.new 'Klass'
cm.stop_doc
@@ -52,7 +53,7 @@ class TestRDocClassModule < XrefTestCase
end
def test_ancestors
- assert_equal [@parent], @child.ancestors
+ assert_equal [@parent, "Object"], @child.ancestors
end
def test_comment_equals
@@ -70,14 +71,41 @@ class TestRDocClassModule < XrefTestCase
assert_equal "comment 1\n---\ncomment 2\n---\n* comment 3", cm.comment
end
+ def test_comment_equals_comment
+ cm = RDoc::ClassModule.new 'Klass'
+
+ cm.comment = comment 'comment'
+
+ assert_equal 'comment', cm.comment.text
+ end
+
+ def test_docuent_self_or_methods
+ assert @c1.document_self_or_methods
+
+ @c1.document_self = false
+
+ assert @c1.document_self_or_methods
+
+ @c1_m.document_self = false
+
+ assert @c1.document_self_or_methods
+
+ @c1__m.document_self = false
+
+ refute @c1.document_self_or_methods
+ end
+
def test_each_ancestor
- ancestors = []
+ assert_equal [@parent], @child.each_ancestor.to_a
+ end
- @child.each_ancestor do |mod|
- ancestors << mod
- end
+ def test_each_ancestor_cycle
+ m_incl = RDoc::Include.new 'M', nil
+
+ m = @top_level.add_module RDoc::NormalModule, 'M'
+ m.add_include m_incl
- assert_equal [@parent], ancestors
+ assert_empty m.each_ancestor.to_a
end
# handle making a short module alias of yourself
@@ -89,7 +117,7 @@ class TestRDocClassModule < XrefTestCase
end
def test_from_module_comment
- tl = RDoc::TopLevel.new 'file.rb'
+ tl = @store.add_file 'file.rb'
klass = tl.add_class RDoc::NormalModule, 'Klass'
klass.add_comment 'really a class', tl
@@ -99,7 +127,8 @@ class TestRDocClassModule < XrefTestCase
end
def test_marshal_dump
- tl = RDoc::TopLevel.new 'file.rb'
+ @store.path = Dir.tmpdir
+ tl = @store.add_file 'file.rb'
ns = tl.add_module RDoc::NormalModule, 'Namespace'
@@ -120,20 +149,32 @@ class TestRDocClassModule < XrefTestCase
i1 = RDoc::Include.new 'I1', ''
i1.record_location tl
+ e1 = RDoc::Extend.new 'E1', ''
+ e1.record_location tl
+
+ section_comment = RDoc::Comment.new('section comment')
+ section_comment.location = tl
+
+ assert_equal 1, cm.sections.length, 'sanity, default section only'
+ s0 = cm.sections.first
+ s1 = cm.add_section 'section', section_comment
+
cm.add_attribute a1
cm.add_attribute a2
cm.add_method m1
cm.add_constant c1
cm.add_include i1
+ cm.add_extend e1
cm.add_comment 'this is a comment', tl
loaded = Marshal.load Marshal.dump cm
+ loaded.store = @store
assert_equal cm, loaded
inner = RDoc::Markup::Document.new(
RDoc::Markup::Paragraph.new('this is a comment'))
- inner.file = tl.absolute_name
+ inner.file = tl
comment = RDoc::Markup::Document.new inner
@@ -142,9 +183,15 @@ class TestRDocClassModule < XrefTestCase
assert_equal [c1], loaded.constants
assert_equal 'Namespace::Klass', loaded.full_name
assert_equal [i1], loaded.includes
+ assert_equal [e1], loaded.extends
assert_equal [m1], loaded.method_list
assert_equal 'Klass', loaded.name
assert_equal 'Super', loaded.superclass
+ assert_equal [tl], loaded.in_files
+ assert_equal 'Namespace', loaded.parent.name
+
+ expected = { nil => s0, 'section' => s1 }
+ assert_equal expected, loaded.sections_hash
assert_equal tl, loaded.attributes.first.file
@@ -152,11 +199,13 @@ class TestRDocClassModule < XrefTestCase
assert_equal tl, loaded.includes.first.file
+ assert_equal tl, loaded.extends.first.file
+
assert_equal tl, loaded.method_list.first.file
end
def test_marshal_load_version_0
- tl = RDoc::TopLevel.new 'file.rb'
+ tl = @store.add_file 'file.rb'
ns = tl.add_module RDoc::NormalModule, 'Namespace'
cm = ns.add_class RDoc::NormalClass, 'Klass', 'Super'
@@ -165,25 +214,29 @@ class TestRDocClassModule < XrefTestCase
c = RDoc::Constant.new('C1', nil, '')
i = RDoc::Include.new('I1', '')
+ s0 = cm.sections.first
+
cm.add_attribute a
cm.add_method m
cm.add_constant c
cm.add_include i
cm.add_comment 'this is a comment', tl
- loaded = Marshal.load "\x04\bU:\x16RDoc::NormalClass[\x0Ei\x00\"\nKlass" \
- "\"\x15Namespace::KlassI\"\nSuper\x06:\x06EF" \
- "o:\eRDoc::Markup::Document\x06:\v@parts[\x06" \
- "o:\x1CRDoc::Markup::Paragraph\x06;\b[\x06I" \
- "\"\x16this is a comment\x06;\x06F[\x06[\aI" \
- "\"\aa1\x06;\x06FI\"\aRW\x06;\x06F[\x06[\aI" \
- "\"\aC1\x06;\x06Fo;\a\x06;\b[\x00[\x06[\aI" \
- "\"\aI1\x06;\x06Fo;\a\x06;\b[\x00[\a[\aI" \
- "\"\nclass\x06;\x06F[\b[\a:\vpublic[\x00[\a" \
- ":\x0Eprotected[\x00[\a:\fprivate[\x00[\aI" \
- "\"\rinstance\x06;\x06F[\b[\a;\n[\x06I" \
+ loaded = Marshal.load "\x04\bU:\x16RDoc::NormalClass[\x0Ei\x00\"\nKlass" +
+ "\"\x15Namespace::KlassI\"\nSuper\x06:\x06EF" +
+ "o:\eRDoc::Markup::Document\x06:\v@parts[\x06" +
+ "o:\x1CRDoc::Markup::Paragraph\x06;\b[\x06I" +
+ "\"\x16this is a comment\x06;\x06F[\x06[\aI" +
+ "\"\aa1\x06;\x06FI\"\aRW\x06;\x06F[\x06[\aI" +
+ "\"\aC1\x06;\x06Fo;\a\x06;\b[\x00[\x06[\aI" +
+ "\"\aI1\x06;\x06Fo;\a\x06;\b[\x00[\a[\aI" +
+ "\"\nclass\x06;\x06F[\b[\a:\vpublic[\x00[\a" +
+ ":\x0Eprotected[\x00[\a:\fprivate[\x00[\aI" +
+ "\"\rinstance\x06;\x06F[\b[\a;\n[\x06I" +
"\"\am1\x06;\x06F[\a;\v[\x00[\a;\f[\x00"
+ loaded.store = @store
+
assert_equal cm, loaded
comment = RDoc::Markup::Document.new(
@@ -197,12 +250,300 @@ class TestRDocClassModule < XrefTestCase
assert_equal [m], loaded.method_list
assert_equal 'Klass', loaded.name
assert_equal 'Super', loaded.superclass
- assert_equal nil, loaded.file
+ assert_nil loaded.file
+ assert_empty loaded.in_files
+ assert_nil loaded.parent
+ assert loaded.current_section
+
+ expected = { nil => s0 }
+ assert_equal expected, loaded.sections_hash
+ end
+
+ def test_marshal_load_version_1
+ tl = @store.add_file 'file.rb'
+
+ ns = tl.add_module RDoc::NormalModule, 'Namespace'
+
+ cm = ns.add_class RDoc::NormalClass, 'Klass', 'Super'
+ cm.record_location tl
+
+ a1 = RDoc::Attr.new nil, 'a1', 'RW', ''
+ a1.record_location tl
+ a2 = RDoc::Attr.new nil, 'a2', 'RW', '', true
+ a2.record_location tl
+
+ m1 = RDoc::AnyMethod.new nil, 'm1'
+ m1.record_location tl
+
+ c1 = RDoc::Constant.new 'C1', nil, ''
+ c1.record_location tl
+
+ i1 = RDoc::Include.new 'I1', ''
+ i1.record_location tl
+
+ s0 = cm.sections.first
+
+ cm.add_attribute a1
+ cm.add_attribute a2
+ cm.add_method m1
+ cm.add_constant c1
+ cm.add_include i1
+ cm.add_comment 'this is a comment', tl
+
+ loaded = Marshal.load "\x04\bU:\x16RDoc::NormalClass[\x0Ei\x06I\"\nKlass" +
+ "\x06:\x06EFI\"\x15Namespace::Klass\x06;\x06FI" +
+ "\"\nSuper\x06;\x06Fo:\eRDoc::Markup::Document\a" +
+ ":\v@parts[\x06o;\a\a;\b[\x06o" +
+ ":\x1CRDoc::Markup::Paragraph\x06;\b" +
+ "[\x06I\"\x16this is a comment\x06;\x06F" +
+ ":\n@fileI\"\ffile.rb\x06;\x06F;\n0[\a[\nI" +
+ "\"\aa2\x06;\x06FI\"\aRW\x06;\x06F:\vpublicT@\x11" +
+ "[\nI\"\aa1\x06;\x06FI\"\aRW\x06;\x06F;\vF@\x11" +
+ "[\x06[\bI\"\aC1\x06;\x06Fo;\a\a;\b[\x00;\n0@\x11" +
+ "[\x06[\bI\"\aI1\x06;\x06Fo;\a\a;\b[\x00;\n0@\x11" +
+ "[\a[\aI\"\nclass\x06;\x06F[\b[\a;\v[\x00" +
+ "[\a:\x0Eprotected[\x00[\a:\fprivate[\x00[\aI" +
+ "\"\rinstance\x06;\x06F[\b[\a;\v[\x06[\aI" +
+ "\"\am1\x06;\x06F@\x11[\a;\f[\x00[\a;\r[\x00"
+
+ loaded.store = @store
+
+ assert_equal cm, loaded
+
+ inner = RDoc::Markup::Document.new(
+ RDoc::Markup::Paragraph.new('this is a comment'))
+ inner.file = tl
+
+ comment = RDoc::Markup::Document.new inner
+
+ assert_equal [a2, a1], loaded.attributes.sort
+ assert_equal comment, loaded.comment
+ assert_equal [c1], loaded.constants
+ assert_equal 'Namespace::Klass', loaded.full_name
+ assert_equal [i1], loaded.includes
+ assert_empty loaded.extends
+ assert_equal [m1], loaded.method_list
+ assert_equal 'Klass', loaded.name
+ assert_equal 'Super', loaded.superclass
+ assert_empty loaded.in_files
+ assert_nil loaded.parent
+ assert loaded.current_section
+
+ assert_equal tl, loaded.attributes.first.file
+ assert_equal tl, loaded.constants.first.file
+ assert_equal tl, loaded.includes.first.file
+ assert_equal tl, loaded.method_list.first.file
+
+ expected = { nil => s0 }
+ assert_equal expected, loaded.sections_hash
+ end
+
+ def test_marshal_load_version_2
+ tl = @store.add_file 'file.rb'
+
+ ns = tl.add_module RDoc::NormalModule, 'Namespace'
+
+ cm = ns.add_class RDoc::NormalClass, 'Klass', 'Super'
+ cm.record_location tl
+
+ a1 = RDoc::Attr.new nil, 'a1', 'RW', ''
+ a1.record_location tl
+ a2 = RDoc::Attr.new nil, 'a2', 'RW', '', true
+ a2.record_location tl
+
+ m1 = RDoc::AnyMethod.new nil, 'm1'
+ m1.record_location tl
+
+ c1 = RDoc::Constant.new 'C1', nil, ''
+ c1.record_location tl
+
+ i1 = RDoc::Include.new 'I1', ''
+ i1.record_location tl
+
+ e1 = RDoc::Extend.new 'E1', ''
+ e1.record_location tl
+
+ s0 = cm.sections.first
+
+ cm.add_attribute a1
+ cm.add_attribute a2
+ cm.add_method m1
+ cm.add_constant c1
+ cm.add_include i1
+ cm.add_extend e1
+ cm.add_comment 'this is a comment', tl
+
+ loaded = Marshal.load "\x04\bU:\x16RDoc::NormalClass[\x0Fi\aI\"\nKlass" +
+ "\x06:\x06EFI\"\x15Namespace::Klass\x06;\x06FI" +
+ "\"\nSuper\x06;\x06Fo:\eRDoc::Markup::Document\a" +
+ ":\v@parts[\x06o;\a\a;\b[\x06o" +
+ ":\x1CRDoc::Markup::Paragraph\x06;\b" +
+ "[\x06I\"\x16this is a comment\x06;\x06F" +
+ ":\n@fileI\"\ffile.rb\x06;\x06F;\n0[\a[\nI" +
+ "\"\aa2\x06;\x06FI\"\aRW\x06;\x06F:\vpublicT@\x11" +
+ "[\nI\"\aa1\x06;\x06FI\"\aRW\x06;\x06F;\vF@\x11" +
+ "[\x06[\bI\"\aC1\x06;\x06Fo;\a\a;\b[\x00;\n0@\x11" +
+ "[\x06[\bI\"\aI1\x06;\x06Fo;\a\a;\b[\x00;\n0@\x11" +
+ "[\a[\aI\"\nclass\x06;\x06F[\b[\a;\v[\x00" +
+ "[\a:\x0Eprotected[\x00[\a:\fprivate[\x00[\aI" +
+ "\"\rinstance\x06;\x06F[\b[\a;\v[\x06[\aI" +
+ "\"\am1\x06;\x06F@\x11[\a;\f[\x00[\a;\r[\x00" +
+ "[\x06[\bI\"\aE1\x06;\x06Fo;\a\a;\b[\x00;\n0@\x11"
+
+ loaded.store = @store
+
+ assert_equal cm, loaded
+
+ inner = RDoc::Markup::Document.new(
+ RDoc::Markup::Paragraph.new('this is a comment'))
+ inner.file = tl
+
+ comment = RDoc::Markup::Document.new inner
+
+ assert_equal [a2, a1], loaded.attributes.sort
+ assert_equal comment, loaded.comment
+ assert_equal [c1], loaded.constants
+ assert_equal 'Namespace::Klass', loaded.full_name
+ assert_equal [i1], loaded.includes
+ assert_equal [e1], loaded.extends
+ assert_equal [m1], loaded.method_list
+ assert_equal 'Klass', loaded.name
+ assert_equal 'Super', loaded.superclass
+ assert_empty loaded.in_files
+ assert_nil loaded.parent
+ assert loaded.current_section
+
+ assert_equal tl, loaded.attributes. first.file
+ assert_equal tl, loaded.constants. first.file
+ assert_equal tl, loaded.includes. first.file
+ assert_equal tl, loaded.extends. first.file
+ assert_equal tl, loaded.method_list.first.file
+
+ expected = { nil => s0 }
+ assert_equal expected, loaded.sections_hash
+ end
+
+ def test_marshal_load_version_3
+ tl = @store.add_file 'file.rb'
+
+ ns = tl.add_module RDoc::NormalModule, 'Namespace'
+
+ cm = ns.add_class RDoc::NormalClass, 'Klass', 'Super'
+ cm.record_location tl
+
+ a1 = RDoc::Attr.new nil, 'a1', 'RW', ''
+ a1.record_location tl
+ a2 = RDoc::Attr.new nil, 'a2', 'RW', '', true
+ a2.record_location tl
+
+ m1 = RDoc::AnyMethod.new nil, 'm1'
+ m1.record_location tl
+
+ c1 = RDoc::Constant.new 'C1', nil, ''
+ c1.record_location tl
+
+ i1 = RDoc::Include.new 'I1', ''
+ i1.record_location tl
+
+ e1 = RDoc::Extend.new 'E1', ''
+ e1.record_location tl
+
+ section_comment = RDoc::Comment.new('section comment')
+ section_comment.location = tl
+
+ assert_equal 1, cm.sections.length, 'sanity, default section only'
+ s0 = cm.sections.first
+ s1 = cm.add_section 'section', section_comment
+
+ cm.add_attribute a1
+ cm.add_attribute a2
+ cm.add_method m1
+ cm.add_constant c1
+ cm.add_include i1
+ cm.add_extend e1
+ cm.add_comment 'this is a comment', tl
+
+ loaded = Marshal.load "\x04\bU:\x16RDoc::NormalClass[\x13i\bI\"\nKlass" +
+ "\x06:\x06ETI\"\x15Namespace::Klass\x06;\x06TI" +
+ "\"\nSuper\x06;\x06To:\eRDoc::Markup::Document\a" +
+ ":\v@parts[\x06o;\a\a;\b[\x06o" +
+ ":\x1CRDoc::Markup::Paragraph\x06;\b[\x06I" +
+ "\"\x16this is a comment\x06;\x06T:\n@fileI" +
+ "\"\ffile.rb\x06;\x06T;\n0[\a[\nI\"\aa2\x06;" +
+ "\x06TI\"\aRW\x06;\x06T:\vpublicT@\x11[\nI" +
+ "\"\aa1\x06;\x06TI\"\aRW\x06;\x06T;\vF@\x11" +
+ "[\x06U:\x13RDoc::Constant[\x0Fi\x00I\"\aC1\x06" +
+ ";\x06TI\"\x19Namespace::Klass::C1\x06;\x06T00o" +
+ ";\a\a;\b[\x00;\n0@\x11@\ac\x16RDoc::NormalClass0" +
+ "[\x06[\bI\"\aI1\x06;\x06To;\a\a;\b[\x00;\n0@\x11" +
+ "[\a[\aI\"\nclass\x06;\x06T[\b[\a;\v[\x00[\a" +
+ ":\x0Eprotected[\x00[\a:\fprivate[\x00[\aI" +
+ "\"\rinstance\x06;\x06T[\b[\a;\v[\x06[\aI" +
+ "\"\am1\x06;\x06T@\x11[\a;\r[\x00[\a;\x0E[\x00" +
+ "[\x06[\bI\"\aE1\x06;\x06To;\a\a;\b[\x00;\n0@\x11" +
+ "[\aU:\eRDoc::Context::Section[\bi\x000o;\a\a;\b" +
+ "[\x00;\n0U;\x0F[\bi\x00I\"\fsection\x06;\x06To" +
+ ";\a\a;\b[\x06o;\a\a;\b[\x06o;\t\x06;\b[\x06I" +
+ "\"\x14section comment\x06;\x06T;\n@\x11;\n0" +
+ "[\x06@\x11I\"\x0ENamespace\x06" +
+ ";\x06Tc\x17RDoc::NormalModule"
+
+ loaded.store = @store
+
+ assert_equal cm, loaded
+
+ inner = RDoc::Markup::Document.new(
+ RDoc::Markup::Paragraph.new('this is a comment'))
+ inner.file = tl
+
+ comment = RDoc::Markup::Document.new inner
+
+ assert_equal [a2, a1], loaded.attributes.sort
+ assert_equal comment, loaded.comment
+ assert_equal [c1], loaded.constants
+ assert_equal 'Namespace::Klass', loaded.full_name
+ assert_equal [i1], loaded.includes
+ assert_equal [e1], loaded.extends
+ assert_equal [m1], loaded.method_list
+ assert_equal 'Klass', loaded.name
+ assert_equal 'Super', loaded.superclass
+ assert_equal 'Namespace', loaded.parent.name
+ assert loaded.current_section
+
+ expected = {
+ nil => s0,
+ 'section' => s1,
+ }
+
+ assert_equal expected, loaded.sections_hash
+ assert_equal [tl], loaded.in_files
+
+ assert_equal tl, loaded.attributes. first.file
+ assert_equal tl, loaded.constants. first.file
+ assert_equal tl, loaded.includes. first.file
+ assert_equal tl, loaded.extends. first.file
+ assert_equal tl, loaded.method_list.first.file
+ end
+
+ def test_merge
+ tl = @store.add_file 'one.rb'
+ p1 = tl.add_class RDoc::NormalClass, 'Parent'
+ c1 = p1.add_class RDoc::NormalClass, 'Klass'
+
+ c2 = RDoc::NormalClass.new 'Klass'
+
+ c2.merge c1
+
+ assert_equal 'Parent', c1.parent_name, 'original parent name'
+ assert_equal 'Parent', c2.parent_name, 'merged parent name'
+
+ assert c1.current_section, 'original current_section'
+ assert c2.current_section, 'merged current_section'
end
def test_merge_attributes
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
+ tl1 = @store.add_file 'one.rb'
+ tl2 = @store.add_file 'two.rb'
cm1 = RDoc::ClassModule.new 'Klass'
@@ -237,7 +578,7 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_attributes_version_0
- tl1 = RDoc::TopLevel.new 'one.rb'
+ tl1 = @store.add_file 'one.rb'
cm1 = RDoc::ClassModule.new 'Klass'
@@ -270,7 +611,7 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_collections_drop
- tl = RDoc::TopLevel.new 'file'
+ tl = @store.add_file 'file'
cm1 = RDoc::ClassModule.new 'C'
cm1.record_location tl
@@ -297,17 +638,21 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_comment
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
+ tl1 = @store.add_file 'one.rb'
+ tl2 = @store.add_file 'two.rb'
- cm1 = RDoc::ClassModule.new 'Klass'
+ cm1 = tl1.add_class RDoc::ClassModule, 'Klass'
cm1.add_comment 'klass 1', tl1
+ cm1.record_location tl1
- cm2 = RDoc::ClassModule.new 'Klass'
+ cm2 = tl1.add_class RDoc::NormalClass, 'Klass'
cm2.add_comment 'klass 2', tl2
cm2.add_comment 'klass 3', tl1
+ cm2.record_location tl1
+ cm2.record_location tl2
cm2 = Marshal.load Marshal.dump cm2
+ cm2.store = @store
cm1.merge cm2
@@ -322,7 +667,7 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_comment_version_0
- tl = RDoc::TopLevel.new 'file.rb'
+ tl = @store.add_file 'file.rb'
cm1 = RDoc::ClassModule.new 'Klass'
cm1.add_comment 'klass 1', tl
@@ -347,17 +692,19 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_constants
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
+ tl1 = @store.add_file 'one.rb'
+ tl2 = @store.add_file 'two.rb'
- cm1 = RDoc::ClassModule.new 'Klass'
+ cm1 = tl1.add_class RDoc::ClassModule, 'Klass'
const = cm1.add_constant RDoc::Constant.new('C1', nil, 'one')
const.record_location tl1
const = cm1.add_constant RDoc::Constant.new('C3', nil, 'one')
const.record_location tl1
- cm2 = RDoc::ClassModule.new 'Klass'
+ store = RDoc::Store.new
+ tl = store.add_file 'one.rb'
+ cm2 = tl.add_class RDoc::ClassModule, 'Klass'
cm2.instance_variable_set :@comment, @RM::Document.new
const = cm2.add_constant RDoc::Constant.new('C2', nil, 'two')
@@ -381,16 +728,18 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_constants_version_0
- tl1 = RDoc::TopLevel.new 'one.rb'
+ tl1 = @store.add_file 'one.rb'
- cm1 = RDoc::ClassModule.new 'Klass'
+ cm1 = tl1.add_class RDoc::ClassModule, 'Klass'
const = cm1.add_constant RDoc::Constant.new('C1', nil, 'one')
const.record_location tl1
const = cm1.add_constant RDoc::Constant.new('C3', nil, 'one')
const.record_location tl1
- cm2 = RDoc::ClassModule.new 'Klass'
+ store = RDoc::Store.new
+ tl = store.add_file 'one.rb'
+ cm2 = tl.add_class RDoc::ClassModule, 'Klass'
cm2.instance_variable_set :@comment, @RM::Document.new
const = cm2.add_constant RDoc::Constant.new('C2', nil, 'two')
@@ -411,18 +760,55 @@ class TestRDocClassModule < XrefTestCase
assert_equal expected, cm1.constants.sort
end
+ def test_merge_extends
+ tl1 = @store.add_file 'one.rb'
+ cm1 = tl1.add_class RDoc::ClassModule, 'Klass'
+
+ ext = cm1.add_extend RDoc::Extend.new('I1', 'one')
+ ext.record_location tl1
+ ext = cm1.add_extend RDoc::Extend.new('I3', 'one')
+ ext.record_location tl1
+
+ tl2 = @store.add_file 'two.rb'
+ tl2.store = RDoc::Store.new
+
+ cm2 = tl2.add_class RDoc::ClassModule, 'Klass'
+ cm2.instance_variable_set :@comment, @RM::Document.new
+
+ ext = cm2.add_extend RDoc::Extend.new('I2', 'two')
+ ext.record_location tl2
+ ext = cm2.add_extend RDoc::Extend.new('I3', 'one')
+ ext.record_location tl1
+ ext = cm2.add_extend RDoc::Extend.new('I4', 'one')
+ ext.record_location tl1
+
+ cm1.merge cm2
+
+ expected = [
+ RDoc::Extend.new('I2', 'two'),
+ RDoc::Extend.new('I3', 'one'),
+ RDoc::Extend.new('I4', 'one'),
+ ]
+
+ expected.each do |a| a.parent = cm1 end
+
+ assert_equal expected, cm1.extends.sort
+ end
+
def test_merge_includes
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
+ tl1 = @store.add_file 'one.rb'
- cm1 = RDoc::ClassModule.new 'Klass'
+ cm1 = tl1.add_class RDoc::ClassModule, 'Klass'
incl = cm1.add_include RDoc::Include.new('I1', 'one')
incl.record_location tl1
incl = cm1.add_include RDoc::Include.new('I3', 'one')
incl.record_location tl1
- cm2 = RDoc::ClassModule.new 'Klass'
+ tl2 = @store.add_file 'two.rb'
+ tl2.store = RDoc::Store.new
+
+ cm2 = tl2.add_class RDoc::ClassModule, 'Klass'
cm2.instance_variable_set :@comment, @RM::Document.new
incl = cm2.add_include RDoc::Include.new('I2', 'two')
@@ -446,16 +832,19 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_includes_version_0
- tl1 = RDoc::TopLevel.new 'one.rb'
+ tl1 = @store.add_file 'one.rb'
- cm1 = RDoc::ClassModule.new 'Klass'
+ cm1 = tl1.add_class RDoc::ClassModule, 'Klass'
incl = cm1.add_include RDoc::Include.new('I1', 'one')
incl.record_location tl1
incl = cm1.add_include RDoc::Include.new('I3', 'one')
incl.record_location tl1
- cm2 = RDoc::ClassModule.new 'Klass'
+ tl2 = @store.add_file 'one.rb'
+ tl2.store = RDoc::Store.new
+
+ cm2 = tl2.add_class RDoc::ClassModule, 'Klass'
cm2.instance_variable_set :@comment, @RM::Document.new
incl = cm2.add_include RDoc::Include.new('I2', 'two')
@@ -477,10 +866,10 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_methods
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
+ tl1 = @store.add_file 'one.rb'
+ tl2 = @store.add_file 'two.rb'
- cm1 = RDoc::ClassModule.new 'Klass'
+ cm1 = tl1.add_class RDoc::NormalClass, 'Klass'
meth = cm1.add_method RDoc::AnyMethod.new(nil, 'm1')
meth.record_location tl1
@@ -488,6 +877,7 @@ class TestRDocClassModule < XrefTestCase
meth.record_location tl1
cm2 = RDoc::ClassModule.new 'Klass'
+ cm2.store = @store
cm2.instance_variable_set :@comment, @RM::Document.new
meth = cm2.add_method RDoc::AnyMethod.new(nil, 'm2')
@@ -511,9 +901,9 @@ class TestRDocClassModule < XrefTestCase
end
def test_merge_methods_version_0
- tl1 = RDoc::TopLevel.new 'one.rb'
+ tl1 = @store.add_file 'one.rb'
- cm1 = RDoc::ClassModule.new 'Klass'
+ cm1 = tl1.add_class RDoc::NormalClass, 'Klass'
meth = cm1.add_method RDoc::AnyMethod.new(nil, 'm1')
meth.record_location tl1
@@ -521,6 +911,7 @@ class TestRDocClassModule < XrefTestCase
meth.record_location tl1
cm2 = RDoc::ClassModule.new 'Klass'
+ cm2.store = @store
cm2.instance_variable_set :@comment, @RM::Document.new
meth = cm2.add_method RDoc::AnyMethod.new(nil, 'm2')
@@ -541,49 +932,176 @@ class TestRDocClassModule < XrefTestCase
assert_equal expected, cm1.method_list.sort
end
+ def test_merge_sections
+ store1 = @store
+
+ tl1_1 = store1.add_file 'one.rb'
+
+ cm1 = tl1_1.add_class RDoc::ClassModule, 'Klass'
+ cm1.record_location tl1_1
+
+ s1_0 = cm1.sections.first
+ s1_1 = cm1.add_section 'section 1', comment('comment 1', tl1_1)
+ cm1.add_section 'section 2', comment('comment 2 a', tl1_1)
+ cm1.add_section 'section 4', comment('comment 4 a', tl1_1)
+
+ store2 = RDoc::Store.new
+ tl2_1 = store2.add_file 'one.rb'
+ tl2_2 = store2.add_file 'two.rb'
+
+ cm2 = tl2_1.add_class RDoc::ClassModule, 'Klass'
+ cm2.record_location tl2_1
+ cm2.record_location tl2_2
+
+ cm2.sections.first
+ s2_2 = cm2.add_section 'section 2', comment('comment 2 b', tl2_1)
+ s2_3 = cm2.add_section 'section 3', comment('comment 3', tl2_2)
+ cm2.add_section 'section 4', comment('comment 4 b', tl2_2)
+
+ cm1.merge cm2
+
+ expected = [
+ s1_0,
+ s1_1,
+ s2_2,
+ s2_3,
+ RDoc::Context::Section.new(cm1, 'section 4', nil)
+ ]
+
+ merged_sections = cm1.sections.sort_by do |s|
+ s.title || ''
+ end
+
+ assert_equal expected, merged_sections
+
+ assert_equal [comment('comment 2 b', tl2_1)],
+ cm1.sections_hash['section 2'].comments
+
+ expected_s4_comments = [
+ comment('comment 4 a', tl2_1),
+ comment('comment 4 b', tl2_2),
+ ]
+
+ assert_equal expected_s4_comments, cm1.sections_hash['section 4'].comments
+ end
+
+ def test_merge_sections_overlap
+ store1 = @store
+
+ tl1_1 = store1.add_file 'one.rb'
+ tl1_3 = store1.add_file 'three.rb'
+
+ cm1 = tl1_1.add_class RDoc::ClassModule, 'Klass'
+ cm1.record_location tl1_1
+
+ cm1.add_section 'section', comment('comment 1 a', tl1_1)
+ cm1.add_section 'section', comment('comment 3', tl1_3)
+
+ store2 = RDoc::Store.new
+ tl2_1 = store2.add_file 'one.rb'
+ tl2_2 = store2.add_file 'two.rb'
+ tl2_3 = store2.add_file 'three.rb'
+
+ cm2 = tl2_1.add_class RDoc::ClassModule, 'Klass'
+ cm2.record_location tl2_1
+ cm2.record_location tl2_2
+
+ s2_0 = cm2.sections.first
+ s2_1 = cm2.add_section 'section', comment('comment 1 b', tl1_1)
+ cm2.add_section 'section', comment('comment 2', tl2_2)
+
+ cm1.merge_sections cm2
+
+ expected = [
+ s2_0,
+ s2_1,
+ ]
+
+ merged_sections = cm1.sections.sort_by do |s|
+ s.title || ''
+ end
+
+ assert_equal expected, merged_sections
+
+ expected = [
+ comment('comment 1 b', tl2_1),
+ comment('comment 3', tl2_3),
+ comment('comment 2', tl2_2),
+ ]
+
+ comments = cm1.sections_hash['section'].comments
+
+ assert_equal expected, comments.sort_by { |c| c.file.name }
+ end
+
def test_parse
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
+ tl1 = @store.add_file 'one.rb'
+ tl2 = @store.add_file 'two.rb'
cm = RDoc::ClassModule.new 'Klass'
cm.add_comment 'comment 1', tl1
cm.add_comment 'comment 2', tl2
doc1 = @RM::Document.new @RM::Paragraph.new 'comment 1'
- doc1.file = tl1.absolute_name
+ doc1.file = tl1
doc2 = @RM::Document.new @RM::Paragraph.new 'comment 2'
- doc2.file = tl2.absolute_name
+ doc2.file = tl2
expected = @RM::Document.new doc1, doc2
assert_equal expected, cm.parse(cm.comment_location)
end
- def test_parse_comment_location
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
+ def test_parse_comment
+ tl1 = @store.add_file 'one.rb'
+
+ cm = RDoc::ClassModule.new 'Klass'
+ cm.comment = comment 'comment 1', tl1
+
+ doc = @RM::Document.new @RM::Paragraph.new 'comment 1'
+ doc.file = tl1
+
+ assert_equal doc, cm.parse(cm.comment)
+ end
+
+ def test_parse_comment_format
+ tl1 = @store.add_file 'one.rb'
cm = RDoc::ClassModule.new 'Klass'
+ cm.comment = comment 'comment ((*1*))', tl1
+ cm.comment.format = 'rd'
+
+ doc = @RM::Document.new @RM::Paragraph.new 'comment <em>1</em>'
+ doc.file = tl1
+
+ assert_equal doc, cm.parse(cm.comment)
+ end
+
+ def test_parse_comment_location
+ tl1 = @store.add_file 'one.rb'
+ tl2 = @store.add_file 'two.rb'
+
+ cm = tl1.add_class RDoc::NormalClass, 'Klass'
cm.add_comment 'comment 1', tl1
cm.add_comment 'comment 2', tl2
cm = Marshal.load Marshal.dump cm
doc1 = @RM::Document.new @RM::Paragraph.new 'comment 1'
- doc1.file = tl1.absolute_name
+ doc1.file = tl1
doc2 = @RM::Document.new @RM::Paragraph.new 'comment 2'
- doc2.file = tl2.absolute_name
+ doc2.file = tl2
assert_same cm.comment_location, cm.parse(cm.comment_location)
end
def test_remove_nodoc_children
- parent = RDoc::ClassModule.new 'A'
+ parent = @top_level.add_class RDoc::ClassModule, 'A'
parent.modules_hash.replace 'B' => true, 'C' => true
- RDoc::TopLevel.all_modules_hash.replace 'A::B' => true
+ @store.modules_hash.replace 'A::B' => true
parent.classes_hash.replace 'D' => true, 'E' => true
- RDoc::TopLevel.all_classes_hash.replace 'A::D' => true
+ @store.classes_hash.replace 'A::D' => true
parent.remove_nodoc_children
@@ -591,6 +1109,83 @@ class TestRDocClassModule < XrefTestCase
assert_equal %w[D], parent.classes_hash.keys
end
+ def test_search_record
+ @c2_c3.add_comment 'This is a comment.', @xref_data
+
+ expected = [
+ 'C3',
+ 'C2::C3',
+ 'C2::C3',
+ '',
+ 'C2/C3.html',
+ '',
+ "<p>This is a comment.\n"
+ ]
+
+ assert_equal expected, @c2_c3.search_record
+ end
+
+ def test_search_record_merged
+ @c2_c3.add_comment 'comment A', @store.add_file('a.rb')
+ @c2_c3.add_comment 'comment B', @store.add_file('b.rb')
+
+ expected = [
+ 'C3',
+ 'C2::C3',
+ 'C2::C3',
+ '',
+ 'C2/C3.html',
+ '',
+ "<p>comment A\n<p>comment B\n"
+ ]
+
+ assert_equal expected, @c2_c3.search_record
+ end
+
+ def test_store_equals
+ # version 2
+ loaded = Marshal.load "\x04\bU:\x16RDoc::NormalClass[\x0Fi\aI\"\nKlass" +
+ "\x06:\x06EFI\"\x15Namespace::Klass\x06;\x06FI" +
+ "\"\nSuper\x06;\x06Fo:\eRDoc::Markup::Document\a" +
+ ":\v@parts[\x06o;\a\a;\b[\x06o" +
+ ":\x1CRDoc::Markup::Paragraph\x06;\b" +
+ "[\x06I\"\x16this is a comment\x06;\x06F" +
+ ":\n@fileI\"\ffile.rb\x06;\x06F;\n0[\a[\nI" +
+ "\"\aa2\x06;\x06FI\"\aRW\x06;\x06F:\vpublicT@\x11" +
+ "[\nI\"\aa1\x06;\x06FI\"\aRW\x06;\x06F;\vF@\x11" +
+ "[\x06[\bI\"\aC1\x06;\x06Fo;\a\a;\b[\x00;\n0@\x11" +
+ "[\x06[\bI\"\aI1\x06;\x06Fo;\a\a;\b[\x00;\n0@\x11" +
+ "[\a[\aI\"\nclass\x06;\x06F[\b[\a;\v[\x00" +
+ "[\a:\x0Eprotected[\x00[\a:\fprivate[\x00[\aI" +
+ "\"\rinstance\x06;\x06F[\b[\a;\v[\x06[\aI" +
+ "\"\am1\x06;\x06F@\x11[\a;\f[\x00[\a;\r[\x00" +
+ "[\x06[\bI\"\aE1\x06;\x06Fo;\a\a;\b[\x00;\n0@\x11"
+
+ loaded.store = @store
+
+ assert_same @store, loaded.store
+
+ a = loaded.attributes.first
+ assert_same @store, a.store
+ assert_same @store, a.file.store
+
+ c = loaded.constants.first
+ assert_same @store, c.store
+ assert_same @store, c.file.store
+
+ i = loaded.includes.first
+ assert_same @store, i.store
+ assert_same @store, i.file.store
+
+ e = loaded.extends.first
+ assert_same @store, e.store
+ assert_same @store, e.file.store
+
+ m = loaded.method_list.first
+ assert_same @store, m.store
+ assert_same @store, m.file.store
+ end
+
def test_superclass
assert_equal @c3_h1, @c3_h2.superclass
end
@@ -668,6 +1263,30 @@ class TestRDocClassModule < XrefTestCase
assert_equal 'O1::A1', o1_a1_m.full_name
end
+ def test_update_aliases_reparent_root
+ store = RDoc::Store.new
+
+ top_level = store.add_file 'file.rb'
+
+ klass = top_level.add_class RDoc::NormalClass, 'Klass'
+ object = top_level.add_class RDoc::NormalClass, 'Object'
+
+ const = RDoc::Constant.new 'A', nil, ''
+ const.record_location top_level
+ const.is_alias_for = klass
+
+ top_level.add_module_alias klass, 'A', top_level
+
+ object.add_constant const
+
+ object.update_aliases
+
+ assert_equal %w[A Klass Object], store.classes_hash.keys.sort
+
+ assert_equal 'A', store.classes_hash['A'].full_name
+ assert_equal 'Klass', store.classes_hash['Klass'].full_name
+ end
+
def test_update_includes
a = RDoc::Include.new 'M1', nil
b = RDoc::Include.new 'M2', nil
@@ -681,16 +1300,30 @@ class TestRDocClassModule < XrefTestCase
@m1_m2.document_self = nil
assert @m1_m2.remove_from_documentation?
- assert RDoc::TopLevel.all_modules_hash.key? @m1_m2.full_name
- refute RDoc::TopLevel.all_modules_hash[@m1_m2.full_name].nil?
- RDoc::TopLevel.remove_nodoc RDoc::TopLevel.all_modules_hash
- refute RDoc::TopLevel.all_modules_hash.key? @m1_m2.full_name
+ assert @store.modules_hash.key? @m1_m2.full_name
+ refute @store.modules_hash[@m1_m2.full_name].nil?
+
+ @store.remove_nodoc @store.modules_hash
+ refute @store.modules_hash.key? @m1_m2.full_name
@c1.update_includes
assert_equal [a, c], @c1.includes
end
+ def test_update_includes_trim
+ a = RDoc::Include.new 'D::M', nil
+ b = RDoc::Include.new 'D::M', nil
+
+ @c1.add_include a
+ @c1.add_include b
+ @c1.ancestors # cache included modules
+
+ @c1.update_includes
+
+ assert_equal [a], @c1.includes
+ end
+
def test_update_includes_with_colons
a = RDoc::Include.new 'M1', nil
b = RDoc::Include.new 'M1::M2', nil
@@ -704,15 +1337,75 @@ class TestRDocClassModule < XrefTestCase
@m1_m2.document_self = nil
assert @m1_m2.remove_from_documentation?
- assert RDoc::TopLevel.all_modules_hash.key? @m1_m2.full_name
- refute RDoc::TopLevel.all_modules_hash[@m1_m2.full_name].nil?
- RDoc::TopLevel.remove_nodoc RDoc::TopLevel.all_modules_hash
- refute RDoc::TopLevel.all_modules_hash.key? @m1_m2.full_name
+ assert @store.modules_hash.key? @m1_m2.full_name
+ refute @store.modules_hash[@m1_m2.full_name].nil?
+ @store.remove_nodoc @store.modules_hash
+ refute @store.modules_hash.key? @m1_m2.full_name
@c1.update_includes
assert_equal [a, c], @c1.includes
end
+ def test_update_extends
+ a = RDoc::Extend.new 'M1', nil
+ b = RDoc::Extend.new 'M2', nil
+ c = RDoc::Extend.new 'C', nil
+
+ @c1.add_extend a
+ @c1.add_extend b
+ @c1.add_extend c
+ @c1.each_extend do |extend| extend.module end # cache extended modules
+
+ @m1_m2.document_self = nil
+ assert @m1_m2.remove_from_documentation?
+
+ assert @store.modules_hash.key? @m1_m2.full_name
+ refute @store.modules_hash[@m1_m2.full_name].nil?
+ @store.remove_nodoc @store.modules_hash
+ refute @store.modules_hash.key? @m1_m2.full_name
+
+ @c1.update_extends
+
+ assert_equal [a, c], @c1.extends
+ end
+
+ def test_update_extends_trim
+ a = RDoc::Extend.new 'D::M', nil
+ b = RDoc::Extend.new 'D::M', nil
+
+ @c1.add_extend a
+ @c1.add_extend b
+ @c1.each_extend do |extend| extend.module end # cache extended modules
+
+ @c1.update_extends
+
+ assert_equal [a], @c1.extends
+ end
+
+ def test_update_extends_with_colons
+ a = RDoc::Extend.new 'M1', nil
+ b = RDoc::Extend.new 'M1::M2', nil
+ c = RDoc::Extend.new 'C', nil
+
+ @c1.add_extend a
+ @c1.add_extend b
+ @c1.add_extend c
+ @c1.each_extend do |extend| extend.module end # cache extended modules
+
+ @m1_m2.document_self = nil
+ assert @m1_m2.remove_from_documentation?
+
+ assert @store.modules_hash.key? @m1_m2.full_name
+ refute @store.modules_hash[@m1_m2.full_name].nil?
+
+ @store.remove_nodoc @store.modules_hash
+ refute @store.modules_hash.key? @m1_m2.full_name
+
+ @c1.update_extends
+
+ assert_equal [a, c], @c1.extends
+ end
+
end
diff --git a/test/rdoc/test_rdoc_code_object.rb b/test/rdoc/test_rdoc_code_object.rb
index c7a37488cc..ef8a5df713 100644
--- a/test/rdoc/test_rdoc_code_object.rb
+++ b/test/rdoc/test_rdoc_code_object.rb
@@ -1,9 +1,6 @@
# coding: US-ASCII
-require 'rubygems'
-require 'minitest/autorun'
require File.expand_path '../xref_test_case', __FILE__
-require 'rdoc/code_object'
class TestRDocCodeObject < XrefTestCase
@@ -32,6 +29,16 @@ class TestRDocCodeObject < XrefTestCase
assert_equal 'I am a comment', @co.comment
end
+ def test_comment_equals_comment
+ @co.comment = comment ''
+
+ assert_equal '', @co.comment.text
+
+ @co.comment = comment 'I am a comment'
+
+ assert_equal 'I am a comment', @co.comment.text
+ end
+
def test_comment_equals_document
doc = RDoc::Markup::Document.new
@co.comment = doc
@@ -167,7 +174,7 @@ class TestRDocCodeObject < XrefTestCase
def test_file_name
assert_equal nil, @co.file_name
- @co.record_location RDoc::TopLevel.new 'lib/file.rb'
+ @co.record_location @store.add_file 'lib/file.rb'
assert_equal 'lib/file.rb', @co.file_name
end
@@ -256,6 +263,26 @@ class TestRDocCodeObject < XrefTestCase
refute @co.ignored?
end
+ def test_section
+ parent = RDoc::Context.new
+ section = parent.sections.first
+
+ @co.parent = parent
+ @co.instance_variable_set :@section, section
+
+ assert_equal section, @co.section
+
+ @co.instance_variable_set :@section, nil
+ @co.instance_variable_set :@section_title, nil
+
+ assert_equal section, @co.section
+
+ @co.instance_variable_set :@section, nil
+ @co.instance_variable_set :@section_title, 'new title'
+
+ assert_equal 'new title', @co.section.title
+ end
+
def test_start_doc
@co.document_self = false
@co.document_children = false
diff --git a/test/rdoc/test_rdoc_comment.rb b/test/rdoc/test_rdoc_comment.rb
new file mode 100644
index 0000000000..1afc94c251
--- /dev/null
+++ b/test/rdoc/test_rdoc_comment.rb
@@ -0,0 +1,504 @@
+# coding: us-ascii
+
+require 'rdoc/test_case'
+
+class TestRDocComment < RDoc::TestCase
+
+ def setup
+ super
+
+ @top_level = @store.add_file 'file.rb'
+ @comment = RDoc::Comment.new
+ @comment.location = @top_level
+ @comment.text = 'this is a comment'
+ end
+
+ def test_empty_eh
+ refute_empty @comment
+
+ @comment = ''
+
+ assert_empty @comment
+ end
+
+ def test_equals2
+ assert_equal @comment, @comment.dup
+
+ c2 = @comment.dup
+ c2.text = nil
+
+ refute_equal @comment, c2
+
+ c3 = @comment.dup
+ c3.location = nil
+
+ refute_equal @comment, c3
+ end
+
+ def test_extract_call_seq
+ m = RDoc::AnyMethod.new nil, 'm'
+
+ comment = RDoc::Comment.new <<-COMMENT, @top_level
+call-seq:
+ bla => true or false
+
+moar comment
+ COMMENT
+
+ comment.extract_call_seq m
+
+ assert_equal "bla => true or false\n", m.call_seq
+ end
+
+ def test_extract_call_seq_blank
+ m = RDoc::AnyMethod.new nil, 'm'
+
+ comment = RDoc::Comment.new <<-COMMENT, @top_level
+call-seq:
+ bla => true or false
+
+ COMMENT
+
+ comment.extract_call_seq m
+
+ assert_equal "bla => true or false\n", m.call_seq
+ end
+
+ def test_extract_call_seq_commented
+ m = RDoc::AnyMethod.new nil, 'm'
+
+ comment = RDoc::Comment.new <<-COMMENT, @top_level
+# call-seq:
+# bla => true or false
+#
+# moar comment
+ COMMENT
+
+ comment.extract_call_seq m
+
+ assert_equal nil, m.call_seq
+ end
+
+ def test_extract_call_seq_no_blank
+ m = RDoc::AnyMethod.new nil, 'm'
+
+ comment = RDoc::Comment.new <<-COMMENT, @top_level
+call-seq:
+ bla => true or false
+ COMMENT
+
+ comment.extract_call_seq m
+
+ assert_equal "bla => true or false\n", m.call_seq
+ end
+
+ def test_extract_call_seq_undent
+ m = RDoc::AnyMethod.new nil, 'm'
+
+ comment = RDoc::Comment.new <<-COMMENT, @top_level
+call-seq:
+ bla => true or false
+moar comment
+ COMMENT
+
+ comment.extract_call_seq m
+
+ assert_equal "bla => true or false\nmoar comment\n", m.call_seq
+ end
+
+ def test_extract_call_seq_c
+ comment = RDoc::Comment.new <<-COMMENT
+call-seq:
+ commercial() -> Date <br />
+ commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
+ commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
+
+If no arguments are given:
+* ruby 1.8: returns a +Date+ for 1582-10-15 (the Day of Calendar Reform in
+ Italy)
+* ruby 1.9: returns a +Date+ for julian day 0
+
+Otherwise, returns a +Date+ for the commercial week year, commercial week,
+and commercial week day given. Ignores the 4th argument.
+ COMMENT
+
+ method_obj = RDoc::AnyMethod.new nil, 'blah'
+
+ comment.extract_call_seq method_obj
+
+ expected = <<-CALL_SEQ.chomp
+commercial() -> Date <br />
+commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
+commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
+
+ CALL_SEQ
+
+ assert_equal expected, method_obj.call_seq
+ end
+
+ def test_extract_call_seq_c_no_blank
+ comment = RDoc::Comment.new <<-COMMENT
+call-seq:
+ commercial() -> Date <br />
+ commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
+ commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
+ COMMENT
+
+ method_obj = RDoc::AnyMethod.new nil, 'blah'
+
+ comment.extract_call_seq method_obj
+
+ expected = <<-CALL_SEQ.chomp
+commercial() -> Date <br />
+commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
+commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
+
+ CALL_SEQ
+
+ assert_equal expected, method_obj.call_seq
+ end
+
+ def test_extract_call_seq_c_separator
+ comment = RDoc::Comment.new <<-'COMMENT'
+call-seq:
+ ARGF.readlines(sep=$/) -> array
+ ARGF.readlines(limit) -> array
+ ARGF.readlines(sep, limit) -> array
+
+ ARGF.to_a(sep=$/) -> array
+ ARGF.to_a(limit) -> array
+ ARGF.to_a(sep, limit) -> array
+
+Reads +ARGF+'s current file in its entirety, returning an +Array+ of its
+lines, one line per element. Lines are assumed to be separated by _sep_.
+
+ lines = ARGF.readlines
+ lines[0] #=> "This is line one\n"
+
+ COMMENT
+
+ method_obj = RDoc::AnyMethod.new nil, 'blah'
+
+ comment.extract_call_seq method_obj
+
+ expected = <<-CALL_SEQ
+ARGF.readlines(sep=$/) -> array
+ARGF.readlines(limit) -> array
+ARGF.readlines(sep, limit) -> array
+ARGF.to_a(sep=$/) -> array
+ARGF.to_a(limit) -> array
+ARGF.to_a(sep, limit) -> array
+ CALL_SEQ
+
+ assert_equal expected, method_obj.call_seq
+
+ expected = <<-'COMMENT'
+
+Reads +ARGF+'s current file in its entirety, returning an +Array+ of its
+lines, one line per element. Lines are assumed to be separated by _sep_.
+
+ lines = ARGF.readlines
+ lines[0] #=> "This is line one\n"
+
+ COMMENT
+
+ assert_equal expected, comment.text
+ end
+
+ def test_force_encoding
+ skip "Encoding not implemented" unless Object.const_defined? :Encoding
+
+ @comment.force_encoding Encoding::UTF_8
+
+ assert_equal Encoding::UTF_8, @comment.text.encoding
+ end
+
+ def test_format
+ assert_equal 'rdoc', @comment.format
+ end
+
+ def test_format_equals
+ c = comment 'content'
+ document = c.parse
+
+ c.format = RDoc::RD
+
+ assert_equal RDoc::RD, c.format
+ refute_same document, c.parse
+ end
+
+ def test_initialize_copy
+ copy = @comment.dup
+
+ refute_same @comment.text, copy.text
+ assert_same @comment.location, copy.location
+ end
+
+ def test_location
+ assert_equal @top_level, @comment.location
+ end
+
+ def test_normalize
+ @comment.text = <<-TEXT
+ # comment
+ TEXT
+
+ assert_same @comment, @comment.normalize
+
+ assert_equal 'comment', @comment.text
+ end
+
+ def test_normalize_twice
+ @comment.text = <<-TEXT
+ # comment
+ TEXT
+
+ @comment.normalize
+
+ text = @comment.text
+
+ @comment.normalize
+
+ assert_same text, @comment.text, 'normalize not cached'
+ end
+
+ def test_normalize_document
+ @comment.text = nil
+ @comment.document = @RM::Document.new
+
+ assert_same @comment, @comment.normalize
+
+ assert_nil @comment.text
+ end
+
+ def test_normalize_eh
+ refute @comment.normalized?
+
+ @comment.normalize
+
+ assert @comment.normalized?
+ end
+
+ def test_text
+ assert_equal 'this is a comment', @comment.text
+ end
+
+ def test_text_equals
+ @comment.text = 'other'
+
+ assert_equal 'other', @comment.text
+ refute @comment.normalized?
+ end
+
+ def test_text_equals_no_text
+ c = RDoc::Comment.new nil, @top_level
+ c.document = @RM::Document.new
+
+ e = assert_raises RDoc::Error do
+ c.text = 'other'
+ end
+
+ assert_equal 'replacing document-only comment is not allowed', e.message
+ end
+
+ def test_text_equals_parsed
+ document = @comment.parse
+
+ @comment.text = 'other'
+
+ refute_equal document, @comment.parse
+ end
+
+ def test_tomdoc_eh
+ refute @comment.tomdoc?
+
+ @comment.format = 'tomdoc'
+
+ assert @comment.tomdoc?
+ end
+
+ def test_parse
+ parsed = @comment.parse
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new('this is a comment'))
+
+ expected.file = @top_level
+
+ assert_equal expected, parsed
+ assert_same parsed, @comment.parse
+ end
+
+ def test_parse_rd
+ c = comment 'it ((*works*))'
+ c.format = 'rd'
+
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('it <em>works</em>'))
+ expected.file = @top_level
+
+ assert_equal expected, c.parse
+ end
+
+ def test_remove_private_encoding
+ skip "Encoding not implemented" unless Object.const_defined? :Encoding
+
+ comment = RDoc::Comment.new <<-EOS, @top_level
+# This is text
+#--
+# this is private
+ EOS
+
+ comment.force_encoding Encoding::IBM437
+
+ comment.remove_private
+
+ assert_equal Encoding::IBM437, comment.text.encoding
+ end
+
+ def test_remove_private_hash
+ @comment.text = <<-TEXT
+#--
+# private
+#++
+# public
+ TEXT
+
+ @comment.remove_private
+
+ assert_equal "# public\n", @comment.text
+ end
+
+ def test_remove_private_hash_trail
+ comment = RDoc::Comment.new <<-EOS, @top_level
+# This is text
+#--
+# this is private
+ EOS
+
+ expected = RDoc::Comment.new <<-EOS, @top_level
+# This is text
+ EOS
+
+ comment.remove_private
+
+ assert_equal expected, comment
+ end
+
+ def test_remove_private_long
+ comment = RDoc::Comment.new <<-EOS, @top_level
+#-----
+#++
+# this is text
+#-----
+ EOS
+
+ expected = RDoc::Comment.new <<-EOS, @top_level
+# this is text
+ EOS
+
+ comment.remove_private
+
+ assert_equal expected, comment
+ end
+
+ def test_remove_private_rule
+ comment = RDoc::Comment.new <<-EOS, @top_level
+# This is text with a rule:
+# ---
+# this is also text
+ EOS
+
+ expected = comment.dup
+
+ comment.remove_private
+
+ assert_equal expected, comment
+ end
+
+ def test_remove_private_star
+ @comment.text = <<-TEXT
+/*
+ *--
+ * private
+ *++
+ * public
+ */
+ TEXT
+
+ @comment.remove_private
+
+ assert_equal "/*\n * public\n */\n", @comment.text
+ end
+
+ def test_remove_private_star2
+ @comment.text = <<-TEXT
+/*--
+ * private
+ *++
+ * public
+ */
+ TEXT
+
+ @comment.remove_private
+
+ assert_equal "/*--\n * private\n *++\n * public\n */\n", @comment.text
+ end
+
+ def test_remove_private_toggle
+ comment = RDoc::Comment.new <<-EOS, @top_level
+# This is text
+#--
+# this is private
+#++
+# This is text again.
+ EOS
+
+ expected = RDoc::Comment.new <<-EOS, @top_level
+# This is text
+# This is text again.
+ EOS
+
+ comment.remove_private
+
+ assert_equal expected, comment
+ end
+
+ def test_remove_private_toggle_encoding
+ skip "Encoding not implemented" unless Object.const_defined? :Encoding
+
+ comment = RDoc::Comment.new <<-EOS, @top_level
+# This is text
+#--
+# this is private
+#++
+# This is text again.
+ EOS
+
+ comment.force_encoding Encoding::IBM437
+
+ comment.remove_private
+
+ assert_equal Encoding::IBM437, comment.text.encoding
+ end
+
+ def test_remove_private_toggle_encoding_ruby_bug?
+ skip "Encoding not implemented" unless Object.const_defined? :Encoding
+
+ comment = RDoc::Comment.new <<-EOS, @top_level
+#--
+# this is private
+#++
+# This is text again.
+ EOS
+
+ comment.force_encoding Encoding::IBM437
+
+ comment.remove_private
+
+ assert_equal Encoding::IBM437, comment.text.encoding
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_constant.rb b/test/rdoc/test_rdoc_constant.rb
index b915f5cc7a..1a2e43a6e4 100644
--- a/test/rdoc/test_rdoc_constant.rb
+++ b/test/rdoc/test_rdoc_constant.rb
@@ -8,6 +8,138 @@ class TestRDocConstant < XrefTestCase
@const = @c1.constants.first
end
+ def test_full_name
+ assert_equal 'C1::CONST', @const.full_name
+ end
+
+ def test_is_alias_for
+ top_level = @store.add_file 'file.rb'
+
+ c = RDoc::Constant.new 'CONST', nil, 'comment'
+ top_level.add_constant c
+
+ assert_nil c.is_alias_for
+
+ c.is_alias_for = 'C1'
+
+ assert_equal @c1, c.is_alias_for
+
+ c.is_alias_for = 'unknown'
+
+ assert_equal 'unknown', c.is_alias_for
+ end
+
+ def test_marshal_dump
+ top_level = @store.add_file 'file.rb'
+
+ c = RDoc::Constant.new 'CONST', nil, 'this is a comment'
+ c.record_location top_level
+
+ aliased = top_level.add_class RDoc::NormalClass, 'Aliased'
+ c.is_alias_for = aliased
+
+ cm = top_level.add_class RDoc::NormalClass, 'Klass'
+ cm.add_constant c
+
+ section = cm.sections.first
+
+ loaded = Marshal.load Marshal.dump c
+ loaded.store = @store
+
+ comment = doc(para('this is a comment'))
+
+ assert_equal c, loaded
+
+ assert_equal aliased, loaded.is_alias_for
+ assert_equal comment, loaded.comment
+ assert_equal top_level, loaded.file
+ assert_equal 'Klass::CONST', loaded.full_name
+ assert_equal 'CONST', loaded.name
+ assert_nil loaded.visibility
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
+ end
+
+ def test_marshal_load
+ top_level = @store.add_file 'file.rb'
+
+ c = RDoc::Constant.new 'CONST', nil, 'this is a comment'
+ c.record_location top_level
+
+ cm = top_level.add_class RDoc::NormalClass, 'Klass'
+ cm.add_constant c
+
+ section = cm.sections.first
+
+ loaded = Marshal.load Marshal.dump c
+ loaded.store = @store
+
+ comment = doc(para('this is a comment'))
+
+ assert_equal c, loaded
+
+ assert_nil loaded.is_alias_for
+ assert_equal comment, loaded.comment
+ assert_equal top_level, loaded.file
+ assert_equal 'Klass::CONST', loaded.full_name
+ assert_equal 'CONST', loaded.name
+ assert_nil loaded.visibility
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
+ end
+
+ def test_marshal_load_version_0
+ top_level = @store.add_file 'file.rb'
+
+ aliased = top_level.add_class RDoc::NormalClass, 'Aliased'
+ cm = top_level.add_class RDoc::NormalClass, 'Klass'
+ section = cm.sections.first
+
+ loaded = Marshal.load "\x04\bU:\x13RDoc::Constant[\x0Fi\x00I" +
+ "\"\nCONST\x06:\x06ETI\"\x11Klass::CONST\x06" +
+ ";\x06T0I\"\fAliased\x06;\x06To" +
+ ":\eRDoc::Markup::Document\a:\v@parts[\x06o" +
+ ":\x1CRDoc::Markup::Paragraph\x06;\b[\x06I" +
+ "\"\x16this is a comment\x06;\x06T:\n@file0I" +
+ "\"\ffile.rb\x06;\x06TI\"\nKlass\x06" +
+ ";\x06Tc\x16RDoc::NormalClass0"
+
+ loaded.store = @store
+
+ comment = doc(para('this is a comment'))
+
+ assert_equal aliased, loaded.is_alias_for
+ assert_equal comment, loaded.comment
+ assert_equal top_level, loaded.file
+ assert_equal 'Klass::CONST', loaded.full_name
+ assert_equal 'CONST', loaded.name
+ assert_nil loaded.visibility
+ assert_equal cm, loaded.parent
+ assert_equal section, loaded.section
+ end
+
+ def test_marshal_round_trip
+ top_level = @store.add_file 'file.rb'
+
+ c = RDoc::Constant.new 'CONST', nil, 'this is a comment'
+ c.record_location top_level
+ c.is_alias_for = 'Unknown'
+
+ cm = top_level.add_class RDoc::NormalClass, 'Klass'
+ cm.add_constant c
+
+ section = cm.sections.first
+
+ loaded = Marshal.load Marshal.dump c
+ loaded.store = @store
+
+ reloaded = Marshal.load Marshal.dump loaded
+ reloaded.store = @store
+
+ assert_equal section, reloaded.section
+ assert_equal 'Unknown', reloaded.is_alias_for
+ end
+
def test_path
assert_equal 'C1.html#CONST', @const.path
end
diff --git a/test/rdoc/test_rdoc_context.rb b/test/rdoc/test_rdoc_context.rb
index 2fb8ef7bb7..bd0baaa725 100644
--- a/test/rdoc/test_rdoc_context.rb
+++ b/test/rdoc/test_rdoc_context.rb
@@ -1,5 +1,3 @@
-require 'rubygems'
-require 'minitest/autorun'
require File.expand_path '../xref_test_case', __FILE__
class TestRDocContext < XrefTestCase
@@ -8,6 +6,10 @@ class TestRDocContext < XrefTestCase
super
@context = RDoc::Context.new
+ @context.store = @store
+
+ @enumerator = # 1.8 vs 1.9
+ Object.const_defined?(:Enumerator) ? Enumerator : Enumerable::Enumerator
end
def test_initialize
@@ -40,7 +42,7 @@ class TestRDocContext < XrefTestCase
end
def test_add_alias_method_attr
- top_level = RDoc::TopLevel.new 'file.rb'
+ top_level = @store.add_file 'file.rb'
attr = RDoc::Attr.new nil, 'old_name', 'R', ''
@@ -60,7 +62,7 @@ class TestRDocContext < XrefTestCase
end
def test_add_alias_method
- top_level = RDoc::TopLevel.new 'file.rb'
+ top_level = @store.add_file 'file.rb'
meth = RDoc::AnyMethod.new nil, 'old_name'
meth.singleton = false
@@ -103,7 +105,7 @@ class TestRDocContext < XrefTestCase
@c1.add_class RDoc::NormalClass, 'Klass', 'Object'
assert_includes @c1.classes.map { |k| k.full_name }, 'C1::Klass'
- assert_includes RDoc::TopLevel.classes.map { |k| k.full_name }, 'C1::Klass'
+ assert_includes @store.all_classes.map { |k| k.full_name }, 'C1::Klass'
end
def test_add_class_basic_object
@@ -142,7 +144,7 @@ class TestRDocContext < XrefTestCase
@c1.add_class RDoc::NormalClass, 'Klass', 'Object'
assert_includes @c1.classes.map { |k| k.full_name }, 'C1::Klass'
- assert_includes RDoc::TopLevel.classes.map { |k| k.full_name }, 'C1::Klass'
+ assert_includes @store.all_classes.map { |k| k.full_name }, 'C1::Klass'
end
def test_add_class_superclass
@@ -163,9 +165,9 @@ class TestRDocContext < XrefTestCase
refute_includes @c1.modules.map { |k| k.full_name }, 'C1::Klass',
'c1 modules'
- assert_includes RDoc::TopLevel.classes.map { |k| k.full_name }, 'C1::Klass',
+ assert_includes @store.all_classes.map { |k| k.full_name }, 'C1::Klass',
'TopLevel classes'
- refute_includes RDoc::TopLevel.modules.map { |k| k.full_name }, 'C1::Klass',
+ refute_includes @store.all_modules.map { |k| k.full_name }, 'C1::Klass',
'TopLevel modules'
end
@@ -176,6 +178,13 @@ class TestRDocContext < XrefTestCase
assert_equal [const], @context.constants
end
+ def test_add_extend
+ ext = RDoc::Extend.new 'Name', 'comment'
+ @context.add_extend ext
+
+ assert_equal [ext], @context.extends
+ end
+
def test_add_include
incl = RDoc::Include.new 'Name', 'comment'
@context.add_include incl
@@ -183,16 +192,6 @@ class TestRDocContext < XrefTestCase
assert_equal [incl], @context.includes
end
- def test_add_include_twice
- incl1 = RDoc::Include.new 'Name', 'comment'
- @context.add_include incl1
-
- incl2 = RDoc::Include.new 'Name', 'comment'
- @context.add_include incl2
-
- assert_equal [incl1], @context.includes
- end
-
def test_add_method
meth = RDoc::AnyMethod.new nil, 'old_name'
meth.visibility = nil
@@ -217,6 +216,34 @@ class TestRDocContext < XrefTestCase
assert_equal %w[old_name new_name], @context.method_list.map { |m| m.name }
end
+ def test_add_method_duplicate
+ @store.rdoc.options.verbosity = 2
+
+ meth1 = RDoc::AnyMethod.new nil, 'name'
+ meth1.record_location @store.add_file 'first.rb'
+ meth1.visibility = nil
+ meth1.comment = comment 'first'
+
+ @context.add_method meth1
+
+ meth2 = RDoc::AnyMethod.new nil, 'name'
+ meth2.record_location @store.add_file 'second.rb'
+ meth2.comment = comment 'second'
+
+ _, err = capture_io do
+ @context.add_method meth2
+ end
+
+ expected = 'Duplicate method (unknown)#name in file second.rb, ' \
+ 'previously in file first.rb'
+
+ assert_equal expected, err.chomp
+
+ method = @context.method_list.first
+
+ assert_equal 'first', method.comment.text
+ end
+
def test_add_module
@c1.add_module RDoc::NormalModule, 'Mod'
@@ -224,18 +251,35 @@ class TestRDocContext < XrefTestCase
end
def test_add_module_alias
- tl = RDoc::TopLevel.new 'file.rb'
+ tl = @store.add_file 'file.rb'
c3_c4 = @c2.add_module_alias @c2_c3, 'C4', tl
- c4 = @c2.find_module_named('C4')
-
alias_constant = @c2.constants.first
- assert_equal c4, c3_c4
+ assert_equal 'C2::C4', c3_c4.full_name
assert_equal tl, alias_constant.file
end
+ def test_add_module_alias_top_level
+ store = RDoc::Store.new
+
+ top_level = store.add_file 'file.rb'
+
+ klass = top_level.add_class RDoc::NormalClass, 'Klass'
+ klass.comment = 'klass comment'
+
+ object = top_level.add_class RDoc::NormalClass, 'Object'
+
+ top_level.add_module_alias klass, 'A', top_level
+
+ refute_empty object.constants
+
+ constant = object.constants.first
+
+ assert_equal 'klass comment', constant.comment
+ end
+
def test_add_module_class
k = @c1.add_class RDoc::NormalClass, 'Klass', nil
m = @c1.add_module RDoc::NormalModule, 'Klass'
@@ -255,18 +299,20 @@ class TestRDocContext < XrefTestCase
def test_add_section
default_section = @context.sections.first
- @context.add_section nil, '# comment'
+ @context.add_section nil, comment('comment', @top_level)
assert_equal 1, @context.sections.length
- assert_equal '# comment', @context.sections.first.comment
+ assert_equal [comment("comment", @top_level)],
+ @context.sections.first.comments
- @context.add_section nil, '# new comment'
+ @context.add_section nil, comment('new comment', @top_level)
assert_equal 1, @context.sections.length
- assert_equal "# comment\n# ---\n# new comment",
- @context.sections.first.comment
+ assert_equal [comment('comment', @top_level),
+ comment('new comment', @top_level)],
+ @context.sections.first.comments
- @context.add_section 'other', ''
+ @context.add_section 'other', comment('', @top_level)
assert_equal 2, @context.sections.length
@@ -275,6 +321,23 @@ class TestRDocContext < XrefTestCase
assert_equal default_section, @context.current_section
end
+ def test_add_section_no_comment
+ default_section = @context.sections.first
+
+ @context.add_section nil
+
+ assert_equal 1, @context.sections.length
+
+ @context.add_section 'other'
+
+ assert_equal 2, @context.sections.length
+
+ new_section = @context.sections.find { |section| section.title == 'other' }
+
+ assert new_section
+ assert_equal default_section, @context.current_section
+ end
+
def test_add_to
incl = RDoc::Include.new 'Name', 'comment'
arr = []
@@ -288,7 +351,8 @@ class TestRDocContext < XrefTestCase
def test_add_to_temporary_section
incl = RDoc::Include.new 'Name', 'comment'
arr = []
- section = @context.add_section 'temporary', ''
+ section =
+ @context.add_section 'temporary', RDoc::Comment.new('', @top_level)
@context.temporary_section = section
@context.add_to arr, incl
@@ -316,19 +380,30 @@ class TestRDocContext < XrefTestCase
refute_includes arr, incl
end
+ def bench_add_include
+ cm = RDoc::ClassModule.new 'Klass'
+
+ assert_performance_linear 0.9 do |count|
+ count.times do |i|
+ cm.add_include RDoc::Include.new("N::M#{i}", nil)
+ end
+ end
+ end
+
def test_child_name
assert_equal 'C1::C1', @c1.child_name('C1')
end
def test_classes
assert_equal %w[C2::C3], @c2.classes.map { |k| k.full_name }
- assert_equal %w[C3::H1 C3::H2], @c3.classes.map { |k| k.full_name }
+ assert_equal %w[C3::H1 C3::H2], @c3.classes.map { |k| k.full_name }.sort
end
def test_current_section
default_section = @context.current_section
- new_section = @context.add_section 'other', ''
+ new_section =
+ @context.add_section 'other', RDoc::Comment.new('', @top_level)
@context.temporary_section = new_section
assert_equal new_section, @context.current_section
@@ -338,7 +413,7 @@ class TestRDocContext < XrefTestCase
def test_defined_in_eh
assert @c1.defined_in?(@c1.top_level)
- refute @c1.defined_in?(RDoc::TopLevel.new('name.rb'))
+ refute @c1.defined_in?(@store.add_file('name.rb'))
end
def test_equals2
@@ -347,6 +422,10 @@ class TestRDocContext < XrefTestCase
refute_equal @c2_c3, @c3
end
+ def test_each_method_enumerator
+ assert_kind_of @enumerator, @c1.each_method
+ end
+
def test_each_section
sects = []
consts = []
@@ -375,6 +454,10 @@ class TestRDocContext < XrefTestCase
assert_equal expected_attrs, attrs
end
+ def test_each_section_enumerator
+ assert_kind_of @enumerator, @c1.each_section
+ end
+
def test_find_attribute_named
assert_equal nil, @c1.find_attribute_named('none')
assert_equal 'R', @c1.find_attribute_named('attr').rw
@@ -448,6 +531,16 @@ class TestRDocContext < XrefTestCase
assert_equal @c1__m, @c1.find_symbol('::m')
end
+ def test_find_symbol_module
+ assert_nil @m1_m2.find_symbol_module 'N'
+ assert_nil @m1_m2.find_symbol_module 'M2::M1'
+
+ @m1_m2.parent = nil # loaded from legacy ri store
+
+ assert_nil @m1_m2.find_symbol_module 'N'
+ assert_nil @m1_m2.find_symbol_module 'M2::M1'
+ end
+
def test_fully_documented_eh
context = RDoc::Context.new
@@ -650,14 +743,51 @@ class TestRDocContext < XrefTestCase
assert_equal [@pub, @prot, @priv], methods
end
+ def test_section_contents
+ default = @context.sections.first
+ @context.add_method RDoc::AnyMethod.new(nil, 'm1')
+
+ b = @context.add_section 'B'
+ m = @context.add_method RDoc::AnyMethod.new(nil, 'm2')
+ m.section = b
+
+ assert_equal [default, b], @context.section_contents
+ end
+
+ def test_section_contents_no_default
+ @context = RDoc::Context.new
+ b = @context.add_section 'B'
+ m = @context.add_method RDoc::AnyMethod.new(nil, 'm')
+ m.section = b
+
+ assert_equal [b], @context.section_contents
+ end
+
+ def test_section_contents_only_default
+ @context = RDoc::Context.new
+
+ @context.add_method RDoc::AnyMethod.new(nil, 'm')
+
+ assert_empty @context.section_contents
+ end
+
+ def test_section_contents_unused
+ @context = RDoc::Context.new
+
+ @context.add_method RDoc::AnyMethod.new(nil, 'm')
+ @context.add_section 'B'
+
+ assert_empty @context.section_contents
+ end
+
def test_set_current_section
default_section = @context.sections.first
- @context.set_current_section nil, ''
+ @context.set_current_section nil, RDoc::Comment.new('', @top_level)
assert_equal default_section, @context.current_section
- @context.set_current_section 'other', ''
+ @context.set_current_section 'other', RDoc::Comment.new('', @top_level)
new_section = @context.sections.find { |section|
section != default_section
@@ -666,6 +796,38 @@ class TestRDocContext < XrefTestCase
assert_equal new_section, @context.current_section
end
+ def test_sort_sections
+ c = RDoc::Context.new
+ c.add_section 'C'
+ c.add_section 'A'
+ c.add_section 'B'
+
+ titles = c.sort_sections.map { |section| section.title }
+
+ assert_equal [nil, 'A', 'B', 'C'], titles
+ end
+
+ def test_sort_sections_tomdoc
+ c = RDoc::Context.new
+ c.add_section 'Public'
+ c.add_section 'Internal'
+ c.add_section 'Deprecated'
+
+ titles = c.sort_sections.map { |section| section.title }
+
+ assert_equal [nil, 'Public', 'Internal', 'Deprecated'], titles
+ end
+
+ def test_sort_sections_tomdoc_missing
+ c = RDoc::Context.new
+ c.add_section 'Internal'
+ c.add_section 'Public'
+
+ titles = c.sort_sections.map { |section| section.title }
+
+ assert_equal [nil, 'Public', 'Internal'], titles
+ end
+
def util_visibilities
@pub = RDoc::AnyMethod.new nil, 'pub'
@prot = RDoc::AnyMethod.new nil, 'prot'
diff --git a/test/rdoc/test_rdoc_context_section.rb b/test/rdoc/test_rdoc_context_section.rb
index d37a4d222e..716d3ae6bb 100644
--- a/test/rdoc/test_rdoc_context_section.rb
+++ b/test/rdoc/test_rdoc_context_section.rb
@@ -1,14 +1,49 @@
-require 'rubygems'
-require 'cgi'
-require 'minitest/autorun'
-require 'rdoc'
-require 'rdoc/code_objects'
+require 'rdoc/test_case'
-class TestRDocContextSection < MiniTest::Unit::TestCase
+class TestRDocContextSection < RDoc::TestCase
def setup
+ super
+
+ @top_level = @store.add_file 'file.rb'
+
+ @klass = @top_level.add_class RDoc::NormalClass, 'Object'
+
@S = RDoc::Context::Section
- @s = @S.new nil, 'section', '# comment'
+ @s = @S.new @klass, 'section', comment('# comment', @top_level)
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
+ def test_add_comment
+ file1 = @store.add_file 'file1.rb'
+
+ klass = file1.add_class RDoc::NormalClass, 'Klass'
+
+ c1 = RDoc::Comment.new "# :section: section\n", file1
+ c2 = RDoc::Comment.new "# hello\n", file1
+ c3 = RDoc::Comment.new "# world\n", file1
+
+ s = @S.new klass, 'section', c1
+
+ assert_empty s.comments
+
+ s.add_comment nil
+
+ assert_empty s.comments
+
+ s.add_comment c2
+
+ assert_equal [c2], s.comments
+
+ s.add_comment c3
+
+ assert_equal [c2, c3], s.comments
end
def test_aref
@@ -19,27 +54,75 @@ class TestRDocContextSection < MiniTest::Unit::TestCase
assert_equal 'one+two', @S.new(nil, 'one two', nil).aref
end
- def test_comment_equals
- @s.comment = "# :section: section\n"
+ def test_extract_comment
+ assert_equal '', @s.extract_comment(comment('')).text
+ assert_equal '', @s.extract_comment(comment("# :section: b\n")).text
+ assert_equal '# c', @s.extract_comment(comment("# :section: b\n# c")).text
+ assert_equal '# c',
+ @s.extract_comment(comment("# a\n# :section: b\n# c")).text
+ end
+
+ def test_marshal_dump
+ loaded = Marshal.load Marshal.dump @s
- assert_equal "# comment", @s.comment
+ expected = RDoc::Comment.new('comment', @top_level).parse
+ expected = doc(expected)
- @s.comment = "# :section: section\n# other"
+ assert_equal 'section', loaded.title
+ assert_equal expected, loaded.comments
+ assert_nil loaded.parent, 'parent is set manually'
+ end
- assert_equal "# comment\n# ---\n# other", @s.comment
+ def test_marshal_dump_no_comment
+ s = @S.new @klass, 'section', comment('')
- s = @S.new nil, nil, nil
+ loaded = Marshal.load Marshal.dump s
+
+ assert_equal 'section', loaded.title
+ assert_empty loaded.comments
+ assert_nil loaded.parent, 'parent is set manually'
+ end
- s.comment = "# :section:\n# other"
+ def test_marshal_load_version_0
+ loaded = Marshal.load "\x04\bU:\eRDoc::Context::Section" +
+ "[\bi\x00I\"\fsection\x06:\x06EFo" +
+ ":\eRDoc::Markup::Document\a:\v@parts" +
+ "[\x06o;\a\a;\b[\x06o" +
+ ":\x1CRDoc::Markup::Paragraph\x06;\b" +
+ "[\x06I\"\fcomment\x06;\x06F:\n@fileI" +
+ "\"\ffile.rb\x06;\x06F;\n0"
- assert_equal "# other", s.comment
+ expected = doc RDoc::Comment.new('comment', @top_level).parse
+
+ assert_equal 'section', loaded.title
+ assert_equal expected, loaded.comments
+ assert_nil loaded.parent, 'parent is set manually'
end
- def test_extract_comment
- assert_equal '', @s.extract_comment('')
- assert_equal '', @s.extract_comment("# :section: b\n")
- assert_equal '# c', @s.extract_comment("# :section: b\n# c")
- assert_equal '# c', @s.extract_comment("# a\n# :section: b\n# c")
+ def test_remove_comment_array
+ other = @store.add_file 'other.rb'
+
+ other_comment = comment('bogus', other)
+
+ @s.add_comment other_comment
+
+ @s.remove_comment comment('bogus', @top_level)
+
+ assert_equal [other_comment], @s.comments
+ end
+
+ def test_remove_comment_document
+ other = @store.add_file 'other.rb'
+
+ other_comment = comment('bogus', other)
+
+ @s.add_comment other_comment
+
+ loaded = Marshal.load Marshal.dump @s
+
+ loaded.remove_comment comment('bogus', @top_level)
+
+ assert_equal doc(other_comment.parse), loaded.comments
end
def test_sequence
diff --git a/test/rdoc/test_rdoc_cross_reference.rb b/test/rdoc/test_rdoc_cross_reference.rb
index 06062ba125..45afd80d31 100644
--- a/test/rdoc/test_rdoc_cross_reference.rb
+++ b/test/rdoc/test_rdoc_cross_reference.rb
@@ -1,5 +1,3 @@
-require 'rubygems'
-require 'minitest/autorun'
require File.expand_path '../xref_test_case', __FILE__
class TestRDocCrossReference < XrefTestCase
@@ -95,7 +93,7 @@ class TestRDocCrossReference < XrefTestCase
end
def test_resolve_file
- assert_ref @xref_data, 'xref_data.rb'
+ refute_ref 'xref_data.rb'
end
def test_resolve_method
@@ -131,6 +129,30 @@ class TestRDocCrossReference < XrefTestCase
assert_ref @c2_c3_m, '::C2::C3#m(*)'
end
+ def test_resolve_page
+ page = @store.add_file 'README.txt'
+ page.parser = RDoc::Parser::Simple
+
+ assert_ref page, 'README'
+ end
+
+ def test_resolve_percent
+ i_percent = RDoc::AnyMethod.new nil, '%'
+ i_percent.singleton = false
+ @c1.add_method i_percent
+
+ c_percent = RDoc::AnyMethod.new nil, '%'
+ c_percent.singleton = true
+ @c1.add_method c_percent
+
+ assert_ref i_percent, '%'
+ assert_ref i_percent, '#%'
+ assert_ref c_percent, '::%'
+
+ assert_ref i_percent, 'C1#%'
+ assert_ref c_percent, 'C1::%'
+ end
+
def test_resolve_no_ref
assert_equal '', @xref.resolve('', '')
diff --git a/test/rdoc/test_rdoc_encoding.rb b/test/rdoc/test_rdoc_encoding.rb
index b5ffd7714c..d43bc2e244 100644
--- a/test/rdoc/test_rdoc_encoding.rb
+++ b/test/rdoc/test_rdoc_encoding.rb
@@ -1,15 +1,12 @@
# coding: US-ASCII
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc'
-require 'rdoc/encoding'
+require 'rdoc/test_case'
-require 'tempfile'
-
-class TestRDocEncoding < MiniTest::Unit::TestCase
+class TestRDocEncoding < RDoc::TestCase
def setup
+ super
+
@tempfile = Tempfile.new 'test_rdoc_encoding'
end
@@ -100,6 +97,22 @@ class TestRDocEncoding < MiniTest::Unit::TestCase
assert_equal Encoding::UTF_8, content.encoding
end
+ def test_class_read_file_encoding_invalid
+ skip "Encoding not implemented" unless Object.const_defined? :Encoding
+
+ @tempfile.write "# coding: ascii\nM\xE4r"
+ @tempfile.flush
+
+ contents = :junk
+ _, err = capture_io do
+ contents = RDoc::Encoding.read_file @tempfile.path, Encoding::UTF_8
+ end
+
+ assert_equal "unable to convert \"\\xE4\" on US-ASCII for #{@tempfile.path}, skipping\n", err
+
+ assert_nil contents
+ end
+
def test_class_read_file_encoding_with_signature
skip "Encoding not implemented" unless defined? ::Encoding
diff --git a/test/rdoc/test_rdoc_extend.rb b/test/rdoc/test_rdoc_extend.rb
new file mode 100644
index 0000000000..149931549d
--- /dev/null
+++ b/test/rdoc/test_rdoc_extend.rb
@@ -0,0 +1,94 @@
+require File.expand_path '../xref_test_case', __FILE__
+
+class TestRDocExtend < XrefTestCase
+
+ def setup
+ super
+
+ @ext = RDoc::Extend.new 'M1', 'comment'
+ @ext.parent = @m1
+ @ext.store = @store
+ end
+
+ def test_module
+ assert_equal @m1, @ext.module
+ assert_equal 'Unknown', RDoc::Extend.new('Unknown', 'comment').module
+ end
+
+ def test_module_extended
+ m1 = @xref_data.add_module RDoc::NormalModule, 'Mod1'
+ m1.add_module RDoc::NormalModule, 'Mod3'
+ m1_m2 = m1.add_module RDoc::NormalModule, 'Mod2'
+ m1_m2_m3 = m1_m2.add_module RDoc::NormalModule, 'Mod3'
+ m1_m2_m3.add_module RDoc::NormalModule, 'Mod4'
+ m1_m2.add_module RDoc::NormalModule, 'Mod4'
+ m1_m2_k0 = m1_m2.add_class RDoc::NormalClass, 'Klass0'
+ m1_m2_k0_m4 = m1_m2_k0.add_module RDoc::NormalModule, 'Mod4'
+ m1_m2_k0_m4.add_module RDoc::NormalModule, 'Mod6'
+ m1_m2_k0.add_module RDoc::NormalModule, 'Mod5'
+
+ e0_m4 = RDoc::Extend.new 'Mod4', nil
+ e0_m5 = RDoc::Extend.new 'Mod5', nil
+ e0_m6 = RDoc::Extend.new 'Mod6', nil
+ e0_m1 = RDoc::Extend.new 'Mod1', nil
+ e0_m2 = RDoc::Extend.new 'Mod2', nil
+ e0_m3 = RDoc::Extend.new 'Mod3', nil
+
+ m1_m2_k0.add_extend e0_m4
+ m1_m2_k0.add_extend e0_m5
+ m1_m2_k0.add_extend e0_m6
+ m1_m2_k0.add_extend e0_m1
+ m1_m2_k0.add_extend e0_m2
+ m1_m2_k0.add_extend e0_m3
+
+ assert_equal [e0_m4, e0_m5, e0_m6, e0_m1, e0_m2, e0_m3], m1_m2_k0.extends
+ assert_equal ['Object'], m1_m2_k0.ancestors
+
+ m1_k1 = m1.add_class RDoc::NormalClass, 'Klass1'
+
+ e1_m1 = RDoc::Extend.new 'Mod1', nil
+ e1_m2 = RDoc::Extend.new 'Mod2', nil
+ e1_m3 = RDoc::Extend.new 'Mod3', nil
+ e1_m4 = RDoc::Extend.new 'Mod4', nil
+ e1_k0_m4 = RDoc::Extend.new 'Klass0::Mod4', nil
+
+ m1_k1.add_extend e1_m1
+ m1_k1.add_extend e1_m2
+ m1_k1.add_extend e1_m3
+ m1_k1.add_extend e1_m4
+ m1_k1.add_extend e1_k0_m4
+
+ assert_equal [e1_m1, e1_m2, e1_m3, e1_m4, e1_k0_m4], m1_k1.extends
+ assert_equal ['Object'], m1_k1.ancestors
+
+ m1_k2 = m1.add_class RDoc::NormalClass, 'Klass2'
+
+ e2_m1 = RDoc::Extend.new 'Mod1', nil
+ e2_m2 = RDoc::Extend.new 'Mod2', nil
+ e2_m3 = RDoc::Extend.new 'Mod3', nil
+ e2_k0_m4 = RDoc::Extend.new 'Klass0::Mod4', nil
+
+ m1_k2.add_extend e2_m1
+ m1_k2.add_extend e2_m3
+ m1_k2.add_extend e2_m2
+ m1_k2.add_extend e2_k0_m4
+
+ assert_equal [e2_m1, e2_m3, e2_m2, e2_k0_m4], m1_k2.extends
+ assert_equal ['Object'], m1_k2.ancestors
+
+ m1_k3 = m1.add_class RDoc::NormalClass, 'Klass3'
+
+ e3_m1 = RDoc::Extend.new 'Mod1', nil
+ e3_m2 = RDoc::Extend.new 'Mod2', nil
+ e3_m4 = RDoc::Extend.new 'Mod4', nil
+
+ m1_k3.add_extend e3_m1
+ m1_k3.add_extend e3_m2
+ m1_k3.add_extend e3_m4
+
+ assert_equal [e3_m1, e3_m2, e3_m4], m1_k3.extends
+ assert_equal ['Object'], m1_k3.ancestors
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_generator_darkfish.rb b/test/rdoc/test_rdoc_generator_darkfish.rb
index faea1ae34a..d1c2f66665 100644
--- a/test/rdoc/test_rdoc_generator_darkfish.rb
+++ b/test/rdoc/test_rdoc_generator_darkfish.rb
@@ -1,16 +1,12 @@
-require 'minitest/autorun'
-require 'rdoc/rdoc'
-require 'rdoc/generator/darkfish'
-require 'tmpdir'
-require 'fileutils'
+require 'rdoc/test_case'
-class TestRDocGeneratorDarkfish < MiniTest::Unit::TestCase
+class TestRDocGeneratorDarkfish < RDoc::TestCase
def setup
- @pwd = Dir.pwd
+ super
+
@lib_dir = "#{@pwd}/lib"
$LOAD_PATH.unshift @lib_dir # ensure we load from this RDoc
- RDoc::TopLevel.reset
@options = RDoc::Options.new
@options.option_parser = OptionParser.new
@@ -22,22 +18,27 @@ class TestRDocGeneratorDarkfish < MiniTest::Unit::TestCase
@options.generator = RDoc::Generator::Darkfish
$LOAD_PATH.each do |path|
- darkfish_dir = File.join path, 'rdoc/generator/template/darkfish'
+ darkfish_dir = File.join path, 'rdoc/generator/template/darkfish/'
next unless File.directory? darkfish_dir
@options.template_dir = darkfish_dir
break
end
- rd = RDoc::RDoc.new
- rd.options = @options
- RDoc::RDoc.current = rd
+ @rdoc.options = @options
+
+ @g = @options.generator.new @store, @options
+ @rdoc.generator = @g
+
+ @top_level = @store.add_file 'file.rb'
+ @top_level.parser = RDoc::Parser::Ruby
+ @klass = @top_level.add_class RDoc::NormalClass, 'Klass'
- @g = @options.generator.new @options
+ @alias_constant = RDoc::Constant.new 'A', nil, ''
+ @alias_constant.record_location @top_level
- rd.generator = @g
+ @top_level.add_constant @alias_constant
- @top_level = RDoc::TopLevel.new 'file.rb'
- @klass = @top_level.add_class RDoc::NormalClass, 'Object'
+ @klass.add_module_alias @klass, 'A', @top_level
@meth = RDoc::AnyMethod.new nil, 'method'
@meth_bang = RDoc::AnyMethod.new nil, 'method!'
@@ -49,9 +50,16 @@ class TestRDocGeneratorDarkfish < MiniTest::Unit::TestCase
@ignored = @top_level.add_class RDoc::NormalClass, 'Ignored'
@ignored.ignore
+
+ @store.complete :private
+
+ @object = @store.find_class_or_module 'Object'
+ @klass_alias = @store.find_class_or_module 'Klass::A'
end
def teardown
+ super
+
$LOAD_PATH.shift
Dir.chdir @pwd
FileUtils.rm_rf @tmpdir
@@ -65,15 +73,23 @@ class TestRDocGeneratorDarkfish < MiniTest::Unit::TestCase
refute File.exist?(path), "#{path} exists"
end
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
def test_generate
- top_level = RDoc::TopLevel.new 'file.rb'
+ top_level = @store.add_file 'file.rb'
top_level.add_class @klass.class, @klass.name
- @g.generate [top_level]
+ @g.generate
assert_file 'index.html'
assert_file 'Object.html'
- assert_file 'file_rb.html'
+ assert_file 'table_of_contents.html'
+ assert_file 'js/search_index.js'
encoding = if Object.const_defined? :Encoding then
Regexp.escape Encoding.default_external.name
@@ -85,37 +101,73 @@ class TestRDocGeneratorDarkfish < MiniTest::Unit::TestCase
File.read('index.html'))
assert_match(/<meta content="text\/html; charset=#{encoding}"/,
File.read('Object.html'))
- assert_match(/<meta content="text\/html; charset=#{encoding}"/,
- File.read('file_rb.html'))
refute_match(/Ignored/, File.read('index.html'))
end
def test_generate_dry_run
- @options.dry_run = true
- top_level = RDoc::TopLevel.new 'file.rb'
+ @g.dry_run = true
+ top_level = @store.add_file 'file.rb'
top_level.add_class @klass.class, @klass.name
- @g.generate [top_level]
+ @g.generate
refute_file 'index.html'
refute_file 'Object.html'
- refute_file 'file_rb.html'
+ end
+
+ def test_generate_static
+ FileUtils.mkdir_p 'dir/images'
+ FileUtils.touch 'dir/images/image.png'
+ FileUtils.mkdir_p 'file'
+ FileUtils.touch 'file/file.txt'
+
+ @options.static_path = [
+ File.expand_path('dir'),
+ File.expand_path('file/file.txt'),
+ ]
+
+ @g.generate
+
+ assert_file 'images/image.png'
+ assert_file 'file.txt'
+ end
+
+ def test_generate_static_dry_run
+ FileUtils.mkdir 'static'
+ FileUtils.touch 'static/image.png'
+
+ @options.static_path = [File.expand_path('static')]
+ @g.dry_run = true
+
+ @g.generate
+
+ refute_file 'image.png'
+ end
+
+ def test_setup
+ @g.setup
+
+ assert_equal [@klass_alias, @ignored, @klass, @object],
+ @g.classes.sort_by { |klass| klass.full_name }
+ assert_equal [@top_level], @g.files
+ assert_equal [@meth, @meth, @meth_bang, @meth_bang], @g.methods
+ assert_equal [@klass_alias, @klass, @object], @g.modsort
end
def test_template_for
- classpage = Pathname.new @options.template_dir + '/classpage.rhtml'
+ classpage = Pathname.new @options.template_dir + 'class.rhtml'
- template = @g.send(:template_for, classpage)
+ template = @g.send(:template_for, classpage, true, RDoc::ERBIO)
assert_kind_of RDoc::ERBIO, template
assert_same template, @g.send(:template_for, classpage)
end
def test_template_for_dry_run
- classpage = Pathname.new @options.template_dir + '/classpage.rhtml'
+ classpage = Pathname.new @options.template_dir + 'class.rhtml'
- template = @g.send(:template_for, classpage)
+ template = @g.send(:template_for, classpage, true, ERB)
assert_kind_of ERB, template
assert_same template, @g.send(:template_for, classpage)
diff --git a/test/rdoc/test_rdoc_generator_json_index.rb b/test/rdoc/test_rdoc_generator_json_index.rb
new file mode 100644
index 0000000000..717159eeda
--- /dev/null
+++ b/test/rdoc/test_rdoc_generator_json_index.rb
@@ -0,0 +1,275 @@
+# coding: US-ASCII
+
+require 'rdoc/test_case'
+
+class TestRDocGeneratorJsonIndex < RDoc::TestCase
+
+ def setup
+ super
+
+ @tmpdir = File.join Dir.tmpdir, "test_rdoc_generator_darkfish_#{$$}"
+ FileUtils.mkdir_p @tmpdir
+
+ @options = RDoc::Options.new
+ @options.files = []
+ # JsonIndex is used in conjunction with another generator
+ @options.setup_generator 'darkfish'
+ @options.template_dir = ''
+ @options.op_dir = @tmpdir
+ @options.option_parser = OptionParser.new
+ @options.finish
+
+ @darkfish = RDoc::Generator::Darkfish.new @store, @options
+ @g = RDoc::Generator::JsonIndex.new @darkfish, @options
+
+ @rdoc.options = @options
+ @rdoc.generator = @g
+
+ @top_level = @store.add_file 'file.rb'
+ @top_level.parser = RDoc::Parser::Ruby
+
+ @klass = @top_level.add_class RDoc::NormalClass, 'C'
+
+ @meth = @klass.add_method RDoc::AnyMethod.new(nil, 'meth')
+ @meth.record_location @top_level
+
+ @nest_klass = @klass.add_class RDoc::NormalClass, 'D'
+ @nest_klass.record_location @top_level
+
+ @nest_meth = @nest_klass.add_method RDoc::AnyMethod.new(nil, 'meth')
+
+ @ignored = @top_level.add_class RDoc::NormalClass, 'Ignored'
+ @ignored.ignore
+
+ @page = @store.add_file 'page.rdoc'
+ @page.parser = RDoc::Parser::Simple
+
+ @top_levels = [@top_level, @page].sort
+ @klasses = [@klass, @nest_klass, @ignored]
+
+ Dir.chdir @tmpdir
+ end
+
+ def teardown
+ super
+
+ Dir.chdir @pwd
+ FileUtils.rm_rf @tmpdir
+ end
+
+ def assert_file path
+ assert File.file?(path), "#{path} is not a file"
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
+ def test_build_index
+ index = @g.build_index
+
+ expected = {
+ :index => {
+ :searchIndex => %w[c d meth() meth() page],
+ :longSearchIndex => %w[c c::d c#meth() c::d#meth()],
+ :info => [
+ @klass.search_record[2..-1],
+ @nest_klass.search_record[2..-1],
+ @meth.search_record[2..-1],
+ @nest_meth.search_record[2..-1],
+ @page.search_record[2..-1],
+ ],
+ },
+ }
+
+ expected[:index][:longSearchIndex] << ''
+
+ assert_equal expected, index
+ end
+
+ def test_class_dir
+ assert_equal @darkfish.class_dir, @g.class_dir
+ end
+
+ def test_file_dir
+ assert_equal @darkfish.file_dir, @g.file_dir
+ end
+
+ def test_generate
+ @g.generate
+
+ assert_file 'js/searcher.js'
+ assert_file 'js/navigation.js'
+ assert_file 'js/search_index.js'
+
+ json = File.read 'js/search_index.js'
+
+ json =~ /\Avar search_data = /
+
+ assignment = $&
+ index = $'
+
+ refute_empty assignment
+
+ index = JSON.parse index
+
+ info = [
+ @klass.search_record[2..-1],
+ @nest_klass.search_record[2..-1],
+ @meth.search_record[2..-1],
+ @nest_meth.search_record[2..-1],
+ @page.search_record[2..-1],
+ ]
+
+ expected = {
+ 'index' => {
+ 'searchIndex' => [
+ 'c',
+ 'd',
+ 'meth()',
+ 'meth()',
+ 'page',
+ ],
+ 'longSearchIndex' => [
+ 'c',
+ 'c::d',
+ 'c#meth()',
+ 'c::d#meth()',
+ '',
+ ],
+ 'info' => info,
+ },
+ }
+
+ assert_equal expected, index
+ end
+
+ def test_generate_utf_8
+ skip "Encoding not implemented" unless Object.const_defined? :Encoding
+
+ text = "5\xB0"
+ text.force_encoding Encoding::ISO_8859_1
+ @klass.add_comment comment(text), @top_level
+
+ @g.generate
+
+ json = File.read 'js/search_index.js'
+ json.force_encoding Encoding::UTF_8
+
+ json =~ /\Avar search_data = /
+
+ index = $'
+
+ index = JSON.parse index
+
+ klass_record = @klass.search_record[2..-1]
+ klass_record[-1] = "<p>5\xc2\xb0\n"
+ klass_record.last.force_encoding Encoding::UTF_8
+
+ info = [
+ klass_record,
+ @nest_klass.search_record[2..-1],
+ @meth.search_record[2..-1],
+ @nest_meth.search_record[2..-1],
+ @page.search_record[2..-1],
+ ]
+
+ expected = {
+ 'index' => {
+ 'searchIndex' => [
+ 'c',
+ 'd',
+ 'meth()',
+ 'meth()',
+ 'page',
+ ],
+ 'longSearchIndex' => [
+ 'c',
+ 'c::d',
+ 'c#meth()',
+ 'c::d#meth()',
+ '',
+ ],
+ 'info' => info,
+ },
+ }
+
+ assert_equal expected, index
+ end
+
+ def test_index_classes
+ @g.reset @top_levels, @klasses
+
+ @g.index_classes
+
+ expected = {
+ :searchIndex => %w[c d],
+ :longSearchIndex => %w[c c::d],
+ :info => [
+ @klass.search_record[2..-1],
+ @nest_klass.search_record[2..-1],
+ ],
+ }
+
+ assert_equal expected, @g.index
+ end
+
+ def test_index_classes_nodoc
+ @klass.document_self = false
+ @nest_klass.document_self = false
+ @meth.document_self = false
+ @nest_meth.document_self = false
+
+ @g.reset @top_levels, @klasses
+
+ @g.index_classes
+
+ expected = {
+ :searchIndex => [],
+ :longSearchIndex => [],
+ :info => [],
+ }
+
+ assert_equal expected, @g.index
+ end
+
+ def test_index_methods
+ @g.reset @top_levels, @klasses
+
+ @g.index_methods
+
+ expected = {
+ :searchIndex => %w[meth() meth()],
+ :longSearchIndex => %w[c#meth() c::d#meth()],
+ :info => [
+ @meth.search_record[2..-1],
+ @nest_meth.search_record[2..-1],
+ ],
+ }
+
+ assert_equal expected, @g.index
+ end
+
+ def test_index_pages
+ @g.reset @top_levels, @klasses
+
+ @g.index_pages
+
+ expected = {
+ :searchIndex => %w[page],
+ :longSearchIndex => [''],
+ :info => [@page.search_record[2..-1]],
+ }
+
+ assert_equal expected, @g.index
+ end
+
+ def test_search_string
+ assert_equal 'cd', @g.search_string('C d')
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_generator_markup.rb b/test/rdoc/test_rdoc_generator_markup.rb
new file mode 100644
index 0000000000..1b44085283
--- /dev/null
+++ b/test/rdoc/test_rdoc_generator_markup.rb
@@ -0,0 +1,56 @@
+require 'rdoc/test_case'
+
+class TestRDocGeneratorMarkup < RDoc::TestCase
+
+ include RDoc::Text
+ include RDoc::Generator::Markup
+
+ attr_reader :store
+
+ def setup
+ super
+
+ @options = RDoc::Options.new
+ @rdoc.options = @options
+
+ @parent = self
+ @path = '/index.html'
+ @symbols = {}
+ end
+
+ def test_aref_to
+ assert_equal 'Foo/Bar.html', aref_to('Foo/Bar.html')
+ end
+
+ def test_as_href
+ assert_equal '../index.html', as_href('Foo/Bar.html')
+ end
+
+ def test_cvs_url
+ assert_equal 'http://example/this_page',
+ cvs_url('http://example/', 'this_page')
+
+ assert_equal 'http://example/?page=this_page&foo=bar',
+ cvs_url('http://example/?page=%s&foo=bar', 'this_page')
+ end
+
+ def test_description
+ @comment = '= Hello'
+
+ assert_equal "\n<h1 id=\"label-Hello\">Hello</h1>\n", description
+ end
+
+ def test_formatter
+ assert_kind_of RDoc::Markup::ToHtmlCrossref, formatter
+ refute formatter.show_hash
+ assert_same self, formatter.context
+ end
+
+ attr_reader :path
+
+ def find_symbol name
+ @symbols[name]
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_generator_ri.rb b/test/rdoc/test_rdoc_generator_ri.rb
index 2be006843c..a2bcec534d 100644
--- a/test/rdoc/test_rdoc_generator_ri.rb
+++ b/test/rdoc/test_rdoc_generator_ri.rb
@@ -1,26 +1,22 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/rdoc'
-require 'rdoc/generator/ri'
-require 'tmpdir'
-require 'fileutils'
+require 'rdoc/test_case'
-class TestRDocGeneratorRI < MiniTest::Unit::TestCase
+class TestRDocGeneratorRI < RDoc::TestCase
def setup
- @options = RDoc::Options.new
- @options.encoding = Encoding::UTF_8 if Object.const_defined? :Encoding
+ super
- @pwd = Dir.pwd
- RDoc::TopLevel.reset
+ @options = RDoc::Options.new
+ if Object.const_defined? :Encoding then
+ @options.encoding = Encoding::UTF_8
+ @store.encoding = Encoding::UTF_8
+ end
@tmpdir = File.join Dir.tmpdir, "test_rdoc_generator_ri_#{$$}"
FileUtils.mkdir_p @tmpdir
- Dir.chdir @tmpdir
- @g = RDoc::Generator::RI.new @options
+ @g = RDoc::Generator::RI.new @store, @options
- @top_level = RDoc::TopLevel.new 'file.rb'
+ @top_level = @store.add_file 'file.rb'
@klass = @top_level.add_class RDoc::NormalClass, 'Object'
@meth = RDoc::AnyMethod.new nil, 'method'
@@ -35,9 +31,13 @@ class TestRDocGeneratorRI < MiniTest::Unit::TestCase
@klass.add_method @meth
@klass.add_method @meth_bang
@klass.add_attribute @attr
+
+ Dir.chdir @tmpdir
end
def teardown
+ super
+
Dir.chdir @pwd
FileUtils.rm_rf @tmpdir
end
@@ -51,7 +51,7 @@ class TestRDocGeneratorRI < MiniTest::Unit::TestCase
end
def test_generate
- @g.generate nil
+ @g.generate
assert_file File.join(@tmpdir, 'cache.ri')
@@ -70,16 +70,15 @@ class TestRDocGeneratorRI < MiniTest::Unit::TestCase
end
def test_generate_dry_run
- @options.dry_run = true
- @g = RDoc::Generator::RI.new @options
+ @store.dry_run = true
+ @g = RDoc::Generator::RI.new @store, @options
- top_level = RDoc::TopLevel.new 'file.rb'
+ top_level = @store.add_file 'file.rb'
top_level.add_class @klass.class, @klass.name
- @g.generate nil
+ @g.generate
refute_file File.join(@tmpdir, 'cache.ri')
-
refute_file File.join(@tmpdir, 'Object')
end
diff --git a/test/rdoc/test_rdoc_include.rb b/test/rdoc/test_rdoc_include.rb
index 71eaf9abf8..464a698018 100644
--- a/test/rdoc/test_rdoc_include.rb
+++ b/test/rdoc/test_rdoc_include.rb
@@ -7,6 +7,8 @@ class TestRDocInclude < XrefTestCase
@inc = RDoc::Include.new 'M1', 'comment'
@inc.parent = @m1
+ @inc.record_location @top_level
+ @inc.store = @store
end
def test_module
@@ -92,5 +94,15 @@ class TestRDocInclude < XrefTestCase
assert_equal [m1_m2_m4, m1_m2, m1, 'Object'], m1_k3.ancestors
end
+ def test_store_equals
+ incl = RDoc::Include.new 'M', nil
+ incl.record_location RDoc::TopLevel.new @top_level.name
+
+ incl.store = @store
+
+ assert_same @top_level, incl.file
+ assert_same @store, incl.file.store
+ end
+
end
diff --git a/test/rdoc/test_rdoc_markdown.rb b/test/rdoc/test_rdoc_markdown.rb
new file mode 100644
index 0000000000..f3eb22227c
--- /dev/null
+++ b/test/rdoc/test_rdoc_markdown.rb
@@ -0,0 +1,977 @@
+# coding: UTF-8
+
+require 'rubygems'
+require 'minitest/autorun'
+require 'pp'
+
+require 'rdoc'
+require 'rdoc/markup/block_quote'
+require 'rdoc/markdown'
+
+class TestRDocMarkdown < RDoc::TestCase
+
+ def setup
+ @RM = RDoc::Markup
+
+ @parser = RDoc::Markdown.new
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
+ def test_class_parse
+ doc = RDoc::Markdown.parse "hello\n\nworld"
+
+ expected = doc(para("hello"), para("world"))
+
+ assert_equal expected, doc
+ end
+
+ def test_emphasis
+ assert_equal '_word_', @parser.emphasis('word')
+ assert_equal '<em>two words</em>', @parser.emphasis('two words')
+ assert_equal '<em>*bold*</em>', @parser.emphasis('*bold*')
+ end
+
+ def test_parse_auto_link_email
+ doc = parse "Autolink: <nobody-0+_./!%~$@example>"
+
+ expected = doc(para("Autolink: mailto:nobody-0+_./!%~$@example"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_auto_link_url
+ doc = parse "Autolink: <http://example>"
+
+ expected = doc(para("Autolink: http://example"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_block_quote
+ doc = parse <<-BLOCK_QUOTE
+> this is
+> a block quote
+ BLOCK_QUOTE
+
+ expected =
+ doc(
+ block(
+ para("this is\na block quote")))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_block_quote_continue
+ doc = parse <<-BLOCK_QUOTE
+> this is
+a block quote
+ BLOCK_QUOTE
+
+ expected =
+ doc(
+ block(
+ para("this is\na block quote")))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_block_quote_list
+ doc = parse <<-BLOCK_QUOTE
+> text
+>
+> * one
+> * two
+ BLOCK_QUOTE
+
+ expected =
+ doc(
+ block(
+ para("text"),
+ list(:BULLET,
+ item(nil, para("one")),
+ item(nil, para("two")))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_block_quote_newline
+ doc = parse <<-BLOCK_QUOTE
+> this is
+a block quote
+
+ BLOCK_QUOTE
+
+ expected =
+ doc(
+ block(
+ para("this is\na block quote")))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_block_quote_separate
+ doc = parse <<-BLOCK_QUOTE
+> this is
+a block quote
+
+> that continues
+ BLOCK_QUOTE
+
+ expected =
+ doc(
+ block(
+ para("this is\na block quote"),
+ para("that continues")))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_char_entity
+ doc = parse '&pi; &nn;'
+
+ expected = doc(para('π &nn;'))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_code
+ doc = parse "Code: `text`"
+
+ expected = doc(para("Code: <code>text</code>"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_code_github
+ doc = parse <<-MD
+Example:
+
+```
+code goes here
+```
+ MD
+
+ expected =
+ doc(
+ para("Example:"),
+ verb("code goes here\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_code_github_format
+ doc = parse <<-MD
+Example:
+
+``` ruby
+code goes here
+```
+ MD
+
+ code = verb("code goes here\n")
+ code.format = :ruby
+
+ expected =
+ doc(
+ para("Example:"),
+ code)
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_definition_list
+ doc = parse <<-MD
+one
+: This is a definition
+
+two
+: This is another definition
+ MD
+
+ expected = doc(
+ list(:NOTE,
+ item(%w[one], para("This is a definition")),
+ item(%w[two], para("This is another definition"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_definition_list_indents
+ doc = parse <<-MD
+zero
+: Indented zero characters
+
+one
+ : Indented one characters
+
+two
+ : Indented two characters
+
+three
+ : Indented three characters
+
+four
+ : Indented four characters
+
+ MD
+
+ expected = doc(
+ list(:NOTE,
+ item(%w[zero], para("Indented zero characters")),
+ item(%w[one], para("Indented one characters")),
+ item(%w[two], para("Indented two characters")),
+ item(%w[three], para("Indented three characters"))),
+ para("four\n : Indented four characters"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_definition_list_multi_description
+ doc = parse <<-MD
+label
+: This is a definition
+
+: This is another definition
+ MD
+
+ expected = doc(
+ list(:NOTE,
+ item(%w[label], para("This is a definition")),
+ item(nil, para("This is another definition"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_definition_list_multi_label
+ doc = parse <<-MD
+one
+two
+: This is a definition
+ MD
+
+ expected = doc(
+ list(:NOTE,
+ item(%w[one two], para("This is a definition"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_definition_list_multi_line
+ doc = parse <<-MD
+one
+: This is a definition
+that extends to two lines
+
+two
+: This is another definition
+that also extends to two lines
+ MD
+
+ expected = doc(
+ list(:NOTE,
+ item(%w[one],
+ para("This is a definition\nthat extends to two lines")),
+ item(%w[two],
+ para("This is another definition\nthat also extends to two lines"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_definition_list_no
+ @parser.definition_lists = false
+
+ doc = parse <<-MD
+one
+: This is a definition
+
+two
+: This is another definition
+ MD
+
+ expected = doc(
+ para("one\n: This is a definition"),
+ para("two\n: This is another definition"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_entity_dec
+ doc = parse "Entity: &#65;"
+
+ expected = doc(para("Entity: A"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_entity_hex
+ doc = parse "Entity: &#x41;"
+
+ expected = doc(para("Entity: A"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_entity_named
+ doc = parse "Entity: &pi;"
+
+ expected = doc(para("Entity: π"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_emphasis_star
+ doc = parse "it *works*\n"
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new("it _works_"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_emphasis_underscore
+ doc = parse "it _works_\n"
+
+ expected =
+ doc(
+ para("it _works_"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_emphasis_underscore_embedded
+ doc = parse "foo_bar bar_baz\n"
+
+ expected =
+ doc(
+ para("foo_bar bar_baz"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_emphasis_underscore_in_word
+ doc = parse "it foo_bar_baz\n"
+
+ expected =
+ doc(
+ para("it foo_bar_baz"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_escape
+ assert_equal doc(para("Backtick: `")), parse("Backtick: \\`")
+
+ assert_equal doc(para("Backslash: \\")), parse("Backslash: \\\\")
+
+ assert_equal doc(para("Colon: :")), parse("Colon: \\:")
+ end
+
+ def test_parse_heading_atx
+ doc = parse "# heading\n"
+
+ expected = @RM::Document.new(
+ @RM::Heading.new(1, "heading"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_heading_setext_dash
+ doc = parse <<-MD
+heading
+---
+ MD
+
+ expected = @RM::Document.new(
+ @RM::Heading.new(2, "heading"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_heading_setext_equals
+ doc = parse <<-MD
+heading
+===
+ MD
+
+ expected = @RM::Document.new(
+ @RM::Heading.new(1, "heading"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_html
+ @parser.html = true
+
+ doc = parse "<address>Links here</address>\n"
+
+ expected = doc(
+ @RM::Raw.new("<address>Links here</address>"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_html_hr
+ @parser.html = true
+
+ doc = parse "<hr>\n"
+
+ expected = doc(raw("<hr>"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_html_no_html
+ @parser.html = false
+
+ doc = parse "<address>Links here</address>\n"
+
+ expected = doc()
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_image
+ doc = parse "image ![alt text](path/to/image.jpg)"
+
+ expected = doc(para("image {alt text}[path/to/image.jpg]"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_line_break
+ doc = parse "Some text \nwith extra lines"
+
+ expected = doc(
+ para("Some text", hard_break, "with extra lines"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_link_reference_id
+ doc = parse <<-MD
+This is [an example][id] reference-style link.
+
+[id]: http://example.com "Optional Title Here"
+ MD
+
+ expected = doc(
+ para("This is {an example}[http://example.com] reference-style link."))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_link_reference_id_adjacent
+ doc = parse <<-MD
+[this] [this] should work
+
+[this]: example
+ MD
+
+ expected = doc(
+ para("{this}[example] should work"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_link_reference_id_eof
+ doc = parse <<-MD.chomp
+This is [an example][id] reference-style link.
+
+[id]: http://example.com "Optional Title Here"
+ MD
+
+ expected = doc(
+ para("This is {an example}[http://example.com] reference-style link."))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_link_reference_id_many
+ doc = parse <<-MD
+This is [an example][id] reference-style link.
+
+And [another][id].
+
+[id]: http://example.com "Optional Title Here"
+ MD
+
+ expected = doc(
+ para("This is {an example}[http://example.com] reference-style link."),
+ para("And {another}[http://example.com]."))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_link_reference_implicit
+ doc = parse <<-MD
+This is [an example][] reference-style link.
+
+[an example]: http://example.com "Optional Title Here"
+ MD
+
+ expected = doc(
+ para("This is {an example}[http://example.com] reference-style link."))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_bullet
+ doc = parse <<-MD
+* one
+* two
+ MD
+
+ expected = doc(
+ list(:BULLET,
+ item(nil, para("one")),
+ item(nil, para("two"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_bullet_auto_link
+ doc = parse <<-MD
+* <http://example/>
+ MD
+
+ expected = doc(
+ list(:BULLET,
+ item(nil, para("http://example/"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_bullet_continue
+ doc = parse <<-MD
+* one
+
+* two
+ MD
+
+ expected = doc(
+ list(:BULLET,
+ item(nil, para("one")),
+ item(nil, para("two"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_bullet_multiline
+ doc = parse <<-MD
+* one
+ two
+ MD
+
+ expected = doc(
+ list(:BULLET,
+ item(nil, para("one\n two"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_bullet_nest
+ doc = parse <<-MD
+* outer
+ * inner
+ MD
+
+ expected = doc(
+ list(:BULLET,
+ item(nil,
+ para("outer"),
+ list(:BULLET,
+ item(nil,
+ para("inner"))))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_bullet_nest_loose
+ doc = parse <<-MD
+* outer
+
+ * inner
+ MD
+
+ expected = doc(
+ list(:BULLET,
+ item(nil,
+ para("outer"),
+ list(:BULLET,
+ item(nil, para("inner"))))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_bullet_nest_continue
+ doc = parse <<-MD
+* outer
+ * inner
+ continue inner
+* outer 2
+ MD
+
+ expected = doc(
+ list(:BULLET,
+ item(nil,
+ para("outer"),
+ list(:BULLET,
+ item(nil,
+ para("inner\n continue inner")))),
+ item(nil,
+ para("outer 2"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_number
+ doc = parse <<-MD
+1. one
+1. two
+ MD
+
+ expected = doc(
+ list(:NUMBER,
+ item(nil, para("one")),
+ item(nil, para("two"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_list_number_continue
+ doc = parse <<-MD
+1. one
+
+1. two
+ MD
+
+ expected = doc(
+ list(:NUMBER,
+ item(nil, para("one")),
+ item(nil, para("two"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_note
+ @parser.notes = true
+
+ doc = parse <<-MD
+Some text.[^1]
+
+[^1]: With a footnote
+ MD
+
+ expected = doc(
+ para("Some text.{*1}[rdoc-label:foottext-1:footmark-1]"),
+ @RM::Rule.new(1),
+ para("{^1}[rdoc-label:footmark-1:foottext-1] With a footnote"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_note_indent
+ @parser.notes = true
+
+ doc = parse <<-MD
+Some text.[^1]
+
+[^1]: With a footnote
+
+ more
+ MD
+
+ expected = doc(
+ para("Some text.{*1}[rdoc-label:foottext-1:footmark-1]"),
+ rule(1),
+ para("{^1}[rdoc-label:footmark-1:foottext-1] With a footnote\n\nmore"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_note_inline
+ @parser.notes = true
+
+ doc = parse <<-MD
+Some text. ^[With a footnote]
+ MD
+
+ expected = doc(
+ para("Some text. {*1}[rdoc-label:foottext-1:footmark-1]"),
+ @RM::Rule.new(1),
+ para("{^1}[rdoc-label:footmark-1:foottext-1] With a footnote"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_note_no_notes
+ @parser.notes = false
+
+ assert_raises RuntimeError do # TODO use a real error
+ parse "Some text.[^1]"
+ end
+ end
+
+ def test_parse_note_multiple
+ @parser.notes = true
+
+ doc = parse <<-MD
+Some text[^1]
+with inline notes^[like this]
+and an extra note.[^2]
+
+[^1]: With a footnote
+
+[^2]: Which should be numbered correctly
+ MD
+
+ expected = doc(
+ para("Some text{*1}[rdoc-label:foottext-1:footmark-1]\n" +
+ "with inline notes{*2}[rdoc-label:foottext-2:footmark-2]\n" +
+ "and an extra note.{*3}[rdoc-label:foottext-3:footmark-3]"),
+
+ rule(1),
+
+ para("{^1}[rdoc-label:footmark-1:foottext-1] With a footnote"),
+ para("{^2}[rdoc-label:footmark-2:foottext-2] like this"),
+ para("{^3}[rdoc-label:footmark-3:foottext-3] " +
+ "Which should be numbered correctly"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph
+ doc = parse "it worked\n"
+
+ expected = doc(para("it worked"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_break_on_newline
+ @parser.break_on_newline = true
+
+ doc = parse "one\ntwo\n"
+
+ expected = doc(para("one", hard_break, "two"))
+
+ assert_equal expected, doc
+
+ doc = parse "one \ntwo\nthree\n"
+
+ expected = doc(para("one", hard_break, "two", hard_break, "three"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_stars
+ doc = parse "it worked ****\n"
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new("it worked ****"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_html
+ @parser.html = true
+
+ doc = parse "<address>Links here</address>"
+
+ expected = doc(raw("<address>Links here</address>"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_html_no_html
+ @parser.html = false
+
+ doc = parse "<address>Links here</address>"
+
+ expected = doc()
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_indent_one
+ doc = parse <<-MD
+ text
+ MD
+
+ expected = doc(para("text"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_indent_two
+ doc = parse <<-MD
+ text
+ MD
+
+ expected = doc(para("text"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_indent_three
+ doc = parse <<-MD
+ text
+ MD
+
+ expected = doc(para("text"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_multiline
+ doc = parse "one\ntwo"
+
+ expected = doc(para("one\ntwo"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_paragraph_two
+ doc = parse "one\n\ntwo"
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new("one"),
+ @RM::Paragraph.new("two"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_plain
+ doc = parse "it worked"
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new("it worked"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_reference_link_embedded_bracket
+ doc = parse "With [embedded [brackets]] [b].\n\n[b]: /url/\n"
+
+ expected =
+ doc(
+ para("With {embedded [brackets]}[/url/]."))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_rule_dash
+ doc = parse "- - -\n\n"
+
+ expected = @RM::Document.new(@RM::Rule.new(1))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_rule_underscore
+ doc = parse "_ _ _\n\n"
+
+ expected = @RM::Document.new(@RM::Rule.new(1))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_rule_star
+ doc = parse "* * *\n\n"
+
+ expected = @RM::Document.new(@RM::Rule.new(1))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_strong_star
+ doc = parse "it **works**\n"
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new("it *works*"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_strong_underscore
+ doc = parse "it __works__\n"
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new("it *works*"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_strong_emphasis_star
+ doc = parse "it ***works***\n"
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new("it <b>_works_</b>"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_strong_emphasis_underscore
+ doc = parse "it ___works___\n"
+
+ expected = @RM::Document.new(
+ @RM::Paragraph.new("it <b>_works_</b>"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_style
+ @parser.css = true
+
+ doc = parse "<style>h1 { color: red }</style>\n"
+
+ expected = doc(
+ @RM::Raw.new("<style>h1 { color: red }</style>"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_style_disabled
+ doc = parse "<style>h1 { color: red }</style>\n"
+
+ expected = doc()
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_verbatim
+ doc = parse <<-MD
+ text
+ MD
+
+ expected = doc(verb("text\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_parse_verbatim_eof
+ doc = parse " text"
+
+ expected = doc(verb("text\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_strong
+ assert_equal '*word*', @parser.strong('word')
+ assert_equal '<b>two words</b>', @parser.strong('two words')
+ assert_equal '<b>_emphasis_</b>', @parser.strong('_emphasis_')
+ end
+
+ def parse text
+ @parser.parse text
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markdown_test.rb b/test/rdoc/test_rdoc_markdown_test.rb
new file mode 100644
index 0000000000..7dfe727ef5
--- /dev/null
+++ b/test/rdoc/test_rdoc_markdown_test.rb
@@ -0,0 +1,1891 @@
+require 'rubygems'
+require 'minitest/autorun'
+require 'pp'
+
+require 'rdoc'
+require 'rdoc/markdown'
+
+class TestRDocMarkdownTest < RDoc::TestCase
+
+ MARKDOWN_TEST_PATH = File.expand_path '../MarkdownTest_1.0.3/', __FILE__
+
+ def setup
+ super
+
+ @parser = RDoc::Markdown.new
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
+ def test_amps_and_angle_encoding
+ input = File.read "#{MARKDOWN_TEST_PATH}/Amps and angle encoding.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("AT&T has an ampersand in their name."),
+ para("AT&T is another way to write it."),
+ para("This & that."),
+ para("4 < 5."),
+ para("6 > 5."),
+ para("Here's a {link}[http://example.com/?foo=1&bar=2] with " +
+ "an ampersand in the URL."),
+ para("Here's a link with an amersand in the link text: " +
+ "{AT&T}[http://att.com/]."),
+ para("Here's an inline {link}[/script?foo=1&bar=2]."),
+ para("Here's an inline {link}[/script?foo=1&bar=2]."))
+
+ assert_equal expected, doc
+ end
+
+ def test_auto_links
+ input = File.read "#{MARKDOWN_TEST_PATH}/Auto links.text"
+
+ doc = @parser.parse input
+
+ # TODO verify rdoc auto-links too
+ expected =
+ doc(
+ para("Link: http://example.com/."),
+ para("With an ampersand: http://example.com/?foo=1&bar=2"),
+ list(:BULLET,
+ item(nil, para("In a list?")),
+ item(nil, para("http://example.com/")),
+ item(nil, para("It should."))),
+ block(
+ para("Blockquoted: http://example.com/")),
+ para("Auto-links should not occur here: " +
+ "<code><http://example.com/></code>"),
+ verb("or here: <http://example.com/>\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_backslash_escapes
+ input = File.read "#{MARKDOWN_TEST_PATH}/Backslash escapes.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("These should all get escaped:"),
+
+ para("Backslash: \\"),
+ para("Backtick: `"),
+ para("Asterisk: *"),
+ para("Underscore: _"),
+ para("Left brace: {"),
+ para("Right brace: }"),
+ para("Left bracket: ["),
+ para("Right bracket: ]"),
+ para("Left paren: ("),
+ para("Right paren: )"),
+ para("Greater-than: >"),
+ para("Hash: #"),
+ para("Period: ."),
+ para("Bang: !"),
+ para("Plus: +"),
+ para("Minus: -"),
+
+ para("These should not, because they occur within a code block:"),
+
+ verb("Backslash: \\\\\n",
+ "\n",
+ "Backtick: \\`\n",
+ "\n",
+ "Asterisk: \\*\n",
+ "\n",
+ "Underscore: \\_\n",
+ "\n",
+ "Left brace: \\{\n",
+ "\n",
+ "Right brace: \\}\n",
+ "\n",
+ "Left bracket: \\[\n",
+ "\n",
+ "Right bracket: \\]\n",
+ "\n",
+ "Left paren: \\(\n",
+ "\n",
+ "Right paren: \\)\n",
+ "\n",
+ "Greater-than: \\>\n",
+ "\n",
+ "Hash: \\#\n",
+ "\n",
+ "Period: \\.\n",
+ "\n",
+ "Bang: \\!\n",
+ "\n",
+ "Plus: \\+\n",
+ "\n",
+ "Minus: \\-\n"),
+
+ para("Nor should these, which occur in code spans:"),
+
+ para("Backslash: <code>\\\\</code>"),
+ para("Backtick: <code>\\`</code>"),
+ para("Asterisk: <code>\\*</code>"),
+ para("Underscore: <code>\\_</code>"),
+ para("Left brace: <code>\\{</code>"),
+ para("Right brace: <code>\\}</code>"),
+ para("Left bracket: <code>\\[</code>"),
+ para("Right bracket: <code>\\]</code>"),
+ para("Left paren: <code>\\(</code>"),
+ para("Right paren: <code>\\)</code>"),
+ para("Greater-than: <code>\\></code>"),
+ para("Hash: <code>\\#</code>"),
+ para("Period: <code>\\.</code>"),
+ para("Bang: <code>\\!</code>"),
+ para("Plus: <code>\\+</code>"),
+ para("Minus: <code>\\-</code>"),
+
+ para("These should get escaped, even though they're matching pairs for\n" +
+ "other Markdown constructs:"),
+
+ para("\*asterisks\*"),
+ para("\_underscores\_"),
+ para("`backticks`"),
+
+ para("This is a code span with a literal backslash-backtick " +
+ "sequence: <code>\\`</code>"),
+
+ para("This is a tag with unescaped backticks " +
+ "<span attr='`ticks`'>bar</span>."),
+
+ para("This is a tag with backslashes " +
+ "<span attr='\\\\backslashes\\\\'>bar</span>."))
+
+ assert_equal expected, doc
+ end
+
+ def test_blockquotes_with_code_blocks
+ input = File.read "#{MARKDOWN_TEST_PATH}/Blockquotes with code blocks.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ block(
+ para("Example:"),
+ verb("sub status {\n",
+ " print \"working\";\n",
+ "}\n"),
+ para("Or:"),
+ verb("sub status {\n",
+ " return \"working\";\n",
+ "}\n")))
+
+ assert_equal expected, doc
+ end
+
+ def test_code_blocks
+ input = File.read "#{MARKDOWN_TEST_PATH}/Code Blocks.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ verb("code block on the first line\n"),
+ para("Regular text."),
+
+ verb("code block indented by spaces\n"),
+ para("Regular text."),
+
+ verb("the lines in this block \n",
+ "all contain trailing spaces \n"),
+ para("Regular Text."),
+
+ verb("code block on the last line\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_code_spans
+ input = File.read "#{MARKDOWN_TEST_PATH}/Code Spans.text"
+
+ doc = @parser.parse input
+
+ expected = doc(
+ para("<code><test a=\"</code> content of attribute <code>\"></code>"),
+ para("Fix for backticks within HTML tag: " +
+ "<span attr='`ticks`'>like this</span>"),
+ para("Here's how you put <code>`backticks`</code> in a code span."))
+
+ assert_equal expected, doc
+ end
+
+ def test_hard_wrapped_paragraphs_with_list_like_lines
+ input = File.read "#{MARKDOWN_TEST_PATH}/Hard-wrapped paragraphs with list-like lines.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("In Markdown 1.0.0 and earlier. Version\n" +
+ "8. This line turns into a list item.\n" +
+ "Because a hard-wrapped line in the\n" +
+ "middle of a paragraph looked like a\n" +
+ "list item."),
+ para("Here's one with a bullet.\n" +
+ "* criminey."))
+
+ assert_equal expected, doc
+ end
+
+ def test_horizontal_rules
+ input = File.read "#{MARKDOWN_TEST_PATH}/Horizontal rules.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("Dashes:"),
+
+ rule(1),
+ rule(1),
+ rule(1),
+ rule(1),
+ verb("---\n"),
+
+ rule(1),
+ rule(1),
+ rule(1),
+ rule(1),
+ verb("- - -\n"),
+
+ para("Asterisks:"),
+
+ rule(1),
+ rule(1),
+ rule(1),
+ rule(1),
+ verb("***\n"),
+
+ rule(1),
+ rule(1),
+ rule(1),
+ rule(1),
+ verb("* * *\n"),
+
+ para("Underscores:"),
+
+ rule(1),
+ rule(1),
+ rule(1),
+ rule(1),
+ verb("___\n"),
+
+ rule(1),
+ rule(1),
+ rule(1),
+ rule(1),
+ verb("_ _ _\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_inline_html_advanced
+ input = File.read "#{MARKDOWN_TEST_PATH}/Inline HTML (Advanced).text"
+
+ @parser.html = true
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("Simple block on one line:"),
+ raw("<div>foo</div>"),
+ para("And nested without indentation:"),
+ raw(<<-RAW.chomp))
+<div>
+<div>
+<div>
+foo
+</div>
+<div style=">"/>
+</div>
+<div>bar</div>
+</div>
+ RAW
+
+ assert_equal expected, doc
+ end
+
+ def test_inline_html_simple
+ input = File.read "#{MARKDOWN_TEST_PATH}/Inline HTML (Simple).text"
+
+ @parser.html = true
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("Here's a simple block:"),
+ raw("<div>\n\tfoo\n</div>"),
+
+ para("This should be a code block, though:"),
+ verb("<div>\n",
+ "\tfoo\n",
+ "</div>\n"),
+
+ para("As should this:"),
+ verb("<div>foo</div>\n"),
+
+ para("Now, nested:"),
+ raw("<div>\n\t<div>\n\t\t<div>\n\t\t\tfoo\n" +
+ "\t\t</div>\n\t</div>\n</div>"),
+
+ para("This should just be an HTML comment:"),
+ raw("<!-- Comment -->"),
+
+ para("Multiline:"),
+ raw("<!--\nBlah\nBlah\n-->"),
+
+ para("Code block:"),
+ verb("<!-- Comment -->\n"),
+
+ para("Just plain comment, with trailing spaces on the line:"),
+ raw("<!-- foo -->"),
+
+ para("Code:"),
+ verb("<hr />\n"),
+
+ para("Hr's:"),
+ raw("<hr>"),
+ raw("<hr/>"),
+ raw("<hr />"),
+
+ raw("<hr>"),
+ raw("<hr/>"),
+ raw("<hr />"),
+
+ raw("<hr class=\"foo\" id=\"bar\" />"),
+ raw("<hr class=\"foo\" id=\"bar\"/>"),
+ raw("<hr class=\"foo\" id=\"bar\" >"))
+
+ assert_equal expected, doc
+ end
+
+ def test_inline_html_comments
+ input = File.read "#{MARKDOWN_TEST_PATH}/Inline HTML comments.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("Paragraph one."),
+
+ raw("<!-- This is a simple comment -->"),
+
+ raw("<!--\n\tThis is another comment.\n-->"),
+
+ para("Paragraph two."),
+
+ raw("<!-- one comment block -- -- with two comments -->"),
+
+ para("The end."))
+
+ assert_equal expected, doc
+ end
+
+ def test_links_inline_style
+ input = File.read "#{MARKDOWN_TEST_PATH}/Links, inline style.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("Just a {URL}[/url/]."),
+ para("{URL and title}[/url/]."),
+ para("{URL and title}[/url/]."),
+ para("{URL and title}[/url/]."),
+ para("{URL and title}[/url/]."),
+ para("{Empty}[]."))
+
+ assert_equal expected, doc
+ end
+
+ def test_links_reference_style
+ input = File.read "#{MARKDOWN_TEST_PATH}/Links, reference style.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("Foo {bar}[/url/]."),
+ para("Foo {bar}[/url/]."),
+ para("Foo {bar}[/url/]."),
+
+ para("With {embedded [brackets]}[/url/]."),
+
+ para("Indented {once}[/url]."),
+ para("Indented {twice}[/url]."),
+ para("Indented {thrice}[/url]."),
+ para("Indented [four][] times."),
+
+ verb("[four]: /url\n"),
+
+ rule(1),
+
+ para("{this}[foo] should work"),
+ para("So should {this}[foo]."),
+ para("And {this}[foo]."),
+ para("And {this}[foo]."),
+ para("And {this}[foo]."),
+
+ para("But not [that] []."),
+ para("Nor [that][]."),
+ para("Nor [that]."),
+
+ para("[Something in brackets like {this}[foo] should work]"),
+ para("[Same with {this}[foo].]"),
+
+ para("In this case, {this}[/somethingelse/] points to something else."),
+ para("Backslashing should suppress [this] and [this]."),
+
+ rule(1),
+
+ para("Here's one where the {link breaks}[/url/] across lines."),
+ para("Here's another where the {link breaks}[/url/] across lines, " +
+ "but with a line-ending space."))
+
+ assert_equal expected, doc
+ end
+
+ def test_links_shortcut_references
+ input = File.read "#{MARKDOWN_TEST_PATH}/Links, shortcut references.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("This is the {simple case}[/simple]."),
+ para("This one has a {line break}[/foo]."),
+ para("This one has a {line break}[/foo] with a line-ending space."),
+ para("{this}[/that] and the {other}[/other]"))
+
+ assert_equal expected, doc
+ end
+
+ def test_literal_quotes_in_titles
+ input = File.read "#{MARKDOWN_TEST_PATH}/Literal quotes in titles.text"
+
+ doc = @parser.parse input
+
+ # TODO support title attribute
+ expected =
+ doc(
+ para("Foo {bar}[/url/]."),
+ para("Foo {bar}[/url/]."))
+
+ assert_equal expected, doc
+ end
+
+ def test_markdown_documentation_basics
+ input = File.read "#{MARKDOWN_TEST_PATH}/Markdown Documentation - Basics.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ head(1, "Markdown: Basics"),
+
+ raw(<<-RAW.chomp),
+<ul id="ProjectSubmenu">
+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+ <li><a class="selected" title="Markdown Basics">Basics</a></li>
+ <li><a href="/projects/markdown/syntax" title="Markdown Syntax Documentation">Syntax</a></li>
+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+ RAW
+
+ head(2, "Getting the Gist of Markdown's Formatting Syntax"),
+
+ para("This page offers a brief overview of what it's like to use Markdown.\n" +
+ "The {syntax page}[/projects/markdown/syntax] provides complete, detailed documentation for\n" +
+ "every feature, but Markdown should be very easy to pick up simply by\n" +
+ "looking at a few examples of it in action. The examples on this page\n" +
+ "are written in a before/after style, showing example syntax and the\n" +
+ "HTML output produced by Markdown."),
+
+ para("It's also helpful to simply try Markdown out; the {Dingus}[/projects/markdown/dingus] is a\n" +
+ "web application that allows you type your own Markdown-formatted text\n" +
+ "and translate it to XHTML."),
+
+ para("<b>Note:</b> This document is itself written using Markdown; you\n" +
+ "can {see the source for it by adding '.text' to the URL}[/projects/markdown/basics.text]."),
+
+ head(2, "Paragraphs, Headers, Blockquotes"),
+
+ para("A paragraph is simply one or more consecutive lines of text, separated\n" +
+ "by one or more blank lines. (A blank line is any line that looks like a\n" +
+ "blank line -- a line containing nothing spaces or tabs is considered\n" +
+ "blank.) Normal paragraphs should not be intended with spaces or tabs."),
+
+ para("Markdown offers two styles of headers: _Setext_ and _atx_.\n" +
+ "Setext-style headers for <code><h1></code> and <code><h2></code> are created by\n" +
+ "\"underlining\" with equal signs (<code>=</code>) and hyphens (<code>-</code>), respectively.\n" +
+ "To create an atx-style header, you put 1-6 hash marks (<code>#</code>) at the\n" +
+ "beginning of the line -- the number of hashes equals the resulting\n" +
+ "HTML header level."),
+
+ para("Blockquotes are indicated using email-style '<code>></code>' angle brackets."),
+
+ para("Markdown:"),
+
+ verb("A First Level Header\n",
+ "====================\n",
+ "\n",
+ "A Second Level Header\n",
+ "---------------------\n",
+ "\n",
+ "Now is the time for all good men to come to\n",
+ "the aid of their country. This is just a\n",
+ "regular paragraph.\n",
+ "\n",
+ "The quick brown fox jumped over the lazy\n",
+ "dog's back.\n",
+ "\n",
+ "### Header 3\n",
+ "\n",
+ "> This is a blockquote.\n",
+ "> \n",
+ "> This is the second paragraph in the blockquote.\n",
+ ">\n",
+ "> ## This is an H2 in a blockquote\n"),
+
+ para("Output:"),
+
+ verb("<h1>A First Level Header</h1>\n",
+ "\n",
+ "<h2>A Second Level Header</h2>\n",
+ "\n",
+ "<p>Now is the time for all good men to come to\n",
+ "the aid of their country. This is just a\n",
+ "regular paragraph.</p>\n",
+ "\n",
+ "<p>The quick brown fox jumped over the lazy\n",
+ "dog's back.</p>\n",
+ "\n",
+ "<h3>Header 3</h3>\n",
+ "\n",
+ "<blockquote>\n",
+ " <p>This is a blockquote.</p>\n",
+ "\n",
+ " <p>This is the second paragraph in the blockquote.</p>\n",
+ "\n",
+ " <h2>This is an H2 in a blockquote</h2>\n",
+ "</blockquote>\n"),
+
+ head(3, "Phrase Emphasis"),
+ para("Markdown uses asterisks and underscores to indicate spans of emphasis."),
+
+ para("Markdown:"),
+
+ verb("Some of these words *are emphasized*.\n",
+ "Some of these words _are emphasized also_.\n",
+ "\n",
+ "Use two asterisks for **strong emphasis**.\n",
+ "Or, if you prefer, __use two underscores instead__.\n"),
+
+ para("Output:"),
+
+ verb("<p>Some of these words <em>are emphasized</em>.\n",
+ "Some of these words <em>are emphasized also</em>.</p>\n",
+ "\n",
+ "<p>Use two asterisks for <strong>strong emphasis</strong>.\n",
+ "Or, if you prefer, <strong>use two underscores instead</strong>.</p>\n"),
+
+ head(2, "Lists"),
+
+ para("Unordered (bulleted) lists use asterisks, pluses, and hyphens (<code>*</code>,\n" +
+ "<code>+</code>, and <code>-</code>) as list markers. These three markers are\n" +
+ "interchangable; this:"),
+
+ verb("* Candy.\n",
+ "* Gum.\n",
+ "* Booze.\n"),
+
+ para("this:"),
+
+ verb("+ Candy.\n",
+ "+ Gum.\n",
+ "+ Booze.\n"),
+
+ para("and this:"),
+
+ verb("- Candy.\n",
+ "- Gum.\n",
+ "- Booze.\n"),
+
+ para("all produce the same output:"),
+
+ verb("<ul>\n",
+ "<li>Candy.</li>\n",
+ "<li>Gum.</li>\n",
+ "<li>Booze.</li>\n",
+ "</ul>\n"),
+
+ para("Ordered (numbered) lists use regular numbers, followed by periods, as\n" +
+ "list markers:"),
+
+ verb("1. Red\n",
+ "2. Green\n",
+ "3. Blue\n"),
+
+ para("Output:"),
+
+ verb("<ol>\n",
+ "<li>Red</li>\n",
+ "<li>Green</li>\n",
+ "<li>Blue</li>\n",
+ "</ol>\n"),
+
+ para("If you put blank lines between items, you'll get <code><p></code> tags for the\n" +
+ "list item text. You can create multi-paragraph list items by indenting\n" +
+ "the paragraphs by 4 spaces or 1 tab:"),
+
+ verb("* A list item.\n",
+ "\n",
+ " With multiple paragraphs.\n",
+ "\n",
+ "* Another item in the list.\n"),
+
+ para("Output:"),
+
+ verb("<ul>\n",
+ "<li><p>A list item.</p>\n",
+ "<p>With multiple paragraphs.</p></li>\n",
+ "<li><p>Another item in the list.</p></li>\n",
+ "</ul>\n"),
+
+ head(3, "Links"),
+
+ para("Markdown supports two styles for creating links: _inline_ and\n" +
+ "_reference_. With both styles, you use square brackets to delimit the\n" +
+ "text you want to turn into a link."),
+
+ para("Inline-style links use parentheses immediately after the link text.\n" +
+ "For example:"),
+
+ verb("This is an [example link](http://example.com/).\n"),
+
+ para("Output:"),
+
+ verb("<p>This is an <a href=\"http://example.com/\">\n",
+ "example link</a>.</p>\n"),
+
+ para("Optionally, you may include a title attribute in the parentheses:"),
+
+ verb("This is an [example link](http://example.com/ \"With a Title\").\n"),
+
+ para("Output:"),
+
+ verb("<p>This is an <a href=\"http://example.com/\" title=\"With a Title\">\n",
+ "example link</a>.</p>\n"),
+
+ para("Reference-style links allow you to refer to your links by names, which\n" +
+ "you define elsewhere in your document:"),
+
+ verb("I get 10 times more traffic from [Google][1] than from\n",
+ "[Yahoo][2] or [MSN][3].\n",
+ "\n",
+ "[1]: http://google.com/ \"Google\"\n",
+ "[2]: http://search.yahoo.com/ \"Yahoo Search\"\n",
+ "[3]: http://search.msn.com/ \"MSN Search\"\n"),
+
+ para("Output:"),
+
+ verb("<p>I get 10 times more traffic from <a href=\"http://google.com/\"\n",
+ "title=\"Google\">Google</a> than from <a href=\"http://search.yahoo.com/\"\n",
+ "title=\"Yahoo Search\">Yahoo</a> or <a href=\"http://search.msn.com/\"\n",
+ "title=\"MSN Search\">MSN</a>.</p>\n"),
+
+ para("The title attribute is optional. Link names may contain letters,\n" +
+ "numbers and spaces, but are _not_ case sensitive:"),
+
+ verb("I start my morning with a cup of coffee and\n",
+ "[The New York Times][NY Times].\n",
+ "\n",
+ "[ny times]: http://www.nytimes.com/\n"),
+
+ para("Output:"),
+
+ verb("<p>I start my morning with a cup of coffee and\n",
+ "<a href=\"http://www.nytimes.com/\">The New York Times</a>.</p>\n"),
+
+ head(3, "Images"),
+
+ para("Image syntax is very much like link syntax."),
+
+ para("Inline (titles are optional):"),
+
+ verb("![alt text](/path/to/img.jpg \"Title\")\n"),
+
+ para("Reference-style:"),
+
+ verb("![alt text][id]\n",
+ "\n",
+ "[id]: /path/to/img.jpg \"Title\"\n"),
+
+ para("Both of the above examples produce the same output:"),
+
+ verb("<img src=\"/path/to/img.jpg\" alt=\"alt text\" title=\"Title\" />\n"),
+
+ head(3, "Code"),
+
+ para("In a regular paragraph, you can create code span by wrapping text in\n" +
+ "backtick quotes. Any ampersands (<code>&</code>) and angle brackets (<code><</code> or\n" +
+ "<code>></code>) will automatically be translated into HTML entities. This makes\n" +
+ "it easy to use Markdown to write about HTML example code:"),
+
+ verb(
+ "I strongly recommend against using any `<blink>` tags.\n",
+ "\n",
+ "I wish SmartyPants used named entities like `&mdash;`\n",
+ "instead of decimal-encoded entites like `&#8212;`.\n"),
+
+ para("Output:"),
+
+ verb("<p>I strongly recommend against using any\n",
+ "<code>&lt;blink&gt;</code> tags.</p>\n",
+ "\n",
+ "<p>I wish SmartyPants used named entities like\n",
+ "<code>&amp;mdash;</code> instead of decimal-encoded\n",
+ "entites like <code>&amp;#8212;</code>.</p>\n"),
+
+ para("To specify an entire block of pre-formatted code, indent every line of\n" +
+ "the block by 4 spaces or 1 tab. Just like with code spans, <code>&</code>, <code><</code>,\n" +
+ "and <code>></code> characters will be escaped automatically."),
+
+ para("Markdown:"),
+
+ verb("If you want your page to validate under XHTML 1.0 Strict,\n",
+ "you've got to put paragraph tags in your blockquotes:\n",
+ "\n",
+ " <blockquote>\n",
+ " <p>For example.</p>\n",
+ " </blockquote>\n"),
+
+ para("Output:"),
+
+ verb("<p>If you want your page to validate under XHTML 1.0 Strict,\n",
+ "you've got to put paragraph tags in your blockquotes:</p>\n",
+ "\n",
+ "<pre><code>&lt;blockquote&gt;\n",
+ " &lt;p&gt;For example.&lt;/p&gt;\n",
+ "&lt;/blockquote&gt;\n",
+ "</code></pre>\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_markdown_documentation_syntax
+ input = File.read "#{MARKDOWN_TEST_PATH}/Markdown Documentation - Syntax.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ head(1, "Markdown: Syntax"),
+
+ raw(<<-RAW.chomp),
+<ul id="ProjectSubmenu">
+ <li><a href="/projects/markdown/" title="Markdown Project Page">Main</a></li>
+ <li><a href="/projects/markdown/basics" title="Markdown Basics">Basics</a></li>
+ <li><a class="selected" title="Markdown Syntax Documentation">Syntax</a></li>
+ <li><a href="/projects/markdown/license" title="Pricing and License Information">License</a></li>
+ <li><a href="/projects/markdown/dingus" title="Online Markdown Web Form">Dingus</a></li>
+</ul>
+ RAW
+
+ list(:BULLET,
+ item(nil,
+ para("{Overview}[#overview]"),
+ list(:BULLET,
+ item(nil,
+ para("{Philosophy}[#philosophy]")),
+ item(nil,
+ para("{Inline HTML}[#html]")),
+ item(nil,
+ para("{Automatic Escaping for Special Characters}[#autoescape]")))),
+ item(nil,
+ para("{Block Elements}[#block]"),
+ list(:BULLET,
+ item(nil,
+ para("{Paragraphs and Line Breaks}[#p]")),
+ item(nil,
+ para("{Headers}[#header]")),
+ item(nil,
+ para("{Blockquotes}[#blockquote]")),
+ item(nil,
+ para("{Lists}[#list]")),
+ item(nil,
+ para("{Code Blocks}[#precode]")),
+ item(nil,
+ para("{Horizontal Rules}[#hr]")))),
+ item(nil,
+ para("{Span Elements}[#span]"),
+ list(:BULLET,
+ item(nil,
+ para("{Links}[#link]")),
+ item(nil,
+ para("{Emphasis}[#em]")),
+ item(nil,
+ para("{Code}[#code]")),
+ item(nil,
+ para("{Images}[#img]")))),
+ item(nil,
+ para("{Miscellaneous}[#misc]"),
+ list(:BULLET,
+ item(nil,
+ para("{Backslash Escapes}[#backslash]")),
+ item(nil,
+ para("{Automatic Links}[#autolink]"))))),
+
+ para("<b>Note:</b> This document is itself written using Markdown; you\n" +
+ "can {see the source for it by adding '.text' to the URL}[/projects/markdown/syntax.text]."),
+
+ rule(1),
+
+ raw("<h2 id=\"overview\">Overview</h2>"),
+
+ raw("<h3 id=\"philosophy\">Philosophy</h3>"),
+
+ para("Markdown is intended to be as easy-to-read and easy-to-write as is feasible."),
+
+ para("Readability, however, is emphasized above all else. A Markdown-formatted\n" +
+ "document should be publishable as-is, as plain text, without looking\n" +
+ "like it's been marked up with tags or formatting instructions. While\n" +
+ "Markdown's syntax has been influenced by several existing text-to-HTML\n" +
+ "filters -- including {Setext}[http://docutils.sourceforge.net/mirror/setext.html], {atx}[http://www.aaronsw.com/2002/atx/], {Textile}[http://textism.com/tools/textile/], {reStructuredText}[http://docutils.sourceforge.net/rst.html],\n" +
+ "{Grutatext}[http://www.triptico.com/software/grutatxt.html], and {EtText}[http://ettext.taint.org/doc/] -- the single biggest source of\n" +
+ "inspiration for Markdown's syntax is the format of plain text email."),
+
+ para("To this end, Markdown's syntax is comprised entirely of punctuation\n" +
+ "characters, which punctuation characters have been carefully chosen so\n" +
+ "as to look like what they mean. E.g., asterisks around a word actually\n" +
+ "look like \*emphasis\*. Markdown lists look like, well, lists. Even\n" +
+ "blockquotes look like quoted passages of text, assuming you've ever\n" +
+ "used email."),
+
+ raw("<h3 id=\"html\">Inline HTML</h3>"),
+
+ para("Markdown's syntax is intended for one purpose: to be used as a\n" +
+ "format for _writing_ for the web."),
+
+ para("Markdown is not a replacement for HTML, or even close to it. Its\n" +
+ "syntax is very small, corresponding only to a very small subset of\n" +
+ "HTML tags. The idea is _not_ to create a syntax that makes it easier\n" +
+ "to insert HTML tags. In my opinion, HTML tags are already easy to\n" +
+ "insert. The idea for Markdown is to make it easy to read, write, and\n" +
+ "edit prose. HTML is a _publishing_ format; Markdown is a _writing_\n" +
+ "format. Thus, Markdown's formatting syntax only addresses issues that\n" +
+ "can be conveyed in plain text."),
+
+ para("For any markup that is not covered by Markdown's syntax, you simply\n" +
+ "use HTML itself. There's no need to preface it or delimit it to\n" +
+ "indicate that you're switching from Markdown to HTML; you just use\n" +
+ "the tags."),
+
+ para("The only restrictions are that block-level HTML elements -- e.g. <code><div></code>,\n" +
+ "<code><table></code>, <code><pre></code>, <code><p></code>, etc. -- must be separated from surrounding\n" +
+ "content by blank lines, and the start and end tags of the block should\n" +
+ "not be indented with tabs or spaces. Markdown is smart enough not\n" +
+ "to add extra (unwanted) <code><p></code> tags around HTML block-level tags."),
+
+ para("For example, to add an HTML table to a Markdown article:"),
+
+ verb("This is a regular paragraph.\n",
+ "\n",
+ "<table>\n",
+ " <tr>\n",
+ " <td>Foo</td>\n",
+ " </tr>\n",
+ "</table>\n",
+ "\n",
+ "This is another regular paragraph.\n"),
+
+ para("Note that Markdown formatting syntax is not processed within block-level\n" +
+ "HTML tags. E.g., you can't use Markdown-style <code>*emphasis*</code> inside an\n" +
+ "HTML block."),
+
+ para("Span-level HTML tags -- e.g. <code><span></code>, <code><cite></code>, or <code><del></code> -- can be\n" +
+ "used anywhere in a Markdown paragraph, list item, or header. If you\n" +
+ "want, you can even use HTML tags instead of Markdown formatting; e.g. if\n" +
+ "you'd prefer to use HTML <code><a></code> or <code><img></code> tags instead of Markdown's\n" +
+ "link or image syntax, go right ahead."),
+
+ para("Unlike block-level HTML tags, Markdown syntax _is_ processed within\n" +
+ "span-level tags."),
+
+ raw("<h3 id=\"autoescape\">Automatic Escaping for Special Characters</h3>"),
+
+ para("In HTML, there are two characters that demand special treatment: <code><</code>\n" +
+ "and <code>&</code>. Left angle brackets are used to start tags; ampersands are\n" +
+ "used to denote HTML entities. If you want to use them as literal\n" +
+ "characters, you must escape them as entities, e.g. <code>&lt;</code>, and\n" +
+ "<code>&amp;</code>."),
+
+ para("Ampersands in particular are bedeviling for web writers. If you want to\n" +
+ "write about 'AT&T', you need to write '<code>AT&amp;T</code>'. You even need to\n" +
+ "escape ampersands within URLs. Thus, if you want to link to:"),
+
+ verb("http://images.google.com/images?num=30&q=larry+bird\n"),
+
+ para("you need to encode the URL as:"),
+
+ verb("http://images.google.com/images?num=30&amp;q=larry+bird\n"),
+
+ para("in your anchor tag <code>href</code> attribute. Needless to say, this is easy to\n" +
+ "forget, and is probably the single most common source of HTML validation\n" +
+ "errors in otherwise well-marked-up web sites."),
+
+ para("Markdown allows you to use these characters naturally, taking care of\n" +
+ "all the necessary escaping for you. If you use an ampersand as part of\n" +
+ "an HTML entity, it remains unchanged; otherwise it will be translated\n" +
+ "into <code>&amp;</code>."),
+
+ para("So, if you want to include a copyright symbol in your article, you can write:"),
+
+ verb("&copy;\n"),
+
+ para("and Markdown will leave it alone. But if you write:"),
+
+ verb("AT&T\n"),
+
+ para("Markdown will translate it to:"),
+
+ verb("AT&amp;T\n"),
+
+ para("Similarly, because Markdown supports {inline HTML}[#html], if you use\n" +
+ "angle brackets as delimiters for HTML tags, Markdown will treat them as\n" +
+ "such. But if you write:"),
+
+ verb("4 < 5\n"),
+
+ para("Markdown will translate it to:"),
+
+ verb("4 &lt; 5\n"),
+
+ para("However, inside Markdown code spans and blocks, angle brackets and\n" +
+ "ampersands are _always_ encoded automatically. This makes it easy to use\n" +
+ "Markdown to write about HTML code. (As opposed to raw HTML, which is a\n" +
+ "terrible format for writing about HTML syntax, because every single <code><</code>\n" +
+ "and <code>&</code> in your example code needs to be escaped.)"),
+
+ rule(1),
+
+ raw("<h2 id=\"block\">Block Elements</h2>"),
+
+ raw("<h3 id=\"p\">Paragraphs and Line Breaks</h3>"),
+
+ para("A paragraph is simply one or more consecutive lines of text, separated\n" +
+ "by one or more blank lines. (A blank line is any line that looks like a\n" +
+ "blank line -- a line containing nothing but spaces or tabs is considered\n" +
+ "blank.) Normal paragraphs should not be intended with spaces or tabs."),
+
+ para("The implication of the \"one or more consecutive lines of text\" rule is\n" +
+ "that Markdown supports \"hard-wrapped\" text paragraphs. This differs\n" +
+ "significantly from most other text-to-HTML formatters (including Movable\n" +
+ "Type's \"Convert Line Breaks\" option) which translate every line break\n" +
+ "character in a paragraph into a <code><br /></code> tag."),
+
+ para("When you _do_ want to insert a <code><br /></code> break tag using Markdown, you\n" +
+ "end a line with two or more spaces, then type return."),
+
+ para("Yes, this takes a tad more effort to create a <code><br /></code>, but a simplistic\n" +
+ "\"every line break is a <code><br /></code>\" rule wouldn't work for Markdown.\n" +
+ "Markdown's email-style {blockquoting}[#blockquote] and multi-paragraph {list items}[#list]\n" +
+ "work best -- and look better -- when you format them with hard breaks."),
+
+ raw("<h3 id=\"header\">Headers</h3>"),
+
+ para("Markdown supports two styles of headers, {Setext}[http://docutils.sourceforge.net/mirror/setext.html] and {atx}[http://www.aaronsw.com/2002/atx/]."),
+
+ para("Setext-style headers are \"underlined\" using equal signs (for first-level\n" +
+ "headers) and dashes (for second-level headers). For example:"),
+
+ verb("This is an H1\n",
+ "=============\n",
+ "\n",
+ "This is an H2\n",
+ "-------------\n"),
+
+ para("Any number of underlining <code>=</code>'s or <code>-</code>'s will work."),
+
+ para("Atx-style headers use 1-6 hash characters at the start of the line,\n" +
+ "corresponding to header levels 1-6. For example:"),
+
+ verb("# This is an H1\n",
+ "\n",
+ "## This is an H2\n",
+ "\n",
+ "###### This is an H6\n"),
+
+ para("Optionally, you may \"close\" atx-style headers. This is purely\n" +
+ "cosmetic -- you can use this if you think it looks better. The\n" +
+ "closing hashes don't even need to match the number of hashes\n" +
+ "used to open the header. (The number of opening hashes\n" +
+ "determines the header level.) :"),
+
+ verb("# This is an H1 #\n",
+ "\n",
+ "## This is an H2 ##\n",
+ "\n",
+ "### This is an H3 ######\n"),
+
+ raw("<h3 id=\"blockquote\">Blockquotes</h3>"),
+
+ para(
+ "Markdown uses email-style <code>></code> characters for blockquoting. If you're\n" +
+ "familiar with quoting passages of text in an email message, then you\n" +
+ "know how to create a blockquote in Markdown. It looks best if you hard\n" +
+ "wrap the text and put a <code>></code> before every line:"),
+
+ verb("> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,\n",
+ "> consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.\n",
+ "> Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.\n",
+ "> \n",
+ "> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse\n",
+ "> id sem consectetuer libero luctus adipiscing.\n"),
+
+ para("Markdown allows you to be lazy and only put the <code>></code> before the first\n" +
+ "line of a hard-wrapped paragraph:"),
+
+ verb("> This is a blockquote with two paragraphs. Lorem ipsum dolor sit amet,\n",
+ "consectetuer adipiscing elit. Aliquam hendrerit mi posuere lectus.\n",
+ "Vestibulum enim wisi, viverra nec, fringilla in, laoreet vitae, risus.\n",
+ "\n",
+ "> Donec sit amet nisl. Aliquam semper ipsum sit amet velit. Suspendisse\n",
+ "id sem consectetuer libero luctus adipiscing.\n"),
+
+ para("Blockquotes can be nested (i.e. a blockquote-in-a-blockquote) by\n" +
+ "adding additional levels of <code>></code>:"),
+
+ verb("> This is the first level of quoting.\n",
+ ">\n",
+ "> > This is nested blockquote.\n",
+ ">\n",
+ "> Back to the first level.\n"),
+
+ para("Blockquotes can contain other Markdown elements, including headers, lists,\n" +
+ "and code blocks:"),
+
+ verb("> ## This is a header.\n",
+ "> \n",
+ "> 1. This is the first list item.\n",
+ "> 2. This is the second list item.\n",
+ "> \n",
+ "> Here's some example code:\n",
+ "> \n",
+ "> return shell_exec(\"echo $input | $markdown_script\");\n"),
+
+ para("Any decent text editor should make email-style quoting easy. For\n" +
+ "example, with BBEdit, you can make a selection and choose Increase\n" +
+ "Quote Level from the Text menu."),
+
+ raw("<h3 id=\"list\">Lists</h3>"),
+
+ para("Markdown supports ordered (numbered) and unordered (bulleted) lists."),
+
+ para("Unordered lists use asterisks, pluses, and hyphens -- interchangably\n" +
+ "-- as list markers:"),
+
+ verb("* Red\n",
+ "* Green\n",
+ "* Blue\n"),
+
+ para("is equivalent to:"),
+
+ verb("+ Red\n",
+ "+ Green\n",
+ "+ Blue\n"),
+
+ para("and:"),
+
+ verb("- Red\n",
+ "- Green\n",
+ "- Blue\n"),
+
+ para("Ordered lists use numbers followed by periods:"),
+
+ verb("1. Bird\n",
+ "2. McHale\n",
+ "3. Parish\n"),
+
+ para("It's important to note that the actual numbers you use to mark the\n" +
+ "list have no effect on the HTML output Markdown produces. The HTML\n" +
+ "Markdown produces from the above list is:"),
+
+ verb("<ol>\n",
+ "<li>Bird</li>\n",
+ "<li>McHale</li>\n",
+ "<li>Parish</li>\n",
+ "</ol>\n"),
+
+ para("If you instead wrote the list in Markdown like this:"),
+
+ verb("1. Bird\n",
+ "1. McHale\n",
+ "1. Parish\n"),
+
+ para("or even:"),
+
+ verb("3. Bird\n",
+ "1. McHale\n",
+ "8. Parish\n"),
+
+ para("you'd get the exact same HTML output. The point is, if you want to,\n" +
+ "you can use ordinal numbers in your ordered Markdown lists, so that\n" +
+ "the numbers in your source match the numbers in your published HTML.\n" +
+ "But if you want to be lazy, you don't have to."),
+
+ para("If you do use lazy list numbering, however, you should still start the\n" +
+ "list with the number 1. At some point in the future, Markdown may support\n" +
+ "starting ordered lists at an arbitrary number."),
+
+ para("List markers typically start at the left margin, but may be indented by\n" +
+ "up to three spaces. List markers must be followed by one or more spaces\n" +
+ "or a tab."),
+
+ para("To make lists look nice, you can wrap items with hanging indents:"),
+
+ verb("* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n",
+ " Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,\n",
+ " viverra nec, fringilla in, laoreet vitae, risus.\n",
+ "* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.\n",
+ " Suspendisse id sem consectetuer libero luctus adipiscing.\n"),
+
+ para("But if you want to be lazy, you don't have to:"),
+
+ verb("* Lorem ipsum dolor sit amet, consectetuer adipiscing elit.\n",
+ "Aliquam hendrerit mi posuere lectus. Vestibulum enim wisi,\n",
+ "viverra nec, fringilla in, laoreet vitae, risus.\n",
+ "* Donec sit amet nisl. Aliquam semper ipsum sit amet velit.\n",
+ "Suspendisse id sem consectetuer libero luctus adipiscing.\n"),
+
+ para("If list items are separated by blank lines, Markdown will wrap the\n" +
+ "items in <code><p></code> tags in the HTML output. For example, this input:"),
+
+ verb("* Bird\n",
+ "* Magic\n"),
+
+ para("will turn into:"),
+
+ verb("<ul>\n",
+ "<li>Bird</li>\n",
+ "<li>Magic</li>\n",
+ "</ul>\n"),
+
+ para("But this:"),
+
+ verb("* Bird\n",
+ "\n",
+ "* Magic\n"),
+
+ para("will turn into:"),
+
+ verb("<ul>\n",
+ "<li><p>Bird</p></li>\n",
+ "<li><p>Magic</p></li>\n",
+ "</ul>\n"),
+
+ para("List items may consist of multiple paragraphs. Each subsequent\n" +
+ "paragraph in a list item must be intended by either 4 spaces\n" +
+ "or one tab:"),
+
+ verb("1. This is a list item with two paragraphs. Lorem ipsum dolor\n",
+ " sit amet, consectetuer adipiscing elit. Aliquam hendrerit\n",
+ " mi posuere lectus.\n",
+ "\n",
+ " Vestibulum enim wisi, viverra nec, fringilla in, laoreet\n",
+ " vitae, risus. Donec sit amet nisl. Aliquam semper ipsum\n",
+ " sit amet velit.\n",
+ "\n",
+ "2. Suspendisse id sem consectetuer libero luctus adipiscing.\n"),
+
+ para("It looks nice if you indent every line of the subsequent\n" +
+ "paragraphs, but here again, Markdown will allow you to be\n" +
+ "lazy:"),
+
+ verb("* This is a list item with two paragraphs.\n",
+ "\n",
+ " This is the second paragraph in the list item. You're\n",
+ "only required to indent the first line. Lorem ipsum dolor\n",
+ "sit amet, consectetuer adipiscing elit.\n",
+ "\n",
+ "* Another item in the same list.\n"),
+
+ para("To put a blockquote within a list item, the blockquote's <code>></code>\n" +
+ "delimiters need to be indented:"),
+
+ verb("* A list item with a blockquote:\n",
+ "\n",
+ " > This is a blockquote\n",
+ " > inside a list item.\n"),
+
+ para(
+ "To put a code block within a list item, the code block needs\n" +
+ "to be indented _twice_ -- 8 spaces or two tabs:"),
+
+ verb("* A list item with a code block:\n",
+ "\n",
+ " <code goes here>\n"),
+
+ para("It's worth noting that it's possible to trigger an ordered list by\n" +
+ "accident, by writing something like this:"),
+
+ verb("1986. What a great season.\n"),
+
+ para("In other words, a <em>number-period-space</em> sequence at the beginning of a\n" +
+ "line. To avoid this, you can backslash-escape the period:"),
+
+ verb("1986\\. What a great season.\n"),
+
+ raw("<h3 id=\"precode\">Code Blocks</h3>"),
+
+ para("Pre-formatted code blocks are used for writing about programming or\n" +
+ "markup source code. Rather than forming normal paragraphs, the lines\n" +
+ "of a code block are interpreted literally. Markdown wraps a code block\n" +
+ "in both <code><pre></code> and <code><code></code> tags."),
+
+ para("To produce a code block in Markdown, simply indent every line of the\n" +
+ "block by at least 4 spaces or 1 tab. For example, given this input:"),
+
+ verb("This is a normal paragraph:\n",
+ "\n",
+ " This is a code block.\n"),
+
+ para("Markdown will generate:"),
+
+ verb("<p>This is a normal paragraph:</p>\n",
+ "\n",
+ "<pre><code>This is a code block.\n",
+ "</code></pre>\n"),
+
+ para("One level of indentation -- 4 spaces or 1 tab -- is removed from each\n" +
+ "line of the code block. For example, this:"),
+
+ verb("Here is an example of AppleScript:\n",
+ "\n",
+ " tell application \"Foo\"\n",
+ " beep\n",
+ " end tell\n"),
+
+ para("will turn into:"),
+
+ verb("<p>Here is an example of AppleScript:</p>\n",
+ "\n",
+ "<pre><code>tell application \"Foo\"\n",
+ " beep\n",
+ "end tell\n",
+ "</code></pre>\n"),
+
+ para("A code block continues until it reaches a line that is not indented\n" +
+ "(or the end of the article)."),
+
+ para("Within a code block, ampersands (<code>&</code>) and angle brackets (<code><</code> and <code>></code>)\n" +
+ "are automatically converted into HTML entities. This makes it very\n" +
+ "easy to include example HTML source code using Markdown -- just paste\n" +
+ "it and indent it, and Markdown will handle the hassle of encoding the\n" +
+ "ampersands and angle brackets. For example, this:"),
+
+ verb(" <div class=\"footer\">\n",
+ " &copy; 2004 Foo Corporation\n",
+ " </div>\n"),
+
+ para("will turn into:"),
+
+ verb("<pre><code>&lt;div class=\"footer\"&gt;\n",
+ " &amp;copy; 2004 Foo Corporation\n",
+ "&lt;/div&gt;\n",
+ "</code></pre>\n"),
+
+ para("Regular Markdown syntax is not processed within code blocks. E.g.,\n" +
+ "asterisks are just literal asterisks within a code block. This means\n" +
+ "it's also easy to use Markdown to write about Markdown's own syntax."),
+
+ raw("<h3 id=\"hr\">Horizontal Rules</h3>"),
+
+ para("You can produce a horizontal rule tag (<code><hr /></code>) by placing three or\n" +
+ "more hyphens, asterisks, or underscores on a line by themselves. If you\n" +
+ "wish, you may use spaces between the hyphens or asterisks. Each of the\n" +
+ "following lines will produce a horizontal rule:"),
+
+ verb("* * *\n",
+ "\n",
+ "***\n",
+ "\n",
+ "*****\n",
+ "\n",
+ "- - -\n",
+ "\n",
+ "---------------------------------------\n",
+ "\n",
+ "_ _ _\n"),
+
+ rule(1),
+
+ raw("<h2 id=\"span\">Span Elements</h2>"),
+
+ raw("<h3 id=\"link\">Links</h3>"),
+
+ para("Markdown supports two style of links: _inline_ and _reference_."),
+
+ para("In both styles, the link text is delimited by [square brackets]."),
+
+ para("To create an inline link, use a set of regular parentheses immediately\n" +
+ "after the link text's closing square bracket. Inside the parentheses,\n" +
+ "put the URL where you want the link to point, along with an _optional_\n" +
+ "title for the link, surrounded in quotes. For example:"),
+
+ verb("This is [an example](http://example.com/ \"Title\") inline link.\n",
+ "\n",
+ "[This link](http://example.net/) has no title attribute.\n"),
+
+ para("Will produce:"),
+
+ verb("<p>This is <a href=\"http://example.com/\" title=\"Title\">\n",
+ "an example</a> inline link.</p>\n",
+ "\n",
+ "<p><a href=\"http://example.net/\">This link</a> has no\n",
+ "title attribute.</p>\n"),
+
+ para("If you're referring to a local resource on the same server, you can\n" +
+ "use relative paths:"),
+
+ verb("See my [About](/about/) page for details.\n"),
+
+ para("Reference-style links use a second set of square brackets, inside\n" +
+ "which you place a label of your choosing to identify the link:"),
+
+ verb("This is [an example][id] reference-style link.\n"),
+
+ para("You can optionally use a space to separate the sets of brackets:"),
+
+ verb("This is [an example] [id] reference-style link.\n"),
+
+ para("Then, anywhere in the document, you define your link label like this,\n" +
+ "on a line by itself:"),
+
+ verb("[id]: http://example.com/ \"Optional Title Here\"\n"),
+
+ para("That is:"),
+
+ list(:BULLET,
+ item(nil,
+ para("Square brackets containing the link identifier (optionally\n" +
+ "indented from the left margin using up to three spaces);")),
+ item(nil,
+ para("followed by a colon;")),
+ item(nil,
+ para("followed by one or more spaces (or tabs);")),
+ item(nil,
+ para("followed by the URL for the link;")),
+ item(nil,
+ para("optionally followed by a title attribute for the link, enclosed\n" +
+ "in double or single quotes."))),
+
+ para("The link URL may, optionally, be surrounded by angle brackets:"),
+
+ verb("[id]: <http://example.com/> \"Optional Title Here\"\n"),
+
+ para("You can put the title attribute on the next line and use extra spaces\n" +
+ "or tabs for padding, which tends to look better with longer URLs:"),
+
+ verb("[id]: http://example.com/longish/path/to/resource/here\n",
+ " \"Optional Title Here\"\n"),
+
+ para("Link definitions are only used for creating links during Markdown\n" +
+ "processing, and are stripped from your document in the HTML output."),
+
+ para("Link definition names may constist of letters, numbers, spaces, and punctuation -- but they are _not_ case sensitive. E.g. these two links:"),
+
+ verb("[link text][a]\n",
+ "[link text][A]\n"),
+
+ para("are equivalent."),
+
+ para("The <em>implicit link name</em> shortcut allows you to omit the name of the\n" +
+ "link, in which case the link text itself is used as the name.\n" +
+ "Just use an empty set of square brackets -- e.g., to link the word\n" +
+ "\"Google\" to the google.com web site, you could simply write:"),
+
+ verb("[Google][]\n"),
+
+ para("And then define the link:"),
+
+ verb("[Google]: http://google.com/\n"),
+
+ para("Because link names may contain spaces, this shortcut even works for\n" +
+ "multiple words in the link text:"),
+
+
+ verb("Visit [Daring Fireball][] for more information.\n"),
+
+ para("And then define the link:"),
+
+ verb("[Daring Fireball]: http://daringfireball.net/\n"),
+
+ para("Link definitions can be placed anywhere in your Markdown document. I\n" +
+ "tend to put them immediately after each paragraph in which they're\n" +
+ "used, but if you want, you can put them all at the end of your\n" +
+ "document, sort of like footnotes."),
+
+ para("Here's an example of reference links in action:"),
+
+ verb("I get 10 times more traffic from [Google] [1] than from\n",
+ "[Yahoo] [2] or [MSN] [3].\n",
+ "\n",
+ " [1]: http://google.com/ \"Google\"\n",
+ " [2]: http://search.yahoo.com/ \"Yahoo Search\"\n",
+ " [3]: http://search.msn.com/ \"MSN Search\"\n"),
+
+ para("Using the implicit link name shortcut, you could instead write:"),
+
+ verb("I get 10 times more traffic from [Google][] than from\n",
+ "[Yahoo][] or [MSN][].\n",
+ "\n",
+ " [google]: http://google.com/ \"Google\"\n",
+ " [yahoo]: http://search.yahoo.com/ \"Yahoo Search\"\n",
+ " [msn]: http://search.msn.com/ \"MSN Search\"\n"),
+
+ para("Both of the above examples will produce the following HTML output:"),
+
+ verb("<p>I get 10 times more traffic from <a href=\"http://google.com/\"\n",
+ "title=\"Google\">Google</a> than from\n",
+ "<a href=\"http://search.yahoo.com/\" title=\"Yahoo Search\">Yahoo</a>\n",
+ "or <a href=\"http://search.msn.com/\" title=\"MSN Search\">MSN</a>.</p>\n"),
+
+ para("For comparison, here is the same paragraph written using\n" +
+ "Markdown's inline link style:"),
+
+ verb("I get 10 times more traffic from [Google](http://google.com/ \"Google\")\n",
+ "than from [Yahoo](http://search.yahoo.com/ \"Yahoo Search\") or\n",
+ "[MSN](http://search.msn.com/ \"MSN Search\").\n"),
+
+ para("The point of reference-style links is not that they're easier to\n" +
+ "write. The point is that with reference-style links, your document\n" +
+ "source is vastly more readable. Compare the above examples: using\n" +
+ "reference-style links, the paragraph itself is only 81 characters\n" +
+ "long; with inline-style links, it's 176 characters; and as raw HTML,\n" +
+ "it's 234 characters. In the raw HTML, there's more markup than there\n" +
+ "is text."),
+
+ para("With Markdown's reference-style links, a source document much more\n" +
+ "closely resembles the final output, as rendered in a browser. By\n" +
+ "allowing you to move the markup-related metadata out of the paragraph,\n" +
+ "you can add links without interrupting the narrative flow of your\n" +
+ "prose."),
+
+ raw("<h3 id=\"em\">Emphasis</h3>"),
+
+ para("Markdown treats asterisks (<code>*</code>) and underscores (<code>_</code>) as indicators of\n" +
+ "emphasis. Text wrapped with one <code>*</code> or <code>_</code> will be wrapped with an\n" +
+ "HTML <code><em></code> tag; double <code>*</code>'s or <code>_</code>'s will be wrapped with an HTML\n" +
+ "<code><strong></code> tag. E.g., this input:"),
+
+ verb("*single asterisks*\n",
+ "\n",
+ "_single underscores_\n",
+ "\n",
+ "**double asterisks**\n",
+ "\n",
+ "__double underscores__\n"),
+
+ para("will produce:"),
+
+ verb("<em>single asterisks</em>\n",
+ "\n",
+ "<em>single underscores</em>\n",
+ "\n",
+ "<strong>double asterisks</strong>\n",
+ "\n",
+ "<strong>double underscores</strong>\n"),
+
+ para("You can use whichever style you prefer; the lone restriction is that\n" +
+ "the same character must be used to open and close an emphasis span."),
+
+ para("Emphasis can be used in the middle of a word:"),
+
+ verb("un*fucking*believable\n"),
+
+ para("But if you surround an <code>*</code> or <code>_</code> with spaces, it'll be treated as a\n" +
+ "literal asterisk or underscore."),
+
+ para("To produce a literal asterisk or underscore at a position where it\n" +
+ "would otherwise be used as an emphasis delimiter, you can backslash\n" +
+ "escape it:"),
+
+ verb("\\*this text is surrounded by literal asterisks\\*\n"),
+
+ raw("<h3 id=\"code\">Code</h3>"),
+
+ para("To indicate a span of code, wrap it with backtick quotes (<code>`</code>).\n" +
+ "Unlike a pre-formatted code block, a code span indicates code within a\n" +
+ "normal paragraph. For example:"),
+
+ verb("Use the `printf()` function.\n"),
+
+ para("will produce:"),
+
+ verb("<p>Use the <code>printf()</code> function.</p>\n"),
+
+ para("To include a literal backtick character within a code span, you can use\n" +
+ "multiple backticks as the opening and closing delimiters:"),
+
+ verb("``There is a literal backtick (`) here.``\n"),
+
+ para("which will produce this:"),
+
+ verb("<p><code>There is a literal backtick (`) here.</code></p>\n"),
+
+ para("The backtick delimiters surrounding a code span may include spaces --\n" +
+ "one after the opening, one before the closing. This allows you to place\n" +
+ "literal backtick characters at the beginning or end of a code span:"),
+
+ verb("A single backtick in a code span: `` ` ``\n",
+ "\n",
+ "A backtick-delimited string in a code span: `` `foo` ``\n"),
+
+ para("will produce:"),
+
+ verb("<p>A single backtick in a code span: <code>`</code></p>\n",
+ "\n",
+ "<p>A backtick-delimited string in a code span: <code>`foo`</code></p>\n"),
+
+ para("With a code span, ampersands and angle brackets are encoded as HTML\n" +
+ "entities automatically, which makes it easy to include example HTML\n" +
+ "tags. Markdown will turn this:"),
+
+ verb("Please don't use any `<blink>` tags.\n"),
+
+ para("into:"),
+
+ verb("<p>Please don't use any <code>&lt;blink&gt;</code> tags.</p>\n"),
+
+ para("You can write this:"),
+
+ verb("`&#8212;` is the decimal-encoded equivalent of `&mdash;`.\n"),
+
+ para("to produce:"),
+
+ verb( "<p><code>&amp;#8212;</code> is the decimal-encoded\n",
+ "equivalent of <code>&amp;mdash;</code>.</p>\n"),
+
+ raw("<h3 id=\"img\">Images</h3>"),
+
+ para("Admittedly, it's fairly difficult to devise a \"natural\" syntax for\n" +
+ "placing images into a plain text document format."),
+
+ para("Markdown uses an image syntax that is intended to resemble the syntax\n" +
+ "for links, allowing for two styles: _inline_ and _reference_."),
+
+ para("Inline image syntax looks like this:"),
+
+ verb("![Alt text](/path/to/img.jpg)\n",
+ "\n",
+ "![Alt text](/path/to/img.jpg \"Optional title\")\n"),
+
+ para("That is:"),
+
+ list(:BULLET,
+ item(nil,
+ para("An exclamation mark: <code>!</code>;")),
+ item(nil,
+ para("followed by a set of square brackets, containing the <code>alt</code>\n" +
+ "attribute text for the image;")),
+ item(nil,
+ para("followed by a set of parentheses, containing the URL or path to\n" +
+ "the image, and an optional <code>title</code> attribute enclosed in double\n" +
+ "or single quotes."))),
+
+ para("Reference-style image syntax looks like this:"),
+
+ verb("![Alt text][id]\n"),
+
+ para("Where \"id\" is the name of a defined image reference. Image references\n" +
+ "are defined using syntax identical to link references:"),
+
+ verb("[id]: url/to/image \"Optional title attribute\"\n"),
+
+ para("As of this writing, Markdown has no syntax for specifying the\n" +
+ "dimensions of an image; if this is important to you, you can simply\n" +
+ "use regular HTML <code><img></code> tags."),
+
+ rule(1),
+
+ raw("<h2 id=\"misc\">Miscellaneous</h2>"),
+
+ raw("<h3 id=\"autolink\">Automatic Links</h3>"),
+
+ para("Markdown supports a shortcut style for creating \"automatic\" links for URLs and email addresses: simply surround the URL or email address with angle brackets. What this means is that if you want to show the actual text of a URL or email address, and also have it be a clickable link, you can do this:"),
+
+ verb("<http://example.com/>\n"),
+
+ para("Markdown will turn this into:"),
+
+ verb("<a href=\"http://example.com/\">http://example.com/</a>\n"),
+
+ para("Automatic links for email addresses work similarly, except that\n" +
+ "Markdown will also perform a bit of randomized decimal and hex\n" +
+ "entity-encoding to help obscure your address from address-harvesting\n" +
+ "spambots. For example, Markdown will turn this:"),
+
+ verb("<address@example.com>\n"),
+
+ para("into something like this:"),
+
+ verb("<a href=\"&#x6D;&#x61;i&#x6C;&#x74;&#x6F;:&#x61;&#x64;&#x64;&#x72;&#x65;\n",
+ "&#115;&#115;&#64;&#101;&#120;&#x61;&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;\n",
+ "&#109;\">&#x61;&#x64;&#x64;&#x72;&#x65;&#115;&#115;&#64;&#101;&#120;&#x61;\n",
+ "&#109;&#x70;&#x6C;e&#x2E;&#99;&#111;&#109;</a>\n"),
+
+ para("which will render in a browser as a clickable link to \"address@example.com\"."),
+
+ para("(This sort of entity-encoding trick will indeed fool many, if not\n" +
+ "most, address-harvesting bots, but it definitely won't fool all of\n" +
+ "them. It's better than nothing, but an address published in this way\n" +
+ "will probably eventually start receiving spam.)"),
+
+ raw("<h3 id=\"backslash\">Backslash Escapes</h3>"),
+
+ para("Markdown allows you to use backslash escapes to generate literal\n" +
+ "characters which would otherwise have special meaning in Markdown's\n" +
+ "formatting syntax. For example, if you wanted to surround a word with\n" +
+ "literal asterisks (instead of an HTML <code><em></code> tag), you can backslashes\n" +
+ "before the asterisks, like this:"),
+
+ verb("\\*literal asterisks\\*\n"),
+
+ para("Markdown provides backslash escapes for the following characters:"),
+
+ verb("\\ backslash\n",
+ "` backtick\n",
+ "* asterisk\n",
+ "_ underscore\n",
+ "{} curly braces\n",
+ "[] square brackets\n",
+ "() parentheses\n",
+ "# hash mark\n",
+ "+ plus sign\n",
+ "- minus sign (hyphen)\n",
+ ". dot\n",
+ "! exclamation mark\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_nested_blockquotes
+ input = File.read "#{MARKDOWN_TEST_PATH}/Nested blockquotes.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ block(
+ para("foo"),
+ block(
+ para("bar")),
+ para("foo")))
+
+ assert_equal expected, doc
+ end
+
+ def test_ordered_and_unordered_lists
+ input = File.read "#{MARKDOWN_TEST_PATH}/Ordered and unordered lists.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ head(2, 'Unordered'),
+
+ para('Asterisks tight:'),
+ list(:BULLET,
+ item(nil, para("asterisk 1")),
+ item(nil, para("asterisk 2")),
+ item(nil, para("asterisk 3"))),
+ para('Asterisks loose:'),
+ list(:BULLET,
+ item(nil, para("asterisk 1")),
+ item(nil, para("asterisk 2")),
+ item(nil, para("asterisk 3"))),
+
+ rule(1),
+
+ para("Pluses tight:"),
+ list(:BULLET,
+ item(nil, para("Plus 1")),
+ item(nil, para("Plus 2")),
+ item(nil, para("Plus 3"))),
+ para("Pluses loose:"),
+ list(:BULLET,
+ item(nil, para("Plus 1")),
+ item(nil, para("Plus 2")),
+ item(nil, para("Plus 3"))),
+
+ rule(1),
+
+ para("Minuses tight:"),
+ list(:BULLET,
+ item(nil, para("Minus 1")),
+ item(nil, para("Minus 2")),
+ item(nil, para("Minus 3"))),
+ para("Minuses loose:"),
+ list(:BULLET,
+ item(nil, para("Minus 1")),
+ item(nil, para("Minus 2")),
+ item(nil, para("Minus 3"))),
+
+ head(2, "Ordered"),
+
+ para("Tight:"),
+ list(:NUMBER,
+ item(nil, para("First")),
+ item(nil, para("Second")),
+ item(nil, para("Third"))),
+ para("and:"),
+ list(:NUMBER,
+ item(nil, para("One")),
+ item(nil, para("Two")),
+ item(nil, para("Three"))),
+
+ para("Loose using tabs:"),
+ list(:NUMBER,
+ item(nil, para("First")),
+ item(nil, para("Second")),
+ item(nil, para("Third"))),
+ para("and using spaces:"),
+ list(:NUMBER,
+ item(nil, para("One")),
+ item(nil, para("Two")),
+ item(nil, para("Three"))),
+
+ para("Multiple paragraphs:"),
+ list(:NUMBER,
+ item(nil,
+ para("Item 1, graf one."),
+ para("Item 2. graf two. The quick brown fox " +
+ "jumped over the lazy dog's\nback.")),
+ item(nil, para("Item 2.")),
+ item(nil, para("Item 3."))),
+
+ head(2, "Nested"),
+ list(:BULLET,
+ item(nil,
+ para("Tab"),
+ list(:BULLET,
+ item(nil,
+ para("Tab"),
+ list(:BULLET,
+ item(nil,
+ para("Tab"))))))),
+
+ para("Here's another:"),
+ list(:NUMBER,
+ item(nil, para("First")),
+ item(nil, para("Second:"),
+ list(:BULLET,
+ item(nil, para("Fee")),
+ item(nil, para("Fie")),
+ item(nil, para("Foe")))),
+ item(nil, para("Third"))),
+
+ para("Same thing but with paragraphs:"),
+ list(:NUMBER,
+ item(nil, para("First")),
+ item(nil, para("Second:"),
+ list(:BULLET,
+ item(nil, para("Fee")),
+ item(nil, para("Fie")),
+ item(nil, para("Foe")))),
+ item(nil, para("Third"))),
+
+ para("This was an error in Markdown 1.0.1:"),
+ list(:BULLET,
+ item(nil,
+ para("this"),
+ list(:BULLET,
+ item(nil, para("sub"))),
+ para("that"))))
+
+ assert_equal expected, doc
+ end
+
+ def test_strong_and_em_together
+ input = File.read "#{MARKDOWN_TEST_PATH}/Strong and em together.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ para("<b><em>This is strong and em.</em></b>"),
+ para("So is <b>_this_</b> word."),
+ para("<b><em>This is strong and em.</em></b>"),
+ para("So is <b>_this_</b> word."))
+
+ assert_equal expected, doc
+ end
+
+ def test_tabs
+ input = File.read "#{MARKDOWN_TEST_PATH}/Tabs.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ list(:BULLET,
+ item(nil,
+ para("this is a list item\nindented with tabs")),
+ item(nil,
+ para("this is a list item\nindented with spaces"))),
+
+ para("Code:"),
+
+ verb("this code block is indented by one tab\n"),
+
+ para("And:"),
+
+ verb("\tthis code block is indented by two tabs\n"),
+
+ para("And:"),
+
+ verb(
+ "+\tthis is an example list item\n",
+ "\tindented with tabs\n",
+ "\n",
+ "+ this is an example list item\n",
+ " indented with spaces\n"))
+
+ assert_equal expected, doc
+ end
+
+ def test_tidyness
+ input = File.read "#{MARKDOWN_TEST_PATH}/Tidyness.text"
+
+ doc = @parser.parse input
+
+ expected =
+ doc(
+ block(
+ para("A list within a blockquote:"),
+ list(:BULLET,
+ item(nil, para("asterisk 1")),
+ item(nil, para("asterisk 2")),
+ item(nil, para("asterisk 3")))))
+
+ assert_equal expected, doc
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup.rb b/test/rdoc/test_rdoc_markup.rb
index ae6c11e7da..5c28a2c6e6 100644
--- a/test/rdoc/test_rdoc_markup.rb
+++ b/test/rdoc/test_rdoc_markup.rb
@@ -1,9 +1,13 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/markup'
-require 'rdoc/markup/to_test'
+require 'rdoc/test_case'
-class TestRDocMarkup < MiniTest::Unit::TestCase
+class TestRDocMarkup < RDoc::TestCase
+
+ def test_class_parse
+ expected = @RM::Document.new(
+ @RM::Paragraph.new('hello'))
+
+ assert_equal expected, RDoc::Markup.parse('hello')
+ end
def test_convert
str = <<-STR
@@ -44,7 +48,7 @@ the time
m = RDoc::Markup.new
m.add_word_pair '{', '}', :STRIKE
- tt = RDoc::Markup::ToTest.new m
+ tt = RDoc::Markup::ToTest.new nil, m
tt.add_tag :STRIKE, 'STRIKE ', ' STRIKE'
out = m.convert str, tt
diff --git a/test/rdoc/test_rdoc_markup_attribute_manager.rb b/test/rdoc/test_rdoc_markup_attribute_manager.rb
index b65457fc7e..36edea3f73 100644
--- a/test/rdoc/test_rdoc_markup_attribute_manager.rb
+++ b/test/rdoc/test_rdoc_markup_attribute_manager.rb
@@ -1,13 +1,10 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc'
-require 'rdoc/markup'
-require 'rdoc/markup/inline'
-require 'rdoc/markup/to_html_crossref'
+require 'rdoc/test_case'
-class TestRDocMarkupAttributeManager < MiniTest::Unit::TestCase
+class TestRDocMarkupAttributeManager < RDoc::TestCase
def setup
+ super
+
@am = RDoc::Markup::AttributeManager.new
@bold_on = @am.changed_attribute_by_name([], [:BOLD])
@@ -32,8 +29,8 @@ class TestRDocMarkupAttributeManager < MiniTest::Unit::TestCase
end
def crossref(text)
- crossref_bitmap = RDoc::Markup::Attribute.bitmap_for(:_SPECIAL_) |
- RDoc::Markup::Attribute.bitmap_for(:CROSSREF)
+ crossref_bitmap = @am.attributes.bitmap_for(:_SPECIAL_) |
+ @am.attributes.bitmap_for(:CROSSREF)
[ @am.changed_attribute_by_name([], [:CROSSREF, :_SPECIAL_]),
RDoc::Markup::Special.new(crossref_bitmap, text),
@@ -212,7 +209,7 @@ class TestRDocMarkupAttributeManager < MiniTest::Unit::TestCase
end
def test_special
- @am.add_special(RDoc::Markup::ToHtmlCrossref::CROSSREF_REGEXP, :CROSSREF)
+ @am.add_special(RDoc::CrossReference::CROSSREF_REGEXP, :CROSSREF)
#
# The apostrophes in "cats'" and "dogs'" suppress the flagging of these
diff --git a/test/rdoc/test_rdoc_markup_attributes.rb b/test/rdoc/test_rdoc_markup_attributes.rb
new file mode 100644
index 0000000000..636e0cca68
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_attributes.rb
@@ -0,0 +1,39 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupAttributes < RDoc::TestCase
+
+ def setup
+ super
+
+ @as = RDoc::Markup::Attributes.new
+ end
+
+ def test_bitmap_for
+ assert_equal 2, @as.bitmap_for('two')
+ assert_equal 2, @as.bitmap_for('two')
+ assert_equal 4, @as.bitmap_for('three')
+ end
+
+ def test_as_string
+ @as.bitmap_for 'two'
+ @as.bitmap_for 'three'
+
+ assert_equal 'none', @as.as_string(0)
+ assert_equal '_SPECIAL_', @as.as_string(1)
+ assert_equal 'two', @as.as_string(2)
+ assert_equal '_SPECIAL_,two', @as.as_string(3)
+ end
+
+ def test_each_name_of
+ @as.bitmap_for 'two'
+ @as.bitmap_for 'three'
+
+ assert_equal %w[], @as.each_name_of(0).to_a
+ assert_equal %w[], @as.each_name_of(1).to_a
+ assert_equal %w[two], @as.each_name_of(2).to_a
+ assert_equal %w[three], @as.each_name_of(4).to_a
+ assert_equal %w[two three], @as.each_name_of(6).to_a
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_document.rb b/test/rdoc/test_rdoc_markup_document.rb
index 9eea019ae4..564434dfe6 100644
--- a/test/rdoc/test_rdoc_markup_document.rb
+++ b/test/rdoc/test_rdoc_markup_document.rb
@@ -1,12 +1,10 @@
-require 'pp'
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/markup'
+require 'rdoc/test_case'
-class TestRDocMarkupDocument < MiniTest::Unit::TestCase
+class TestRDocMarkupDocument < RDoc::TestCase
def setup
- @RM = RDoc::Markup
+ super
+
@d = @RM::Document.new
end
@@ -47,6 +45,21 @@ class TestRDocMarkupDocument < MiniTest::Unit::TestCase
end
end
+ def test_concat
+ @d.concat [@RM::BlankLine.new, @RM::BlankLine.new]
+
+ refute_empty @d
+ end
+
+ def test_each
+ a = @RM::Document.new
+ b = @RM::Document.new(@RM::Paragraph.new('hi'))
+
+ @d.push a, b
+
+ assert_equal [a, b], @d.map { |sub_doc| sub_doc }
+ end
+
def test_empty_eh
assert_empty @d
@@ -82,6 +95,18 @@ class TestRDocMarkupDocument < MiniTest::Unit::TestCase
assert_equal @d, d2
end
+ def test_file_equals
+ @d.file = 'file.rb'
+
+ assert_equal 'file.rb', @d.file
+ end
+
+ def test_file_equals_top_level
+ @d.file = @store.add_file 'file.rb'
+
+ assert_equal 'file.rb', @d.file
+ end
+
def test_lt2
@d << @RM::BlankLine.new
@@ -148,5 +173,23 @@ class TestRDocMarkupDocument < MiniTest::Unit::TestCase
refute_empty @d
end
+ def test_table_of_contents
+ doc = @RM::Document.new(
+ @RM::Heading.new(1, 'A'),
+ @RM::Paragraph.new('B'),
+ @RM::Heading.new(2, 'C'),
+ @RM::Paragraph.new('D'),
+ @RM::Heading.new(1, 'E'),
+ @RM::Paragraph.new('F'))
+
+ expected = [
+ @RM::Heading.new(1, 'A'),
+ @RM::Heading.new(2, 'C'),
+ @RM::Heading.new(1, 'E'),
+ ]
+
+ assert_equal expected, doc.table_of_contents
+ end
+
end
diff --git a/test/rdoc/test_rdoc_markup_formatter.rb b/test/rdoc/test_rdoc_markup_formatter.rb
index 73e75e2aa1..9512babce3 100644
--- a/test/rdoc/test_rdoc_markup_formatter.rb
+++ b/test/rdoc/test_rdoc_markup_formatter.rb
@@ -1,17 +1,13 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc'
-require 'rdoc/markup'
-require 'rdoc/markup/formatter'
+require 'rdoc/test_case'
-class TestRDocMarkupFormatter < MiniTest::Unit::TestCase
+class TestRDocMarkupFormatter < RDoc::TestCase
class ToTest < RDoc::Markup::Formatter
def initialize markup
- super
+ super nil, markup
- add_tag :TT, '<tt>', '</tt>'
+ add_tag :TT, '<code>', '</code>'
end
def accept_paragraph paragraph
@@ -37,20 +33,25 @@ class TestRDocMarkupFormatter < MiniTest::Unit::TestCase
end
def setup
- @markup = RDoc::Markup.new
+ super
+
+ @markup = @RM.new
@markup.add_special(/[A-Z]+/, :CAPS)
+ @attribute_manager = @markup.attribute_manager
+ @attributes = @attribute_manager.attributes
+
@to = ToTest.new @markup
- @caps = RDoc::Markup::Attribute.bitmap_for :CAPS
- @special = RDoc::Markup::Attribute.bitmap_for :_SPECIAL_
- @tt = RDoc::Markup::Attribute.bitmap_for :TT
+ @caps = @attributes.bitmap_for :CAPS
+ @special = @attributes.bitmap_for :_SPECIAL_
+ @tt = @attributes.bitmap_for :TT
end
def test_convert_tt_special
- converted = @to.convert '<tt>AAA</tt>'
+ converted = @to.convert '<code>AAA</code>'
- assert_equal '<tt>AAA</tt>', converted
+ assert_equal '<code>AAA</code>', converted
end
end
diff --git a/test/rdoc/test_rdoc_markup_hard_break.rb b/test/rdoc/test_rdoc_markup_hard_break.rb
new file mode 100644
index 0000000000..b9f7873160
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_hard_break.rb
@@ -0,0 +1,31 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupHardBreak < RDoc::TestCase
+
+ def setup
+ super
+
+ @hb = RDoc::Markup::HardBreak.new
+ end
+
+ def test_accept
+ visitor = Object.new
+
+ def visitor.accept_hard_break(obj) @obj = obj end
+ def visitor.obj() @obj end
+
+ @hb.accept visitor
+
+ assert_same @hb, visitor.obj
+ end
+
+ def test_equals2
+ other = RDoc::Markup::HardBreak.new
+
+ assert_equal @hb, other
+
+ refute_equal @hb, Object.new
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_heading.rb b/test/rdoc/test_rdoc_markup_heading.rb
new file mode 100644
index 0000000000..eef051a64e
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_heading.rb
@@ -0,0 +1,20 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupHeading < RDoc::TestCase
+
+ def setup
+ super
+
+ @h = RDoc::Markup::Heading.new 1, 'Hello *Friend*!'
+ end
+
+ def test_aref
+ assert_equal 'label-Hello+Friend%21', @h.aref
+ end
+
+ def test_plain_html
+ assert_equal 'Hello <strong>Friend</strong>!', @h.plain_html
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_include.rb b/test/rdoc/test_rdoc_markup_include.rb
new file mode 100644
index 0000000000..37a5b320e9
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_include.rb
@@ -0,0 +1,19 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupInclude < RDoc::TestCase
+
+ def setup
+ super
+
+ @include = @RM::Include.new 'file', [Dir.tmpdir]
+ end
+
+ def test_equals2
+ assert_equal @include, @RM::Include.new('file', [Dir.tmpdir])
+ refute_equal @include, @RM::Include.new('file', %w[.])
+ refute_equal @include, @RM::Include.new('other', [Dir.tmpdir])
+ refute_equal @include, Object.new
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_indented_paragraph.rb b/test/rdoc/test_rdoc_markup_indented_paragraph.rb
index e3e2b630e1..d8dd795e5b 100644
--- a/test/rdoc/test_rdoc_markup_indented_paragraph.rb
+++ b/test/rdoc/test_rdoc_markup_indented_paragraph.rb
@@ -1,11 +1,10 @@
-require 'pp'
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/markup'
+require 'rdoc/test_case'
-class TestRDocMarkupIndentedParagraph < MiniTest::Unit::TestCase
+class TestRDocMarkupIndentedParagraph < RDoc::TestCase
def setup
+ super
+
@IP = RDoc::Markup::IndentedParagraph
end
@@ -36,5 +35,19 @@ class TestRDocMarkupIndentedParagraph < MiniTest::Unit::TestCase
refute_equal one, two
end
+ def test_text
+ paragraph = @IP.new(2, 'hello', ' world')
+
+ assert_equal 'hello world', paragraph.text
+ end
+
+ def test_text_break
+ paragraph = @IP.new(2, 'hello', hard_break, 'world')
+
+ assert_equal 'helloworld', paragraph.text
+
+ assert_equal "hello\n world", paragraph.text("\n")
+ end
+
end
diff --git a/test/rdoc/test_rdoc_markup_paragraph.rb b/test/rdoc/test_rdoc_markup_paragraph.rb
index 6ae1ad9a84..8de1c3cff5 100644
--- a/test/rdoc/test_rdoc_markup_paragraph.rb
+++ b/test/rdoc/test_rdoc_markup_paragraph.rb
@@ -1,9 +1,6 @@
-require 'pp'
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/markup'
+require 'rdoc/test_case'
-class TestRDocMarkupParagraph < MiniTest::Unit::TestCase
+class TestRDocMarkupParagraph < RDoc::TestCase
def test_accept
visitor = Object.new
@@ -14,7 +11,21 @@ class TestRDocMarkupParagraph < MiniTest::Unit::TestCase
paragraph.accept visitor
- assert_equal paragraph, visitor.obj
+ assert_same paragraph, visitor.obj
+ end
+
+ def test_text
+ paragraph = para('hello', ' world')
+
+ assert_equal 'hello world', paragraph.text
+ end
+
+ def test_text_break
+ paragraph = para('hello', hard_break, 'world')
+
+ assert_equal 'helloworld', paragraph.text
+
+ assert_equal "hello\nworld", paragraph.text("\n")
end
end
diff --git a/test/rdoc/test_rdoc_markup_parser.rb b/test/rdoc/test_rdoc_markup_parser.rb
index e214c4defc..45f911acd1 100644
--- a/test/rdoc/test_rdoc_markup_parser.rb
+++ b/test/rdoc/test_rdoc_markup_parser.rb
@@ -1,14 +1,12 @@
# coding: utf-8
-require 'pp'
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/markup'
+require 'rdoc/test_case'
-class TestRDocMarkupParser < MiniTest::Unit::TestCase
+class TestRDocMarkupParser < RDoc::TestCase
def setup
- @RM = RDoc::Markup
+ super
+
@RMP = @RM::Parser
end
@@ -30,6 +28,19 @@ class TestRDocMarkupParser < MiniTest::Unit::TestCase
assert_equal @RM::Heading.new(3, 'heading three'), parser.build_heading(3)
end
+ def test_char_pos
+ parser = @RMP.new
+ s = parser.setup_scanner 'cät'
+
+ s.scan(/\S+/)
+
+ if Object.const_defined? :Encoding then
+ assert_equal 3, parser.char_pos(s.pos)
+ else
+ assert_equal 4, parser.char_pos(s.pos)
+ end
+ end
+
def test_get
parser = util_parser
@@ -148,13 +159,11 @@ the time
STR
expected = [
- @RM::List.new(:BULLET, *[
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l1', 'l1+')),
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l2')),
- ]),
- ]
+ list(:BULLET,
+ item(nil,
+ para('l1 ', 'l1+')),
+ item(nil,
+ para('l2')))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -191,16 +200,16 @@ the time
STR
expected = [
- @RM::List.new(:BULLET, *[
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l1'),
- @RM::List.new(:BULLET, *[
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l1.1', 'text'),
- @RM::Verbatim.new("code\n", " code\n"),
- @RM::Paragraph.new('text'))])),
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l2'))])]
+ list(:BULLET,
+ item(nil,
+ para('l1'),
+ list(:BULLET,
+ item(nil,
+ para('l1.1 ', 'text'),
+ verb("code\n", " code\n"),
+ para('text')))),
+ item(nil,
+ para('l2')))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -326,11 +335,11 @@ the time
STR
expected = [
- @RM::List.new(:LABEL, *[
- @RM::ListItem.new('one',
- @RM::Paragraph.new('item one')),
- @RM::ListItem.new('two',
- @RM::Paragraph.new('item two'))])]
+ list(:LABEL,
+ item(%w[one],
+ para('item one')),
+ item(%w[two],
+ para('item two')))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -343,19 +352,33 @@ the time
STR
expected = [
- @RM::List.new(:LABEL, *[
- @RM::ListItem.new('cat',
- @RM::Paragraph.new('l1'),
- @RM::List.new(:BULLET, *[
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l1.1'))])),
- @RM::ListItem.new('dog',
- @RM::Paragraph.new('l2'))])]
+ list(:LABEL,
+ item(%w[cat],
+ para('l1'),
+ list(:BULLET,
+ item(nil,
+ para('l1.1')))),
+ item(%w[dog],
+ para('l2')))]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
+ def test_parse_label_multi_label
+ str = <<-STR
+[one]
+[two] some description
+ STR
+
+ expected = [
+ list(:LABEL,
+ item(%w[one two],
+ para('some description')))]
assert_equal expected, @RMP.parse(str).parts
end
- def test_parse_label_multiline
+ def test_parse_label_multi_line
str = <<-STR
[cat] l1
continuation
@@ -363,11 +386,11 @@ the time
STR
expected = [
- @RM::List.new(:LABEL, *[
- @RM::ListItem.new('cat',
- @RM::Paragraph.new('l1', 'continuation')),
- @RM::ListItem.new('dog',
- @RM::Paragraph.new('l2'))])]
+ list(:LABEL,
+ item(%w[cat],
+ para('l1 ', 'continuation')),
+ item(%w[dog],
+ para('l2')))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -381,12 +404,11 @@ the time
STR
expected = [
- @RM::List.new(:LABEL, *[
- @RM::ListItem.new('one',
- @RM::Paragraph.new('item one')),
- @RM::ListItem.new('two',
- @RM::Paragraph.new('item two')),
- ])]
+ list(:LABEL,
+ item(%w[one],
+ para('item one')),
+ item(%w[two],
+ para('item two')))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -443,6 +465,17 @@ a. 新しい機能
assert_equal expected, @RMP.parse(str).parts
end
+ def test_parse_line_break
+ str = "now is\nthe time \nfor all"
+
+ expected = [
+ para('now is ', 'the time'),
+ blank_line,
+ para('for all')]
+
+ assert_equal expected, @RMP.parse(str).parts
+ end
+
def test_parse_list_list_1
str = <<-STR
10. para 1
@@ -456,16 +489,16 @@ a. 新しい機能
STR
expected = [
- @RM::List.new(:NUMBER, *[
- @RM::ListItem.new(nil, *[
- @RM::Paragraph.new('para 1'),
- @RM::BlankLine.new,
- @RM::List.new(:LABEL, *[
- @RM::ListItem.new('label 1', *[
- @RM::Paragraph.new('para 1.1'),
- @RM::BlankLine.new,
- @RM::Verbatim.new("code\n"),
- @RM::Paragraph.new('para 1.2')])])])])]
+ list(:NUMBER,
+ item(nil,
+ para('para 1'),
+ blank_line,
+ list(:LABEL,
+ item(%w[label\ 1],
+ para('para 1.1'),
+ blank_line,
+ verb("code\n"),
+ para('para 1.2')))))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -479,15 +512,15 @@ a. 新しい機能
STR
expected = [
- @RM::List.new(:NUMBER, *[
- @RM::ListItem.new(nil, *[
- @RM::Paragraph.new('para'),
- @RM::BlankLine.new,
- @RM::List.new(:NOTE, *[
- @RM::ListItem.new('label 1',
- @RM::Paragraph.new('text 1')),
- @RM::ListItem.new('label 2',
- @RM::Paragraph.new('text 2'))])])])]
+ list(:NUMBER,
+ item(nil,
+ para('para'),
+ blank_line,
+ list(:NOTE,
+ item(%w[label\ 1],
+ para('text 1')),
+ item(%w[label\ 2],
+ para('text 2')))))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -546,11 +579,11 @@ two:: item two
STR
expected = [
- @RM::List.new(:NOTE, *[
- @RM::ListItem.new('one',
- @RM::Paragraph.new('item one')),
- @RM::ListItem.new('two',
- @RM::Paragraph.new('item two'))])]
+ list(:NOTE,
+ item(%w[one],
+ para('item one')),
+ item(%w[two],
+ para('item two')))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -562,11 +595,9 @@ two::
STR
expected = [
- @RM::List.new(:NOTE, *[
- @RM::ListItem.new('one',
- @RM::BlankLine.new),
- @RM::ListItem.new('two',
- @RM::BlankLine.new)])]
+ list(:NOTE,
+ item(%w[one two],
+ blank_line))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -577,11 +608,11 @@ one:: two::
STR
expected = [
- @RM::List.new(:NOTE, *[
- @RM::ListItem.new('one',
- @RM::List.new(:NOTE, *[
- @RM::ListItem.new('two',
- @RM::BlankLine.new)]))])]
+ list(:NOTE,
+ item(%w[one],
+ list(:NOTE,
+ item(%w[two],
+ blank_line))))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -594,14 +625,14 @@ one:: two::
STR
expected = [
- @RM::List.new(:NUMBER, *[
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l1'),
- @RM::List.new(:BULLET, *[
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l1.1'))])),
- @RM::ListItem.new(nil,
- @RM::Paragraph.new('l2'))])]
+ list(:NUMBER,
+ item(nil,
+ para('l1'),
+ list(:BULLET,
+ item(nil,
+ para('l1.1')))),
+ item(nil,
+ para('l2')))]
assert_equal expected, @RMP.parse(str).parts
end
@@ -623,7 +654,7 @@ for all good men
def test_parse_paragraph_multiline
str = "now is the time\nfor all good men"
- expected = @RM::Paragraph.new 'now is the time for all good men'
+ expected = @RM::Paragraph.new 'now is the time ', 'for all good men'
assert_equal [expected], @RMP.parse(str).parts
end
@@ -1185,6 +1216,38 @@ the time
assert_equal expected, @RMP.tokenize(str)
end
+ def test_tokenize_label_newline
+ str = <<-STR
+[cat]
+ l1
+ STR
+
+ expected = [
+ [:LABEL, 'cat', 0, 0],
+ [:NEWLINE, "\n", 5, 0],
+ [:TEXT, 'l1', 2, 1],
+ [:NEWLINE, "\n", 4, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_label_newline_windows
+ str = <<-STR
+[cat]\r
+ l1\r
+ STR
+
+ expected = [
+ [:LABEL, 'cat', 0, 0],
+ [:NEWLINE, "\n", 6, 0],
+ [:TEXT, 'l1', 2, 1],
+ [:NEWLINE, "\n", 5, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
def test_tokenize_lalpha
str = <<-STR
a. l1
@@ -1203,6 +1266,53 @@ b. l1.1
assert_equal expected, @RMP.tokenize(str)
end
+ def test_tokenize_line_break
+ str = "now is\nthe time \nfor all\n"
+
+ expected = [
+ [:TEXT, 'now is', 0, 0],
+ [:NEWLINE, "\n", 6, 0],
+ [:TEXT, 'the time', 0, 1],
+ [:BREAK, " ", 8, 1],
+ [:NEWLINE, "\n", 10, 1],
+ [:TEXT, 'for all', 0, 2],
+ [:NEWLINE, "\n", 7, 2],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_line_break_long
+ str = "now is\nthe time \nfor all\n"
+
+ expected = [
+ [:TEXT, 'now is', 0, 0],
+ [:NEWLINE, "\n", 6, 0],
+ [:TEXT, 'the time ', 0, 1],
+ [:BREAK, ' ', 9, 1],
+ [:NEWLINE, "\n", 11, 1],
+ [:TEXT, 'for all', 0, 2],
+ [:NEWLINE, "\n", 7, 2],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_line_break_no_short
+ str = "now is\nthe time \nfor all\n"
+
+ expected = [
+ [:TEXT, 'now is', 0, 0],
+ [:NEWLINE, "\n", 6, 0],
+ [:TEXT, 'the time ', 0, 1],
+ [:NEWLINE, "\n", 9, 1],
+ [:TEXT, 'for all', 0, 2],
+ [:NEWLINE, "\n", 7, 2],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
def test_tokenize_note
str = <<-STR
cat:: l1
@@ -1237,6 +1347,64 @@ dog::
assert_equal expected, @RMP.tokenize(str)
end
+ def test_tokenize_note_newline
+ str = <<-STR
+cat::
+ l1
+ STR
+
+ expected = [
+ [:NOTE, 'cat', 0, 0],
+ [:NEWLINE, "\n", 5, 0],
+ [:TEXT, 'l1', 2, 1],
+ [:NEWLINE, "\n", 4, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_note_utf_8
+ skip 'Encoding not implemented' unless Object.const_defined? :Encoding
+
+ str = <<-STR
+cät:: l1a
+ l1b
+døg:: l2a
+ l2b
+ STR
+
+ expected = [
+ [:NOTE, 'cät', 0, 0],
+ [:TEXT, 'l1a', 6, 0],
+ [:NEWLINE, "\n", 9, 0],
+ [:TEXT, 'l1b', 6, 1],
+ [:NEWLINE, "\n", 9, 1],
+ [:NOTE, 'døg', 0, 2],
+ [:TEXT, 'l2a', 6, 2],
+ [:NEWLINE, "\n", 9, 2],
+ [:TEXT, 'l2b', 6, 3],
+ [:NEWLINE, "\n", 9, 3],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
+ def test_tokenize_note_newline_windows
+ str = <<-STR
+cat::\r
+ l1\r
+ STR
+
+ expected = [
+ [:NOTE, 'cat', 0, 0],
+ [:NEWLINE, "\n", 6, 0],
+ [:TEXT, 'l1', 2, 1],
+ [:NEWLINE, "\n", 5, 1],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
def test_tokenize_note_not
str = <<-STR
Cat::Dog
@@ -1363,6 +1531,24 @@ for all
assert_equal expected, @RMP.tokenize(str)
end
+ def test_tokenize_rule_windows
+ str = <<-STR
+---\r
+
+--- blah ---\r
+ STR
+
+ expected = [
+ [:RULE, 1, 0, 0],
+ [:NEWLINE, "\n", 4, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:TEXT, "--- blah ---", 0, 2],
+ [:NEWLINE, "\n", 13, 2],
+ ]
+
+ assert_equal expected, @RMP.tokenize(str)
+ end
+
def test_tokenize_ualpha
str = <<-STR
A. l1
@@ -1438,6 +1624,19 @@ Example heading:
assert_equal expected, @RMP.tokenize(str)
end
+ def test_token_pos
+ parser = @RMP.new
+ s = parser.setup_scanner 'cät'
+
+ s.scan(/\S+/)
+
+ if Object.const_defined? :Encoding then
+ assert_equal [3, 0], parser.token_pos(s.pos)
+ else
+ assert_equal [4, 0], parser.token_pos(s.pos)
+ end
+ end
+
# HACK move to Verbatim test case
def test_verbatim_normalize
v = @RM::Verbatim.new "foo\n", "\n", "\n", "bar\n"
diff --git a/test/rdoc/test_rdoc_markup_pre_process.rb b/test/rdoc/test_rdoc_markup_pre_process.rb
index 34867c8c6b..3a991a6397 100644
--- a/test/rdoc/test_rdoc_markup_pre_process.rb
+++ b/test/rdoc/test_rdoc_markup_pre_process.rb
@@ -1,16 +1,11 @@
# coding: utf-8
-require 'tempfile'
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/markup/pre_process'
-require 'rdoc/code_objects'
-require 'rdoc/options'
+require 'rdoc/test_case'
-class TestRDocMarkupPreProcess < MiniTest::Unit::TestCase
+class TestRDocMarkupPreProcess < RDoc::TestCase
def setup
- RDoc::Markup::PreProcess.registered.clear
+ super
@tempfile = Tempfile.new 'test_rdoc_markup_pre_process'
@file_name = File.basename @tempfile.path
@@ -20,11 +15,23 @@ class TestRDocMarkupPreProcess < MiniTest::Unit::TestCase
end
def teardown
- RDoc::Markup::PreProcess.registered.clear
+ super
@tempfile.close
end
+ def test_class_register
+ RDoc::Markup::PreProcess.register 'for_test' do raise 'fail' end
+
+ assert_equal %w[for_test], RDoc::Markup::PreProcess.registered.keys
+ end
+
+ def test_class_post_process
+ RDoc::Markup::PreProcess.post_process do end
+
+ assert_equal 1, RDoc::Markup::PreProcess.post_processors.length
+ end
+
def test_include_file
@tempfile.write <<-INCLUDE
# -*- mode: rdoc; coding: utf-8; fill-column: 74; -*-
@@ -73,6 +80,50 @@ contents of a string.
assert_equal "#\n", text
end
+ def test_handle_comment
+ text = "# :main: M\n"
+ c = comment text
+
+ out = @pp.handle c
+
+ assert_same out, text
+ assert_equal "#\n", text
+ end
+
+ def test_handle_markup
+ c = comment ':markup: rd'
+
+ @pp.handle c
+
+ assert_equal 'rd', c.format
+ end
+
+ def test_handle_markup_empty
+ c = comment ':markup:'
+
+ @pp.handle c
+
+ assert_equal 'rdoc', c.format
+ end
+
+ def test_handle_post_process
+ cd = RDoc::CodeObject.new
+
+ RDoc::Markup::PreProcess.post_process do |text, code_object|
+ code_object.metadata[:stuff] = text
+
+ :junk
+ end
+
+ text = "# a b c\n"
+
+ out = @pp.handle text, cd
+
+ assert_same out, text
+ assert_equal "# a b c\n", text
+ assert_equal "# a b c\n", cd.metadata[:stuff]
+ end
+
def test_handle_unregistered
text = "# :x: y\n"
out = @pp.handle text
diff --git a/test/rdoc/test_rdoc_markup_raw.rb b/test/rdoc/test_rdoc_markup_raw.rb
index 4e57b7df39..16cc60e3a8 100644
--- a/test/rdoc/test_rdoc_markup_raw.rb
+++ b/test/rdoc/test_rdoc_markup_raw.rb
@@ -1,12 +1,10 @@
-require 'pp'
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/markup'
+require 'rdoc/test_case'
-class TestRDocMarkupRaw < MiniTest::Unit::TestCase
+class TestRDocMarkupRaw < RDoc::TestCase
def setup
- @RM = RDoc::Markup
+ super
+
@p = @RM::Raw.new
end
@@ -23,5 +21,9 @@ class TestRDocMarkupRaw < MiniTest::Unit::TestCase
assert_equal @RM::Raw.new('hi', 'there'), @p
end
+ def test_pretty_print
+ assert_equal '[raw: ]', mu_pp(@p)
+ end
+
end
diff --git a/test/rdoc/test_rdoc_markup_to_ansi.rb b/test/rdoc/test_rdoc_markup_to_ansi.rb
index f60d1999c2..5afaf94350 100644
--- a/test/rdoc/test_rdoc_markup_to_ansi.rb
+++ b/test/rdoc/test_rdoc_markup_to_ansi.rb
@@ -1,7 +1,4 @@
-require 'rubygems'
-require 'rdoc/markup/text_formatter_test_case'
-require 'rdoc/markup/to_ansi'
-require 'minitest/autorun'
+require 'rdoc/test_case'
class TestRDocMarkupToAnsi < RDoc::Markup::TextFormatterTestCase
@@ -18,6 +15,10 @@ class TestRDocMarkupToAnsi < RDoc::Markup::TextFormatterTestCase
assert_equal "\e[0m\n", @to.res.join
end
+ def accept_block_quote
+ assert_equal "\e[0m> quote\n", @to.res.join
+ end
+
def accept_document
assert_equal "\e[0mhello\n", @to.res.join
end
@@ -67,7 +68,7 @@ class TestRDocMarkupToAnsi < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_label
- assert_equal "\e[0m", @to.res.join
+ assert_equal "\e[0mcat:\n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -77,7 +78,7 @@ class TestRDocMarkupToAnsi < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_note
- assert_equal "\e[0m", @to.res.join
+ assert_equal "\e[0mcat:\n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -245,10 +246,28 @@ class TestRDocMarkupToAnsi < RDoc::Markup::TextFormatterTestCase
@to.res.join
end
+ def accept_list_item_start_note_multi_description
+ assert_equal "\e[0mlabel:\n description one\n\n description two\n\n",
+ @to.res.join
+ end
+
+ def accept_list_item_start_note_multi_label
+ assert_equal "\e[0mone\ntwo:\n two headers\n\n",
+ @to.res.join
+ end
+
def accept_paragraph_b
assert_equal "\e[0mreg \e[1mbold words\e[m reg\n", @to.end_accepting
end
+ def accept_paragraph_br
+ assert_equal "\e[0mone\ntwo\n", @to.end_accepting
+ end
+
+ def accept_paragraph_break
+ assert_equal "\e[0mhello\nworld\n", @to.end_accepting
+ end
+
def accept_paragraph_i
assert_equal "\e[0mreg \e[4mitalic words\e[m reg\n", @to.end_accepting
end
@@ -328,5 +347,23 @@ words words words words
assert_equal expected, @to.end_accepting
end
+ # functional test
+ def test_convert_list_note
+ note_list = <<-NOTE_LIST
+foo ::
+bar ::
+ hi
+ NOTE_LIST
+
+ expected = <<-EXPECTED
+\e[0mfoo
+bar:
+ hi
+
+ EXPECTED
+
+ assert_equal expected, @to.convert(note_list)
+ end
+
end
diff --git a/test/rdoc/test_rdoc_markup_to_bs.rb b/test/rdoc/test_rdoc_markup_to_bs.rb
index 35a9266b5d..f2e6352b69 100644
--- a/test/rdoc/test_rdoc_markup_to_bs.rb
+++ b/test/rdoc/test_rdoc_markup_to_bs.rb
@@ -1,7 +1,4 @@
-require 'rubygems'
-require 'rdoc/markup/text_formatter_test_case'
-require 'rdoc/markup/to_bs'
-require 'minitest/autorun'
+require 'rdoc/test_case'
class TestRDocMarkupToBs < RDoc::Markup::TextFormatterTestCase
@@ -18,6 +15,10 @@ class TestRDocMarkupToBs < RDoc::Markup::TextFormatterTestCase
assert_equal "\n", @to.res.join
end
+ def accept_block_quote
+ assert_equal "> quote\n", @to.res.join
+ end
+
def accept_document
assert_equal "hello\n", @to.res.join
end
@@ -68,7 +69,7 @@ class TestRDocMarkupToBs < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_label
- assert_equal "\n", @to.res.join
+ assert_equal "cat:\n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -78,7 +79,7 @@ class TestRDocMarkupToBs < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_note
- assert_equal "\n", @to.res.join
+ assert_equal "cat:\n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -252,12 +253,32 @@ class TestRDocMarkupToBs < RDoc::Markup::TextFormatterTestCase
assert_equal "teletype:\n teletype description\n\n", @to.res.join
end
+ def accept_list_item_start_note_multi_description
+ assert_equal "label:\n description one\n\n description two\n\n",
+ @to.res.join
+ end
+
+ def accept_list_item_start_note_multi_label
+ assert_equal "one\ntwo:\n two headers\n\n", @to.res.join
+ end
+
def accept_paragraph_b
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
assert_equal "reg b\bbo\bol\bld\bd \b w\bwo\bor\brd\bds\bs reg\n",
@to.end_accepting
end
+ def accept_paragraph_br
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ assert_equal "one\ntwo\n", @to.end_accepting
+ end
+
+ def accept_paragraph_break
+ skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
+ assert_equal "hello\nworld\n",
+ @to.end_accepting
+ end
+
def accept_paragraph_i
skip "No String#chars, upgrade your ruby" unless ''.respond_to? :chars
assert_equal "reg _\bi_\bt_\ba_\bl_\bi_\bc_\b _\bw_\bo_\br_\bd_\bs reg\n",
diff --git a/test/rdoc/test_rdoc_markup_to_html.rb b/test/rdoc/test_rdoc_markup_to_html.rb
index 2cb16e88ae..cb444a531f 100644
--- a/test/rdoc/test_rdoc_markup_to_html.rb
+++ b/test/rdoc/test_rdoc_markup_to_html.rb
@@ -1,7 +1,4 @@
-require 'rubygems'
-require 'rdoc/markup/formatter_test_case'
-require 'rdoc/markup/to_html'
-require 'minitest/autorun'
+require 'rdoc/test_case'
class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
@@ -10,7 +7,7 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
def setup
super
- @to = RDoc::Markup::ToHtml.new
+ @to = RDoc::Markup::ToHtml.new @options
end
def test_class_gen_relative_url
@@ -30,36 +27,41 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
assert_empty @to.res.join
end
+ def accept_block_quote
+ assert_equal "\n<blockquote>\n<p>quote</p>\n</blockquote>\n", @to.res.join
+ end
+
def accept_document
assert_equal "\n<p>hello</p>\n", @to.res.join
end
def accept_heading
- assert_equal "\n<h5>Hello</h5>\n", @to.res.join
+ assert_equal "\n<h5 id=\"label-Hello\">Hello</h5>\n", @to.res.join
end
def accept_heading_1
- assert_equal "\n<h1>Hello</h1>\n", @to.res.join
+ assert_equal "\n<h1 id=\"label-Hello\">Hello</h1>\n", @to.res.join
end
def accept_heading_2
- assert_equal "\n<h2>Hello</h2>\n", @to.res.join
+ assert_equal "\n<h2 id=\"label-Hello\">Hello</h2>\n", @to.res.join
end
def accept_heading_3
- assert_equal "\n<h3>Hello</h3>\n", @to.res.join
+ assert_equal "\n<h3 id=\"label-Hello\">Hello</h3>\n", @to.res.join
end
def accept_heading_4
- assert_equal "\n<h4>Hello</h4>\n", @to.res.join
+ assert_equal "\n<h4 id=\"label-Hello\">Hello</h4>\n", @to.res.join
end
def accept_heading_b
- assert_equal "\n<h1><b>Hello</b></h1>\n", @to.res.join
+ assert_equal "\n<h1 id=\"label-Hello\"><strong>Hello</strong></h1>\n",
+ @to.res.join
end
def accept_heading_suppressed_crossref
- assert_equal "\n<h1>Hello</h1>\n", @to.res.join
+ assert_equal "\n<h1 id=\"label-Hello\">Hello</h1>\n", @to.res.join
end
def accept_list_end_bullet
@@ -73,14 +75,14 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
assert_equal [], @to.list
assert_equal [], @to.in_list_entry
- assert_equal "<dl class=\"rdoc-list\"></dl>\n", @to.res.join
+ assert_equal "<dl class=\"rdoc-list label-list\"></dl>\n", @to.res.join
end
def accept_list_end_lalpha
assert_equal [], @to.list
assert_equal [], @to.in_list_entry
- assert_equal "<ol style=\"display: lower-alpha\"></ol>\n", @to.res.join
+ assert_equal "<ol style=\"list-style-type: lower-alpha\"></ol>\n", @to.res.join
end
def accept_list_end_number
@@ -94,14 +96,14 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
assert_equal [], @to.list
assert_equal [], @to.in_list_entry
- assert_equal "<table class=\"rdoc-list\"></table>\n", @to.res.join
+ assert_equal "<dl class=\"rdoc-list note-list\"></dl>\n", @to.res.join
end
def accept_list_end_ualpha
assert_equal [], @to.list
assert_equal [], @to.in_list_entry
- assert_equal "<ol style=\"display: upper-alpha\"></ol>\n", @to.res.join
+ assert_equal "<ol style=\"list-style-type: upper-alpha\"></ol>\n", @to.res.join
end
def accept_list_item_end_bullet
@@ -117,7 +119,7 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
end
def accept_list_item_end_note
- assert_equal %w[</td></tr>], @to.in_list_entry
+ assert_equal %w[</dd>], @to.in_list_entry
end
def accept_list_item_end_number
@@ -133,24 +135,49 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
end
def accept_list_item_start_label
- assert_equal "<dl class=\"rdoc-list\"><dt>cat</dt>\n<dd>", @to.res.join
+ assert_equal "<dl class=\"rdoc-list label-list\"><dt>cat\n<dd>", @to.res.join
end
def accept_list_item_start_lalpha
- assert_equal "<ol style=\"display: lower-alpha\"><li>", @to.res.join
+ assert_equal "<ol style=\"list-style-type: lower-alpha\"><li>", @to.res.join
end
def accept_list_item_start_note
- assert_equal "<table class=\"rdoc-list\"><tr><td class=\"rdoc-term\"><p>cat</p></td>\n<td>",
+ assert_equal "<dl class=\"rdoc-list note-list\"><dt>cat\n<dd>",
@to.res.join
end
def accept_list_item_start_note_2
expected = <<-EXPECTED
-<table class="rdoc-list"><tr><td class="rdoc-term"><p><tt>teletype</tt></p></td>
-<td>
+<dl class="rdoc-list note-list"><dt><code>teletype</code>
+<dd>
<p>teletype description</p>
-</td></tr></table>
+</dd></dl>
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ end
+
+ def accept_list_item_start_note_multi_description
+ expected = <<-EXPECTED
+<dl class="rdoc-list note-list"><dt>label
+<dd>
+<p>description one</p>
+</dd><dd>
+<p>description two</p>
+</dd></dl>
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ end
+
+ def accept_list_item_start_note_multi_label
+ expected = <<-EXPECTED
+<dl class="rdoc-list note-list"><dt>one
+<dt>two
+<dd>
+<p>two headers</p>
+</dd></dl>
EXPECTED
assert_equal expected, @to.res.join
@@ -161,7 +188,7 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
end
def accept_list_item_start_ualpha
- assert_equal "<ol style=\"display: upper-alpha\"><li>", @to.res.join
+ assert_equal "<ol style=\"list-style-type: upper-alpha\"><li>", @to.res.join
end
def accept_list_start_bullet
@@ -175,21 +202,21 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
assert_equal [:LABEL], @to.list
assert_equal [false], @to.in_list_entry
- assert_equal '<dl class="rdoc-list">', @to.res.join
+ assert_equal '<dl class="rdoc-list label-list">', @to.res.join
end
def accept_list_start_lalpha
assert_equal [:LALPHA], @to.list
assert_equal [false], @to.in_list_entry
- assert_equal "<ol style=\"display: lower-alpha\">", @to.res.join
+ assert_equal "<ol style=\"list-style-type: lower-alpha\">", @to.res.join
end
def accept_list_start_note
assert_equal [:NOTE], @to.list
assert_equal [false], @to.in_list_entry
- assert_equal "<table class=\"rdoc-list\">", @to.res.join
+ assert_equal "<dl class=\"rdoc-list note-list\">", @to.res.join
end
def accept_list_start_number
@@ -203,7 +230,7 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
assert_equal [:UALPHA], @to.list
assert_equal [false], @to.in_list_entry
- assert_equal "<ol style=\"display: upper-alpha\">", @to.res.join
+ assert_equal "<ol style=\"list-style-type: upper-alpha\">", @to.res.join
end
def accept_paragraph
@@ -211,7 +238,15 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
end
def accept_paragraph_b
- assert_equal "\n<p>reg <b>bold words</b> reg</p>\n", @to.res.join
+ assert_equal "\n<p>reg <strong>bold words</strong> reg</p>\n", @to.res.join
+ end
+
+ def accept_paragraph_br
+ assert_equal "\n<p>one<br>two</p>\n", @to.res.join
+ end
+
+ def accept_paragraph_break
+ assert_equal "\n<p>hello<br>\nworld</p>\n", @to.res.join
end
def accept_paragraph_i
@@ -219,11 +254,11 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
end
def accept_paragraph_plus
- assert_equal "\n<p>reg <tt>teletype</tt> reg</p>\n", @to.res.join
+ assert_equal "\n<p>reg <code>teletype</code> reg</p>\n", @to.res.join
end
def accept_paragraph_star
- assert_equal "\n<p>reg <b>bold</b> reg</p>\n", @to.res.join
+ assert_equal "\n<p>reg <strong>bold</strong> reg</p>\n", @to.res.join
end
def accept_paragraph_underscore
@@ -297,20 +332,155 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
assert_equal expected, @to.end_accepting
end
+ def test_accept_heading_7
+ @to.start_accepting
+
+ @to.accept_heading @RM::Heading.new(7, 'Hello')
+
+ assert_equal "\n<h6 id=\"label-Hello\">Hello</h6>\n", @to.res.join
+ end
+
+ def test_accept_heading_aref_class
+ @to.code_object = RDoc::NormalClass.new 'Foo'
+ @to.start_accepting
+
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal "\n<h1 id=\"label-Hello\">Hello</h1>\n",
+ @to.res.join
+ end
+
+ def test_accept_heading_aref_method
+ @to.code_object = RDoc::AnyMethod.new nil, 'foo'
+ @to.start_accepting
+
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal "\n<h1 id=\"method-i-foo-label-Hello\">Hello</h1>\n",
+ @to.res.join
+ end
+
+ def test_accept_verbatim_parseable
+ verb = @RM::Verbatim.new("class C\n", "end\n")
+
+ @to.start_accepting
+ @to.accept_verbatim verb
+
+ expected = <<-EXPECTED
+
+<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">C</span>
+<span class="ruby-keyword">end</span>
+</pre>
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ end
+
+ def test_accept_verbatim_parseable_error
+ verb = @RM::Verbatim.new("a % 09 # => blah\n")
+
+ @to.start_accepting
+ @to.accept_verbatim verb
+
+ inner = CGI.escapeHTML "a % 09 # => blah"
+
+ expected = <<-EXPECTED
+
+<pre>#{inner}
+</pre>
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ end
+
+ def test_accept_verbatim_ruby
+ verb = @RM::Verbatim.new("1 + 1\n")
+ verb.format = :ruby
+
+ @to.start_accepting
+ @to.accept_verbatim verb
+
+ expected = <<-EXPECTED
+
+<pre class="ruby"><span class="ruby-value">1</span> <span class="ruby-operator">+</span> <span class="ruby-value">1</span>
+</pre>
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ end
+
def test_convert_string
assert_equal '&lt;&gt;', @to.convert_string('<>')
end
+ def test_convert_HYPERLINK_irc
+ result = @to.convert 'irc://irc.freenode.net/#ruby-lang'
+
+ assert_equal "\n<p><a href=\"irc://irc.freenode.net/#ruby-lang\">irc.freenode.net/#ruby-lang</a></p>\n", result
+ end
+
+ def test_convert_RDOCLINK_label_label
+ result = @to.convert 'rdoc-label:label-One'
+
+ assert_equal "\n<p><a href=\"#label-One\">One</a></p>\n", result
+ end
+
+ def test_convert_RDOCLINK_label_foottext
+ result = @to.convert 'rdoc-label:foottext-1'
+
+ assert_equal "\n<p><a href=\"#foottext-1\">*1</a></p>\n", result
+ end
+
+ def test_convert_RDOCLINK_label_footmark
+ result = @to.convert 'rdoc-label:footmark-1'
+
+ assert_equal "\n<p><a href=\"#footmark-1\">^1</a></p>\n", result
+ end
+
+ def test_convert_RDOCLINK_ref
+ result = @to.convert 'rdoc-ref:C'
+
+ assert_equal "\n<p>C</p>\n", result
+ end
+
+ def test_convert_TIDYLINK_footnote
+ result = @to.convert 'text{*1}[rdoc-label:foottext-1:footmark-1]'
+
+ assert_equal "\n<p>text<a id=\"footmark-1\" href=\"#foottext-1\">*1</a></p>\n", result
+ end
+
+ def test_convert_TIDYLINK_rdoc_label
+ result = @to.convert '{foo}[rdoc-label:foottext-1]'
+
+ assert_equal "\n<p><a href=\"#foottext-1\">foo</a></p>\n", result
+ end
+
+ def test_convert_TIDYLINK_irc
+ result = @to.convert '{ruby-lang}[irc://irc.freenode.net/#ruby-lang]'
+
+ assert_equal "\n<p><a href=\"irc://irc.freenode.net/#ruby-lang\">ruby-lang</a></p>\n", result
+ end
+
def test_gen_url
assert_equal '<a href="example">example</a>',
@to.gen_url('link:example', 'example')
end
- def test_gem_url_image_url
+ def test_gen_url_rdoc_label
+ assert_equal '<a href="#foottext-1">example</a>',
+ @to.gen_url('rdoc-label:foottext-1', 'example')
+ end
+
+ def test_gen_url_rdoc_label_id
+ assert_equal '<a id="footmark-1" href="#foottext-1">example</a>',
+ @to.gen_url('rdoc-label:foottext-1:footmark-1', 'example')
+ end
+
+ def test_gen_url_image_url
assert_equal '<img src="http://example.com/image.png" />', @to.gen_url('http://example.com/image.png', 'ignored')
end
- def test_gem_url_ssl_image_url
+ def test_gen_url_ssl_image_url
assert_equal '<img src="https://example.com/image.png" />', @to.gen_url('https://example.com/image.png', 'ignored')
end
@@ -322,6 +492,14 @@ class TestRDocMarkupToHtml < RDoc::Markup::FormatterTestCase
assert_equal '<a href="README.txt">README.txt</a>', link
end
+ def test_handle_special_HYPERLINK_irc
+ special = RDoc::Markup::Special.new 0, 'irc://irc.freenode.net/#ruby-lang'
+
+ link = @to.handle_special_HYPERLINK special
+
+ assert_equal '<a href="irc://irc.freenode.net/#ruby-lang">irc.freenode.net/#ruby-lang</a>', link
+ end
+
def test_list_verbatim_2
str = "* one\n verb1\n verb2\n* two\n"
@@ -339,8 +517,21 @@ verb2</pre>
assert_equal expected, @m.convert(str, @to)
end
+ def test_parseable_eh
+ assert @to.parseable?('def x() end'), 'def'
+ assert @to.parseable?('class C end'), 'class'
+ assert @to.parseable?('module M end'), 'module'
+ assert @to.parseable?('a # => blah'), '=>'
+ assert @to.parseable?('x { |y| ... }'), '{ |x|'
+ assert @to.parseable?('x do |y| ... end'), 'do |x|'
+ refute @to.parseable?('* 1'), '* 1'
+ refute @to.parseable?('# only a comment'), '# only a comment'
+ refute @to.parseable?('<% require "foo" %>'), 'ERB'
+ refute @to.parseable?('class="foo"'), 'HTML class'
+ end
+
def test_to_html
- assert_equal "\n<p><tt>--</tt></p>\n", util_format("<tt>--</tt>")
+ assert_equal "\n<p><code>--</code></p>\n", util_format("<tt>--</tt>")
end
def util_format text
diff --git a/test/rdoc/test_rdoc_markup_to_html_crossref.rb b/test/rdoc/test_rdoc_markup_to_html_crossref.rb
index 4f122512ac..27a60120f4 100644
--- a/test/rdoc/test_rdoc_markup_to_html_crossref.rb
+++ b/test/rdoc/test_rdoc_markup_to_html_crossref.rb
@@ -1,8 +1,3 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/rdoc'
-require 'rdoc/code_objects'
-require 'rdoc/markup/to_html_crossref'
require File.expand_path '../xref_test_case', __FILE__
class TestRDocMarkupToHtmlCrossref < XrefTestCase
@@ -10,25 +5,93 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
def setup
super
- @to = RDoc::Markup::ToHtmlCrossref.new 'index.html', @c1, true
+ @options.hyperlink_all = true
+
+ @to = RDoc::Markup::ToHtmlCrossref.new @options, 'index.html', @c1
end
def test_convert_CROSSREF
result = @to.convert 'C1'
- assert_equal "\n<p><a href=\"C1.html\">C1</a></p>\n", result
+ assert_equal para("<a href=\"C1.html\">C1</a>"), result
+ end
+
+ def test_convert_CROSSREF_label
+ result = @to.convert 'C1@foo'
+ assert_equal para("<a href=\"C1.html#label-foo\">foo at C1</a>"), result
+
+ result = @to.convert 'C1#m@foo'
+ assert_equal para("<a href=\"C1.html#method-i-m-label-foo\">foo at C1#m</a>"),
+ result
end
- def test_convert_HYPERLINK_rdoc_ref
+ def test_convert_CROSSREF_label_period
+ result = @to.convert 'C1@foo.'
+ assert_equal para("<a href=\"C1.html#label-foo\">foo at C1</a>."), result
+ end
+
+ def test_convert_CROSSREF_label_space
+ result = @to.convert 'C1@foo+bar'
+ assert_equal para("<a href=\"C1.html#label-foo+bar\">foo bar at C1</a>"),
+ result
+ end
+
+ def test_convert_RDOCLINK_rdoc_ref
result = @to.convert 'rdoc-ref:C1'
- assert_equal "\n<p><a href=\"C1.html\">C1</a></p>\n", result
+ assert_equal para("<a href=\"C1.html\">C1</a>"), result
+ end
+
+ def test_convert_RDOCLINK_rdoc_ref_method
+ result = @to.convert 'rdoc-ref:C1#m'
+
+ assert_equal para("<a href=\"C1.html#method-i-m\">#m</a>"), result
end
- def test_convert_TIDYLINK_rdoc_ref
- result = @to.convert '{foo}[rdoc-ref:C1]'
+ def test_convert_RDOCLINK_rdoc_ref_method_label
+ result = @to.convert 'rdoc-ref:C1#m@foo'
+
+ assert_equal para("<a href=\"C1.html#method-i-m-label-foo\">foo at C1#m</a>"),
+ result, 'rdoc-ref:C1#m@foo'
+ end
+
+ def test_convert_RDOCLINK_rdoc_ref_method_percent
+ m = @c1.add_method RDoc::AnyMethod.new nil, '%'
+ m.singleton = false
+
+ result = @to.convert 'rdoc-ref:C1#%'
+
+ assert_equal para("<a href=\"C1.html#method-i-25\">#%</a>"), result
+
+ m.singleton = true
+
+ result = @to.convert 'rdoc-ref:C1::%'
+
+ assert_equal para("<a href=\"C1.html#method-c-25\">::%</a>"), result
+ end
+
+ def test_convert_RDOCLINK_rdoc_ref_method_percent_label
+ m = @c1.add_method RDoc::AnyMethod.new nil, '%'
+ m.singleton = false
+
+ result = @to.convert 'rdoc-ref:C1#%@f'
+
+ assert_equal para("<a href=\"C1.html#method-i-25-label-f\">f at C1#%</a>"),
+ result
+
+ m.singleton = true
+
+ result = @to.convert 'rdoc-ref:C1::%@f'
- assert_equal "\n<p><a href=\"C1.html\">foo</a></p>\n", result
+ assert_equal para("<a href=\"C1.html#method-c-25-label-f\">f at C1::%</a>"),
+ result
+ end
+
+ def test_convert_RDOCLINK_rdoc_ref_label
+ result = @to.convert 'rdoc-ref:C1@foo'
+
+ assert_equal para("<a href=\"C1.html#label-foo\">foo at C1</a>"), result,
+ 'rdoc-ref:C1@foo'
end
def test_gen_url
@@ -43,6 +106,11 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
assert_equal "<a href=\"C2/C3.html\">C2::C3</a>", SPECIAL('C2::C3')
end
+ def test_handle_special_CROSSREF_label
+ assert_equal "<a href=\"C1.html#method-i-m-label-foo\">foo at C1#m</a>",
+ SPECIAL('C1#m@foo')
+ end
+
def test_handle_special_CROSSREF_show_hash_false
@to.show_hash = false
@@ -51,8 +119,10 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
end
def test_handle_special_HYPERLINK_rdoc
- RDoc::TopLevel.new 'README.txt'
- @to = RDoc::Markup::ToHtmlCrossref.new 'C2.html', @c2, true
+ readme = @store.add_file 'README.txt'
+ readme.parser = RDoc::Parser::Simple
+
+ @to = RDoc::Markup::ToHtmlCrossref.new @options, 'C2.html', @c2
link = @to.handle_special_HYPERLINK hyper 'C2::C3'
@@ -68,8 +138,10 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
end
def test_handle_special_TIDYLINK_rdoc
- RDoc::TopLevel.new 'README.txt'
- @to = RDoc::Markup::ToHtmlCrossref.new 'C2.html', @c2, true
+ readme = @store.add_file 'README.txt'
+ readme.parser = RDoc::Parser::Simple
+
+ @to = RDoc::Markup::ToHtmlCrossref.new @options, 'C2.html', @c2
link = @to.handle_special_TIDYLINK tidy 'C2::C3'
@@ -79,15 +151,51 @@ class TestRDocMarkupToHtmlCrossref < XrefTestCase
assert_equal '<a href="C4.html">tidy</a>', link
+ link = @to.handle_special_TIDYLINK tidy 'C1#m'
+
+ assert_equal '<a href="C1.html#method-i-m">tidy</a>', link
+
link = @to.handle_special_TIDYLINK tidy 'README.txt'
assert_equal '<a href="README_txt.html">tidy</a>', link
end
+ def test_handle_special_TIDYLINK_label
+ link = @to.handle_special_TIDYLINK tidy 'C1#m@foo'
+
+ assert_equal "<a href=\"C1.html#method-i-m-label-foo\">tidy</a>",
+ link, 'C1#m@foo'
+ end
+
+ def test_to_html_CROSSREF_email
+ @options.hyperlink_all = false
+
+ @to = RDoc::Markup::ToHtmlCrossref.new @options, 'index.html', @c1
+
+ result = @to.to_html 'first.last@example.com'
+
+ assert_equal 'first.last@example.com', result
+ end
+
+ def test_to_html_CROSSREF_email_hyperlink_all
+ result = @to.to_html 'first.last@example.com'
+
+ assert_equal 'first.last@example.com', result
+ end
+
def test_link
assert_equal 'n', @to.link('n', 'n')
- assert_equal '<a href="C1.html#method-c-m">m</a>', @to.link('m', 'm')
+ assert_equal '<a href="C1.html#method-c-m">::m</a>', @to.link('m', 'm')
+ end
+
+ def test_link_class_method_full
+ assert_equal '<a href="Parent.html#method-c-m">Parent.m</a>',
+ @to.link('Parent::m', 'Parent::m')
+ end
+
+ def para text
+ "\n<p>#{text}</p>\n"
end
def SPECIAL text
diff --git a/test/rdoc/test_rdoc_markup_to_html_snippet.rb b/test/rdoc/test_rdoc_markup_to_html_snippet.rb
new file mode 100644
index 0000000000..065b2edbc8
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_to_html_snippet.rb
@@ -0,0 +1,710 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupToHtmlSnippet < RDoc::Markup::FormatterTestCase
+
+ add_visitor_tests
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToHtmlSnippet.new @options, 100, 100
+ @ellipsis = @to.to_html '...'
+ end
+
+ def accept_blank_line
+ assert_empty @to.res.join
+ end
+
+ def accept_block_quote
+ assert_equal "\n<blockquote><p>quote\n</blockquote>\n", @to.res.join
+
+ assert_equal 5, @to.characters
+ end
+
+ def accept_document
+ assert_equal "<p>hello\n", @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def accept_heading
+ assert_equal "<p>Hello\n", @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def accept_heading_1
+ assert_equal "<p>Hello\n", @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def accept_heading_2
+ assert_equal "<p>Hello\n", @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def accept_heading_3
+ assert_equal "<p>Hello\n", @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def accept_heading_4
+ assert_equal "<p>Hello\n", @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def accept_heading_b
+ assert_equal "<p><strong>Hello</strong>\n",
+ @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def accept_heading_suppressed_crossref
+ assert_equal "<p>Hello\n", @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def accept_list_end_bullet
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "\n", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_end_label
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "\n", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_end_lalpha
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "\n", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_end_number
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "\n", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_end_note
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "\n", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_end_ualpha
+ assert_equal [], @to.list
+ assert_equal [], @to.in_list_entry
+
+ assert_equal "\n", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_item_end_bullet
+ assert_equal [''], @to.in_list_entry
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_item_end_label
+ assert_equal [''], @to.in_list_entry
+ assert_equal 4, @to.characters
+ end
+
+ def accept_list_item_end_lalpha
+ assert_equal [''], @to.in_list_entry
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_item_end_note
+ assert_equal [''], @to.in_list_entry
+ assert_equal 4, @to.characters
+ end
+
+ def accept_list_item_end_number
+ assert_equal [''], @to.in_list_entry
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_item_end_ualpha
+ assert_equal [''], @to.in_list_entry
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_item_start_bullet
+ assert_equal "<p>", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_item_start_label
+ assert_equal "<p>cat &mdash; ", @to.res.join
+ assert_equal 4, @to.characters
+ end
+
+ def accept_list_item_start_lalpha
+ assert_equal "<p>", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_item_start_note
+ assert_equal "<p>cat &mdash; ",
+ @to.res.join
+ assert_equal 4, @to.characters
+ end
+
+ def accept_list_item_start_note_2
+ expected = <<-EXPECTED
+<p><code>teletype</code> &mdash; teletype description
+
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ assert_equal 29, @to.characters
+ end
+
+ def accept_list_item_start_note_multi_description
+ expected = <<-EXPECTED
+<p>label &mdash; description one
+<p>description two
+
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ assert_equal 37, @to.characters
+ end
+
+ def accept_list_item_start_note_multi_label
+ expected = <<-EXPECTED
+<p>one, two &mdash; two headers
+
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ assert_equal 18, @to.characters
+ end
+
+ def accept_list_item_start_number
+ assert_equal "<p>", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_item_start_ualpha
+ assert_equal "<p>", @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_start_bullet
+ assert_equal [:BULLET], @to.list
+ assert_equal [''], @to.in_list_entry
+
+ assert_equal '', @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_start_label
+ assert_equal [:LABEL], @to.list
+ assert_equal [''], @to.in_list_entry
+
+ assert_equal '', @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_start_lalpha
+ assert_equal [:LALPHA], @to.list
+ assert_equal [''], @to.in_list_entry
+
+ assert_equal '', @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_start_note
+ assert_equal [:NOTE], @to.list
+ assert_equal [''], @to.in_list_entry
+
+ assert_equal '', @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_start_number
+ assert_equal [:NUMBER], @to.list
+ assert_equal [''], @to.in_list_entry
+
+ assert_equal '', @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_list_start_ualpha
+ assert_equal [:UALPHA], @to.list
+ assert_equal [''], @to.in_list_entry
+
+ assert_equal '', @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_paragraph
+ assert_equal "<p>hi\n", @to.res.join
+
+ assert_equal 2, @to.characters
+ end
+
+ def accept_paragraph_b
+ assert_equal "<p>reg <strong>bold words</strong> reg\n", @to.res.join
+
+ assert_equal 18, @to.characters
+ end
+
+ def accept_paragraph_br
+ assert_equal "<p>one<br>two\n", @to.res.join
+
+ assert_equal 6, @to.characters
+ end
+
+ def accept_paragraph_break
+ assert_equal "<p>hello<br>\nworld\n", @to.res.join
+
+ assert_equal 11, @to.characters
+ end
+
+ def accept_paragraph_i
+ assert_equal "<p>reg <em>italic words</em> reg\n", @to.res.join
+
+ assert_equal 20, @to.characters
+ end
+
+ def accept_paragraph_plus
+ assert_equal "<p>reg <code>teletype</code> reg\n", @to.res.join
+
+ assert_equal 16, @to.characters
+ end
+
+ def accept_paragraph_star
+ assert_equal "<p>reg <strong>bold</strong> reg\n", @to.res.join
+
+ assert_equal 12, @to.characters
+ end
+
+ def accept_paragraph_underscore
+ assert_equal "<p>reg <em>italic</em> reg\n", @to.res.join
+
+ assert_equal 14, @to.characters
+ end
+
+ def accept_raw
+ assert_equal '', @to.res.join
+ assert_equal 0, @to.characters
+ end
+
+ def accept_rule
+ assert_empty @to.res
+ assert_equal 0, @to.characters
+ end
+
+ def accept_verbatim
+ assert_equal "\n<pre>hi\n world</pre>\n", @to.res.join
+ assert_equal 10, @to.characters
+ end
+
+ def end_accepting
+ assert_equal 'hi', @to.res.join
+ end
+
+ def start_accepting
+ assert_equal [], @to.res
+ assert_equal [], @to.in_list_entry
+ assert_equal [], @to.list
+ assert_equal 0, @to.characters
+ end
+
+ def list_nested
+ expected = <<-EXPECTED
+<p>l1
+<p>l1.1
+
+<p>l2
+
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ assert_equal 8, @to.characters
+ end
+
+ def list_verbatim
+ expected = <<-EXPECTED
+<p>list stuff
+
+<pre>* list
+ with
+
+ second
+
+ 1. indented
+ 2. numbered
+
+ third
+
+* second</pre>
+
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ assert_equal 81, @to.characters
+ end
+
+ def test_accept_heading_7
+ @to.start_accepting
+
+ @to.accept_heading @RM::Heading.new(7, 'Hello')
+
+ assert_equal "<p>Hello\n", @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def test_accept_heading_aref_class
+ @to.code_object = RDoc::NormalClass.new 'Foo'
+ @to.start_accepting
+
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal "<p>Hello\n",
+ @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def test_accept_heading_aref_method
+ @to.code_object = RDoc::AnyMethod.new nil, 'foo'
+ @to.start_accepting
+
+ @to.accept_heading @RM::Heading.new(1, 'Hello')
+
+ assert_equal "<p>Hello\n",
+ @to.res.join
+ assert_equal 5, @to.characters
+ end
+
+ def test_accept_verbatim_ruby
+ options = RDoc::Options.new
+ rdoc = RDoc::RDoc.new
+ rdoc.options = options
+ RDoc::RDoc.current = rdoc
+
+ verb = @RM::Verbatim.new("class C\n", "end\n")
+
+ @to.start_accepting
+ @to.accept_verbatim verb
+
+ expected = <<-EXPECTED
+
+<pre class="ruby"><span class="ruby-keyword">class</span> <span class="ruby-constant">C</span>
+<span class="ruby-keyword">end</span>
+</pre>
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ assert_equal 11, @to.characters
+ end
+
+ def test_accept_verbatim_ruby_error
+ options = RDoc::Options.new
+ rdoc = RDoc::RDoc.new
+ rdoc.options = options
+ RDoc::RDoc.current = rdoc
+
+ verb = @RM::Verbatim.new("a % 09 # => blah\n")
+
+ @to.start_accepting
+ @to.accept_verbatim verb
+
+ inner = CGI.escapeHTML "a % 09 # => blah"
+
+ expected = <<-EXPECTED
+
+<pre>#{inner}
+</pre>
+ EXPECTED
+
+ assert_equal expected, @to.res.join
+ assert_equal 16, @to.characters
+ end
+
+ def test_add_paragraph
+ @to = RDoc::Markup::ToHtmlSnippet.new @options, 0, 3
+ assert_throws :done do
+ @to.add_paragraph
+ @to.add_paragraph
+ @to.add_paragraph
+ end
+
+ assert_equal 3, @to.paragraphs
+ end
+
+ def test_convert_limit
+ rdoc = <<-RDOC
+= Hello
+
+This is some text, it *will* be cut off after 100 characters and an ellipsis
+must follow
+
+So there you have it
+ RDOC
+
+ expected = <<-EXPECTED
+<p>Hello
+<p>This is some text, it <strong>will</strong> be cut off after 100 characters
+and an ellipsis must follow
+<p>So there you #{@ellipsis}
+ EXPECTED
+
+ actual = @to.convert rdoc
+
+ assert_equal expected, actual
+ assert_equal 111, @to.characters, 'snippet character length'
+ end
+
+ def test_convert_limit_2
+ rdoc = <<-RDOC
+Outputs formatted RI data for the class or method +name+.
+
+Returns true if +name+ was found, false if it was not an alternative could
+be guessed, raises an error if +name+ couldn't be guessed.
+ RDOC
+
+ expected = <<-EXPECTED
+<p>Outputs formatted RI data for the class or method <code>name</code>.
+<p>Returns true if <code>name</code> was found, false if it was #{@ellipsis}
+ EXPECTED
+
+ actual = @to.convert rdoc
+
+ assert_equal expected, actual
+ assert_equal 159, @to.characters, 'snippet character length'
+ end
+
+ def test_convert_limit_paragraphs
+ @to = RDoc::Markup::ToHtmlSnippet.new @options, 100, 3
+
+ rdoc = <<-RDOC
+= \RDoc - Ruby Documentation System
+
+* {RDoc Project Page}[https://github.com/rdoc/rdoc/]
+* {RDoc Documentation}[http://docs.seattlerb.org/rdoc]
+* {RDoc Bug Tracker}[https://github.com/rdoc/rdoc/issues]
+
+== DESCRIPTION:
+
+RDoc produces HTML and command-line documentation for Ruby projects. RDoc
+includes the +rdoc+ and +ri+ tools for generating and displaying online
+documentation.
+
+See RDoc for a description of RDoc's markup and basic use.
+ RDOC
+
+ expected = <<-EXPECTED
+<p>RDoc - Ruby Documentation System
+<p>RDoc Project Page
+<p>RDoc Documentation
+ EXPECTED
+
+ actual = @to.convert rdoc
+
+ assert_equal expected, actual
+ assert_equal 67, @to.characters
+ end
+
+ def test_convert_limit_in_tag
+ @to = RDoc::Markup::ToHtmlSnippet.new @options, 4
+ rdoc = "* ab *c* d\n"
+
+ expected = "<p>ab <strong>c</strong> #{@ellipsis}\n\n"
+
+ actual = @to.convert rdoc
+
+ assert_equal 4, @to.characters
+ assert_equal expected, actual
+ end
+
+ def test_convert_limit_verbatim
+ rdoc = <<-RDOC
+= Hello There
+
+This is some text, it *will* be cut off after 100 characters
+
+ This one is cut off in this verbatim section
+ RDOC
+
+ expected = <<-EXPECTED
+<p>Hello There
+<p>This is some text, it <strong>will</strong> be cut off after 100 characters
+
+<pre>This one is cut off in this verbatim ...</pre>
+ EXPECTED
+
+ actual = @to.convert rdoc
+
+ assert_equal expected, actual
+ assert_equal 113, @to.characters
+ end
+
+ def test_convert_limit_verbatim_2
+ rdoc = <<-RDOC
+Extracts the class, selector and method name parts from +name+ like
+Foo::Bar#baz.
+
+NOTE: Given Foo::Bar, Bar is considered a class even though it may be a
+ method
+ RDOC
+
+ expected = <<-EXPECTED
+<p>Extracts the class, selector and method name parts from <code>name</code>
+like Foo::Bar#baz.
+<p>NOTE: Given Foo::Bar, #{@ellipsis}
+ EXPECTED
+
+ actual = @to.convert rdoc
+
+ assert_equal expected, actual
+ assert_equal 101, @to.characters
+ end
+
+ def test_convert_limit_verbatim_multiline
+ rdoc = <<-RDOC
+Look for directives in a normal comment block:
+
+ # :stopdoc:
+ # Don't display comment from this point forward
+
+This routine modifies its +comment+ parameter.
+ RDOC
+
+ inner = CGI.escapeHTML "# Don't display comment from this point forward"
+ expected = <<-EXPECTED
+<p>Look for directives in a normal comment block:
+
+<pre># :stopdoc:
+#{inner}</pre>
+ EXPECTED
+
+ actual = @to.convert rdoc
+
+ assert_equal expected, actual
+ assert_equal 105, @to.characters
+ end
+
+ def test_convert_limit_over
+ @to = RDoc::Markup::ToHtmlSnippet.new @options, 4
+ rdoc = "* text\n" * 2
+
+ expected = "<p>text\n"
+ expected.chomp!
+ expected << " #{@ellipsis}\n"
+
+ actual = @to.convert rdoc
+
+ assert_equal 4, @to.characters
+ assert_equal expected, actual
+ end
+
+ def test_convert_string
+ assert_equal '&lt;&gt;', @to.convert_string('<>')
+ end
+
+ def test_convert_RDOCLINK_label_label
+ result = @to.convert 'rdoc-label:label-One'
+
+ assert_equal "<p>One\n", result
+ assert_equal 3, @to.characters
+ end
+
+ def test_convert_RDOCLINK_label_foottext
+ result = @to.convert 'rdoc-label:foottext-1'
+
+ assert_equal "<p>*1\n", result
+ assert_equal 2, @to.characters
+ end
+
+ def test_convert_RDOCLINK_label_footmark
+ result = @to.convert 'rdoc-label:footmark-1'
+
+ assert_equal "<p>^1\n", result
+ assert_equal 2, @to.characters
+ end
+
+ def test_convert_RDOCLINK_ref
+ result = @to.convert 'rdoc-ref:C'
+
+ assert_equal "<p>C\n", result
+ assert_equal 1, @to.characters
+ end
+
+ def test_convert_TIDYLINK_rdoc_label
+ result = @to.convert '{foo}[rdoc-label:foottext-1]'
+
+ assert_equal "<p>foo\n", result
+ assert_equal 3, @to.characters
+ end
+
+ def test_handle_special_HYPERLINK_link
+ special = RDoc::Markup::Special.new 0, 'link:README.txt'
+
+ link = @to.handle_special_HYPERLINK special
+
+ assert_equal 'README.txt', link
+ end
+
+ def test_list_verbatim_2
+ str = "* one\n verb1\n verb2\n* two\n"
+
+ expected = <<-EXPECTED
+<p>one
+
+<pre>verb1
+verb2</pre>
+<p>two
+
+ EXPECTED
+
+ assert_equal expected, @m.convert(str, @to)
+ assert_equal 17, @to.characters
+ end
+
+ def test_on_tags
+ on = RDoc::Markup::AttrChanger.new 2, 0
+
+ @to.on_tags [], on
+
+ assert_equal 2, @to.mask
+ end
+
+ def test_off_tags
+ on = RDoc::Markup::AttrChanger.new 2, 0
+ off = RDoc::Markup::AttrChanger.new 0, 2
+
+ @to.on_tags [], on
+ @to.off_tags [], off
+
+ assert_equal 0, @to.mask
+ end
+
+ def test_to_html
+ assert_equal "<p><code>--</code>\n", util_format("<tt>--</tt>")
+ assert_equal 2, @to.characters
+ end
+
+ def util_format text
+ paragraph = RDoc::Markup::Paragraph.new text
+
+ @to.start_accepting
+ @to.accept_paragraph paragraph
+ @to.end_accepting
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb b/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb
new file mode 100644
index 0000000000..148edb1772
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_to_joined_paragraph.rb
@@ -0,0 +1,32 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupToJoinedParagraph < RDoc::TestCase
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToJoinedParagraph.new
+ end
+
+ def test_accept_paragraph
+ parsed = para('hello', ' ', 'world')
+
+ @to.accept_paragraph parsed
+
+ expected = para('hello world')
+
+ assert_equal expected, parsed
+ end
+
+ def test_accept_paragraph_break
+ parsed = para('hello', ' ', 'world', hard_break, 'everyone')
+
+ @to.accept_paragraph parsed
+
+ expected = para('hello world', hard_break, 'everyone')
+
+ assert_equal expected, parsed
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_to_label.rb b/test/rdoc/test_rdoc_markup_to_label.rb
new file mode 100644
index 0000000000..5fb358bee3
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_to_label.rb
@@ -0,0 +1,112 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupToLabel < RDoc::Markup::FormatterTestCase
+
+ add_visitor_tests
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToLabel.new
+ end
+
+ def empty
+ assert_empty @to.res
+ end
+
+ def end_accepting
+ assert_equal %w[hi], @to.res
+ end
+
+ alias accept_blank_line empty
+ alias accept_block_quote empty
+ alias accept_document empty
+ alias accept_heading empty
+ alias accept_heading_1 empty
+ alias accept_heading_2 empty
+ alias accept_heading_3 empty
+ alias accept_heading_4 empty
+ alias accept_heading_b empty
+ alias accept_heading_suppressed_crossref empty
+ alias accept_list_end_bullet empty
+ alias accept_list_end_label empty
+ alias accept_list_end_lalpha empty
+ alias accept_list_end_note empty
+ alias accept_list_end_number empty
+ alias accept_list_end_ualpha empty
+ alias accept_list_item_end_bullet empty
+ alias accept_list_item_end_label empty
+ alias accept_list_item_end_lalpha empty
+ alias accept_list_item_end_note empty
+ alias accept_list_item_end_number empty
+ alias accept_list_item_end_ualpha empty
+ alias accept_list_item_start_bullet empty
+ alias accept_list_item_start_label empty
+ alias accept_list_item_start_lalpha empty
+ alias accept_list_item_start_note empty
+ alias accept_list_item_start_note_2 empty
+ alias accept_list_item_start_note_multi_description empty
+ alias accept_list_item_start_note_multi_label empty
+ alias accept_list_item_start_number empty
+ alias accept_list_item_start_ualpha empty
+ alias accept_list_start_bullet empty
+ alias accept_list_start_label empty
+ alias accept_list_start_lalpha empty
+ alias accept_list_start_note empty
+ alias accept_list_start_number empty
+ alias accept_list_start_ualpha empty
+ alias accept_paragraph empty
+ alias accept_paragraph_b empty
+ alias accept_paragraph_br empty
+ alias accept_paragraph_break empty
+ alias accept_paragraph_i empty
+ alias accept_paragraph_plus empty
+ alias accept_paragraph_star empty
+ alias accept_paragraph_underscore empty
+ alias accept_raw empty
+ alias accept_rule empty
+ alias accept_verbatim empty
+ alias list_nested empty
+ alias list_verbatim empty
+ alias start_accepting empty
+
+ def test_convert_bold
+ assert_equal 'bold', @to.convert('<b>bold</b>')
+ assert_equal 'bold', @to.convert('*bold*')
+ end
+
+ def test_convert_crossref
+ assert_equal 'SomeClass', @to.convert('SomeClass')
+ assert_equal 'SomeClass', @to.convert('\\SomeClass')
+
+ assert_equal 'some_method', @to.convert('some_method')
+ assert_equal 'some_method', @to.convert('\\some_method')
+
+ assert_equal '%23some_method', @to.convert('#some_method')
+ assert_equal '%23some_method', @to.convert('\\#some_method')
+ end
+
+ def test_convert_em
+ assert_equal 'em', @to.convert('<em>em</em>')
+ assert_equal 'em', @to.convert('*em*')
+ end
+
+ def test_convert_em_dash # for HTML conversion
+ assert_equal '--', @to.convert('--')
+ end
+
+ def test_convert_escape
+ assert_equal 'a+%3E+b', @to.convert('a > b')
+ end
+
+ def test_convert_tidylink
+ assert_equal 'text', @to.convert('{text}[stuff]')
+ assert_equal 'text', @to.convert('text[stuff]')
+ end
+
+ def test_convert_tt
+ assert_equal 'tt', @to.convert('<tt>tt</tt>')
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_to_markdown.rb b/test/rdoc/test_rdoc_markup_to_markdown.rb
new file mode 100644
index 0000000000..56f84b41db
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_to_markdown.rb
@@ -0,0 +1,352 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupToMarkdown < RDoc::Markup::TextFormatterTestCase
+
+ add_visitor_tests
+ add_text_tests
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToMarkdown.new
+ end
+
+ def accept_blank_line
+ assert_equal "\n", @to.res.join
+ end
+
+ def accept_block_quote
+ assert_equal "> quote\n", @to.res.join
+ end
+
+ def accept_document
+ assert_equal "hello\n", @to.res.join
+ end
+
+ def accept_heading
+ assert_equal "##### Hello\n", @to.res.join
+ end
+
+ def accept_list_end_bullet
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_label
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_lalpha
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_note
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_number
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_end_ualpha
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_list_item_end_bullet
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_label
+ assert_equal "cat\n: ", @to.res.join
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_lalpha
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 2, @to.list_index.last
+ end
+
+ def accept_list_item_end_note
+ assert_equal "cat\n: ", @to.res.join
+ assert_equal 0, @to.indent, 'indent'
+ end
+
+ def accept_list_item_end_number
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 2, @to.list_index.last
+ end
+
+ def accept_list_item_end_ualpha
+ assert_equal 0, @to.indent, 'indent'
+ assert_equal 2, @to.list_index.last
+ end
+
+ def accept_list_item_start_bullet
+ assert_equal [""], @to.res
+ assert_equal '* ', @to.prefix
+ end
+
+ def accept_list_item_start_label
+ assert_equal [""], @to.res
+ assert_equal "cat\n: ", @to.prefix
+
+ assert_equal 4, @to.indent
+ end
+
+ def accept_list_item_start_lalpha
+ assert_equal [""], @to.res
+ assert_equal '1. ', @to.prefix
+
+ assert_equal 1, @to.list_index.last
+ assert_equal 4, @to.indent
+ end
+
+ def accept_list_item_start_note
+ assert_equal [""], @to.res
+ assert_equal "cat\n: ", @to.prefix
+
+ assert_equal 4, @to.indent
+ end
+
+ def accept_list_item_start_number
+ assert_equal [""], @to.res
+ assert_equal '1. ', @to.prefix
+
+ assert_equal 1, @to.list_index.last
+ assert_equal 4, @to.indent
+ end
+
+ def accept_list_item_start_ualpha
+ assert_equal [""], @to.res
+ assert_equal '1. ', @to.prefix
+
+ assert_equal 1, @to.list_index.last
+ assert_equal 4, @to.indent
+ end
+
+ def accept_list_start_bullet
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:BULLET], @to.list_type
+ assert_equal [4], @to.list_width
+ end
+
+ def accept_list_start_label
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:LABEL], @to.list_type
+ assert_equal [4], @to.list_width
+ end
+
+ def accept_list_start_lalpha
+ assert_equal "", @to.res.join
+ assert_equal [1], @to.list_index
+ assert_equal [:LALPHA], @to.list_type
+ assert_equal [4], @to.list_width
+ end
+
+ def accept_list_start_note
+ assert_equal "", @to.res.join
+ assert_equal [nil], @to.list_index
+ assert_equal [:NOTE], @to.list_type
+ assert_equal [4], @to.list_width
+ end
+
+ def accept_list_start_number
+ assert_equal "", @to.res.join
+ assert_equal [1], @to.list_index
+ assert_equal [:NUMBER], @to.list_type
+ assert_equal [4], @to.list_width
+ end
+
+ def accept_list_start_ualpha
+ assert_equal "", @to.res.join
+ assert_equal [1], @to.list_index
+ assert_equal [:UALPHA], @to.list_type
+ assert_equal [4], @to.list_width
+ end
+
+ def accept_paragraph
+ assert_equal "hi\n", @to.res.join
+ end
+
+ def accept_raw
+ raw = <<-RAW.rstrip
+<table>
+<tr><th>Name<th>Count
+<tr><td>a<td>1
+<tr><td>b<td>2
+</table>
+ RAW
+
+ assert_equal raw, @to.res.join
+ end
+
+ def accept_rule
+ assert_equal "---\n", @to.res.join
+ end
+
+ def accept_verbatim
+ assert_equal " hi\n world\n\n", @to.res.join
+ end
+
+ def end_accepting
+ assert_equal "hi", @to.end_accepting
+ end
+
+ def start_accepting
+ assert_equal 0, @to.indent
+ assert_equal [""], @to.res
+ assert_empty @to.list_index
+ assert_empty @to.list_type
+ assert_empty @to.list_width
+ end
+
+ def accept_heading_1
+ assert_equal "# Hello\n", @to.end_accepting
+ end
+
+ def accept_heading_2
+ assert_equal "## Hello\n", @to.end_accepting
+ end
+
+ def accept_heading_3
+ assert_equal "### Hello\n", @to.end_accepting
+ end
+
+ def accept_heading_4
+ assert_equal "#### Hello\n", @to.end_accepting
+ end
+
+ def accept_heading_indent
+ assert_equal " # Hello\n", @to.end_accepting
+ end
+
+ def accept_heading_b
+ assert_equal "# **Hello**\n", @to.end_accepting
+ end
+
+ def accept_heading_suppressed_crossref
+ assert_equal "# Hello\n", @to.end_accepting
+ end
+
+ def accept_list_item_start_note_2
+ assert_equal "`teletype`\n: teletype description\n\n", @to.res.join
+ end
+
+ def accept_list_item_start_note_multi_description
+ assert_equal "label\n: description one\n\n: description two\n\n",
+ @to.res.join
+ end
+
+ def accept_list_item_start_note_multi_label
+ assert_equal "one\ntwo\n: two headers\n\n", @to.res.join
+ end
+
+ def accept_paragraph_b
+ assert_equal "reg **bold words** reg\n", @to.end_accepting
+ end
+
+ def accept_paragraph_br
+ assert_equal "one \ntwo\n", @to.end_accepting
+ end
+
+ def accept_paragraph_break
+ assert_equal "hello \nworld\n", @to.end_accepting
+ end
+
+ def accept_paragraph_i
+ assert_equal "reg *italic words* reg\n", @to.end_accepting
+ end
+
+ def accept_paragraph_indent
+ expected = <<-EXPECTED
+ words words words words words words words words words words words words
+ words words words words words words words words words words words words
+ words words words words words words
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def accept_paragraph_plus
+ assert_equal "reg `teletype` reg\n", @to.end_accepting
+ end
+
+ def accept_paragraph_star
+ assert_equal "reg **bold** reg\n", @to.end_accepting
+ end
+
+ def accept_paragraph_underscore
+ assert_equal "reg *italic* reg\n", @to.end_accepting
+ end
+
+ def accept_paragraph_wrap
+ expected = <<-EXPECTED
+words words words words words words words words words words words words words
+words words words words words words words words words words words words words
+words words words words
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def accept_rule_indent
+ assert_equal " ---\n", @to.end_accepting
+ end
+
+ def accept_verbatim_indent
+ assert_equal " hi\n world\n\n", @to.end_accepting
+ end
+
+ def accept_verbatim_big_indent
+ assert_equal " hi\n world\n\n", @to.end_accepting
+ end
+
+ def list_nested
+ expected = <<-EXPECTED
+* l1
+ * l1.1
+
+* l2
+
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+ def list_verbatim
+ expected = <<-EXPECTED # HACK overblown
+* list stuff
+
+ * list
+ with
+
+ second
+
+ 1. indented
+ 2. numbered
+
+ third
+
+ * second
+
+
+ EXPECTED
+
+ assert_equal expected, @to.end_accepting
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_to_rdoc.rb b/test/rdoc/test_rdoc_markup_to_rdoc.rb
index 06cae078c6..4b60d0133e 100644
--- a/test/rdoc/test_rdoc_markup_to_rdoc.rb
+++ b/test/rdoc/test_rdoc_markup_to_rdoc.rb
@@ -1,7 +1,4 @@
-require 'rubygems'
-require 'rdoc/markup/text_formatter_test_case'
-require 'rdoc/markup/to_rdoc'
-require 'minitest/autorun'
+require 'rdoc/test_case'
class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
@@ -18,6 +15,10 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
assert_equal "\n", @to.res.join
end
+ def accept_block_quote
+ assert_equal "> quote\n", @to.res.join
+ end
+
def accept_document
assert_equal "hello\n", @to.res.join
end
@@ -67,7 +68,7 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_label
- assert_equal "\n", @to.res.join
+ assert_equal "cat:\n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -77,7 +78,7 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
end
def accept_list_item_end_note
- assert_equal "\n", @to.res.join
+ assert_equal "cat:\n", @to.res.join
assert_equal 0, @to.indent, 'indent'
end
@@ -244,10 +245,27 @@ class TestRDocMarkupToRDoc < RDoc::Markup::TextFormatterTestCase
assert_equal "<tt>teletype</tt>:\n teletype description\n\n", @to.res.join
end
+ def accept_list_item_start_note_multi_description
+ assert_equal "label:\n description one\n\n description two\n\n",
+ @to.res.join
+ end
+
+ def accept_list_item_start_note_multi_label
+ assert_equal "one\ntwo:\n two headers\n\n", @to.res.join
+ end
+
def accept_paragraph_b
assert_equal "reg <b>bold words</b> reg\n", @to.end_accepting
end
+ def accept_paragraph_br
+ assert_equal "one\ntwo\n", @to.end_accepting
+ end
+
+ def accept_paragraph_break
+ assert_equal "hello\nworld\n", @to.end_accepting
+ end
+
def accept_paragraph_i
assert_equal "reg <em>italic words</em> reg\n", @to.end_accepting
end
@@ -327,6 +345,24 @@ words words words words
assert_equal expected, @to.end_accepting
end
+ # functional test
+ def test_convert_list_note
+ note_list = <<-NOTE_LIST
+foo ::
+bar ::
+ hi
+ NOTE_LIST
+
+ expected = <<-EXPECTED
+foo
+bar:
+ hi
+
+ EXPECTED
+
+ assert_equal expected, @to.convert(note_list)
+ end
+
def test_accept_indented_paragraph
ip = RDoc::Markup::IndentedParagraph.new 2, 'cats are cool'
diff --git a/test/rdoc/test_rdoc_markup_to_table_of_contents.rb b/test/rdoc/test_rdoc_markup_to_table_of_contents.rb
new file mode 100644
index 0000000000..fd0be746d8
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_to_table_of_contents.rb
@@ -0,0 +1,95 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupToTableOfContents < RDoc::Markup::FormatterTestCase
+
+ add_visitor_tests
+
+ def setup
+ super
+
+ @to = RDoc::Markup::ToTableOfContents.new
+ end
+
+ def end_accepting
+ assert_equal %w[hi], @to.res
+ end
+
+ def empty
+ assert_empty @to.res
+ end
+
+ def accept_heading
+ assert_equal [@RM::Heading.new(5, 'Hello')], @to.res
+ end
+
+ def accept_heading_1
+ assert_equal [@RM::Heading.new(1, 'Hello')], @to.res
+ end
+
+ def accept_heading_2
+ assert_equal [@RM::Heading.new(2, 'Hello')], @to.res
+ end
+
+ def accept_heading_3
+ assert_equal [@RM::Heading.new(3, 'Hello')], @to.res
+ end
+
+ def accept_heading_4
+ assert_equal [@RM::Heading.new(4, 'Hello')], @to.res
+ end
+
+ def accept_heading_b
+ assert_equal [@RM::Heading.new(1, '*Hello*')], @to.res
+ end
+
+ def accept_heading_suppressed_crossref
+ assert_equal [@RM::Heading.new(1, '\\Hello')], @to.res
+ end
+
+ alias accept_blank_line empty
+ alias accept_block_quote empty
+ alias accept_document empty
+ alias accept_list_end_bullet empty
+ alias accept_list_end_label empty
+ alias accept_list_end_lalpha empty
+ alias accept_list_end_note empty
+ alias accept_list_end_number empty
+ alias accept_list_end_ualpha empty
+ alias accept_list_item_end_bullet empty
+ alias accept_list_item_end_label empty
+ alias accept_list_item_end_lalpha empty
+ alias accept_list_item_end_note empty
+ alias accept_list_item_end_number empty
+ alias accept_list_item_end_ualpha empty
+ alias accept_list_item_start_bullet empty
+ alias accept_list_item_start_label empty
+ alias accept_list_item_start_lalpha empty
+ alias accept_list_item_start_note empty
+ alias accept_list_item_start_note_2 empty
+ alias accept_list_item_start_note_multi_description empty
+ alias accept_list_item_start_note_multi_label empty
+ alias accept_list_item_start_number empty
+ alias accept_list_item_start_ualpha empty
+ alias accept_list_start_bullet empty
+ alias accept_list_start_label empty
+ alias accept_list_start_lalpha empty
+ alias accept_list_start_note empty
+ alias accept_list_start_number empty
+ alias accept_list_start_ualpha empty
+ alias accept_paragraph empty
+ alias accept_paragraph_b empty
+ alias accept_paragraph_br empty
+ alias accept_paragraph_break empty
+ alias accept_paragraph_i empty
+ alias accept_paragraph_plus empty
+ alias accept_paragraph_star empty
+ alias accept_paragraph_underscore empty
+ alias accept_raw empty
+ alias accept_rule empty
+ alias accept_verbatim empty
+ alias list_nested empty
+ alias list_verbatim empty
+ alias start_accepting empty
+
+end
+
diff --git a/test/rdoc/test_rdoc_markup_to_tt_only.rb b/test/rdoc/test_rdoc_markup_to_tt_only.rb
index f5bb662897..2e950dd1b0 100644
--- a/test/rdoc/test_rdoc_markup_to_tt_only.rb
+++ b/test/rdoc/test_rdoc_markup_to_tt_only.rb
@@ -1,7 +1,4 @@
-require 'rubygems'
-require 'rdoc/markup/formatter_test_case'
-require 'rdoc/markup/to_tt_only'
-require 'minitest/autorun'
+require 'rdoc/test_case'
class TestRDocMarkupToTtOnly < RDoc::Markup::FormatterTestCase
@@ -17,6 +14,10 @@ class TestRDocMarkupToTtOnly < RDoc::Markup::FormatterTestCase
assert_empty @to.end_accepting
end
+ def accept_block_quote
+ assert_empty @to.end_accepting
+ end
+
def accept_document
assert_equal [], @to.res
end
@@ -125,6 +126,10 @@ class TestRDocMarkupToTtOnly < RDoc::Markup::FormatterTestCase
assert_empty @to.end_accepting
end
+ def accept_paragraph_break
+ assert_empty @to.end_accepting
+ end
+
def accept_raw
assert_empty @to.end_accepting
end
@@ -177,10 +182,22 @@ class TestRDocMarkupToTtOnly < RDoc::Markup::FormatterTestCase
assert_equal [nil, 'teletype', nil], @to.res
end
+ def accept_list_item_start_note_multi_description
+ assert_empty @to.res
+ end
+
+ def accept_list_item_start_note_multi_label
+ assert_empty @to.res
+ end
+
def accept_paragraph_b
assert_empty @to.end_accepting
end
+ def accept_paragraph_br
+ assert_empty @to.end_accepting
+ end
+
def accept_paragraph_i
assert_empty @to.end_accepting
end
diff --git a/test/rdoc/test_rdoc_markup_verbatim.rb b/test/rdoc/test_rdoc_markup_verbatim.rb
new file mode 100644
index 0000000000..781d52849a
--- /dev/null
+++ b/test/rdoc/test_rdoc_markup_verbatim.rb
@@ -0,0 +1,29 @@
+require 'rdoc/test_case'
+
+class TestRDocMarkupVerbatim < RDoc::TestCase
+
+ def test_equals2
+ v1 = verb('1 + 1')
+ v2 = verb('1 + 1')
+ v3 = verb('1 + 2')
+ v4 = verb('1 + 1')
+ v4.format = :ruby
+
+ assert_equal v1, v2
+
+ refute_equal v1, v3
+ refute_equal v1, v4
+ end
+
+ def test_ruby_eh
+ verbatim = RDoc::Markup::Verbatim.new
+
+ refute verbatim.ruby?
+
+ verbatim.format = :ruby
+
+ assert verbatim.ruby?
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_method_attr.rb b/test/rdoc/test_rdoc_method_attr.rb
index 007a3f6b35..8fff038289 100644
--- a/test/rdoc/test_rdoc_method_attr.rb
+++ b/test/rdoc/test_rdoc_method_attr.rb
@@ -111,12 +111,45 @@ class TestRDocMethodAttr < XrefTestCase
assert_nil @m1_m.find_method_or_attribute 'm'
end
+ def test_full_name
+ assert_equal 'C1#m', @c1_m.full_name
+ assert_equal 'C1::m', @c1__m.full_name
+ end
+
+ def test_output_name
+ assert_equal '#m', @c1_m.output_name(@c1)
+ assert_equal '::m', @c1__m.output_name(@c1)
+
+ assert_equal 'C1#m', @c1_m.output_name(@c2)
+ assert_equal 'C1.m', @c1__m.output_name(@c2)
+ end
+
+ def test_search_record
+ @c1_m.comment = 'This is a comment.'
+
+ expected = [
+ 'm',
+ 'C1#m',
+ 'm',
+ 'C1',
+ 'C1.html#method-i-m',
+ '(foo)',
+ "<p>This is a comment.\n",
+ ]
+
+ assert_equal expected, @c1_m.search_record
+ end
+
+ def test_equals2
+ assert_equal @c1_m, @c1_m
+ refute_equal @c1_m, @parent_m
+ end
+
def test_to_s
assert_equal 'RDoc::AnyMethod: C1#m', @c1_m.to_s
assert_equal 'RDoc::AnyMethod: C2#b', @c2_b.to_s
assert_equal 'RDoc::AnyMethod: C1::m', @c1__m.to_s
end
-
end
diff --git a/test/rdoc/test_rdoc_normal_class.rb b/test/rdoc/test_rdoc_normal_class.rb
index bd0d67e19c..f3c7890d59 100644
--- a/test/rdoc/test_rdoc_normal_class.rb
+++ b/test/rdoc/test_rdoc_normal_class.rb
@@ -2,15 +2,34 @@ require File.expand_path '../xref_test_case', __FILE__
class TestRDocNormalClass < XrefTestCase
- def test_ancestors_class
- top_level = RDoc::TopLevel.new 'file.rb'
- klass = top_level.add_class RDoc::NormalClass, 'Klass'
+ def test_ancestors
+ klass = @top_level.add_class RDoc::NormalClass, 'Klass'
incl = RDoc::Include.new 'Incl', ''
- sub_klass = klass.add_class RDoc::NormalClass, 'SubClass', 'Klass'
+ sub_klass = @top_level.add_class RDoc::NormalClass, 'SubClass'
+ sub_klass.superclass = klass
sub_klass.add_include incl
- assert_equal [incl.name, klass], sub_klass.ancestors
+ assert_equal [incl.name, klass, 'Object'], sub_klass.ancestors
+ end
+
+ def test_ancestors_multilevel
+ c1 = @top_level.add_class RDoc::NormalClass, 'Outer'
+ c2 = @top_level.add_class RDoc::NormalClass, 'Middle', c1
+ c3 = @top_level.add_class RDoc::NormalClass, 'Inner', c2
+
+ assert_equal [c2, c1, 'Object'], c3.ancestors
+ end
+
+ def test_direct_ancestors
+ incl = RDoc::Include.new 'Incl', ''
+
+ c1 = @top_level.add_class RDoc::NormalClass, 'Outer'
+ c2 = @top_level.add_class RDoc::NormalClass, 'Middle', c1
+ c3 = @top_level.add_class RDoc::NormalClass, 'Inner', c2
+ c3.add_include incl
+
+ assert_equal [incl.name, c2], c3.direct_ancestors
end
def test_definition
diff --git a/test/rdoc/test_rdoc_normal_module.rb b/test/rdoc/test_rdoc_normal_module.rb
index 975bf911fe..120f56a284 100644
--- a/test/rdoc/test_rdoc_normal_module.rb
+++ b/test/rdoc/test_rdoc_normal_module.rb
@@ -9,7 +9,7 @@ class TestRDocNormalModule < XrefTestCase
end
def test_ancestors_module
- top_level = RDoc::TopLevel.new 'file.rb'
+ top_level = @store.add_file 'file.rb'
mod = top_level.add_module RDoc::NormalModule, 'Mod'
incl = RDoc::Include.new 'Incl', ''
diff --git a/test/rdoc/test_rdoc_options.rb b/test/rdoc/test_rdoc_options.rb
index 2f74f45b45..ddd9cb83ae 100644
--- a/test/rdoc/test_rdoc_options.rb
+++ b/test/rdoc/test_rdoc_options.rb
@@ -1,56 +1,130 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/options'
+require 'rdoc/test_case'
-require 'fileutils'
-require 'tmpdir'
-
-class TestRDocOptions < MiniTest::Unit::TestCase
+class TestRDocOptions < RDoc::TestCase
def setup
+ super
+
@options = RDoc::Options.new
@generators = RDoc::RDoc::GENERATORS.dup
end
def teardown
+ super
+
RDoc::RDoc::GENERATORS.replace @generators
end
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
def test_check_files
skip "assumes UNIX permission model" if /mswin|mingw/ =~ RUBY_PLATFORM
+
out, err = capture_io do
- Dir.mktmpdir do |dir|
- Dir.chdir dir do
- FileUtils.touch 'unreadable'
- FileUtils.chmod 0, 'unreadable'
+ temp_dir do
+ FileUtils.touch 'unreadable'
+ FileUtils.chmod 0, 'unreadable'
- @options.files = %w[nonexistent unreadable]
+ @options.files = %w[nonexistent unreadable]
- @options.check_files
- end
+ @options.check_files
end
end
assert_empty @options.files
- assert_equal '', out
+ assert_empty out
+ assert_empty err
+ end
- expected = <<-EXPECTED
-file 'nonexistent' not found
-file 'unreadable' not readable
- EXPECTED
+ def test_check_files_warn
+ @options.verbosity = 2
- assert_equal expected, err
+ out, err = capture_io do
+ @options.files = %w[nonexistent]
+
+ @options.check_files
+ end
+
+ assert_empty out
+ assert_equal "file 'nonexistent' not found\n", err
+ assert_empty @options.files
end
def test_dry_run_default
refute @options.dry_run
end
+ def test_encode_with
+ coder = {}
+ class << coder; alias add []=; end
+
+ @options.encode_with coder
+
+ encoding = Object.const_defined?(:Encoding) ? 'UTF-8' : nil
+
+ expected = {
+ 'charset' => 'UTF-8',
+ 'encoding' => encoding,
+ 'exclude' => [],
+ 'hyperlink_all' => false,
+ 'line_numbers' => false,
+ 'main_page' => nil,
+ 'markup' => 'rdoc',
+ 'rdoc_include' => [],
+ 'show_hash' => false,
+ 'static_path' => [],
+ 'tab_width' => 8,
+ 'title' => nil,
+ 'visibility' => :protected,
+ 'webcvs' => nil,
+ }
+
+ assert_equal expected, coder
+ end
+
+ def test_encode_with_trim_paths
+ subdir = nil
+ coder = {}
+ class << coder; alias add []=; end
+
+ temp_dir do |dir|
+ FileUtils.mkdir 'project'
+ FileUtils.mkdir 'dir'
+ FileUtils.touch 'file'
+
+ Dir.chdir 'project' do
+ subdir = File.expand_path 'subdir'
+ FileUtils.mkdir 'subdir'
+ @options.parse %w[
+ --copy subdir
+ --copy ../file
+ --copy ../
+ --copy /
+ --include subdir
+ --include ../dir
+ --include ../
+ --include /
+ ]
+
+ @options.encode_with coder
+ end
+ end
+
+ assert_equal [subdir], coder['rdoc_include']
+
+ assert_equal [subdir], coder['static_path']
+ end
+
def test_encoding_default
skip "Encoding not implemented" unless Object.const_defined? :Encoding
- assert_equal Encoding.default_external, @options.encoding
+ assert_equal Encoding::UTF_8, @options.encoding
end
def test_generator_descriptions
@@ -67,6 +141,63 @@ file 'unreadable' not readable
assert_equal expected, @options.generator_descriptions
end
+ def test_init_with_encoding
+ skip "Encoding not implemented" unless Object.const_defined? :Encoding
+ RDoc.load_yaml
+
+ @options.encoding = Encoding::IBM437
+
+ options = YAML.load YAML.dump @options
+
+ assert_equal Encoding::IBM437, options.encoding
+ end
+
+ def test_init_with_trim_paths
+ RDoc.load_yaml
+
+ yaml = <<-YAML
+--- !ruby/object:RDoc::Options
+static_path:
+- /etc
+rdoc_include:
+- /etc
+ YAML
+
+ options = YAML.load yaml
+
+ assert_empty options.rdoc_include
+ assert_empty options.static_path
+ end
+
+ def test_parse_copy_files_file_relative
+ file = File.basename __FILE__
+ expected = File.expand_path __FILE__
+
+ Dir.chdir File.expand_path('..', __FILE__) do
+ @options.parse %W[--copy-files #{file}]
+
+ assert_equal [expected], @options.static_path
+ end
+ end
+
+ def test_parse_copy_files_file_absolute
+ @options.parse %W[--copy-files #{File.expand_path __FILE__}]
+
+ assert_equal [File.expand_path(__FILE__)], @options.static_path
+ end
+
+ def test_parse_copy_files_directory_relative
+ @options.parse %w[--copy-files .]
+
+ assert_equal [@pwd], @options.static_path
+ end
+
+ def test_parse_copy_files_directory_absolute
+ @options.parse %w[--copy-files /]
+
+ assert_equal ['/'], @options.static_path
+ end
+
def test_parse_coverage
@options.parse %w[--dcov]
@@ -286,6 +417,17 @@ file 'unreadable' not readable
assert_equal 'MAIN', @options.main_page
end
+ def test_parse_markup
+ out, err = capture_io do
+ @options.parse %w[--markup tomdoc]
+ end
+
+ assert_empty out
+ assert_empty err
+
+ assert_equal 'tomdoc', @options.markup
+ end
+
def test_parse_template
out, err = capture_io do
@options.parse %w[--template darkfish]
@@ -337,13 +479,21 @@ file 'unreadable' not readable
$LOAD_PATH.replace orig_LOAD_PATH
end
- def test_parse_extension_alias
- out, err = capture_io do
- @options.parse %w[--extension foobar=rdoc]
- end
+ def test_parse_write_options
+ tmpdir = File.join Dir.tmpdir, "test_rdoc_options_#{$$}"
+ FileUtils.mkdir_p tmpdir
- assert_empty out
- assert_empty err
+ Dir.chdir tmpdir do
+ e = assert_raises SystemExit do
+ @options.parse %w[--write-options]
+ end
+
+ assert_equal 0, e.status
+
+ assert File.exist? '.rdoc_options'
+ end
+ ensure
+ FileUtils.rm_rf tmpdir
end
def test_setup_generator
@@ -397,5 +547,33 @@ file 'unreadable' not readable
refute @options.update_output_dir
end
+ def test_warn
+ out, err = capture_io do
+ @options.warn "warnings off"
+ end
+
+ assert_empty out
+ assert_empty err
+
+ @options.verbosity = 2
+
+ out, err = capture_io do
+ @options.warn "warnings on"
+ end
+
+ assert_empty out
+ assert_equal "warnings on\n", err
+ end
+
+ def test_write_options
+ temp_dir do |dir|
+ @options.write_options
+
+ assert File.exist? '.rdoc_options'
+
+ assert_equal @options, YAML.load(File.read('.rdoc_options'))
+ end
+ end
+
end
diff --git a/test/rdoc/test_rdoc_parser.rb b/test/rdoc/test_rdoc_parser.rb
index c323efeac3..35a797063a 100644
--- a/test/rdoc/test_rdoc_parser.rb
+++ b/test/rdoc/test_rdoc_parser.rb
@@ -1,14 +1,16 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/parser'
-require 'rdoc/parser/ruby'
-require 'tmpdir'
+require 'rdoc/test_case'
-class TestRDocParser < MiniTest::Unit::TestCase
+class TestRDocParser < RDoc::TestCase
def setup
+ super
+
@RP = RDoc::Parser
@binary_dat = File.expand_path '../binary.dat', __FILE__
+
+ @fn = 'file.rb'
+ @top_level = RDoc::TopLevel.new @fn
+ @options = RDoc::Options.new
end
def test_class_binary_eh_marshal
@@ -29,11 +31,8 @@ class TestRDocParser < MiniTest::Unit::TestCase
end
def test_class_binary_large_japanese_rdoc
- extenc, Encoding.default_external = Encoding.default_external, Encoding::US_ASCII
- file_name = File.expand_path '../test.ja.largedoc', __FILE__
+ file_name = File.expand_path '../test.ja.large.rdoc', __FILE__
assert !@RP.binary?(file_name)
- ensure
- Encoding.default_external = extenc
end
def test_class_binary_japanese_rdoc
@@ -60,13 +59,18 @@ class TestRDocParser < MiniTest::Unit::TestCase
readme_file_name = File.expand_path '../README', __FILE__
assert_equal @RP::Simple, @RP.can_parse(readme_file_name)
+ end
- jtest_largerdoc_file_name = File.expand_path '../test.ja.largedoc', __FILE__
- assert_nil @RP.can_parse(jtest_largerdoc_file_name)
-
- @RP.alias_extension("rdoc", "largedoc")
- assert_equal @RP::Simple, @RP.can_parse(jtest_largerdoc_file_name)
+ def test_class_can_parse_forbidden
+ Tempfile.open 'forbidden' do |io|
+ begin
+ File.chmod 0000, io.path
+ assert_nil @RP.can_parse io.path
+ ensure
+ File.chmod 0400, io.path
+ end
+ end
end
##
@@ -89,5 +93,92 @@ class TestRDocParser < MiniTest::Unit::TestCase
assert_nil @RP.for(nil, @binary_dat, nil, nil, nil)
end
+ def test_class_for_markup
+ content = <<-CONTENT
+# coding: utf-8 markup: rd
+ CONTENT
+
+ parser = @RP.for @top_level, __FILE__, content, @options, nil
+
+ assert_kind_of @RP::RD, parser
+ end
+
+ def test_class_use_markup
+ content = <<-CONTENT
+# coding: utf-8 markup: rd
+ CONTENT
+
+ parser = @RP.use_markup content
+
+ assert_equal @RP::RD, parser
+ end
+
+ def test_class_use_markup_markdown
+ content = <<-CONTENT
+# coding: utf-8 markup: markdown
+ CONTENT
+
+ parser = @RP.use_markup content
+
+ assert_equal @RP::Ruby, parser
+ end
+
+ def test_class_use_markup_modeline
+ content = <<-CONTENT
+# -*- coding: utf-8 -*-
+# markup: rd
+ CONTENT
+
+ parser = @RP.use_markup content
+
+ assert_equal @RP::RD, parser
+ end
+
+ def test_class_use_markup_modeline_shebang
+ content = <<-CONTENT
+#!/bin/sh
+/* -*- coding: utf-8 -*-
+ * markup: rd
+ */
+ CONTENT
+
+ parser = @RP.use_markup content
+
+ assert_equal @RP::RD, parser
+ end
+
+ def test_class_use_markup_shebang
+ content = <<-CONTENT
+#!/usr/bin/env ruby
+# coding: utf-8 markup: rd
+ CONTENT
+
+ parser = @RP.use_markup content
+
+ assert_equal @RP::RD, parser
+ end
+
+ def test_class_use_markup_tomdoc
+ content = <<-CONTENT
+# coding: utf-8 markup: tomdoc
+ CONTENT
+
+ parser = @RP.use_markup content
+
+ assert_equal @RP::Ruby, parser
+ end
+
+ def test_class_use_markup_none
+ parser = @RP.use_markup ''
+
+ assert_nil parser
+ end
+
+ def test_initialize
+ @RP.new @top_level, @fn, '', @options, nil
+
+ assert_equal @RP, @top_level.parser
+ end
+
end
diff --git a/test/rdoc/test_rdoc_parser_c.rb b/test/rdoc/test_rdoc_parser_c.rb
index 438eeee2ab..4e5e6ab1a2 100644
--- a/test/rdoc/test_rdoc_parser_c.rb
+++ b/test/rdoc/test_rdoc_parser_c.rb
@@ -1,9 +1,4 @@
-require 'stringio'
-require 'tempfile'
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/options'
-require 'rdoc/parser/c'
+require 'rdoc/test_case'
=begin
TODO: test call-seq parsing
@@ -51,22 +46,24 @@ class RDoc::Parser::C
public :do_classes, :do_constants
end
-class TestRDocParserC < MiniTest::Unit::TestCase
+class TestRDocParserC < RDoc::TestCase
def setup
+ super
+
@tempfile = Tempfile.new self.class.name
filename = @tempfile.path
- @top_level = RDoc::TopLevel.new filename
+ @top_level = @store.add_file filename
@fn = filename
@options = RDoc::Options.new
- @stats = RDoc::Stats.new 0
-
- RDoc::Parser::C.reset
- RDoc::TopLevel.reset
+ @options.verbosity = 2
+ @stats = RDoc::Stats.new @store, 0
end
def teardown
+ super
+
@tempfile.close
end
@@ -116,18 +113,18 @@ void Init_Blah(void) {
accessor = attrs.shift
assert_equal 'accessor', accessor.name
assert_equal 'RW', accessor.rw
- assert_equal 'This is an accessor', accessor.comment
+ assert_equal 'This is an accessor', accessor.comment.text
assert_equal @top_level, accessor.file
reader = attrs.shift
assert_equal 'reader', reader.name
assert_equal 'R', reader.rw
- assert_equal 'This is a reader', reader.comment
+ assert_equal 'This is a reader', reader.comment.text
writer = attrs.shift
assert_equal 'writer', writer.name
assert_equal 'W', writer.rw
- assert_equal 'This is a writer', writer.comment
+ assert_equal 'This is a writer', writer.comment.text
end
def test_do_attr_rb_define_attr
@@ -150,7 +147,7 @@ void Init_Blah(void) {
accessor = attrs.shift
assert_equal 'accessor', accessor.name
assert_equal 'RW', accessor.rw
- assert_equal 'This is an accessor', accessor.comment
+ assert_equal 'This is an accessor', accessor.comment.text
assert_equal @top_level, accessor.file
end
@@ -211,7 +208,7 @@ void Init_Blah(void) {
assert_equal 'bleh', methods.last.name
assert methods.last.singleton
assert_equal 'blah', methods.last.is_alias_for.name
- assert_equal 'This should show up as an alias', methods.last.comment
+ assert_equal 'This should show up as an alias', methods.last.comment.text
end
def test_do_classes_boot_class
@@ -223,7 +220,7 @@ VALUE cFoo = boot_defclass("Foo", rb_cObject);
EOF
klass = util_get_class content, 'cFoo'
- assert_equal "this is the Foo boot class", klass.comment
+ assert_equal "this is the Foo boot class", klass.comment.text
assert_equal 'Object', klass.superclass
end
@@ -236,7 +233,7 @@ VALUE cFoo = boot_defclass("Foo", 0);
EOF
klass = util_get_class content, 'cFoo'
- assert_equal "this is the Foo boot class", klass.comment
+ assert_equal "this is the Foo boot class", klass.comment.text
assert_equal nil, klass.superclass
end
@@ -251,7 +248,7 @@ void Init_Blah(void) {
refute util_get_class(content, 'cDate')
end
- assert_equal "Enclosing class/module \"cDate\" for alias b a not known\n",
+ assert_equal "Enclosing class or module \"cDate\" for alias b a is not known\n",
err
end
@@ -264,7 +261,21 @@ VALUE cFoo = rb_define_class("Foo", rb_cObject);
EOF
klass = util_get_class content, 'cFoo'
- assert_equal "this is the Foo class", klass.comment
+ assert_equal "this is the Foo class", klass.comment.text
+ end
+
+ def test_do_classes_struct
+ content = <<-EOF
+/* Document-class: Foo
+ * this is the Foo class
+ */
+VALUE cFoo = rb_struct_define_without_accessor(
+ "Foo", rb_cObject, foo_alloc,
+ "some", "various", "fields", NULL);
+ EOF
+
+ klass = util_get_class content, 'cFoo'
+ assert_equal "this is the Foo class", klass.comment.text
end
def test_do_classes_class_under
@@ -277,7 +288,7 @@ VALUE cFoo = rb_define_class_under(rb_mKernel, "Foo", rb_cObject);
klass = util_get_class content, 'cFoo'
assert_equal 'Kernel::Foo', klass.full_name
- assert_equal "this is the Foo class under Kernel", klass.comment
+ assert_equal "this is the Foo class under Kernel", klass.comment.text
end
def test_do_classes_class_under_rb_path2class
@@ -292,7 +303,7 @@ VALUE cFoo = rb_define_class_under(rb_mKernel, "Foo", rb_path2class("A::B"));
assert_equal 'Kernel::Foo', klass.full_name
assert_equal 'A::B', klass.superclass
- assert_equal 'this is Kernel::Foo < A::B', klass.comment
+ assert_equal 'this is Kernel::Foo < A::B', klass.comment.text
end
def test_do_classes_singleton
@@ -315,7 +326,7 @@ VALUE mFoo = rb_define_module("Foo");
EOF
klass = util_get_class content, 'mFoo'
- assert_equal "this is the Foo module", klass.comment
+ assert_equal "this is the Foo module", klass.comment.text
end
def test_do_classes_module_under
@@ -327,7 +338,7 @@ VALUE mFoo = rb_define_module_under(rb_mKernel, "Foo");
EOF
klass = util_get_class content, 'mFoo'
- assert_equal "this is the Foo module under Kernel", klass.comment
+ assert_equal "this is the Foo module under Kernel", klass.comment.text
end
def test_do_constants
@@ -377,6 +388,12 @@ void Init_foo(){
*/
rb_define_const(cFoo, "MULTILINE_NOT_EMPTY", INT2FIX(1));
+ /*
+ * Multiline comment goes here because this comment spans multiple lines.
+ * 1: However, the value extraction should only happen for the first line
+ */
+ rb_define_const(cFoo, "MULTILINE_COLON_ON_SECOND_LINE", INT2FIX(1));
+
}
EOF
@@ -393,7 +410,7 @@ void Init_foo(){
assert_equal @top_level, constants.first.file
- constants = constants.map { |c| [c.name, c.value, c.comment] }
+ constants = constants.map { |c| [c.name, c.value, c.comment.text] }
assert_equal ['PERFECT', '300', 'The highest possible score in bowling '],
constants.shift
@@ -426,6 +443,13 @@ Multiline comment goes here because this comment spans multiple lines.
assert_equal ['MULTILINE_VALUE', '1', comment], constants.shift
assert_equal ['MULTILINE_NOT_EMPTY', 'INT2FIX(1)', comment], constants.shift
+ comment = <<-EOF.chomp
+Multiline comment goes here because this comment spans multiple lines.
+1: However, the value extraction should only happen for the first line
+ EOF
+ assert_equal ['MULTILINE_COLON_ON_SECOND_LINE', 'INT2FIX(1)', comment],
+ constants.shift
+
assert constants.empty?, constants.inspect
end
@@ -445,6 +469,7 @@ void Init_curses(){
@parser = util_parser content
+ @parser.do_modules
@parser.do_classes
@parser.do_constants
@@ -455,7 +480,40 @@ void Init_curses(){
assert_equal 'COLOR_BLACK', constants.first.name
assert_equal 'UINT2NUM(COLOR_BLACK)', constants.first.value
- assert_equal 'Value of the color black', constants.first.comment
+ assert_equal 'Value of the color black', constants.first.comment.text
+ end
+
+ def test_do_constants_file
+ content = <<-EOF
+void Init_File(void) {
+ rb_cFile = rb_define_class("File", rb_cIO);
+ rb_mFConst = rb_define_module_under(rb_cFile, "Constants");
+ rb_include_module(rb_cIO, rb_mFConst);
+
+ /* Document-const: LOCK_SH
+ *
+ * Shared lock
+ */
+ rb_file_const("LOCK_SH", INT2FIX(LOCK_SH));
+}
+ EOF
+
+ @parser = util_parser content
+
+ @parser.do_modules
+ @parser.do_classes
+ @parser.do_constants
+
+ klass = @parser.classes['rb_mFConst']
+
+ constants = klass.constants
+ refute_empty klass.constants
+
+ constant = constants.first
+
+ assert_equal 'LOCK_SH', constant.name
+ assert_equal 'INT2FIX(LOCK_SH)', constant.value
+ assert_equal 'Shared lock', constant.comment.text
end
def test_do_includes
@@ -472,7 +530,7 @@ Init_foo() {
incl = klass.includes.first
assert_equal 'Inc', incl.name
- assert_equal '', incl.comment
+ assert_equal '', incl.comment.text
assert_equal @top_level, incl.file
end
@@ -563,12 +621,63 @@ void Init_Blah(void) {
assert methods.first.singleton
end
+ def test_do_missing
+ parser = util_parser
+
+ klass_a = @top_level.add_class RDoc::ClassModule, 'A'
+ parser.classes['a'] = klass_a
+
+ parser.enclosure_dependencies['c'] << 'b'
+ parser.enclosure_dependencies['b'] << 'a'
+ parser.enclosure_dependencies['d'] << 'a'
+
+ parser.missing_dependencies['d'] = ['d', :class, 'D', 'Object', 'a']
+ parser.missing_dependencies['c'] = ['c', :class, 'C', 'Object', 'b']
+ parser.missing_dependencies['b'] = ['b', :class, 'B', 'Object', 'a']
+
+ parser.do_missing
+
+ assert_equal %w[A A::B A::B::C A::D],
+ @store.all_classes_and_modules.map { |m| m.full_name }.sort
+ end
+
+ def test_do_missing_cycle
+ parser = util_parser
+
+ klass_a = @top_level.add_class RDoc::ClassModule, 'A'
+ parser.classes['a'] = klass_a
+
+ parser.enclosure_dependencies['c'] << 'b'
+ parser.enclosure_dependencies['b'] << 'a'
+
+ parser.missing_dependencies['c'] = ['c', :class, 'C', 'Object', 'b']
+ parser.missing_dependencies['b'] = ['b', :class, 'B', 'Object', 'a']
+
+ parser.enclosure_dependencies['y'] << 'z'
+ parser.enclosure_dependencies['z'] << 'y'
+
+ parser.missing_dependencies['y'] = ['y', :class, 'Y', 'Object', 'z']
+ parser.missing_dependencies['z'] = ['z', :class, 'Z', 'Object', 'y']
+
+ _, err = capture_io do
+ parser.do_missing
+ end
+
+ expected = 'Unable to create class Y (y), class Z (z) ' +
+ 'due to a cyclic class or module creation'
+
+ assert_equal expected, err.chomp
+
+ assert_equal %w[A A::B A::B::C],
+ @store.all_classes_and_modules.map { |m| m.full_name }.sort
+ end
+
def test_find_alias_comment
- parser = util_parser ''
+ parser = util_parser
comment = parser.find_alias_comment 'C', '[]', 'index'
- assert_equal '', comment
+ assert_equal '', comment.text
parser = util_parser <<-C
/*
@@ -580,27 +689,28 @@ rb_define_alias(C, "[]", "index");
comment = parser.find_alias_comment 'C', '[]', 'index'
- assert_equal "/*\n * comment\n */\n\n", comment
+ assert_equal "/*\n * comment\n */\n\n", comment.text
end
- def test_find_class_comment_include
+ def test_find_class_comment
@options.rdoc_include << File.dirname(__FILE__)
content = <<-EOF
/*
- * a comment for class Foo
- *
- * :include: test.txt
+ * Comment 1
*/
-void
-Init_Foo(void) {
- VALUE foo = rb_define_class("Foo", rb_cObject);
-}
+foo = rb_define_class("MyClassName1", rb_cObject);
+
+/*
+ * Comment 2
+ */
+bar = rb_define_class("MyClassName2", rb_cObject);
EOF
- klass = util_get_class content, 'foo'
+ util_get_class content
- assert_equal "a comment for class Foo\n\ntest file", klass.comment
+ assert_equal "Comment 1", @parser.classes['foo'].comment.text
+ assert_equal "Comment 2", @parser.classes['bar'].comment.text
end
def test_find_class_comment_init
@@ -616,7 +726,7 @@ Init_Foo(void) {
klass = util_get_class content, 'foo'
- assert_equal "a comment for class Foo", klass.comment
+ assert_equal "a comment for class Foo", klass.comment.text
end
def test_find_class_comment_define_class
@@ -629,7 +739,7 @@ VALUE foo = rb_define_class("Foo", rb_cObject);
klass = util_get_class content, 'foo'
- assert_equal "a comment for class Foo", klass.comment
+ assert_equal "a comment for class Foo", klass.comment.text
end
def test_find_class_comment_define_class_Init_Foo
@@ -648,7 +758,7 @@ Init_Foo(void) {
klass = util_get_class content, 'foo'
- assert_equal "a comment for class Foo on Init", klass.comment
+ assert_equal "a comment for class Foo on Init", klass.comment.text
end
def test_find_class_comment_define_class_Init_Foo_no_void
@@ -667,7 +777,7 @@ Init_Foo() {
klass = util_get_class content, 'foo'
- assert_equal "a comment for class Foo on Init", klass.comment
+ assert_equal "a comment for class Foo on Init", klass.comment.text
end
def test_find_class_comment_define_class_bogus_comment
@@ -687,7 +797,42 @@ Init_Foo(void) {
klass = util_get_class content, 'foo'
- assert_equal '', klass.comment
+ assert_equal '', klass.comment.text
+ end
+
+ def test_find_class_comment_define_class_under
+ content = <<-EOF
+/*
+ * a comment for class Foo
+ */
+VALUE foo = rb_define_class_under(rb_cObject, "Foo", rb_cObject);
+ EOF
+
+ klass = util_get_class content, 'foo'
+
+ assert_equal "a comment for class Foo", klass.comment.text
+ end
+
+ def test_find_class_comment_define_class_under_Init
+ content = <<-EOF
+/*
+ * a comment for class Foo on Init
+ */
+void
+Init_Foo(void) {
+ /*
+ * a comment for class Foo on rb_define_class
+ */
+ VALUE foo = rb_define_class_under(rb_cObject, "Foo", rb_cObject);
+}
+ EOF
+
+ klass = util_get_class content, 'foo'
+
+ # the inner comment is used since Object::Foo is not necessarily the same
+ # thing as "Foo" for Init_
+ assert_equal "a comment for class Foo on rb_define_class",
+ klass.comment.text
end
def test_find_const_comment_rb_define
@@ -702,7 +847,7 @@ rb_define_const(cFoo, "CONST", value);
comment = parser.find_const_comment 'const', 'CONST'
- assert_equal "/*\n * A comment\n */\n", comment
+ assert_equal "/*\n * A comment\n */\n", comment.text
end
def test_find_const_comment_document_const
@@ -718,7 +863,7 @@ rb_define_const(cFoo, "CONST", value);
comment = parser.find_const_comment nil, 'CONST'
- assert_equal " *\n * A comment\n */", comment
+ assert_equal "/*\n *\n * A comment\n */", comment.text
end
def test_find_const_comment_document_const_full_name
@@ -734,7 +879,7 @@ rb_define_const(cFoo, "CONST", value);
comment = parser.find_const_comment nil, 'CONST', 'Foo'
- assert_equal " *\n * A comment\n */", comment
+ assert_equal "/*\n *\n * A comment\n */", comment.text
end
def test_find_body
@@ -759,7 +904,7 @@ Init_Foo(void) {
assert_equal 'my_method', other_function.name
assert_equal "a comment for other_function",
- other_function.comment
+ other_function.comment.text
assert_equal '()', other_function.params
code = other_function.token_stream.first.text
@@ -832,7 +977,7 @@ Init_Foo(void) {
other_function = klass.method_list.first
assert_equal 'my_method', other_function.name
- assert_equal 'a comment for rb_other_function', other_function.comment
+ assert_equal 'a comment for rb_other_function', other_function.comment.text
assert_equal '()', other_function.params
assert_equal 118, other_function.offset
assert_equal 8, other_function.line
@@ -866,7 +1011,7 @@ Init_Foo(void) {
other_function = klass.method_list.first
assert_equal 'my_method', other_function.name
- assert_equal 'a comment for other_function', other_function.comment
+ assert_equal 'a comment for other_function', other_function.comment.text
assert_equal '()', other_function.params
assert_equal 39, other_function.offset
assert_equal 4, other_function.line
@@ -904,11 +1049,11 @@ Init_Foo(void) {
bar = methods.first
assert_equal 'Foo#bar', bar.full_name
- assert_equal "a comment for bar", bar.comment
+ assert_equal "a comment for bar", bar.comment.text
baz = methods.last
assert_equal 'Foo#baz', baz.full_name
- assert_equal "a comment for bar", baz.comment
+ assert_equal "a comment for bar", baz.comment.text
end
def test_find_body_document_method_equals
@@ -938,7 +1083,7 @@ Init_zlib() {
bar = methods.first
assert_equal 'Zlib::GzipWriter#mtime=', bar.full_name
- assert_equal 'A comment', bar.comment
+ assert_equal 'A comment', bar.comment.text
end
def test_find_body_document_method_same
@@ -979,73 +1124,37 @@ Init_Foo(void) {
s_bar = methods.first
assert_equal 'Foo::bar', s_bar.full_name
- assert_equal "a comment for Foo::bar", s_bar.comment
+ assert_equal "a comment for Foo::bar", s_bar.comment.text
bar = methods.last
assert_equal 'Foo#bar', bar.full_name
- assert_equal "a comment for Foo#bar", bar.comment
+ assert_equal "a comment for Foo#bar", bar.comment.text
end
def test_find_modifiers_call_seq
- comment = <<-COMMENT
-/* call-seq:
- * commercial() -> Date <br />
- * commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
- * commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
- *
- * If no arguments are given:
- * * ruby 1.8: returns a +Date+ for 1582-10-15 (the Day of Calendar Reform in
- * Italy)
- * * ruby 1.9: returns a +Date+ for julian day 0
- *
- * Otherwise, returns a +Date+ for the commercial week year, commercial week,
- * and commercial week day given. Ignores the 4th argument.
- */
-
- COMMENT
-
- parser = util_parser ''
- method_obj = RDoc::AnyMethod.new nil, 'blah'
-
- parser.find_modifiers comment, method_obj
+ comment = RDoc::Comment.new <<-COMMENT
+call-seq:
+ commercial() -> Date <br />
- expected = <<-CALL_SEQ.chomp
-commercial() -> Date <br />
-commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
-commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
-
- CALL_SEQ
-
- assert_equal expected, method_obj.call_seq
- end
-
- def test_find_modifiers_call_seq_no_blank
- comment = <<-COMMENT
-/* call-seq:
- * commercial() -> Date <br />
- * commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
- * commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
- */
+If no arguments are given:
COMMENT
- parser = util_parser ''
+ parser = util_parser
method_obj = RDoc::AnyMethod.new nil, 'blah'
parser.find_modifiers comment, method_obj
expected = <<-CALL_SEQ.chomp
commercial() -> Date <br />
-commercial(cwyear, cweek=41, cwday=5, sg=nil) -> Date [ruby 1.8] <br />
-commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
-
+
CALL_SEQ
assert_equal expected, method_obj.call_seq
end
def test_find_modifiers_nodoc
- comment = <<-COMMENT
+ comment = RDoc::Comment.new <<-COMMENT
/* :nodoc:
*
* Blah
@@ -1053,7 +1162,7 @@ commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
COMMENT
- parser = util_parser ''
+ parser = util_parser
method_obj = RDoc::AnyMethod.new nil, 'blah'
parser.find_modifiers comment, method_obj
@@ -1062,7 +1171,7 @@ commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
end
def test_find_modifiers_yields
- comment = <<-COMMENT
+ comment = RDoc::Comment.new <<-COMMENT
/* :yields: a, b
*
* Blah
@@ -1070,22 +1179,14 @@ commercial(cwyear, cweek=1, cwday=1, sg=nil) -> Date [ruby 1.9]
COMMENT
- parser = util_parser ''
+ parser = util_parser
method_obj = RDoc::AnyMethod.new nil, 'blah'
parser.find_modifiers comment, method_obj
assert_equal 'a, b', method_obj.block_params
- expected = <<-EXPECTED
-/*
- *
- * Blah
- */
-
- EXPECTED
-
- assert_equal expected, comment
+ assert_equal "\n\nBlah", comment.text
end
def test_handle_method_args_minus_1
@@ -1206,14 +1307,14 @@ void Init_Blah(void) {
end
def test_look_for_directives_in
- parser = util_parser ''
+ parser = util_parser
- comment = "# :markup: not_rdoc\n"
+ comment = RDoc::Comment.new "# :other: not_handled\n"
parser.look_for_directives_in @top_level, comment
- assert_equal "# :markup: not_rdoc\n", comment
- assert_equal 'not_rdoc', @top_level.metadata['markup']
+ assert_equal "# :other: not_handled\n", comment.text
+ assert_equal 'not_handled', @top_level.metadata['other']
end
def test_define_method
@@ -1240,7 +1341,7 @@ Init_IO(void) {
klass = util_get_class content, 'rb_cIO'
read_method = klass.method_list.first
assert_equal "read", read_method.name
- assert_equal "Method Comment! ", read_method.comment
+ assert_equal "Method Comment! ", read_method.comment.text
assert_equal "rb_io_s_read", read_method.c_function
assert read_method.singleton
end
@@ -1271,7 +1372,7 @@ Init_IO(void) {
klass = util_get_class content, 'rb_cIO'
read_method = klass.method_list.first
assert_equal "read", read_method.name
- assert_equal "Method Comment! ", read_method.comment
+ assert_equal "Method Comment! ", read_method.comment.text
assert_equal "rb_io_s_read", read_method.c_function
assert read_method.singleton
end
@@ -1301,7 +1402,7 @@ Init_IO(void) {
read_method = klass.method_list.first
assert_equal 'IO#read', read_method.full_name
assert_equal :private, read_method.visibility
- assert_equal "Method Comment! ", read_method.comment
+ assert_equal "Method Comment! ", read_method.comment.text
end
def test_define_method_private_singleton
@@ -1329,7 +1430,7 @@ Init_IO(void) {
klass = util_get_class content, 'rb_cIO'
read_method = klass.method_list.first
assert_equal "read", read_method.name
- assert_equal "Method Comment! ", read_method.comment
+ assert_equal "Method Comment! ", read_method.comment.text
assert_equal :private, read_method.visibility
assert read_method.singleton
end
@@ -1359,12 +1460,12 @@ Init_IO(void) {
klass = util_get_class content, 'rb_cIO'
read_method = klass.method_list.first
assert_equal "read", read_method.name
- assert_equal "Method Comment! ", read_method.comment
+ assert_equal "Method Comment! ", read_method.comment.text
assert read_method.singleton
end
def test_rb_scan_args
- parser = util_parser ''
+ parser = util_parser
assert_equal '(p1)',
parser.rb_scan_args('rb_scan_args(a, b, "1",)')
@@ -1422,13 +1523,39 @@ Init_IO(void) {
parser.rb_scan_args('rb_scan_args(a, b, "*:&",)')
end
- def util_get_class(content, name)
+ def test_scan_order_dependent
+ parser = util_parser <<-C
+void a(void) {
+ mA = rb_define_module("A");
+}
+
+void b(void) {
+ cB = rb_define_class_under(mA, "B", rb_cObject);
+}
+
+void c(void) {
+ mC = rb_define_module_under(cB, "C");
+}
+
+void d(void) {
+ mD = rb_define_class_under(mC, "D");
+}
+ C
+
+ parser.scan
+
+ assert_equal %w[A A::B A::B::C],
+ @store.all_classes_and_modules.map { |m| m.full_name }.sort
+ end
+
+ def util_get_class content, name = nil
@parser = util_parser content
@parser.scan
- @parser.classes[name]
+
+ @parser.classes[name] if name
end
- def util_parser(content)
+ def util_parser content = ''
RDoc::Parser::C.new @top_level, @fn, content, @options, @stats
end
diff --git a/test/rdoc/test_rdoc_parser_markdown.rb b/test/rdoc/test_rdoc_parser_markdown.rb
new file mode 100644
index 0000000000..df0e04d5c1
--- /dev/null
+++ b/test/rdoc/test_rdoc_parser_markdown.rb
@@ -0,0 +1,55 @@
+require 'rdoc/test_case'
+
+class TestRDocParserMarkdown < RDoc::TestCase
+
+ def setup
+ super
+
+ @RP = RDoc::Parser
+
+ @tempfile = Tempfile.new self.class.name
+ filename = @tempfile.path
+
+ @top_level = @store.add_file filename
+ @fn = filename
+ @options = RDoc::Options.new
+ @stats = RDoc::Stats.new @store, 0
+ end
+
+ def teardown
+ super
+
+ @tempfile.close
+ end
+
+ def test_file
+ assert_kind_of RDoc::Parser::Text, util_parser('')
+ end
+
+ def test_class_can_parse
+ assert_equal @RP::Markdown, @RP.can_parse('foo.md')
+ assert_equal @RP::Markdown, @RP.can_parse('foo.md.ja')
+
+ assert_equal @RP::Markdown, @RP.can_parse('foo.markdown')
+ assert_equal @RP::Markdown, @RP.can_parse('foo.markdown.ja')
+ end
+
+ def test_scan
+ parser = util_parser 'it *really* works'
+
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('it _really_ works'))
+ expected.file = @top_level
+
+ parser.scan
+
+ assert_equal expected, @top_level.comment.parse
+ end
+
+ def util_parser content
+ RDoc::Parser::Markdown.new @top_level, @fn, content, @options, @stats
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_parser_rd.rb b/test/rdoc/test_rdoc_parser_rd.rb
new file mode 100644
index 0000000000..b94280f497
--- /dev/null
+++ b/test/rdoc/test_rdoc_parser_rd.rb
@@ -0,0 +1,52 @@
+require 'rdoc/test_case'
+
+class TestRDocParserRd < RDoc::TestCase
+
+ def setup
+ super
+
+ @RP = RDoc::Parser
+
+ @tempfile = Tempfile.new self.class.name
+ filename = @tempfile.path
+
+ @top_level = @store.add_file filename
+ @fn = filename
+ @options = RDoc::Options.new
+ @stats = RDoc::Stats.new @store, 0
+ end
+
+ def teardown
+ super
+
+ @tempfile.close
+ end
+
+ def test_file
+ assert_kind_of RDoc::Parser::Text, util_parser('')
+ end
+
+ def test_class_can_parse
+ assert_equal @RP::RD, @RP.can_parse('foo.rd')
+ assert_equal @RP::RD, @RP.can_parse('foo.rd.ja')
+ end
+
+ def test_scan
+ parser = util_parser 'it ((*really*)) works'
+
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('it <em>really</em> works'))
+ expected.file = @top_level
+
+ parser.scan
+
+ assert_equal expected, @top_level.comment.parse
+ end
+
+ def util_parser content
+ RDoc::Parser::RD.new @top_level, @fn, content, @options, @stats
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_parser_ruby.rb b/test/rdoc/test_rdoc_parser_ruby.rb
index 6086b3ec13..b25a36301e 100644
--- a/test/rdoc/test_rdoc_parser_ruby.rb
+++ b/test/rdoc/test_rdoc_parser_ruby.rb
@@ -1,17 +1,12 @@
# coding: utf-8
-require 'stringio'
-require 'tempfile'
-require 'rubygems'
-require 'minitest/autorun'
+require 'rdoc/test_case'
-require 'rdoc/options'
-require 'rdoc/parser/ruby'
-require 'rdoc/stats'
-
-class TestRDocParserRuby < MiniTest::Unit::TestCase
+class TestRDocParserRuby < RDoc::TestCase
def setup
+ super
+
@tempfile = Tempfile.new self.class.name
@filename = @tempfile.path
@@ -19,19 +14,32 @@ class TestRDocParserRuby < MiniTest::Unit::TestCase
@tempfile2 = Tempfile.new self.class.name
@filename2 = @tempfile2.path
- util_top_level
+ @top_level = @store.add_file @filename
+ @top_level2 = @store.add_file @filename2
+
@options = RDoc::Options.new
@options.quiet = true
@options.option_parser = OptionParser.new
- @stats = RDoc::Stats.new 0
+ @comment = RDoc::Comment.new '', @top_level
+
+ @stats = RDoc::Stats.new @store, 0
end
def teardown
+ super
+
@tempfile.close
@tempfile2.close
end
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding(Encoding.default_external) if defined? Encoding
+ s.chomp
+ end
+
def test_collect_first_comment
p = util_parser <<-CONTENT
# first
@@ -42,7 +50,7 @@ class C; end
comment = p.collect_first_comment
- assert_equal "# first\n", comment
+ assert_equal RDoc::Comment.new("# first\n", @top_level), comment
end
def test_collect_first_comment_encoding
@@ -59,67 +67,46 @@ class C; end
comment = p.collect_first_comment
- assert_equal Encoding::CP852, comment.encoding
+ assert_equal Encoding::CP852, comment.text.encoding
end
- def test_extract_call_seq
- m = RDoc::AnyMethod.new nil, 'm'
- p = util_parser ''
+ def test_get_class_or_module
+ ctxt = RDoc::Context.new
+ ctxt.store = @store
- comment = <<-COMMENT
- # call-seq:
- # bla => true or false
- #
- # moar comment
- COMMENT
+ cont, name_t, given_name = util_parser('A') .get_class_or_module ctxt
- p.extract_call_seq comment, m
+ assert_equal ctxt, cont
+ assert_equal 'A', name_t.text
+ assert_equal 'A', given_name
- assert_equal "bla => true or false\n", m.call_seq
- end
+ cont, name_t, given_name = util_parser('A::B') .get_class_or_module ctxt
- def test_extract_call_seq_blank
- m = RDoc::AnyMethod.new nil, 'm'
- p = util_parser ''
+ assert_equal @store.find_module_named('A'), cont
+ assert_equal 'B', name_t.text
+ assert_equal 'A::B', given_name
- comment = <<-COMMENT
- # call-seq:
- # bla => true or false
- #
- COMMENT
+ cont, name_t, given_name = util_parser('A:: B').get_class_or_module ctxt
- p.extract_call_seq comment, m
+ assert_equal @store.find_module_named('A'), cont
+ assert_equal 'B', name_t.text
+ assert_equal 'A::B', given_name
- assert_equal "bla => true or false\n", m.call_seq
- end
-
- def test_extract_call_seq_no_blank
- m = RDoc::AnyMethod.new nil, 'm'
- p = util_parser ''
-
- comment = <<-COMMENT
- # call-seq:
- # bla => true or false
- COMMENT
-
- p.extract_call_seq comment, m
-
- assert_equal "bla => true or false\n", m.call_seq
+ assert_raises NoMethodError do
+ util_parser("A::\nB").get_class_or_module ctxt
+ end
end
- def test_extract_call_seq_undent
- m = RDoc::AnyMethod.new nil, 'm'
- p = util_parser ''
+ def test_get_class_specification
+ assert_equal 'A', util_parser('A') .get_class_specification
+ assert_equal 'A::B', util_parser('A::B').get_class_specification
+ assert_equal '::A', util_parser('::A').get_class_specification
- comment = <<-COMMENT
- # call-seq:
- # bla => true or false
- # moar comment
- COMMENT
+ assert_equal 'self', util_parser('self').get_class_specification
- p.extract_call_seq comment, m
+ assert_equal '', util_parser('').get_class_specification
- assert_equal "bla => true or false\nmoar comment\n", m.call_seq
+ assert_equal '', util_parser('$g').get_class_specification
end
def test_get_symbol_or_name
@@ -149,159 +136,32 @@ class C; end
def test_look_for_directives_in_attr
util_parser ""
- comment = "# :attr: my_attr\n"
+ comment = RDoc::Comment.new "# :attr: my_attr\n", @top_level
@parser.look_for_directives_in @top_level, comment
- assert_equal "# :attr: my_attr\n", comment
+ assert_equal "# :attr: my_attr\n", comment.text
- comment = "# :attr_reader: my_method\n"
+ comment = RDoc::Comment.new "# :attr_reader: my_method\n", @top_level
@parser.look_for_directives_in @top_level, comment
- assert_equal "# :attr_reader: my_method\n", comment
+ assert_equal "# :attr_reader: my_method\n", comment.text
- comment = "# :attr_writer: my_method\n"
+ comment = RDoc::Comment.new "# :attr_writer: my_method\n", @top_level
@parser.look_for_directives_in @top_level, comment
- assert_equal "# :attr_writer: my_method\n", comment
- end
-
- def test_remove_private_comments
- util_parser ''
-
- comment = <<-EOS
-# This is text
-#--
-# this is private
- EOS
-
- expected = <<-EOS
-# This is text
- EOS
-
- @parser.remove_private_comments(comment)
-
- assert_equal expected, comment
- end
-
- def test_remove_private_comments_encoding
- skip "Encoding not implemented" unless Object.const_defined? :Encoding
-
- util_parser ''
-
- comment = <<-EOS
-# This is text
-#--
-# this is private
- EOS
- comment.force_encoding Encoding::IBM437
-
- @parser.remove_private_comments comment
-
- assert_equal Encoding::IBM437, comment.encoding
- end
-
- def test_remove_private_comments_long
- util_parser ''
-
- comment = <<-EOS
-#-----
-#++
-# this is text
-#-----
- EOS
-
- expected = <<-EOS
-# this is text
- EOS
-
- @parser.remove_private_comments(comment)
-
- assert_equal expected, comment
- end
-
- def test_remove_private_comments_rule
- util_parser ''
-
- comment = <<-EOS
-# This is text with a rule:
-# ---
-# this is also text
- EOS
-
- expected = comment.dup
-
- @parser.remove_private_comments(comment)
-
- assert_equal expected, comment
- end
-
- def test_remove_private_comments_toggle
- util_parser ''
-
- comment = <<-EOS
-# This is text
-#--
-# this is private
-#++
-# This is text again.
- EOS
-
- expected = <<-EOS
-# This is text
-# This is text again.
- EOS
-
- @parser.remove_private_comments(comment)
-
- assert_equal expected, comment
- end
-
- def test_remove_private_comments_toggle_encoding
- skip "Encoding not implemented" unless Object.const_defined? :Encoding
-
- util_parser ''
-
- comment = <<-EOS
-# This is text
-#--
-# this is private
-#++
-# This is text again.
- EOS
-
- comment.force_encoding Encoding::IBM437
-
- @parser.remove_private_comments comment
-
- assert_equal Encoding::IBM437, comment.encoding
- end
-
- def test_remove_private_comments_toggle_encoding_ruby_bug?
- skip "Encoding not implemented" unless Object.const_defined? :Encoding
-
- util_parser ''
-
- comment = <<-EOS
-#--
-# this is private
-#++
-# This is text again.
- EOS
-
- comment.force_encoding Encoding::IBM437
-
- @parser.remove_private_comments comment
-
- assert_equal Encoding::IBM437, comment.encoding
+ assert_equal "# :attr_writer: my_method\n", comment.text
end
def test_look_for_directives_in_commented
util_parser ""
- comment = "# how to make a section:\n# # :section: new section\n"
+ comment = RDoc::Comment.new <<-COMMENT, @top_level
+# how to make a section:
+# # :section: new section
+ COMMENT
@parser.look_for_directives_in @top_level, comment
@@ -310,43 +170,48 @@ class C; end
assert_equal nil, section.comment
assert_equal "# how to make a section:\n# # :section: new section\n",
- comment
+ comment.text
end
def test_look_for_directives_in_method
util_parser ""
- comment = "# :method: my_method\n"
+ comment = RDoc::Comment.new "# :method: my_method\n", @top_level
@parser.look_for_directives_in @top_level, comment
- assert_equal "# :method: my_method\n", comment
+ assert_equal "# :method: my_method\n", comment.text
- comment = "# :singleton-method: my_method\n"
+ comment = RDoc::Comment.new "# :singleton-method: my_method\n", @top_level
@parser.look_for_directives_in @top_level, comment
- assert_equal "# :singleton-method: my_method\n", comment
+ assert_equal "# :singleton-method: my_method\n", comment.text
end
def test_look_for_directives_in_section
util_parser ""
- comment = "# :section: new section\n# woo stuff\n"
+ comment = RDoc::Comment.new <<-COMMENT, @top_level
+# :section: new section
+# woo stuff
+ COMMENT
@parser.look_for_directives_in @top_level, comment
section = @top_level.current_section
assert_equal 'new section', section.title
- assert_equal "# woo stuff\n", section.comment
+ assert_equal [comment("# woo stuff\n", @top_level)], section.comments
- assert_equal '', comment
+ assert_empty comment
end
def test_look_for_directives_in_unhandled
util_parser ""
- @parser.look_for_directives_in @top_level, "# :unhandled: blah\n"
+ comment = RDoc::Comment.new "# :unhandled: blah\n", @top_level
+
+ @parser.look_for_directives_in @top_level, comment
assert_equal 'blah', @top_level.metadata['unhandled']
end
@@ -420,7 +285,7 @@ class C; end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# my attr\n"
+ comment = RDoc::Comment.new "##\n# my attr\n", @top_level
util_parser "attr :foo, :bar"
@@ -432,7 +297,7 @@ class C; end
foo = klass.attributes.first
assert_equal 'foo', foo.name
- assert_equal 'my attr', foo.comment
+ assert_equal 'my attr', foo.comment.text
assert_equal @top_level, foo.file
assert_equal 0, foo.offset
assert_equal 1, foo.line
@@ -443,7 +308,7 @@ class C; end
klass.parent = @top_level
klass.stop_doc
- comment = "##\n# my attr\n"
+ comment = RDoc::Comment.new "##\n# my attr\n", @top_level
util_parser "attr :foo, :bar"
@@ -458,7 +323,7 @@ class C; end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# my attr\n"
+ comment = RDoc::Comment.new "##\n# my attr\n", @top_level
util_parser "attr_accessor :foo, :bar"
@@ -471,7 +336,7 @@ class C; end
foo = klass.attributes.first
assert_equal 'foo', foo.name
assert_equal 'RW', foo.rw
- assert_equal 'my attr', foo.comment
+ assert_equal 'my attr', foo.comment.text
assert_equal @top_level, foo.file
assert_equal 0, foo.offset
assert_equal 1, foo.line
@@ -479,14 +344,14 @@ class C; end
bar = klass.attributes.last
assert_equal 'bar', bar.name
assert_equal 'RW', bar.rw
- assert_equal 'my attr', bar.comment
+ assert_equal 'my attr', bar.comment.text
end
def test_parse_attr_accessor_nodoc
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# my attr\n"
+ comment = RDoc::Comment.new "##\n# my attr\n", @top_level
util_parser "attr_accessor :foo, :bar # :nodoc:"
@@ -502,7 +367,7 @@ class C; end
klass.parent = @top_level
klass.stop_doc
- comment = "##\n# my attr\n"
+ comment = RDoc::Comment.new "##\n# my attr\n", @top_level
util_parser "attr_accessor :foo, :bar"
@@ -517,7 +382,7 @@ class C; end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# my attr\n"
+ comment = RDoc::Comment.new "##\n# my attr\n", @top_level
util_parser "attr_writer :foo, :bar"
@@ -530,20 +395,20 @@ class C; end
foo = klass.attributes.first
assert_equal 'foo', foo.name
assert_equal 'W', foo.rw
- assert_equal "my attr", foo.comment
+ assert_equal "my attr", foo.comment.text
assert_equal @top_level, foo.file
bar = klass.attributes.last
assert_equal 'bar', bar.name
assert_equal 'W', bar.rw
- assert_equal "my attr", bar.comment
+ assert_equal "my attr", bar.comment.text
end
def test_parse_meta_attr
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :attr: \n# my method\n"
+ comment = RDoc::Comment.new "##\n# :attr: \n# my method\n", @top_level
util_parser "add_my_method :foo, :bar"
@@ -555,7 +420,7 @@ class C; end
foo = klass.attributes.first
assert_equal 'foo', foo.name
assert_equal 'RW', foo.rw
- assert_equal "my method", foo.comment
+ assert_equal "my method", foo.comment.text
assert_equal @top_level, foo.file
end
@@ -563,7 +428,8 @@ class C; end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :attr_accessor: \n# my method\n"
+ comment =
+ RDoc::Comment.new "##\n# :attr_accessor: \n# my method\n", @top_level
util_parser "add_my_method :foo, :bar"
@@ -575,7 +441,7 @@ class C; end
foo = klass.attributes.first
assert_equal 'foo', foo.name
assert_equal 'RW', foo.rw
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
end
@@ -583,7 +449,7 @@ class C; end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :attr: foo\n# my method\n"
+ comment = RDoc::Comment.new "##\n# :attr: foo\n# my method\n", @top_level
util_parser "add_my_method :foo, :bar"
@@ -595,7 +461,7 @@ class C; end
foo = klass.attributes.first
assert_equal 'foo', foo.name
assert_equal 'RW', foo.rw
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
end
@@ -603,7 +469,8 @@ class C; end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :attr_reader: \n# my method\n"
+ comment =
+ RDoc::Comment.new "##\n# :attr_reader: \n# my method\n", @top_level
util_parser "add_my_method :foo, :bar"
@@ -614,7 +481,7 @@ class C; end
foo = klass.attributes.first
assert_equal 'foo', foo.name
assert_equal 'R', foo.rw
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
end
@@ -623,7 +490,7 @@ class C; end
klass.parent = @top_level
klass.stop_doc
- comment = "##\n# :attr: \n# my method\n"
+ comment = RDoc::Comment.new "##\n# :attr: \n# my method\n", @top_level
util_parser "add_my_method :foo, :bar"
@@ -638,7 +505,8 @@ class C; end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :attr_writer: \n# my method\n"
+ comment =
+ RDoc::Comment.new "##\n# :attr_writer: \n# my method\n", @top_level
util_parser "add_my_method :foo, :bar"
@@ -649,12 +517,12 @@ class C; end
foo = klass.attributes.first
assert_equal 'foo', foo.name
assert_equal 'W', foo.rw
- assert_equal "my method", foo.comment
+ assert_equal "my method", foo.comment.text
assert_equal @top_level, foo.file
end
def test_parse_class
- comment = "##\n# my class\n"
+ comment = RDoc::Comment.new "##\n# my class\n", @top_level
util_parser "class Foo\nend"
@@ -664,7 +532,7 @@ class C; end
foo = @top_level.classes.first
assert_equal 'Foo', foo.full_name
- assert_equal 'my class', foo.comment
+ assert_equal 'my class', foo.comment.text
assert_equal [@top_level], foo.in_files
assert_equal 0, foo.offset
assert_equal 1, foo.line
@@ -681,7 +549,7 @@ end
tk = @parser.get_tk
- @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
foo = @top_level.classes.first
assert_equal 'Foo', foo.full_name
@@ -712,7 +580,7 @@ end
tk = @parser.get_tk
- @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
foo = @top_level.classes.first
assert_equal 'Foo', foo.full_name
@@ -721,7 +589,7 @@ end
end
def test_parse_class_nodoc
- comment = "##\n# my class\n"
+ comment = RDoc::Comment.new "##\n# my class\n", @top_level
util_parser "class Foo # :nodoc:\nend"
@@ -737,10 +605,23 @@ end
assert_equal 1, foo.line
end
+ def test_parse_class_single_root
+ comment = RDoc::Comment.new "##\n# my class\n", @top_level
+
+ util_parser "class << ::Foo\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = @store.all_modules.first
+ assert_equal 'Foo', foo.full_name
+ end
+
def test_parse_class_stopdoc
@top_level.stop_doc
- comment = "##\n# my class\n"
+ comment = RDoc::Comment.new "##\n# my class\n", @top_level
util_parser "class Foo\nend"
@@ -772,7 +653,7 @@ end
tk = @parser.get_tk
- @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
foo = @top_level.classes.first
assert_equal 'Foo', foo.full_name
@@ -794,7 +675,7 @@ end
tk = @parser.get_tk
- @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_class @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
const_fail_meta = @top_level.classes.first
assert_equal 'ConstFailMeta', const_fail_meta.full_name
@@ -803,21 +684,20 @@ end
end
def test_parse_class_nested_superclass
- util_top_level
foo = @top_level.add_module RDoc::NormalModule, 'Foo'
util_parser "class Bar < Super\nend"
tk = @parser.get_tk
- @parser.parse_class foo, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_class foo, RDoc::Parser::Ruby::NORMAL, tk, @comment
bar = foo.classes.first
assert_equal 'Super', bar.superclass
end
def test_parse_module
- comment = "##\n# my module\n"
+ comment = RDoc::Comment.new "##\n# my module\n", @top_level
util_parser "module Foo\nend"
@@ -827,13 +707,13 @@ end
foo = @top_level.modules.first
assert_equal 'Foo', foo.full_name
- assert_equal 'my module', foo.comment
+ assert_equal 'my module', foo.comment.text
end
def test_parse_module_nodoc
@top_level.stop_doc
- comment = "##\n# my module\n"
+ comment = RDoc::Comment.new "##\n# my module\n", @top_level
util_parser "module Foo # :nodoc:\nend"
@@ -849,7 +729,7 @@ end
def test_parse_module_stopdoc
@top_level.stop_doc
- comment = "##\n# my module\n"
+ comment = RDoc::Comment.new "##\n# my module\n", @top_level
util_parser "module Foo\nend"
@@ -859,7 +739,7 @@ end
foo = @top_level.modules.first
assert_equal 'Foo', foo.full_name
- assert_equal 'my module', foo.comment
+ assert_empty foo.comment
end
def test_parse_class_colon3
@@ -872,9 +752,24 @@ end
util_parser code
- @parser.parse_class @top_level, false, @parser.get_tk, ''
+ @parser.parse_class @top_level, false, @parser.get_tk, @comment
+
+ assert_equal %w[A B], @store.all_classes.map { |c| c.full_name }.sort
+ end
+
+ def test_parse_class_colon3_self_reference
+ code = <<-CODE
+class A::B
+ class ::A
+ end
+end
+ CODE
+
+ util_parser code
+
+ @parser.parse_class @top_level, false, @parser.get_tk, @comment
- assert_equal %w[A B], RDoc::TopLevel.classes.map { |c| c.full_name }
+ assert_equal %w[A A::B], @store.all_classes.map { |c| c.full_name }.sort
end
def test_parse_class_single
@@ -891,23 +786,44 @@ end
util_parser code
- @parser.parse_class @top_level, false, @parser.get_tk, ''
+ @parser.parse_class @top_level, false, @parser.get_tk, @comment
+
+ assert_equal %w[A], @store.all_classes.map { |c| c.full_name }
- assert_equal %w[A], RDoc::TopLevel.classes.map { |c| c.full_name }
- assert_equal %w[A::B A::d], RDoc::TopLevel.modules.map { |c| c.full_name }
+ modules = @store.all_modules.sort_by { |c| c.full_name }
+ assert_equal %w[A::B A::d], modules.map { |c| c.full_name }
- b = RDoc::TopLevel.modules.first
+ b = modules.first
assert_equal 10, b.offset
assert_equal 2, b.line
# make sure method/alias was not added to enclosing class/module
- a = RDoc::TopLevel.all_classes_hash['A']
+ a = @store.classes_hash['A']
assert_empty a.method_list
# make sure non-constant-named module will be removed from documentation
- d = RDoc::TopLevel.all_modules_hash['A::d']
+ d = @store.modules_hash['A::d']
assert d.remove_from_documentation?
+ end
+ def test_parse_class_single_gvar
+ code = <<-CODE
+class << $g
+ def m
+ end
+end
+ CODE
+
+ util_parser code
+
+ @parser.parse_class @top_level, false, @parser.get_tk, ''
+
+ assert_empty @store.all_classes
+ mod = @store.all_modules.first
+
+ refute mod.document_self
+
+ assert_empty mod.method_list
end
# TODO this is really a Context#add_class test
@@ -925,13 +841,16 @@ end
util_parser code
- @parser.parse_module @top_level, false, @parser.get_tk, ''
+ @parser.parse_module @top_level, false, @parser.get_tk, @comment
+
+ assert_equal %w[A],
+ @store.all_modules.map { |c| c.full_name }
+ assert_equal %w[A::B A::C A::Object],
+ @store.all_classes.map { |c| c.full_name }.sort
- assert_equal %w[A], RDoc::TopLevel.modules.map { |c| c.full_name }
- assert_equal %w[A::B A::C A::Object], RDoc::TopLevel.classes.map { |c| c.full_name }.sort
- assert_equal 'Object', RDoc::TopLevel.classes_hash['A::B'].superclass
- assert_equal 'Object', RDoc::TopLevel.classes_hash['A::Object'].superclass
- assert_equal 'A::Object', RDoc::TopLevel.classes_hash['A::C'].superclass.full_name
+ assert_equal 'Object', @store.classes_hash['A::B'].superclass
+ assert_equal 'Object', @store.classes_hash['A::Object'].superclass
+ assert_equal 'A::Object', @store.classes_hash['A::C'].superclass.full_name
end
def test_parse_class_mistaken_for_module
@@ -954,7 +873,7 @@ end
@parser.scan
- assert_equal %w[Foo::Baz], RDoc::TopLevel.modules_hash.keys
+ assert_equal %w[Foo::Baz], @store.modules_hash.keys
assert_empty @top_level.modules
foo = @top_level.classes.first
@@ -968,9 +887,9 @@ end
end
def test_parse_class_definition_encountered_after_class_reference
- # The code below is not strictly legal Ruby (Foo must have been defined
- # before Foo.bar is encountered), but RDoc might encounter Foo.bar before
- # Foo if they live in different files.
+ # The code below is not legal Ruby (Foo must have been defined before
+ # Foo.bar is encountered), but RDoc might encounter Foo.bar before Foo if
+ # they live in different files.
code = <<-EOF
def Foo.bar
@@ -984,9 +903,8 @@ end
@parser.scan
- assert_empty RDoc::TopLevel.modules_hash
- # HACK why does it fail?
- #assert_empty @top_level.modules
+ assert_empty @store.modules_hash
+ assert_empty @store.all_modules
foo = @top_level.classes.first
assert_equal 'Foo', foo.full_name
@@ -997,13 +915,14 @@ end
end
def test_parse_module_relative_to_top_level_namespace
- comment = <<-EOF
+ comment = RDoc::Comment.new <<-EOF, @top_level
#
# Weirdly named module
#
EOF
- code = comment + <<-EOF
+ code = <<-EOF
+#{comment.text}
module ::Foo
class Helper
end
@@ -1015,7 +934,7 @@ EOF
foo = @top_level.modules.first
assert_equal 'Foo', foo.full_name
- assert_equal 'Weirdly named module', foo.comment
+ assert_equal 'Weirdly named module', foo.comment.text
helper = foo.classes.first
assert_equal 'Foo::Helper', helper.full_name
@@ -1025,7 +944,7 @@ EOF
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :attr: foo\n# my attr\n"
+ comment = RDoc::Comment.new "##\n# :attr: foo\n# my attr\n", @top_level
util_parser "\n"
@@ -1036,7 +955,7 @@ EOF
foo = klass.attributes.first
assert_equal 'foo', foo.name
assert_equal 'RW', foo.rw
- assert_equal 'my attr', foo.comment
+ assert_equal 'my attr', foo.comment.text
assert_equal @top_level, foo.file
assert_equal 0, foo.offset
assert_equal 1, foo.line
@@ -1058,7 +977,7 @@ EOF
klass.parent = @top_level
klass.stop_doc
- comment = "##\n# :attr: foo\n# my attr\n"
+ comment = RDoc::Comment.new "##\n# :attr: foo\n# my attr\n", @top_level
util_parser "\n"
@@ -1073,7 +992,7 @@ EOF
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :method: foo\n# my method\n"
+ comment = RDoc::Comment.new "##\n# :method: foo\n# my method\n", @top_level
util_parser "\n"
@@ -1083,7 +1002,7 @@ EOF
foo = klass.method_list.first
assert_equal 'foo', foo.name
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
assert_equal 0, foo.offset
assert_equal 1, foo.line
@@ -1106,9 +1025,10 @@ EOF
assert_equal klass.current_section, foo.section
stream = [
- tk(:COMMENT, 1, 1, nil, "# File #{@top_level.absolute_name}, line 1"),
+ tk(:COMMENT, 0, 1, 1, nil,
+ "# File #{@top_level.absolute_name}, line 1"),
RDoc::Parser::Ruby::NEWLINE_TOKEN,
- tk(:SPACE, 1, 1, nil, ''),
+ tk(:SPACE, 0, 1, 1, nil, ''),
]
assert_equal stream, foo.token_stream
@@ -1119,7 +1039,7 @@ EOF
klass.parent = @top_level
klass.stop_doc
- comment = "##\n# :method: foo\n# my method\n"
+ comment = RDoc::Comment.new "##\n# :method: foo\n# my method\n", @top_level
util_parser "\n"
@@ -1131,15 +1051,13 @@ EOF
end
def test_parse_constant
- util_top_level
-
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
util_parser "A = v"
tk = @parser.get_tk
- @parser.parse_constant klass, tk, ''
+ @parser.parse_constant klass, tk, @comment
foo = klass.constants.first
@@ -1150,52 +1068,47 @@ EOF
end
def test_parse_constant_attrasgn
- util_top_level
-
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
util_parser "A[k] = v"
tk = @parser.get_tk
- @parser.parse_constant klass, tk, ''
+ @parser.parse_constant klass, tk, @comment
assert klass.constants.empty?
end
def test_parse_constant_alias
- util_top_level
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
- cB = klass.add_class RDoc::NormalClass, 'B'
+ klass.add_class RDoc::NormalClass, 'B'
util_parser "A = B"
tk = @parser.get_tk
- @parser.parse_constant klass, tk, ''
+ @parser.parse_constant klass, tk, @comment
- assert_equal cB, klass.find_module_named('A')
+ assert_equal 'Foo::A', klass.find_module_named('A').full_name
end
def test_parse_constant_alias_same_name
foo = @top_level.add_class RDoc::NormalClass, 'Foo'
- top_bar = @top_level.add_class RDoc::NormalClass, 'Bar'
+ @top_level.add_class RDoc::NormalClass, 'Bar'
bar = foo.add_class RDoc::NormalClass, 'Bar'
- assert RDoc::TopLevel.find_class_or_module('::Bar')
+ assert @store.find_class_or_module('::Bar')
util_parser "A = ::Bar"
tk = @parser.get_tk
- @parser.parse_constant foo, tk, ''
+ @parser.parse_constant foo, tk, @comment
- assert_equal top_bar, bar.find_module_named('A')
+ assert_equal 'A', bar.find_module_named('A').full_name
end
def test_parse_constant_stopdoc
- util_top_level
-
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
klass.stop_doc
@@ -1203,7 +1116,7 @@ EOF
tk = @parser.get_tk
- @parser.parse_constant klass, tk, ''
+ @parser.parse_constant klass, tk, @comment
assert_empty klass.constants
end
@@ -1212,7 +1125,7 @@ EOF
klass = RDoc::NormalClass.new 'C'
klass.parent = @top_level
- comment = "# my include\n"
+ comment = RDoc::Comment.new "# my include\n", @top_level
util_parser "include I"
@@ -1224,15 +1137,35 @@ EOF
incl = klass.includes.first
assert_equal 'I', incl.name
- assert_equal 'my include', incl.comment
+ assert_equal 'my include', incl.comment.text
assert_equal @top_level, incl.file
end
+ def test_parse_extend
+ klass = RDoc::NormalClass.new 'C'
+ klass.parent = @top_level
+
+ comment = RDoc::Comment.new "# my extend\n", @top_level
+
+ util_parser "extend I"
+
+ @parser.get_tk # extend
+
+ @parser.parse_extend klass, comment
+
+ assert_equal 1, klass.extends.length
+
+ ext = klass.extends.first
+ assert_equal 'I', ext.name
+ assert_equal 'my extend', ext.comment.text
+ assert_equal @top_level, ext.file
+ end
+
def test_parse_meta_method
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# my method\n"
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
@@ -1242,7 +1175,7 @@ EOF
foo = klass.method_list.first
assert_equal 'foo', foo.name
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
assert_equal 0, foo.offset
assert_equal 1, foo.line
@@ -1265,16 +1198,17 @@ EOF
assert_equal klass.current_section, foo.section
stream = [
- tk(:COMMENT, 1, 1, nil, "# File #{@top_level.absolute_name}, line 1"),
+ tk(:COMMENT, 0, 1, 1, nil,
+ "# File #{@top_level.absolute_name}, line 1"),
RDoc::Parser::Ruby::NEWLINE_TOKEN,
- tk(:SPACE, 1, 1, nil, ''),
- tk(:IDENTIFIER, 1, 0, 'add_my_method', 'add_my_method'),
- tk(:SPACE, 1, 13, nil, ' '),
- tk(:SYMBOL, 1, 14, nil, ':foo'),
- tk(:COMMA, 1, 18, nil, ','),
- tk(:SPACE, 1, 19, nil, ' '),
- tk(:SYMBOL, 1, 20, nil, ':bar'),
- tk(:NL, 1, 24, nil, "\n"),
+ tk(:SPACE, 0, 1, 1, nil, ''),
+ tk(:IDENTIFIER, 0, 1, 0, 'add_my_method', 'add_my_method'),
+ tk(:SPACE, 0, 1, 13, nil, ' '),
+ tk(:SYMBOL, 0, 1, 14, nil, ':foo'),
+ tk(:COMMA, 0, 1, 18, nil, ','),
+ tk(:SPACE, 0, 1, 19, nil, ' '),
+ tk(:SYMBOL, 0, 1, 20, nil, ':bar'),
+ tk(:NL, 0, 1, 24, nil, "\n"),
]
assert_equal stream, foo.token_stream
@@ -1284,7 +1218,7 @@ EOF
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# my method\n"
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
content = <<-CONTENT
inline(:my_method) do |*args|
@@ -1298,14 +1232,31 @@ end
@parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
- assert_nil @parser.get_tk
+ assert_equal tk(:NL, 0, 3, 3, 3, "\n"), @parser.get_tk
+ end
+
+ def test_parse_meta_method_define_method
+ klass = RDoc::NormalClass.new 'Foo'
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
+
+ util_parser "define_method :foo do end"
+
+ tk = @parser.get_tk
+
+ @parser.parse_meta_method klass, RDoc::Parser::Ruby::NORMAL, tk, comment
+
+ foo = klass.method_list.first
+ assert_equal 'foo', foo.name
+ assert_equal 'my method', foo.comment.text
+ assert_equal @top_level, foo.file
end
def test_parse_meta_method_name
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :method: woo_hoo!\n# my method\n"
+ comment =
+ RDoc::Comment.new "##\n# :method: woo_hoo!\n# my method\n", @top_level
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
@@ -1315,7 +1266,7 @@ end
foo = klass.method_list.first
assert_equal 'woo_hoo!', foo.name
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
end
@@ -1323,7 +1274,8 @@ end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :singleton-method:\n# my method\n"
+ comment =
+ RDoc::Comment.new "##\n# :singleton-method:\n# my method\n", @top_level
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
@@ -1334,7 +1286,7 @@ end
foo = klass.method_list.first
assert_equal 'foo', foo.name
assert_equal true, foo.singleton, 'singleton method'
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
end
@@ -1342,7 +1294,9 @@ end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# :singleton-method: woo_hoo!\n# my method\n"
+ comment =
+ RDoc::Comment.new "##\n# :singleton-method: woo_hoo!\n# my method\n",
+ @top_level
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
@@ -1353,13 +1307,13 @@ end
foo = klass.method_list.first
assert_equal 'woo_hoo!', foo.name
assert_equal true, foo.singleton, 'singleton method'
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
end
def test_parse_meta_method_string_name
klass = RDoc::NormalClass.new 'Foo'
- comment = "##\n# my method\n"
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
util_parser "add_my_method 'foo'"
@@ -1369,7 +1323,7 @@ end
foo = klass.method_list.first
assert_equal 'foo', foo.name
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
end
@@ -1378,7 +1332,7 @@ end
klass.parent = @top_level
klass.stop_doc
- comment = "##\n# my method\n"
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
util_parser "add_my_method :foo, :bar\nadd_my_method :baz"
@@ -1391,7 +1345,7 @@ end
def test_parse_meta_method_unknown
klass = RDoc::NormalClass.new 'Foo'
- comment = "##\n# my method\n"
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
util_parser "add_my_method ('foo')"
@@ -1401,7 +1355,7 @@ end
foo = klass.method_list.first
assert_equal 'unknown', foo.name
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
end
@@ -1409,7 +1363,7 @@ end
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
- comment = "##\n# my method\n"
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
util_parser "def foo() :bar end"
@@ -1419,7 +1373,7 @@ end
foo = klass.method_list.first
assert_equal 'foo', foo.name
- assert_equal 'my method', foo.comment
+ assert_equal 'my method', foo.comment.text
assert_equal @top_level, foo.file
assert_equal 0, foo.offset
assert_equal 1, foo.line
@@ -1442,19 +1396,20 @@ end
assert_equal klass.current_section, foo.section
stream = [
- tk(:COMMENT, 1, 1, nil, "# File #{@top_level.absolute_name}, line 1"),
+ tk(:COMMENT, 0, 1, 1, nil,
+ "# File #{@top_level.absolute_name}, line 1"),
RDoc::Parser::Ruby::NEWLINE_TOKEN,
- tk(:SPACE, 1, 1, nil, ''),
- tk(:DEF, 1, 0, 'def', 'def'),
- tk(:SPACE, 1, 3, nil, ' '),
- tk(:IDENTIFIER, 1, 4, 'foo', 'foo'),
- tk(:LPAREN, 1, 7, nil, '('),
- tk(:RPAREN, 1, 8, nil, ')'),
- tk(:SPACE, 1, 9, nil, ' '),
- tk(:COLON, 1, 10, nil, ':'),
- tk(:IDENTIFIER, 1, 11, 'bar', 'bar'),
- tk(:SPACE, 1, 14, nil, ' '),
- tk(:END, 1, 15, 'end', 'end'),
+ tk(:SPACE, 0, 1, 1, nil, ''),
+ tk(:DEF, 0, 1, 0, 'def', 'def'),
+ tk(:SPACE, 3, 1, 3, nil, ' '),
+ tk(:IDENTIFIER, 4, 1, 4, 'foo', 'foo'),
+ tk(:LPAREN, 7, 1, 7, nil, '('),
+ tk(:RPAREN, 8, 1, 8, nil, ')'),
+ tk(:SPACE, 9, 1, 9, nil, ' '),
+ tk(:COLON, 10, 1, 10, nil, ':'),
+ tk(:IDENTIFIER, 11, 1, 11, 'bar', 'bar'),
+ tk(:SPACE, 14, 1, 14, nil, ' '),
+ tk(:END, 15, 1, 15, 'end', 'end'),
]
assert_equal stream, foo.token_stream
@@ -1468,19 +1423,34 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
assert klass.aliases.empty?
end
+ def test_parse_method_ampersand
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ util_parser "def self.&\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
+
+ ampersand = klass.method_list.first
+ assert_equal '&', ampersand.name
+ assert ampersand.singleton
+ end
+
def test_parse_method_false
util_parser "def false.foo() :bar end"
tk = @parser.get_tk
- @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
- klass = RDoc::TopLevel.find_class_named 'FalseClass'
+ klass = @store.find_class_named 'FalseClass'
foo = klass.method_list.first
assert_equal 'foo', foo.name
@@ -1494,9 +1464,9 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
- assert klass.method_list.empty?
+ assert_empty klass.method_list
end
def test_parse_method_gvar
@@ -1504,11 +1474,27 @@ end
tk = @parser.get_tk
- @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
assert @top_level.method_list.empty?
end
+ def test_parse_method_gvar_insane
+ util_parser "def $stdout.foo() class << $other; end; end"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
+
+ assert @top_level.method_list.empty?
+
+ assert_empty @store.all_classes
+
+ assert_equal 1, @store.all_modules.length
+
+ refute @store.all_modules.first.document_self
+ end
+
def test_parse_method_internal_gvar
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
@@ -1517,7 +1503,7 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
assert_equal 1, klass.method_list.length
end
@@ -1530,7 +1516,7 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
assert_equal 1, klass.method_list.length
end
@@ -1543,7 +1529,7 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
assert_equal 1, klass.method_list.length
end
@@ -1553,9 +1539,9 @@ end
tk = @parser.get_tk
- @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
- klass = RDoc::TopLevel.find_class_named 'NilClass'
+ klass = @store.find_class_named 'NilClass'
foo = klass.method_list.first
assert_equal 'foo', foo.name
@@ -1569,7 +1555,7 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
foo = klass.method_list.first
assert_equal '(arg1, arg2 = {})', foo.params
@@ -1584,7 +1570,7 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
foo = klass.method_list.first
assert_equal '(arg1, arg2)', foo.params
@@ -1598,18 +1584,33 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
foo = klass.method_list.first
assert_equal '(arg1, arg2, arg3)', foo.params
end
+ def test_parse_method_star
+ klass = RDoc::NormalClass.new 'Foo'
+ klass.parent = @top_level
+
+ util_parser "def self.*\nend"
+
+ tk = @parser.get_tk
+
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
+
+ ampersand = klass.method_list.first
+ assert_equal '*', ampersand.name
+ assert ampersand.singleton
+ end
+
def test_parse_method_stopdoc
klass = RDoc::NormalClass.new 'Foo'
klass.parent = @top_level
klass.stop_doc
- comment = "##\n# my method\n"
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
util_parser "def foo() :bar end"
@@ -1627,9 +1628,9 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
- object = RDoc::TopLevel.find_class_named 'Object'
+ object = @store.find_class_named 'Object'
foo = object.method_list.first
assert_equal 'Object#foo', foo.full_name
@@ -1643,9 +1644,9 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
- object = RDoc::TopLevel.find_class_named 'Object'
+ object = @store.find_class_named 'Object'
foo = object.method_list.first
assert_equal 'Object::foo', foo.full_name
@@ -1656,9 +1657,9 @@ end
tk = @parser.get_tk
- @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method @top_level, RDoc::Parser::Ruby::NORMAL, tk, @comment
- klass = RDoc::TopLevel.find_class_named 'TrueClass'
+ klass = @store.find_class_named 'TrueClass'
foo = klass.method_list.first
assert_equal 'foo', foo.name
@@ -1677,7 +1678,7 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
omega = klass.method_list.first
assert_equal "def \317\211", omega.text
@@ -1695,7 +1696,7 @@ module Foo
end
CODE
- @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil
foo = @top_level.modules.first
assert_equal 'Foo', foo.full_name, 'module Foo'
@@ -1706,18 +1707,44 @@ end
end
def test_parse_statements_class_nested
- comment = "##\n# my method\n"
+ comment = RDoc::Comment.new "##\n# my method\n", @top_level
- util_parser "module Foo\n#{comment}class Bar\nend\nend"
+ util_parser "module Foo\n#{comment.text}class Bar\nend\nend"
- @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, nil, ''
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL
foo = @top_level.modules.first
assert_equal 'Foo', foo.full_name, 'module Foo'
bar = foo.classes.first
assert_equal 'Foo::Bar', bar.full_name, 'class Foo::Bar'
- assert_equal 'my method', bar.comment
+ assert_equal 'my method', bar.comment.text
+ end
+
+ def test_parse_statements_def_percent_string_pound
+ util_parser "class C\ndef a\n%r{#}\nend\ndef b() end\nend"
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL
+
+ x = @top_level.classes.first
+
+ assert_equal 2, x.method_list.length
+ a = x.method_list.first
+
+ expected = [
+ tk(:COMMENT, 0, 2, 1, nil, "# File #{@filename}, line 2"),
+ tk(:NL, 0, 0, 0, nil, "\n"),
+ tk(:SPACE, 0, 1, 1, nil, ''),
+ tk(:DEF, 8, 2, 0, 'def', 'def'),
+ tk(:SPACE, 11, 2, 3, nil, ' '),
+ tk(:IDENTIFIER, 12, 2, 4, 'a', 'a'),
+ tk(:NL, 13, 2, 5, nil, "\n"),
+ tk(:DREGEXP, 14, 3, 0, nil, '%r{#}'),
+ tk(:NL, 19, 3, 5, nil, "\n"),
+ tk(:END, 20, 4, 0, 'end', 'end'),
+ ]
+
+ assert_equal expected, a.token_stream
end
def test_parse_statements_encoding
@@ -1738,8 +1765,8 @@ end
foo = @top_level.classes.first.method_list.first
assert_equal 'foo', foo.name
- assert_equal 'this is my method', foo.comment
- assert_equal Encoding::CP852, foo.comment.encoding
+ assert_equal 'this is my method', foo.comment.text
+ assert_equal Encoding::CP852, foo.comment.text.encoding
end
def test_parse_statements_identifier_meta_method
@@ -1822,8 +1849,25 @@ EOF
assert_equal 'unknown', @top_level.classes.first.external_aliases[0].old_name
end
- def test_parse_statements_identifier_constant
+ def test_parse_statements_identifier_args
+ comment = "##\n# :args: x\n# :method: b\n# my method\n"
+
+ util_parser "module M\n#{comment}def_delegator :a, :b, :b\nend"
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL
+
+ m = @top_level.modules.first
+ assert_equal 'M', m.full_name
+
+ b = m.method_list.first
+ assert_equal 'M#b', b.full_name
+ assert_equal 'x', b.params
+ assert_equal 'my method', b.comment.text
+
+ assert_nil m.params, 'Module parameter not removed'
+ end
+
+ def test_parse_statements_identifier_constant
sixth_constant = <<-EOF
Class.new do
rule :file do
@@ -1934,6 +1978,24 @@ EOF
assert_equal 'RW', foo.rw
end
+ def test_parse_statements_identifier_define_method
+ util_parser <<-RUBY
+class C
+ ##
+ # :method: a
+ define_method :a do end
+ ##
+ # :method: b
+ define_method :b do end
+end
+ RUBY
+
+ @parser.parse_statements @top_level
+ c = @top_level.classes.first
+
+ assert_equal %w[a b], c.method_list.map { |m| m.name }
+ end
+
def test_parse_statements_identifier_include
content = "class Foo\ninclude Bar\nend"
@@ -1991,10 +2053,10 @@ end
@parser.parse_statements @top_level
- date, date_time = @top_level.classes
+ date, date_time = @top_level.classes.sort_by { |c| c.full_name }
date_now = date.method_list.first
- date_time_now = date_time.method_list.first
+ date_time_now = date_time.method_list.sort_by { |m| m.full_name }.first
assert_equal :private, date_now.visibility
assert_equal :public, date_time_now.visibility
@@ -2016,10 +2078,11 @@ end
@parser.parse_statements @top_level
- date, date_time = @top_level.classes
+ # TODO sort classes by default
+ date, date_time = @top_level.classes.sort_by { |c| c.full_name }
date_now = date.method_list.first
- date_time_now = date_time.method_list.first
+ date_time_now = date_time.method_list.sort_by { |m| m.full_name }.first
assert_equal :public, date_now.visibility, date_now.full_name
assert_equal :private, date_time_now.visibility, date_time_now.full_name
@@ -2035,9 +2098,25 @@ end
assert_equal 1, @top_level.requires.length
end
- def test_parse_statements_stopdoc_TkALIAS
- util_top_level
+ def test_parse_statements_identifier_yields
+ comment = "##\n# :yields: x\n# :method: b\n# my method\n"
+
+ util_parser "module M\n#{comment}def_delegator :a, :b, :b\nend"
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL
+
+ m = @top_level.modules.first
+ assert_equal 'M', m.full_name
+
+ b = m.method_list.first
+ assert_equal 'M#b', b.full_name
+ assert_equal 'x', b.block_params
+ assert_equal 'my method', b.comment.text
+
+ assert_nil m.params, 'Module parameter not removed'
+ end
+ def test_parse_statements_stopdoc_TkALIAS
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
util_parser "\n# :stopdoc:\nalias old new"
@@ -2049,8 +2128,6 @@ end
end
def test_parse_statements_stopdoc_TkIDENTIFIER_alias_method
- util_top_level
-
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
util_parser "\n# :stopdoc:\nalias_method :old :new"
@@ -2062,8 +2139,6 @@ end
end
def test_parse_statements_stopdoc_TkIDENTIFIER_metaprogrammed
- util_top_level
-
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
util_parser "\n# :stopdoc:\n# attr :meta"
@@ -2075,8 +2150,6 @@ end
end
def test_parse_statements_stopdoc_TkCONSTANT
- util_top_level
-
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
util_parser "\n# :stopdoc:\nA = v"
@@ -2087,8 +2160,6 @@ end
end
def test_parse_statements_stopdoc_TkDEF
- util_top_level
-
klass = @top_level.add_class RDoc::NormalClass, 'Foo'
util_parser "\n# :stopdoc:\ndef m\n end"
@@ -2098,6 +2169,25 @@ end
assert_empty klass.method_list
end
+ def test_parse_statements_super
+ m = RDoc::AnyMethod.new '', 'm'
+ util_parser 'super'
+
+ @parser.parse_statements @top_level, RDoc::Parser::Ruby::NORMAL, m
+
+ assert m.calls_super
+ end
+
+ def test_parse_statements_super_no_method
+ content = "super"
+
+ util_parser content
+
+ @parser.parse_statements @top_level
+
+ assert_nil @parser.get_tk
+ end
+
def test_parse_statements_while_begin
util_parser <<-RUBY
class A
@@ -2220,12 +2310,104 @@ end
tk = @parser.get_tk
- @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, ''
+ @parser.parse_method klass, RDoc::Parser::Ruby::NORMAL, tk, @comment
foo = klass.method_list.first
assert_equal 'nth(i)', foo.block_params
end
+ def test_read_directive
+ parser = util_parser '# :category: test'
+
+ directive, value = parser.read_directive %w[category]
+
+ assert_equal 'category', directive
+ assert_equal 'test', value
+
+ assert_kind_of RDoc::RubyToken::TkNL, parser.get_tk
+ end
+
+ def test_read_directive_allow
+ parser = util_parser '# :category: test'
+
+ directive = parser.read_directive []
+
+ assert_nil directive
+
+ assert_kind_of RDoc::RubyToken::TkNL, parser.get_tk
+ end
+
+ def test_read_directive_empty
+ parser = util_parser '# test'
+
+ directive = parser.read_directive %w[category]
+
+ assert_nil directive
+
+ assert_kind_of RDoc::RubyToken::TkNL, parser.get_tk
+ end
+
+ def test_read_directive_no_comment
+ parser = util_parser ''
+
+ directive = parser.read_directive %w[category]
+
+ assert_nil directive
+
+ assert_kind_of RDoc::RubyToken::TkNL, parser.get_tk
+ end
+
+ def test_read_directive_one_liner
+ parser = util_parser '; end # :category: test'
+
+ directive, value = parser.read_directive %w[category]
+
+ assert_equal 'category', directive
+ assert_equal 'test', value
+
+ assert_kind_of RDoc::RubyToken::TkSEMICOLON, parser.get_tk
+ end
+
+ def test_read_documentation_modifiers
+ c = RDoc::Context.new
+
+ parser = util_parser '# :category: test'
+
+ parser.read_documentation_modifiers c, %w[category]
+
+ assert_equal 'test', c.current_section.title
+ end
+
+ def test_read_documentation_modifiers_notnew
+ m = RDoc::AnyMethod.new nil, 'initialize'
+
+ parser = util_parser '# :notnew: test'
+
+ parser.read_documentation_modifiers m, %w[notnew]
+
+ assert m.dont_rename_initialize
+ end
+
+ def test_read_documentation_modifiers_not_dash_new
+ m = RDoc::AnyMethod.new nil, 'initialize'
+
+ parser = util_parser '# :not-new: test'
+
+ parser.read_documentation_modifiers m, %w[not-new]
+
+ assert m.dont_rename_initialize
+ end
+
+ def test_read_documentation_modifiers_not_new
+ m = RDoc::AnyMethod.new nil, 'initialize'
+
+ parser = util_parser '# :not_new: test'
+
+ parser.read_documentation_modifiers m, %w[not_new]
+
+ assert m.dont_rename_initialize
+ end
+
def test_sanity_integer
util_parser '1'
assert_equal '1', @parser.get_tk.text
@@ -2255,7 +2437,7 @@ end
def test_sanity_interpolation_curly
util_parser '%{ #{} }'
- assert_equal '%{ #{} }', @parser.get_tk.text
+ assert_equal '%Q{ #{} }', @parser.get_tk.text
assert_equal RDoc::RubyToken::TkNL, @parser.get_tk.class
end
@@ -2312,11 +2494,11 @@ end
foo = @top_level.classes.first
- assert_equal 'Foo comment', foo.comment
+ assert_equal 'Foo comment', foo.comment.text
m = foo.method_list.first
- assert_equal 'm comment', m.comment
+ assert_equal 'm comment', m.comment.text
end
def test_scan_block_comment_nested # Issue #41
@@ -2338,12 +2520,12 @@ end
foo = @top_level.modules.first
assert_equal 'Foo', foo.full_name
- assert_equal 'findmeindoc', foo.comment
+ assert_equal 'findmeindoc', foo.comment.text
bar = foo.classes.first
assert_equal 'Foo::Bar', bar.full_name
- assert_equal '', bar.comment
+ assert_equal '', bar.comment.text
end
def test_scan_block_comment_notflush
@@ -2386,11 +2568,46 @@ end
foo = @top_level.classes.first
assert_equal "= DESCRIPTION\n\nThis is a simple test class\n\n= RUMPUS\n\nIs a silly word",
- foo.comment
+ foo.comment.text
m = foo.method_list.first
- assert_equal 'A nice girl', m.comment
+ assert_equal 'A nice girl', m.comment.text
+ end
+
+ def test_scan_constant_nodoc
+ content = <<-CONTENT # newline is after M is important
+module M
+
+ C = v # :nodoc:
+end
+ CONTENT
+
+ util_parser content
+
+ @parser.scan
+
+ c = @top_level.modules.first.constants.first
+
+ assert c.documented?
+ end
+
+ def test_scan_constant_nodoc_block
+ content = <<-CONTENT # newline is after M is important
+module M
+
+ C = v do # :nodoc:
+ end
+end
+ CONTENT
+
+ util_parser content
+
+ @parser.scan
+
+ c = @top_level.modules.first.constants.first
+
+ assert c.documented?
end
def test_scan_meta_method_block
@@ -2415,6 +2632,157 @@ class C
assert_equal 2, @top_level.classes.first.method_list.length
end
+ def test_scan_markup_override
+ content = <<-CONTENT
+# *awesome*
+class C
+ # :markup: rd
+ # ((*radical*))
+ def m
+ end
+end
+ CONTENT
+
+ util_parser content
+
+ @parser.scan
+
+ c = @top_level.classes.first
+
+ assert_equal 'rdoc', c.comment.format
+
+ assert_equal 'rd', c.method_list.first.comment.format
+ end
+
+ def test_scan_markup_first_comment
+ content = <<-CONTENT
+# :markup: rd
+
+# ((*awesome*))
+class C
+ # ((*radical*))
+ def m
+ end
+end
+ CONTENT
+
+ util_parser content
+
+ @parser.scan
+
+ c = @top_level.classes.first
+
+ assert_equal 'rd', c.comment.format
+
+ assert_equal 'rd', c.method_list.first.comment.format
+ end
+
+ def test_scan_tomdoc_meta
+ util_parser <<-RUBY
+# :markup: tomdoc
+
+class C
+
+ # Signature
+ #
+ # find_by_<field>[_and_<field>...](args)
+ #
+ # field - A field name.
+
+end
+
+ RUBY
+
+ @parser.scan
+
+ c = @top_level.classes.first
+
+ m = c.method_list.first
+
+ assert_equal "find_by_<field>[_and_<field>...]", m.name
+ assert_equal "find_by_<field>[_and_<field>...](args)\n", m.call_seq
+
+ expected =
+ doc(
+ head(3, 'Signature'),
+ list(:NOTE,
+ item(%w[field],
+ para('A field name.'))))
+ expected.file = @top_level
+
+ assert_equal expected, m.comment.parse
+ end
+
+ def test_scan_stopdoc
+ util_parser <<-RUBY
+class C
+ # :stopdoc:
+ class Hidden
+ end
+end
+ RUBY
+
+ @parser.scan
+
+ c = @top_level.classes.first
+
+ hidden = c.classes.first
+
+ refute hidden.document_self
+ assert hidden.ignored?
+ end
+
+ def test_scan_stopdoc_class_alias
+ util_parser <<-RUBY
+# :stopdoc:
+module A
+ B = C
+end
+ RUBY
+
+ @parser.scan
+
+ assert_empty @store.all_classes
+
+ assert_equal 1, @store.all_modules.length
+ m = @store.all_modules.first
+
+ assert m.ignored?
+ end
+
+ def test_scan_stopdoc_nested
+ util_parser <<-RUBY
+# :stopdoc:
+class A::B
+end
+ RUBY
+
+ @parser.scan
+
+ a = @store.modules_hash['A']
+ a_b = @store.classes_hash['A::B']
+
+ refute a.document_self, 'A is inside stopdoc'
+ assert a.ignored?, 'A is inside stopdoc'
+
+ refute a_b.document_self, 'A::B is inside stopdoc'
+ assert a_b.ignored?, 'A::B is inside stopdoc'
+ end
+
+ def test_scan_struct_self_brackets
+ util_parser <<-RUBY
+class C < M.m
+ def self.[]
+ end
+end
+ RUBY
+
+ @parser.scan
+
+ c = @store.find_class_named 'C'
+ assert_equal %w[C::[]], c.method_list.map { |m| m.full_name }
+ end
+
def test_stopdoc_after_comment
util_parser <<-EOS
module Bar
@@ -2433,21 +2801,21 @@ class C
foo = @top_level.modules.first.modules.first
assert_equal 'Foo', foo.name
- assert_equal 'hello', foo.comment
+ assert_equal 'hello', foo.comment.text
baz = @top_level.modules.first.classes.first
assert_equal 'Baz', baz.name
- assert_equal 'there', baz.comment
+ assert_equal 'there', baz.comment.text
end
- def tk(klass, line, char, name, text)
+ def tk klass, scan, line, char, name, text
klass = RDoc::RubyToken.const_get "Tk#{klass.to_s.upcase}"
token = if klass.instance_method(:initialize).arity == 3 then
- raise ArgumentError, "name not used for #{klass}" unless name.nil?
- klass.new nil, line, char
+ raise ArgumentError, "name not used for #{klass}" if name
+ klass.new scan, line, char
else
- klass.new nil, line, char, name
+ klass.new scan, line, char, name
end
token.set_text text
@@ -2467,11 +2835,5 @@ class C
second_file_content, @options, @stats
end
- def util_top_level
- RDoc::TopLevel.reset
- @top_level = RDoc::TopLevel.new @filename
- @top_level2 = RDoc::TopLevel.new @filename2
- end
-
end
diff --git a/test/rdoc/test_rdoc_parser_simple.rb b/test/rdoc/test_rdoc_parser_simple.rb
index 8cedfaa2fc..356ea07504 100644
--- a/test/rdoc/test_rdoc_parser_simple.rb
+++ b/test/rdoc/test_rdoc_parser_simple.rb
@@ -1,24 +1,22 @@
-require 'tempfile'
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/options'
-require 'rdoc/parser'
+require 'rdoc/test_case'
-class TestRDocParserSimple < MiniTest::Unit::TestCase
+class TestRDocParserSimple < RDoc::TestCase
def setup
+ super
+
@tempfile = Tempfile.new self.class.name
filename = @tempfile.path
- @top_level = RDoc::TopLevel.new filename
+ @top_level = @store.add_file filename
@fn = filename
@options = RDoc::Options.new
- @stats = RDoc::Stats.new 0
-
- RDoc::TopLevel.reset
+ @stats = RDoc::Stats.new @store, 0
end
def teardown
+ super
+
@tempfile.close
end
@@ -45,7 +43,7 @@ Regular expressions (<i>regexp</i>s) are patterns which describe the
contents of a string.
TEXT
- assert_equal expected, @top_level.comment
+ assert_equal expected, @top_level.comment.text
end
# RDoc stops processing comments if it finds a comment line CONTAINING
@@ -74,21 +72,39 @@ contents of a string.
# # ---
def test_remove_private_comments
- parser = util_parser ''
- text = "foo\n\n--\nbar\n++\n\nbaz\n"
+ parser = util_parser "foo\n\n--\nbar\n++\n\nbaz\n"
+
+ parser.scan
- expected = "foo\n\n\n\nbaz\n"
+ expected = "foo\n\n\nbaz"
- assert_equal expected, parser.remove_private_comments(text)
+ assert_equal expected, @top_level.comment.text
+ end
+
+ def test_remove_private_comments_rule
+ parser = util_parser "foo\n---\nbar"
+
+ parser.scan
+
+ expected = "foo\n---\nbar"
+
+ assert_equal expected, @top_level.comment.text
end
def test_remove_private_comments_star
- parser = util_parser ''
+ parser = util_parser "* foo\n* bar\n"
+
+ parser.scan
- text = "* foo\n* bar\n"
- expected = text.dup
+ assert_equal "* foo\n* bar", @top_level.comment.text
+ end
+
+ def test_scan
+ parser = util_parser 'it *really* works'
+
+ parser.scan
- assert_equal expected, parser.remove_private_comments(text)
+ assert_equal 'it *really* works', @top_level.comment.text
end
def util_parser(content)
diff --git a/test/rdoc/test_rdoc_rd.rb b/test/rdoc/test_rdoc_rd.rb
new file mode 100644
index 0000000000..d917a63661
--- /dev/null
+++ b/test/rdoc/test_rdoc_rd.rb
@@ -0,0 +1,30 @@
+require 'rdoc/test_case'
+
+class TestRDocRd < RDoc::TestCase
+
+ def test_class_parse
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('hello'))
+
+ assert_equal expected, RDoc::RD.parse("hello")
+ end
+
+ def test_class_parse_begin_end
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('hello'))
+
+ assert_equal expected, RDoc::RD.parse("=begin\nhello\n=end\n")
+ end
+
+ def test_class_parse_newline
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('hello'))
+
+ assert_equal expected, RDoc::RD.parse("hello\n")
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_rd_block_parser.rb b/test/rdoc/test_rdoc_rd_block_parser.rb
new file mode 100644
index 0000000000..541c26fd89
--- /dev/null
+++ b/test/rdoc/test_rdoc_rd_block_parser.rb
@@ -0,0 +1,523 @@
+require 'rdoc/test_case'
+
+class TestRDocRdBlockParser < RDoc::TestCase
+
+ def setup
+ super
+
+ @block_parser = RDoc::RD::BlockParser.new
+ end
+
+ def mu_pp(obj)
+ s = ""
+ s = PP.pp obj, s
+ s = s.force_encoding(Encoding.default_external) if defined? Encoding
+ s.chomp
+ end
+
+ def test_parse_desclist
+ list = <<-LIST
+:one
+ desc one
+:two
+ desc two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NOTE,
+ @RM::ListItem.new("one", @RM::Paragraph.new("desc one")),
+ @RM::ListItem.new("two", @RM::Paragraph.new("desc two"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_enumlist
+ list = <<-LIST
+(1) one
+(1) two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("one")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("two"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_enumlist_paragraphs
+ list = <<-LIST
+(1) one
+
+ two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("one"),
+ @RM::Paragraph.new("two"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_enumlist_multiline
+ list = <<-LIST
+(1) one
+ two
+ LIST
+
+ contents = "one\n two" # 1.8 vs 1.9
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil, @RM::Paragraph.new(*contents))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_enumlist_verbatim
+ list = <<-LIST
+(1) item
+ verbatim
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("item"),
+ @RM::Verbatim.new("verbatim\n"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_enumlist_verbatim_continue
+ list = <<-LIST
+(1) one
+ verbatim
+ two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("one"),
+ @RM::Verbatim.new("verbatim\n"),
+ @RM::Paragraph.new("two"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_footnote
+ expected =
+ doc(
+ @RM::Paragraph.new("{*1}[rdoc-label:foottext-1:footmark-1]"),
+ @RM::Rule.new(1),
+ @RM::Paragraph.new("{^1}[rdoc-label:footmark-1:foottext-1]", "text"))
+
+ assert_equal expected, parse("((-text-))")
+ end
+
+ def test_parse_include
+ @block_parser.include_path = [Dir.tmpdir]
+
+ expected = doc(@RM::Include.new("parse_include", [Dir.tmpdir]))
+
+ assert_equal expected, parse("<<< parse_include")
+ end
+
+ def test_parse_include_subtree
+ @block_parser.include_path = [Dir.tmpdir]
+
+ expected =
+ doc(
+ @RM::BlankLine.new,
+ @RM::Paragraph.new("include <em>worked</em>"),
+ @RM::BlankLine.new,
+ @RM::BlankLine.new)
+
+ Tempfile.open %w[parse_include .rd] do |io|
+ io.puts "=begin\ninclude ((*worked*))\n=end"
+ io.flush
+
+ str = <<-STR
+<<< #{File.basename io.path}
+ STR
+
+ assert_equal expected, parse(str)
+ end
+ end
+
+ def test_parse_heading
+ assert_equal doc(@RM::Heading.new(1, "H")), parse("= H")
+ assert_equal doc(@RM::Heading.new(2, "H")), parse("== H")
+ assert_equal doc(@RM::Heading.new(3, "H")), parse("=== H")
+ assert_equal doc(@RM::Heading.new(4, "H")), parse("==== H")
+ assert_equal doc(@RM::Heading.new(5, "H")), parse("+ H")
+ assert_equal doc(@RM::Heading.new(6, "H")), parse("++ H")
+ end
+
+ def test_parse_itemlist
+ list = <<-LIST
+* one
+* two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("one")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("two"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_itemlist_multiline
+ list = <<-LIST
+* one
+ two
+ LIST
+
+ contents = "one\n two" # 1.8 vs 1.9
+
+ expected =
+ doc(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil, @RM::Paragraph.new(*contents))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_itemlist_nest
+ list = <<-LIST
+* one
+ * inner
+* two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("one"),
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("inner")))),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("two"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_itemlist_paragraphs
+ list = <<-LIST
+* one
+
+ two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("one"),
+ @RM::Paragraph.new("two"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_itemlist_verbatim
+ list = <<-LIST
+* item
+ verbatim
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("item"),
+ @RM::Verbatim.new("verbatim\n"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_itemlist_verbatim_continue
+ list = <<-LIST
+* one
+ verbatim
+ two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("one"),
+ @RM::Verbatim.new("verbatim\n"),
+ @RM::Paragraph.new("two"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_lists
+ list = <<-LIST
+(1) one
+(1) two
+* three
+* four
+(1) five
+(1) six
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("one")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("two"))),
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("three")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("four"))),
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("five")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("six"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_lists_nest
+ list = <<-LIST
+(1) one
+(1) two
+ * three
+ * four
+(1) five
+(1) six
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("one")),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("two"),
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("three")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("four")))),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("five")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("six"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_lists_nest_verbatim
+ list = <<-LIST
+(1) one
+(1) two
+ * three
+ * four
+ verbatim
+(1) five
+(1) six
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("one")),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("two"),
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("three")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("four"))),
+ @RM::Verbatim.new("verbatim\n")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("five")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("six"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_lists_nest_verbatim2
+ list = <<-LIST
+(1) one
+(1) two
+ * three
+ * four
+ verbatim
+(1) five
+(1) six
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:NUMBER,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("one")),
+ @RM::ListItem.new(nil,
+ @RM::Paragraph.new("two"),
+ @RM::List.new(:BULLET,
+ @RM::ListItem.new(nil, @RM::Paragraph.new("three")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("four"))),
+ @RM::Verbatim.new("verbatim\n")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("five")),
+ @RM::ListItem.new(nil, @RM::Paragraph.new("six"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_methodlist
+ list = <<-LIST
+--- Array#each {|i| ... }
+ yield block for each item.
+--- Array#index(val)
+ return index of first item which equals with val. if it hasn't
+ same item, return nil.
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:LABEL,
+ @RM::ListItem.new(
+ "<tt>Array#each {|i| ... }</tt>",
+ @RM::Paragraph.new("yield block for each item.")),
+ @RM::ListItem.new(
+ "<tt>Array#index(val)</tt>",
+ @RM::Paragraph.new("return index of first item which equals with val. if it hasn't same item, return nil."))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_methodlist_empty
+ list = <<-LIST
+--- A#b
+
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:LABEL,
+ @RM::ListItem.new("<tt>A#b</tt>")))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_methodlist_paragraph
+ list = <<-LIST
+--- A#b
+
+ one
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:LABEL,
+ @RM::ListItem.new(
+ "<tt>A#b</tt>",
+ @RM::Paragraph.new("one"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_methodlist_paragraph2
+ list = <<-LIST.chomp
+--- A#b
+
+ one
+two
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:LABEL,
+ @RM::ListItem.new(
+ "<tt>A#b</tt>",
+ @RM::Paragraph.new("one"))),
+ @RM::Paragraph.new("two"))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_methodlist_paragraph_verbatim
+ list = <<-LIST.chomp
+--- A#b
+
+ text
+ verbatim
+ LIST
+
+ expected =
+ doc(
+ @RM::List.new(:LABEL,
+ @RM::ListItem.new(
+ "<tt>A#b</tt>",
+ @RM::Paragraph.new("text"),
+ @RM::Verbatim.new("verbatim\n"))))
+
+ assert_equal expected, parse(list)
+ end
+
+ def test_parse_verbatim
+ assert_equal doc(@RM::Verbatim.new("verbatim\n")), parse(" verbatim")
+ end
+
+ def test_parse_verbatim_blankline
+ expected = doc(@RM::Verbatim.new("one\n", "\n", "two\n"))
+
+ verbatim = <<-VERBATIM
+ one
+
+ two
+ VERBATIM
+
+ assert_equal expected, parse(verbatim)
+ end
+
+ def test_parse_verbatim_indent
+ expected = doc(@RM::Verbatim.new("one\n", " two\n"))
+
+ verbatim = <<-VERBATIM
+ one
+ two
+ VERBATIM
+
+ assert_equal expected, parse(verbatim)
+ end
+
+ def test_parse_verbatim_multi
+ expected = doc(@RM::Verbatim.new("one\n", "two\n"))
+
+ verbatim = <<-VERBATIM
+ one
+ two
+ VERBATIM
+
+ assert_equal expected, parse(verbatim)
+ end
+
+ def test_parse_textblock
+ assert_equal doc(@RM::Paragraph.new("text")), parse("text")
+ end
+
+ def test_parse_textblock_multi
+ expected = doc(@RM::Paragraph.new("one two"))
+
+ assert_equal expected, parse("one\ntwo")
+ end
+
+ def parse text
+ text = ["=begin", text, "=end"].join "\n"
+
+ doc = @block_parser.parse text.lines.to_a
+
+ assert_equal @RM::BlankLine.new, doc.parts.shift, "=begin blankline"
+ assert_equal @RM::BlankLine.new, doc.parts.pop, "=end blankline"
+
+ doc
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_rd_inline.rb b/test/rdoc/test_rdoc_rd_inline.rb
new file mode 100644
index 0000000000..d601ecca1a
--- /dev/null
+++ b/test/rdoc/test_rdoc_rd_inline.rb
@@ -0,0 +1,63 @@
+require 'rdoc/test_case'
+
+class TestRDocRdInline < RDoc::TestCase
+
+ def setup
+ super
+
+ @inline = RDoc::RD::Inline.new '+text+', 'text'
+ end
+
+ def test_class_new
+ inline = RDoc::RD::Inline.new @inline
+
+ refute_equal inline.rdoc, inline.reference
+ end
+
+ def test_initialize
+ inline = RDoc::RD::Inline.new 'text'
+
+ assert_equal inline.rdoc, inline.reference
+ refute_same inline.rdoc, inline.reference
+ end
+
+ def test_initialize_inline
+ inline = RDoc::RD::Inline.new @inline
+
+ assert_equal '+text+', inline.rdoc
+ assert_equal 'text', inline.reference
+ end
+
+ def test_append_inline
+ out = @inline.append @inline
+
+ assert_same @inline, out
+
+ assert_equal '+text++text+', @inline.rdoc
+ assert_equal 'texttext', @inline.reference
+ end
+
+ def test_append_string
+ @inline.append ' more'
+
+ assert_equal '+text+ more', @inline.rdoc
+ assert_equal 'text more', @inline.reference
+ end
+
+ def test_equals2
+ assert_equal @inline, RDoc::RD::Inline.new('+text+', 'text')
+ refute_equal @inline, RDoc::RD::Inline.new('+text+', 'other')
+ refute_equal @inline, RDoc::RD::Inline.new('+other+', 'text')
+ refute_equal @inline, Object.new
+ end
+
+ def test_inspect
+ assert_equal '(inline: +text+)', @inline.inspect
+ end
+
+ def test_to_s
+ assert_equal '+text+', @inline.to_s
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_rd_inline_parser.rb b/test/rdoc/test_rdoc_rd_inline_parser.rb
new file mode 100644
index 0000000000..6b6c00f886
--- /dev/null
+++ b/test/rdoc/test_rdoc_rd_inline_parser.rb
@@ -0,0 +1,173 @@
+require 'rdoc/test_case'
+
+class TestRDocRdInlineParser < RDoc::TestCase
+
+ def setup
+ super
+
+ @block_parser = RDoc::RD::BlockParser.new
+ @block_parser.instance_variable_set :@i, 0
+ @inline_parser = RDoc::RD::InlineParser.new @block_parser
+ end
+
+ def test_parse
+ assert_equal 'regular <em>emphasis</em>', parse('regular ((*emphasis*))')
+ end
+
+ def test_parse_code
+ assert_equal '<code>text</code>', parse('(({text}))')
+ end
+
+ def test_parse_em
+ assert_equal '<em>text</em>', parse('((*text*))')
+ end
+
+ def test_parse_footnote
+ assert_equal '{*1}[rdoc-label:foottext-1:footmark-1]', parse('((-text-))')
+
+ expected = [
+ @RM::Paragraph.new('{^1}[rdoc-label:footmark-1:foottext-1]', 'text')
+ ]
+
+ assert_equal expected, @block_parser.footnotes
+ end
+
+ def test_parse_index
+ assert_equal '<span id="label-text">text</span>', parse('((:text:))')
+
+ assert_includes @block_parser.labels, 'text'
+ end
+
+ def test_parse_kbd
+ assert_equal '<tt>text</tt>', parse('((%text%))')
+ end
+
+ def test_parse_multiple
+ assert_equal '<em>one</em> <em>two</em>', parse('((*one*)) ((*two*))')
+ end
+
+ def test_parse_newline
+ assert_equal "one\ntwo", parse("one\ntwo")
+ end
+
+ def test_parse_quote
+ assert_equal 'one " two', parse('one " two')
+ end
+
+ def test_parse_ref
+ assert_equal '{text}[rdoc-label:text]', parse('((<text>))')
+ end
+
+ def test_parse_ref_em
+ assert_equal '{<em>text</em>}[rdoc-label:text]', parse('((<((*text*))>))')
+ end
+
+ def test_parse_ref_filename_quote
+ assert_equal '{RD/foo}[rdoc-label:RD/foo]', parse('((<RD/"foo">))')
+ end
+
+ def test_parse_ref_filename
+ assert_equal '{RD}[rdoc-label:RD/]', parse('((<RD/>))')
+ end
+
+ def test_parse_ref_quote
+ assert_equal '{text \\"}[rdoc-label:text \\"]', parse('((<text \">))')
+ end
+
+ def test_parse_ref_quote_content
+ assert_equal '{<em>text</em>}[rdoc-label:text]',
+ parse('((<"((*text*))">))')
+ end
+
+ def test_parse_ref_quote_content_multi
+ assert_equal '{<em>one</em> <em>two</em>}[rdoc-label:one two]',
+ parse('((<"((*one*)) ((*two*))">))')
+ end
+
+ def test_parse_ref_substitute
+ assert_equal '{text}[rdoc-label:thing]', parse('((<text|thing>))')
+ end
+
+ def test_parse_ref_substitute_element_quote
+ assert_equal '{text}[rdoc-label:"RD"]',
+ parse('((<text|"RD">))')
+ end
+
+ def test_parse_ref_substitute_filename
+ assert_equal '{text}[rdoc-label:RD/]', parse('((<text|RD/>))')
+ end
+
+ def test_parse_ref_substitute_filename_label
+ assert_equal '{text}[rdoc-label:RD/label]',
+ parse('((<text|RD/label>))')
+ end
+
+ def test_parse_ref_substitute_filename_quote
+ assert_equal '{text}[rdoc-label:"RD"/]', parse('((<text|"RD"/>))')
+ end
+
+ def test_parse_ref_substitute_multi_content
+ assert_equal '{<em>one</em> two}[rdoc-label:thing]',
+ parse('((<((*one*)) two|thing>))')
+ end
+
+ def test_parse_ref_substitute_multi_content2
+ assert_equal '{<em>one</em> \\" two}[rdoc-label:thing]',
+ parse('((<((*one*)) \" two|thing>))')
+ end
+
+ def test_parse_ref_substitute_multi_content3
+ assert_equal '{<em>one</em> \\" <em>two</em>}[rdoc-label:thing]',
+ parse('((<((*one*)) \" ((*two*))|thing>))')
+ end
+
+ def test_parse_ref_substitute_quote
+ assert_equal '{one | two}[rdoc-label:thing]',
+ parse('((<"one | two"|thing>))')
+ end
+
+ def test_parse_ref_substitute_quote_content
+ assert_equal '{<em>text</em>}[rdoc-label:thing]',
+ parse('((<"((*text*))"|thing>))')
+ end
+
+ def test_parse_ref_substitute_url
+ assert_equal '{text}[http://example]',
+ parse('((<text|URL:http://example>))')
+ end
+
+ def test_parse_ref_url
+ assert_equal '{http://example}[http://example]',
+ parse('((<URL:http://example>))')
+ end
+
+ def test_parse_var
+ assert_equal '+text+', parse('((|text|))')
+ end
+
+ def test_parse_verb
+ assert_equal '<tt>text</tt>', parse("(('text'))")
+ end
+
+ def test_parse_verb_backslash
+ assert_equal "<tt>(('text'))</tt>", parse("(('(('text\\'))'))")
+ end
+
+ def test_parse_verb_backslash_backslash
+ assert_equal '<tt>text \\</tt>', parse("(('text \\\\'))")
+ end
+
+ def test_parse_verb_backslash_quote
+ assert_equal '<tt>text "</tt>', parse("(('text \\\"'))")
+ end
+
+ def test_parse_verb_multiple
+ assert_equal '<tt>((*text*))</tt>', parse("(('((*text*))'))")
+ end
+
+ def parse text
+ @inline_parser.parse text
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_rdoc.rb b/test/rdoc/test_rdoc_rdoc.rb
index aedccc9dbf..fd6b3f81e4 100644
--- a/test/rdoc/test_rdoc_rdoc.rb
+++ b/test/rdoc/test_rdoc_rdoc.rb
@@ -1,47 +1,107 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/rdoc'
+require 'rdoc/test_case'
-require 'fileutils'
-require 'tempfile'
-require 'tmpdir'
-
-class TestRDocRDoc < MiniTest::Unit::TestCase
+class TestRDocRDoc < RDoc::TestCase
def setup
- RDoc::TopLevel.reset
+ super
@rdoc = RDoc::RDoc.new
@rdoc.options = RDoc::Options.new
- @stats = RDoc::Stats.new 0, 0
+ @stats = RDoc::Stats.new @store, 0, 0
@rdoc.instance_variable_set :@stats, @stats
end
- def test_class_reset
- tl = RDoc::TopLevel.new 'file.rb'
- tl.add_class RDoc::NormalClass, 'C'
- tl.add_class RDoc::NormalModule, 'M'
+ def test_document # functional test
+ options = RDoc::Options.new
+ options.files = [File.expand_path('../xref_data.rb')]
+ options.setup_generator 'ri'
+ options.main_page = 'MAIN_PAGE.rdoc'
+ options.title = 'title'
- c = RDoc::Parser::C
- enclosure_classes = c.send :class_variable_get, :@@enclosure_classes
- enclosure_classes['A'] = 'B'
- known_bodies = c.send :class_variable_get, :@@known_bodies
- known_bodies['A'] = 'B'
+ rdoc = RDoc::RDoc.new
- RDoc::RDoc.reset
+ temp_dir do
+ capture_io do
+ rdoc.document options
+ end
- assert_empty RDoc::TopLevel.all_classes_hash
- assert_empty RDoc::TopLevel.all_files_hash
- assert_empty RDoc::TopLevel.all_modules_hash
+ assert File.directory? 'doc'
+ assert_equal rdoc, rdoc.store.rdoc
+ end
- assert_empty c.send :class_variable_get, :@@enclosure_classes
- assert_empty c.send :class_variable_get, :@@known_bodies
+ store = rdoc.store
+
+ assert_equal 'MAIN_PAGE.rdoc', store.main
+ assert_equal 'title', store.title
end
def test_gather_files
- file = File.expand_path __FILE__
- assert_equal [file], @rdoc.gather_files([file, file])
+ a = File.expand_path __FILE__
+ b = File.expand_path '../test_rdoc_text.rb', __FILE__
+
+ assert_equal [a, b], @rdoc.gather_files([b, a, b])
+ end
+
+ def test_handle_pipe
+ $stdin = StringIO.new "hello"
+
+ out, = capture_io do
+ @rdoc.handle_pipe
+ end
+
+ assert_equal "\n<p>hello</p>\n", out
+ ensure
+ $stdin = STDIN
+ end
+
+ def test_handle_pipe_rd
+ $stdin = StringIO.new "=begin\nhello\n=end"
+
+ @rdoc.options.markup = 'rd'
+
+ out, = capture_io do
+ @rdoc.handle_pipe
+ end
+
+ assert_equal "\n<p>hello</p>\n", out
+ ensure
+ $stdin = STDIN
+ end
+
+ def test_load_options
+ temp_dir do
+ options = RDoc::Options.new
+ options.markup = 'tomdoc'
+ options.write_options
+
+ options = @rdoc.load_options
+
+ assert_equal 'tomdoc', options.markup
+ end
+ end
+
+ def test_load_options_invalid
+ temp_dir do
+ open '.rdoc_options', 'w' do |io|
+ io.write "a: !ruby.yaml.org,2002:str |\nfoo"
+ end
+
+ e = assert_raises RDoc::Error do
+ @rdoc.load_options
+ end
+
+ options_file = File.expand_path '.rdoc_options'
+ assert_equal "#{options_file} is not a valid rdoc options file", e.message
+ end
+ end
+
+ def load_options_no_file
+ temp_dir do
+ options = @rdoc.load_options
+
+ assert_kind_of RDoc::Options, options
+ end
end
def test_normalized_file_list
@@ -62,9 +122,29 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
assert_empty files
end
+ def test_normalized_file_list_non_file_directory
+ skip '/dev/stdin is not a character special' unless
+ File.chardev? '/dev/stdin'
+
+ files = nil
+
+ out, err = capture_io do
+ files = @rdoc.normalized_file_list %w[/dev/stdin]
+ end
+
+ files = files.map { |file| File.expand_path file }
+
+ assert_empty files
+
+ assert_empty out
+ assert_match %r%^rdoc can't parse%, err
+ assert_match %r%/dev/stdin$%, err
+ end
+
def test_parse_file_encoding
skip "Encoding not implemented" unless Object.const_defined? :Encoding
@rdoc.options.encoding = Encoding::ISO_8859_1
+ @rdoc.store = RDoc::Store.new
Tempfile.open 'test.txt' do |io|
io.write 'hi'
@@ -76,6 +156,31 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
end
end
+ def test_parse_file_forbidden
+ @rdoc.store = RDoc::Store.new
+
+ Tempfile.open 'test.txt' do |io|
+ io.write 'hi'
+ io.rewind
+
+ File.chmod 0000, io.path
+
+ begin
+ top_level = :bug
+
+ _, err = capture_io do
+ top_level = @rdoc.parse_file io.path
+ end
+
+ assert_match "Unable to read #{io.path},", err
+
+ assert_nil top_level
+ ensure
+ File.chmod 0400, io.path
+ end
+ end
+ end
+
def test_remove_unparseable
file_list = %w[
blah.class
@@ -89,9 +194,35 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
assert_empty @rdoc.remove_unparseable file_list
end
- def test_setup_output_dir
- skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
+ def test_remove_unparseable_tags_emacs
+ temp_dir do
+ open 'TAGS', 'w' do |io| # emacs
+ io.write "\f\nlib/foo.rb,43\n"
+ end
+
+ file_list = %w[
+ TAGS
+ ]
+
+ assert_empty @rdoc.remove_unparseable file_list
+ end
+ end
+ def test_remove_unparseable_tags_vim
+ temp_dir do
+ open 'TAGS', 'w' do |io| # emacs
+ io.write "!_TAG_"
+ end
+
+ file_list = %w[
+ TAGS
+ ]
+
+ assert_empty @rdoc.remove_unparseable file_list
+ end
+ end
+
+ def test_setup_output_dir
Dir.mktmpdir {|d|
path = File.join d, 'testdir'
@@ -105,8 +236,6 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
end
def test_setup_output_dir_dry_run
- skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
-
@rdoc.options.dry_run = true
Dir.mktmpdir do |d|
@@ -119,8 +248,6 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
end
def test_setup_output_dir_exists
- skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
-
Dir.mktmpdir {|path|
open @rdoc.output_flag_file(path), 'w' do |io|
io.puts Time.at 0
@@ -135,8 +262,6 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
end
def test_setup_output_dir_exists_empty_created_rid
- skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
-
Dir.mktmpdir {|path|
open @rdoc.output_flag_file(path), 'w' do end
@@ -162,8 +287,6 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
end
def test_setup_output_dir_exists_not_rdoc
- skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
-
Dir.mktmpdir do |dir|
e = assert_raises RDoc::Error do
@rdoc.setup_output_dir dir, false
@@ -174,8 +297,6 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
end
def test_update_output_dir
- skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
-
Dir.mktmpdir do |d|
@rdoc.update_output_dir d, Time.now, {}
@@ -184,8 +305,6 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
end
def test_update_output_dir_dont
- skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
-
Dir.mktmpdir do |d|
@rdoc.options.update_output_dir = false
@rdoc.update_output_dir d, Time.now, {}
@@ -195,8 +314,6 @@ class TestRDocRDoc < MiniTest::Unit::TestCase
end
def test_update_output_dir_dry_run
- skip "No Dir::mktmpdir, upgrade your ruby" unless Dir.respond_to? :mktmpdir
-
Dir.mktmpdir do |d|
@rdoc.options.dry_run = true
@rdoc.update_output_dir d, Time.now, {}
diff --git a/test/rdoc/test_rdoc_ri_driver.rb b/test/rdoc/test_rdoc_ri_driver.rb
index e219993e57..8fb91c5e1c 100644
--- a/test/rdoc/test_rdoc_ri_driver.rb
+++ b/test/rdoc/test_rdoc_ri_driver.rb
@@ -1,16 +1,9 @@
-require 'pp'
-require 'rubygems'
-require 'minitest/autorun'
-require 'tmpdir'
-require 'fileutils'
-require 'stringio'
-require 'rdoc/ri/driver'
-require 'rdoc/rdoc'
+require 'rdoc/test_case'
-class TestRDocRIDriver < MiniTest::Unit::TestCase
+class TestRDocRIDriver < RDoc::TestCase
def setup
- @RM = RDoc::Markup
+ super
@tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_driver_#{$$}"
@home_ri = File.join @tmpdir, 'dot_ri'
@@ -23,14 +16,22 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
ENV['HOME'] = @tmpdir
ENV.delete 'RI'
- @options = RDoc::RI::Driver.process_args []
- @options[:home] = @tmpdir
+ @options = RDoc::RI::Driver.default_options
+ @options[:use_system] = false
+ @options[:use_site] = false
+ @options[:use_home] = false
+ @options[:use_gems] = false
+
+ @options[:home] = @tmpdir
@options[:use_stdout] = true
- @options[:formatter] = @RM::ToRdoc
+ @options[:formatter] = @RM::ToRdoc
+
@driver = RDoc::RI::Driver.new @options
end
def teardown
+ super
+
ENV['HOME'] = @orig_home
ENV['RI'] = @orig_ri
FileUtils.rm_rf @tmpdir
@@ -56,7 +57,7 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
util_store
out, = capture_io do
- RDoc::RI::Driver.dump @store.cache_path
+ RDoc::RI::Driver.dump @store1.cache_path
end
assert_match %r%:class_methods%, out
@@ -85,8 +86,8 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
expected = @RM::Document.new(
@RM::Rule.new(1),
@RM::Paragraph.new('Also found in:'),
- @RM::Verbatim.new("ruby core\n",
- "~/.ri\n"))
+ @RM::Verbatim.new("ruby core", "\n",
+ "~/.rdoc", "\n"))
assert_equal expected, out
end
@@ -107,26 +108,44 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
def test_add_from
util_store
- @store.type = :system
+ @store1.type = :system
out = @RM::Document.new
- @driver.add_from out, @store
+ @driver.add_from out, @store1
expected = @RM::Document.new @RM::Paragraph.new("(from ruby core)")
assert_equal expected, out
end
- def test_add_includes_empty
+ def test_add_extends
+ util_store
+
out = @RM::Document.new
- @driver.add_includes out, []
+ @driver.add_extends out, [[[@cFooExt], @store1]]
+
+ expected = @RM::Document.new(
+ @RM::Rule.new(1),
+ @RM::Heading.new(1, "Extended by:"),
+ @RM::Paragraph.new("Ext (from #{@store1.friendly_path})"),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new("Extend thingy"),
+ @RM::BlankLine.new)
+
+ assert_equal expected, out
+ end
+
+ def test_add_extension_modules_empty
+ out = @RM::Document.new
+
+ @driver.add_extension_modules out, 'Includes', []
assert_empty out
end
- def test_add_includes_many
+ def test_add_extension_modules_many
util_store
out = @RM::Document.new
@@ -134,23 +153,23 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
enum = RDoc::Include.new 'Enumerable', nil
@cFoo.add_include enum
- @driver.add_includes out, [[[@cFooInc, enum], @store]]
+ @driver.add_extension_modules out, 'Includes', [[[@cFooInc, enum], @store1]]
expected = @RM::Document.new(
@RM::Rule.new(1),
@RM::Heading.new(1, "Includes:"),
- @RM::Paragraph.new("(from #{@store.friendly_path})"),
+ @RM::Paragraph.new("(from #{@store1.friendly_path})"),
@RM::BlankLine.new,
@RM::Paragraph.new("Inc"),
@RM::BlankLine.new,
@RM::Paragraph.new("Include thingy"),
@RM::BlankLine.new,
- @RM::Verbatim.new("Enumerable\n"))
+ @RM::Verbatim.new("Enumerable", "\n"))
assert_equal expected, out
end
- def test_add_includes_many_no_doc
+ def test_add_extension_modules_many_no_doc
util_store
out = @RM::Document.new
@@ -159,29 +178,29 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
@cFoo.add_include enum
@cFooInc.instance_variable_set :@comment, ''
- @driver.add_includes out, [[[@cFooInc, enum], @store]]
+ @driver.add_extension_modules out, 'Includes', [[[@cFooInc, enum], @store1]]
expected = @RM::Document.new(
@RM::Rule.new(1),
@RM::Heading.new(1, "Includes:"),
- @RM::Paragraph.new("(from #{@store.friendly_path})"),
- @RM::Verbatim.new("Inc\n",
- "Enumerable\n"))
+ @RM::Paragraph.new("(from #{@store1.friendly_path})"),
+ @RM::Verbatim.new("Inc", "\n",
+ "Enumerable", "\n"))
assert_equal expected, out
end
- def test_add_includes_one
+ def test_add_extension_modules_one
util_store
out = @RM::Document.new
- @driver.add_includes out, [[[@cFooInc], @store]]
+ @driver.add_extension_modules out, 'Includes', [[[@cFooInc], @store1]]
expected = @RM::Document.new(
@RM::Rule.new(1),
@RM::Heading.new(1, "Includes:"),
- @RM::Paragraph.new("Inc (from #{@store.friendly_path})"),
+ @RM::Paragraph.new("Inc (from #{@store1.friendly_path})"),
@RM::BlankLine.new,
@RM::Paragraph.new("Include thingy"),
@RM::BlankLine.new)
@@ -189,6 +208,137 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
assert_equal expected, out
end
+ def test_add_includes
+ util_store
+
+ out = @RM::Document.new
+
+ @driver.add_includes out, [[[@cFooInc], @store1]]
+
+ expected = @RM::Document.new(
+ @RM::Rule.new(1),
+ @RM::Heading.new(1, "Includes:"),
+ @RM::Paragraph.new("Inc (from #{@store1.friendly_path})"),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new("Include thingy"),
+ @RM::BlankLine.new)
+
+ assert_equal expected, out
+ end
+
+ def test_add_method
+ util_store
+
+ out = doc
+
+ @driver.add_method out, 'Foo::Bar#blah'
+
+ expected =
+ doc(
+ head(1, 'Foo::Bar#blah'),
+ blank_line,
+ para('(from ~/.rdoc)'),
+ head(3, 'Implementation from Bar'),
+ rule(1),
+ verb("blah(5) => 5\n",
+ "blah(6) => 6\n"),
+ rule(1),
+ blank_line,
+ blank_line)
+
+ assert_equal expected, out
+ end
+
+ def test_add_method_attribute
+ util_store
+
+ out = doc
+
+ @driver.add_method out, 'Foo::Bar#attr'
+
+ expected =
+ doc(
+ head(1, 'Foo::Bar#attr'),
+ blank_line,
+ para('(from ~/.rdoc)'),
+ rule(1),
+ blank_line,
+ blank_line)
+
+ assert_equal expected, out
+ end
+
+ def test_add_method_inherited
+ util_multi_store
+
+ out = doc
+
+ @driver.add_method out, 'Bar#inherit'
+
+ expected =
+ doc(
+ head(1, 'Bar#inherit'),
+ blank_line,
+ para('(from ~/.rdoc)'),
+ head(3, 'Implementation from Foo'),
+ rule(1),
+ blank_line,
+ blank_line)
+
+ assert_equal expected, out
+ end
+
+ def test_add_method_overriden
+ util_multi_store
+
+ out = doc
+
+ @driver.add_method out, 'Bar#override'
+
+ expected =
+ doc(
+ head(1, 'Bar#override'),
+ blank_line,
+ para("(from #{@store2.path})"),
+ rule(1),
+ blank_line,
+ para('must be displayed'),
+ blank_line,
+ blank_line)
+
+ assert_equal expected, out
+ end
+
+ def test_add_method_documentation
+ util_store
+
+ out = doc()
+
+ missing = RDoc::AnyMethod.new nil, 'missing'
+ @cFoo.add_method missing
+
+ @driver.add_method_documentation out, @cFoo
+
+ expected =
+ doc(
+ head(1, 'Foo#inherit'),
+ blank_line,
+ para('(from ~/.rdoc)'),
+ rule(1),
+ blank_line,
+ blank_line,
+ head(1, 'Foo#override'),
+ blank_line,
+ para('(from ~/.rdoc)'),
+ rule(1),
+ blank_line,
+ para('must not be displayed in Bar#override'),
+ blank_line,
+ blank_line)
+
+ assert_equal expected, out
+ end
+
def test_add_method_list
out = @RM::Document.new
@@ -241,35 +391,48 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
expected = {
'Ambiguous' => [@store1, @store2],
'Bar' => [@store2],
- 'Foo' => [@store1],
+ 'Ext' => [@store1],
+ 'Foo' => [@store1, @store2],
'Foo::Bar' => [@store1],
'Foo::Baz' => [@store1, @store2],
'Inc' => [@store1],
}
- assert_equal expected, @driver.classes
+ classes = @driver.classes
+
+ assert_equal expected.keys.sort, classes.keys.sort
+
+ expected.each do |klass, stores|
+ assert_equal stores, classes[klass].sort_by { |store| store.path },
+ "mismatch for #{klass}"
+ end
end
def test_class_document
util_store
- tl1 = RDoc::TopLevel.new 'one.rb'
- tl2 = RDoc::TopLevel.new 'two.rb'
+ tl1 = @store1.add_file 'one.rb'
+ tl2 = @store1.add_file 'two.rb'
@cFoo.add_comment 'one', tl1
@cFoo.add_comment 'two', tl2
- @store.save_class @cFoo
+
+ @store1.save_class @cFoo
found = [
- [@store, @store.load_class(@cFoo.full_name)]
+ [@store1, @store1.load_class(@cFoo.full_name)]
]
- out = @driver.class_document @cFoo.full_name, found, [], []
+ extends = [[[@cFooExt], @store1]]
+ includes = [[[@cFooInc], @store1]]
+
+ out = @driver.class_document @cFoo.full_name, found, [], includes, extends
expected = @RM::Document.new
@driver.add_class expected, 'Foo', []
- @driver.add_includes expected, []
- @driver.add_from expected, @store
+ @driver.add_includes expected, includes
+ @driver.add_extends expected, extends
+ @driver.add_from expected, @store1
expected << @RM::Rule.new(1)
doc = @RM::Document.new(@RM::Paragraph.new('one'))
@@ -375,6 +538,32 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
assert_match %r%^ attr_accessor attr%, out
assert_equal 1, out.scan(/-\n/).length
+
+ refute_match %r%Foo::Bar#blah%, out
+ end
+
+ def test_display_class_all
+ util_store
+
+ @driver.show_all = true
+
+ out, = capture_io do
+ @driver.display_class 'Foo::Bar'
+ end
+
+ assert_match %r%^= Foo::Bar%, out
+ assert_match %r%^\(from%, out
+
+ assert_match %r%^= Class methods:%, out
+ assert_match %r%^ new%, out
+ assert_match %r%^= Instance methods:%, out
+ assert_match %r%^ blah%, out
+ assert_match %r%^= Attributes:%, out
+ assert_match %r%^ attr_accessor attr%, out
+
+ assert_equal 6, out.scan(/-\n/).length
+
+ assert_match %r%Foo::Bar#blah%, out
end
def test_display_class_ambiguous
@@ -421,6 +610,14 @@ class TestRDocRIDriver < MiniTest::Unit::TestCase
assert_match %r%^= Inc$%, out
end
+ def test_display_class_page
+ out, = capture_io do
+ @driver.display_class 'ruby:README'
+ end
+
+ assert_empty out
+ end
+
def test_display_method
util_store
@@ -509,6 +706,68 @@ Foo::Bar#bother
assert_match %r%things.*stuff%, out
end
+ def test_display_page
+ util_store
+
+ out, = capture_io do
+ @driver.display_page 'home:README.rdoc'
+ end
+
+ assert_match %r%= README%, out
+ end
+
+ def test_display_page_add_extension
+ util_store
+
+ out, = capture_io do
+ @driver.display_page 'home:README'
+ end
+
+ assert_match %r%= README%, out
+ end
+
+ def test_display_page_ambiguous
+ util_store
+
+ other = @store1.add_file 'README.md'
+ other.parser = RDoc::Parser::Simple
+ other.comment =
+ doc(
+ head(1, 'README.md'),
+ para('This is the other README'))
+
+ @store1.save_page other
+
+ out, = capture_io do
+ @driver.display_page 'home:README'
+ end
+
+ assert_match %r%= README pages in ~/\.rdoc%, out
+ assert_match %r%README\.rdoc%, out
+ assert_match %r%README\.md%, out
+ end
+
+ def test_display_page_list
+ util_store
+
+ other = @store1.add_file 'OTHER.rdoc'
+ other.parser = RDoc::Parser::Simple
+ other.comment =
+ doc(
+ head(1, 'OTHER'),
+ para('This is OTHER'))
+
+ @store1.save_page other
+
+ out, = capture_io do
+ @driver.display_page_list @store1
+ end
+
+ assert_match %r%= Pages in ~/\.rdoc%, out
+ assert_match %r%README\.rdoc%, out
+ assert_match %r%OTHER\.rdoc%, out
+ end
+
def test_expand_class
util_store
@@ -532,6 +791,17 @@ Foo::Bar#bother
end
assert_equal 'Z', e.name
+
+ @driver.stores << RDoc::Store.new(nil, :system)
+
+ assert_equal 'ruby:README', @driver.expand_name('ruby:README')
+ assert_equal 'ruby:', @driver.expand_name('ruby:')
+
+ e = assert_raises RDoc::RI::Driver::NotFoundError do
+ @driver.expand_name 'nonexistent_gem:'
+ end
+
+ assert_equal 'nonexistent_gem', e.name
end
def test_find_methods
@@ -544,7 +814,7 @@ Foo::Bar#bother
end
expected = [
- [@store, 'Foo::Bar', 'Foo::Bar', :both, nil],
+ [@store1, 'Foo::Bar', 'Foo::Bar', :both, nil],
]
assert_equal expected, items
@@ -560,11 +830,12 @@ Foo::Bar#bother
end
expected = [
- [@store, 'Ambiguous', 'Ambiguous', :both, 'blah'],
- [@store, 'Foo', 'Foo', :both, 'blah'],
- [@store, 'Foo::Bar', 'Foo::Bar', :both, 'blah'],
- [@store, 'Foo::Baz', 'Foo::Baz', :both, 'blah'],
- [@store, 'Inc', 'Inc', :both, 'blah'],
+ [@store1, 'Ambiguous', 'Ambiguous', :both, 'blah'],
+ [@store1, 'Ext', 'Ext', :both, 'blah'],
+ [@store1, 'Foo', 'Foo', :both, 'blah'],
+ [@store1, 'Foo::Bar', 'Foo::Bar', :both, 'blah'],
+ [@store1, 'Foo::Baz', 'Foo::Baz', :both, 'blah'],
+ [@store1, 'Inc', 'Inc', :both, 'blah'],
]
assert_equal expected, items
@@ -596,6 +867,21 @@ Foo::Bar#bother
assert_equal found, sorted
end
+ def test_find_store
+ @driver.stores << RDoc::Store.new(nil, :system)
+ @driver.stores << RDoc::Store.new('doc/gem-1.0/ri', :gem)
+
+ assert_equal 'ruby', @driver.find_store('ruby')
+ assert_equal 'gem-1.0', @driver.find_store('gem-1.0')
+ assert_equal 'gem-1.0', @driver.find_store('gem')
+
+ e = assert_raises RDoc::RI::Driver::NotFoundError do
+ @driver.find_store 'nonexistent'
+ end
+
+ assert_equal 'nonexistent', e.name
+ end
+
def test_formatter
tty = Object.new
def tty.tty?() true; end
@@ -609,20 +895,21 @@ Foo::Bar#bother
driver.instance_variable_set :@paging, true
assert_instance_of @RM::ToBs, driver.formatter(StringIO.new)
-
- driver.instance_variable_set :@formatter_klass, @RM::ToHtml
-
- assert_instance_of @RM::ToHtml, driver.formatter(tty)
end
def test_in_path_eh
path = ENV['PATH']
- refute @driver.in_path?('/nonexistent')
+ test_path = File.expand_path '..', __FILE__
+
+ temp_dir do |dir|
+ nonexistent = File.join dir, 'nonexistent'
+ refute @driver.in_path?(nonexistent)
- ENV['PATH'] = File.expand_path '..', __FILE__
+ ENV['PATH'] = test_path
- assert @driver.in_path?(File.basename(__FILE__))
+ assert @driver.in_path?(File.basename(__FILE__))
+ end
ensure
ENV['PATH'] = path
end
@@ -658,7 +945,7 @@ Foo::Bar#bother
@driver.list_known_classes
end
- assert_equal "Ambiguous\nFoo\nFoo::Bar\nFoo::Baz\nInc\n", out
+ assert_equal "Ambiguous\nExt\nFoo\nFoo::Bar\nFoo::Baz\nInc\n", out
end
def test_list_known_classes_name
@@ -700,15 +987,15 @@ Foo::Bar#bother
index = RDoc::AnyMethod.new nil, '[]'
index.record_location @top_level
@cFoo.add_method index
- @store.save_method @cFoo, index
+ @store1.save_method @cFoo, index
c_index = RDoc::AnyMethod.new nil, '[]'
c_index.singleton = true
c_index.record_location @top_level
@cFoo.add_method c_index
- @store.save_method @cFoo, c_index
+ @store1.save_method @cFoo, c_index
- @store.save_cache
+ @store1.save_cache
assert_equal %w[Foo#[]], @driver.list_methods_matching('Foo#[]')
assert_equal %w[Foo::[]], @driver.list_methods_matching('Foo::[]')
@@ -717,7 +1004,7 @@ Foo::Bar#bother
def test_load_method
util_store
- method = @driver.load_method(@store, :instance_methods, 'Foo', '#',
+ method = @driver.load_method(@store1, :instance_methods, 'Foo', '#',
'inherit')
assert_equal @inherit, method
@@ -735,11 +1022,11 @@ Foo::Bar#bother
def test_load_methods_matching
util_store
- expected = [[@store, [@inherit]]]
+ expected = [[@store1, [@inherit]]]
assert_equal expected, @driver.load_methods_matching('Foo#inherit')
- expected = [[@store, [@blah]]]
+ expected = [[@store1, [@blah]]]
assert_equal expected, @driver.load_methods_matching('.blah')
@@ -768,6 +1055,18 @@ Foo::Bar#bother
refute @driver.paging?
end
+ def test_page_in_presence_of_child_status
+ skip 'this test hangs on travis-ci.org' if ENV['CI']
+ @driver.use_stdout = false
+
+ with_dummy_pager do
+ @driver.page do |io|
+ refute_equal $stdout, io
+ assert @driver.paging?
+ end
+ end
+ end
+
def test_page_stdout
@driver.use_stdout = true
@@ -798,6 +1097,20 @@ Foo::Bar#bother
assert_equal 'foo', meth, '::foo method'
end
+ def test_parse_name_page
+ klass, type, meth = @driver.parse_name 'ruby:README'
+
+ assert_equal 'ruby', klass, 'ruby project'
+ assert_equal ':', type, 'ruby type'
+ assert_equal 'README', meth, 'ruby page'
+
+ klass, type, meth = @driver.parse_name 'ruby:'
+
+ assert_equal 'ruby', klass, 'ruby project'
+ assert_equal ':', type, 'ruby type'
+ assert_equal nil, meth, 'ruby page'
+ end
+
def test_parse_name_single_class
klass, type, meth = @driver.parse_name 'Foo'
@@ -958,13 +1271,11 @@ Foo::Bar#bother
def util_multi_store
util_store
- @store1 = @store
-
- @top_level = RDoc::TopLevel.new 'file.rb'
-
@home_ri2 = "#{@home_ri}2"
@store2 = RDoc::RI::Store.new @home_ri2
+ @top_level = @store2.add_file 'file.rb'
+
# as if seen in a namespace like class Ambiguous::Other
@mAmbiguous = @top_level.add_module RDoc::NormalModule, 'Ambiguous'
@@ -980,29 +1291,31 @@ Foo::Bar#bother
@override.comment = 'must be displayed'
@override.record_location @top_level
- @store2.save_class @mAmbiguous
- @store2.save_class @cBar
- @store2.save_class @cFoo_Baz
-
- @store2.save_method @cBar, @override
- @store2.save_method @cBar, @baz
-
- @store2.save_cache
+ @store2.save
@driver.stores = [@store1, @store2]
-
- RDoc::RDoc.reset
end
def util_store
- @store = RDoc::RI::Store.new @home_ri
+ @store1 = RDoc::RI::Store.new @home_ri, :home
- @top_level = RDoc::TopLevel.new 'file.rb'
+ @top_level = @store1.add_file 'file.rb'
+
+ @readme = @store1.add_file 'README.rdoc'
+ @readme.parser = RDoc::Parser::Simple
+ @readme.comment =
+ doc(
+ head(1, 'README'),
+ para('This is a README'))
@cFoo = @top_level.add_class RDoc::NormalClass, 'Foo'
+ @mExt = @top_level.add_module RDoc::NormalModule, 'Ext'
@mInc = @top_level.add_module RDoc::NormalModule, 'Inc'
@cAmbiguous = @top_level.add_class RDoc::NormalClass, 'Ambiguous'
+ doc = @RM::Document.new @RM::Paragraph.new('Extend thingy')
+ @cFooExt = @cFoo.add_extend RDoc::Extend.new('Ext', doc)
+ @cFooExt.record_location @top_level
doc = @RM::Document.new @RM::Paragraph.new('Include thingy')
@cFooInc = @cFoo.add_include RDoc::Include.new('Inc', doc)
@cFooInc.record_location @top_level
@@ -1033,28 +1346,12 @@ Foo::Bar#bother
# overriden by Bar in multi_store
@overriden = @cFoo.add_method RDoc::AnyMethod.new(nil, 'override')
- @overriden.comment = 'must not be displayed'
+ @overriden.comment = 'must not be displayed in Bar#override'
@overriden.record_location @top_level
- @store.save_class @cFoo
- @store.save_class @cFoo_Bar
- @store.save_class @cFoo_Baz
- @store.save_class @mInc
- @store.save_class @cAmbiguous
-
- @store.save_method @cFoo_Bar, @blah
- @store.save_method @cFoo_Bar, @bother
- @store.save_method @cFoo_Bar, @new
- @store.save_method @cFoo_Bar, @attr
-
- @store.save_method @cFoo, @inherit
- @store.save_method @cFoo, @overriden
-
- @store.save_cache
-
- @driver.stores = [@store]
+ @store1.save
- RDoc::RDoc.reset
+ @driver.stores = [@store1]
end
end
diff --git a/test/rdoc/test_rdoc_ri_paths.rb b/test/rdoc/test_rdoc_ri_paths.rb
index e6f33d7d5e..0ef80345bb 100644
--- a/test/rdoc/test_rdoc_ri_paths.rb
+++ b/test/rdoc/test_rdoc_ri_paths.rb
@@ -1,42 +1,154 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'tmpdir'
-require 'fileutils'
-require 'rdoc/ri/paths'
+require 'rdoc/test_case'
-class TestRDocRIPaths < MiniTest::Unit::TestCase
+class TestRDocRIPaths < RDoc::TestCase
def setup
- RDoc::RI::Paths.instance_variable_set :@gemdirs, %w[/nonexistent/gemdir]
+ super
+
+ @orig_gem_path = Gem.path
+
+ @tempdir = File.join Dir.tmpdir, "test_rdoc_ri_paths_#{$$}"
+ Gem.use_paths @tempdir
+ Gem.ensure_gem_subdirectories @tempdir
+
+ specs = [
+ @rake_10 = Gem::Specification.new('rake', '10.0.1'),
+ @rdoc_4_0 = Gem::Specification.new('rdoc', '4.0'),
+ @rdoc_3_12 = Gem::Specification.new('rdoc', '3.12'),
+ @nodoc = Gem::Specification.new('nodoc', '1.0'),
+ ]
+
+ specs.each do |spec|
+ spec.loaded_from = File.join @tempdir, spec.spec_file
+
+ open spec.spec_file, 'w' do |file|
+ file.write spec.to_ruby_for_cache
+ end
+
+ FileUtils.mkdir_p File.join(spec.doc_dir, 'ri') unless
+ spec.name == 'nodoc'
+ end
+
+ Gem::Specification.reset
+ Gem::Specification.all = specs
end
def teardown
- RDoc::RI::Paths.instance_variable_set :@gemdirs, nil
+ super
+
+ Gem.use_paths(*@orig_gem_path)
+ Gem::Specification.reset
+ FileUtils.rm_rf @tempdir
+ end
+
+ def test_class_each
+ enum = RDoc::RI::Paths.each true, true, true, :all
+
+ path = enum.map { |dir,| dir }
+
+ assert_equal RDoc::RI::Paths.system_dir, path.shift
+ assert_equal RDoc::RI::Paths.site_dir, path.shift
+ assert_equal RDoc::RI::Paths.home_dir, path.shift
+ assert_equal File.join(@nodoc.doc_dir, 'ri'), path.shift
+ assert_equal File.join(@rake_10.doc_dir, 'ri'), path.shift
+ assert_equal File.join(@rdoc_4_0.doc_dir, 'ri'), path.shift
+ assert_equal File.join(@rdoc_3_12.doc_dir, 'ri'), path.shift
+ assert_empty path
+ end
+
+ def test_class_gemdirs_latest
+ Dir.chdir @tempdir do
+ gemdirs = RDoc::RI::Paths.gemdirs :latest
+
+ expected = [
+ File.join(@rake_10.doc_dir, 'ri'),
+ File.join(@rdoc_4_0.doc_dir, 'ri'),
+ ]
+
+ assert_equal expected, gemdirs
+ end
+ end
+
+ def test_class_gemdirs_legacy
+ Dir.chdir @tempdir do
+ gemdirs = RDoc::RI::Paths.gemdirs true
+
+ expected = [
+ File.join(@rake_10.doc_dir, 'ri'),
+ File.join(@rdoc_4_0.doc_dir, 'ri'),
+ ]
+
+ assert_equal expected, gemdirs
+ end
+ end
+
+ def test_class_gemdirs_all
+ Dir.chdir @tempdir do
+ gemdirs = RDoc::RI::Paths.gemdirs :all
+
+ expected = [
+ File.join(@nodoc.doc_dir, 'ri'),
+ File.join(@rake_10.doc_dir, 'ri'),
+ File.join(@rdoc_4_0.doc_dir, 'ri'),
+ File.join(@rdoc_3_12.doc_dir, 'ri'),
+ ]
+
+ assert_equal expected, gemdirs
+ end
+ end
+
+ def test_class_gem_dir
+ dir = RDoc::RI::Paths.gem_dir 'rake', '10.0.1'
+
+ expected = File.join @rake_10.doc_dir, 'ri'
+
+ assert_equal expected, dir
+ end
+
+ def test_class_home_dir
+ dir = RDoc::RI::Paths.home_dir
+
+ assert_equal RDoc::RI::Paths::HOMEDIR, dir
end
def test_class_path_nonexistent
- path = RDoc::RI::Paths.path true, true, true, true, '/nonexistent'
+ temp_dir do |dir|
+ nonexistent = File.join dir, 'nonexistent'
+ dir = RDoc::RI::Paths.path true, true, true, true, nonexistent
- refute_includes path, '/nonexistent'
+ refute_includes dir, nonexistent
+ end
end
def test_class_raw_path
path = RDoc::RI::Paths.raw_path true, true, true, true
- assert_equal RDoc::RI::Paths::SYSDIR, path.shift
- assert_equal RDoc::RI::Paths::SITEDIR, path.shift
- assert_equal RDoc::RI::Paths::HOMEDIR, path.shift
- assert_equal '/nonexistent/gemdir', path.shift
+ assert_equal RDoc::RI::Paths.system_dir, path.shift
+ assert_equal RDoc::RI::Paths.site_dir, path.shift
+ assert_equal RDoc::RI::Paths.home_dir, path.shift
+ assert_equal File.join(@rake_10.doc_dir, 'ri'), path.shift
end
def test_class_raw_path_extra_dirs
path = RDoc::RI::Paths.raw_path true, true, true, true, '/nonexistent'
- assert_equal '/nonexistent', path.shift
- assert_equal RDoc::RI::Paths::SYSDIR, path.shift
- assert_equal RDoc::RI::Paths::SITEDIR, path.shift
- assert_equal RDoc::RI::Paths::HOMEDIR, path.shift
- assert_equal '/nonexistent/gemdir', path.shift
+ assert_equal '/nonexistent', path.shift
+ assert_equal RDoc::RI::Paths.system_dir, path.shift
+ assert_equal RDoc::RI::Paths.site_dir, path.shift
+ assert_equal RDoc::RI::Paths.home_dir, path.shift
+ assert_equal File.join(@rake_10.doc_dir, 'ri'), path.shift
+ end
+
+ def test_class_site_dir
+ dir = RDoc::RI::Paths.site_dir
+
+ assert_equal File.join(RDoc::RI::Paths::BASE, 'site'), dir
+ end
+
+ def test_class_system_dir
+ dir = RDoc::RI::Paths.system_dir
+
+ assert_equal File.join(RDoc::RI::Paths::BASE, 'system'), dir
end
end
diff --git a/test/rdoc/test_rdoc_ruby_lex.rb b/test/rdoc/test_rdoc_ruby_lex.rb
index 4398f4119f..1dc11e95a3 100644
--- a/test/rdoc/test_rdoc_ruby_lex.rb
+++ b/test/rdoc/test_rdoc_ruby_lex.rb
@@ -1,9 +1,219 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/rdoc'
-require 'rdoc/ruby_lex'
+require 'rdoc/test_case'
+
+class TestRDocRubyLex < RDoc::TestCase
+
+ def setup
+ @TK = RDoc::RubyToken
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding(Encoding.default_external) if defined? Encoding
+ s.chomp
+ end
+
+ def test_class_tokenize
+ tokens = RDoc::RubyLex.tokenize "def x() end", nil
+
+ expected = [
+ @TK::TkDEF .new( 0, 1, 0, "def"),
+ @TK::TkSPACE .new( 3, 1, 3, " "),
+ @TK::TkIDENTIFIER.new( 4, 1, 4, "x"),
+ @TK::TkLPAREN .new( 5, 1, 5, "("),
+ @TK::TkRPAREN .new( 6, 1, 6, ")"),
+ @TK::TkSPACE .new( 7, 1, 7, " "),
+ @TK::TkEND .new( 8, 1, 8, "end"),
+ @TK::TkNL .new(11, 1, 11, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize___END__
+ tokens = RDoc::RubyLex.tokenize '__END__', nil
+
+ expected = [
+ @TK::TkEND_OF_SCRIPT.new(0, 1, 0, '__END__'),
+ @TK::TkNL .new(7, 1, 7, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_character_literal
+ tokens = RDoc::RubyLex.tokenize "?\\", nil
+
+ expected = [
+ @TK::TkSTRING.new( 0, 1, 0, "\\"),
+ @TK::TkNL .new( 2, 1, 2, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_def_heredoc
+ tokens = RDoc::RubyLex.tokenize <<-'RUBY', nil
+def x
+ <<E
+Line 1
+Line 2
+E
+end
+ RUBY
+
+ expected = [
+ @TK::TkDEF .new( 0, 1, 0, 'def'),
+ @TK::TkSPACE .new( 3, 1, 3, ' '),
+ @TK::TkIDENTIFIER.new( 4, 1, 4, 'x'),
+ @TK::TkNL .new( 5, 1, 5, "\n"),
+ @TK::TkSPACE .new( 6, 2, 0, ' '),
+ @TK::TkSTRING .new( 8, 2, 2, %Q{"Line 1\nLine 2\n"}),
+ @TK::TkNL .new(27, 5, 28, "\n"),
+ @TK::TkEND .new(28, 6, 0, 'end'),
+ @TK::TkNL .new(31, 6, 28, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_hash_symbol
+ tokens = RDoc::RubyLex.tokenize '{ class:"foo" }', nil
+
+ expected = [
+ @TK::TkLBRACE .new( 0, 1, 0, '{'),
+ @TK::TkSPACE .new( 1, 1, 1, ' '),
+ @TK::TkIDENTIFIER.new( 2, 1, 2, 'class'),
+ @TK::TkSYMBEG .new( 7, 1, 7, ':'),
+ @TK::TkSTRING .new( 8, 1, 8, '"foo"'),
+ @TK::TkSPACE .new(13, 1, 13, ' '),
+ @TK::TkRBRACE .new(14, 1, 14, '}'),
+ @TK::TkNL .new(15, 1, 15, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_heredoc_indent
+ tokens = RDoc::RubyLex.tokenize <<-'RUBY', nil
+string = <<-STRING
+Line 1
+Line 2
+STRING
+ RUBY
+
+ expected = [
+ @TK::TkIDENTIFIER.new( 0, 1, 0, 'string'),
+ @TK::TkSPACE .new( 6, 1, 6, ' '),
+ @TK::TkASSIGN .new( 7, 1, 7, '='),
+ @TK::TkSPACE .new( 8, 1, 8, ' '),
+ @TK::TkSTRING .new( 9, 1, 9, %Q{"Line 1\nLine 2\n"}),
+ @TK::TkNL .new(39, 4, 40, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_heredoc_percent_N
+ tokens = RDoc::RubyLex.tokenize <<-'RUBY', nil
+a b <<-U
+%N
+U
+ RUBY
+
+ expected = [
+ @TK::TkIDENTIFIER.new( 0, 1, 0, 'a'),
+ @TK::TkSPACE .new( 1, 1, 1, ' '),
+ @TK::TkIDENTIFIER.new( 2, 1, 2, 'b'),
+ @TK::TkSPACE .new( 3, 1, 3, ' '),
+ @TK::TkSTRING .new( 4, 1, 4, %Q{"%N\n"}),
+ @TK::TkNL .new(13, 3, 14, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_percent_1
+ tokens = RDoc::RubyLex.tokenize 'v%10==10', nil
+
+ expected = [
+ @TK::TkIDENTIFIER.new(0, 1, 0, 'v'),
+ @TK::TkMOD.new( 1, 1, 1, '%'),
+ @TK::TkINTEGER.new( 2, 1, 2, '10'),
+ @TK::TkEQ.new( 4, 1, 4, '=='),
+ @TK::TkINTEGER.new( 6, 1, 6, '10'),
+ @TK::TkNL.new( 8, 1, 8, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_percent_r
+ tokens = RDoc::RubyLex.tokenize '%r[hi]', nil
+
+ expected = [
+ @TK::TkREGEXP.new( 0, 1, 0, '%r[hi]'),
+ @TK::TkNL .new( 6, 1, 6, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_percent_w
+ tokens = RDoc::RubyLex.tokenize '%w[hi]', nil
+
+ expected = [
+ @TK::TkDSTRING.new( 0, 1, 0, '%w[hi]'),
+ @TK::TkNL .new( 6, 1, 6, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_regexp
+ tokens = RDoc::RubyLex.tokenize "/hay/", nil
+
+ expected = [
+ @TK::TkREGEXP.new( 0, 1, 0, "/hay/"),
+ @TK::TkNL .new( 5, 1, 5, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_regexp_backref
+ tokens = RDoc::RubyLex.tokenize "/[csh](..) [csh]\\1 in/", nil
+
+ expected = [
+ @TK::TkREGEXP.new( 0, 1, 0, "/[csh](..) [csh]\\1 in/"),
+ @TK::TkNL .new(22, 1, 22, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_regexp_escape
+ tokens = RDoc::RubyLex.tokenize "/\\//", nil
+
+ expected = [
+ @TK::TkREGEXP.new( 0, 1, 0, "/\\//"),
+ @TK::TkNL .new( 4, 1, 4, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
+
+ def test_class_tokenize_string
+ tokens = RDoc::RubyLex.tokenize "'hi'", nil
+
+ expected = [
+ @TK::TkSTRING.new( 0, 1, 0, "'hi'"),
+ @TK::TkNL .new( 4, 1, 4, "\n"),
+ ]
+
+ assert_equal expected, tokens
+ end
-class TestRubyLex < MiniTest::Unit::TestCase
def test_unary_minus
ruby_lex = RDoc::RubyLex.new("-1", nil)
assert_equal("-1", ruby_lex.token.value)
@@ -20,4 +230,6 @@ class TestRubyLex < MiniTest::Unit::TestCase
2.times { ruby_lex.token } # skip "0" and "+"
assert_equal("-0.1", ruby_lex.token.value)
end
+
end
+
diff --git a/test/rdoc/test_rdoc_ruby_token.rb b/test/rdoc/test_rdoc_ruby_token.rb
new file mode 100644
index 0000000000..ed8c8275ba
--- /dev/null
+++ b/test/rdoc/test_rdoc_ruby_token.rb
@@ -0,0 +1,19 @@
+require 'rdoc/test_case'
+
+class TestRDocRubyToken < RDoc::TestCase
+
+ def test_Token_text
+ token = RDoc::RubyToken::Token.new 0, 0, 0, 'text'
+
+ assert_equal 'text', token.text
+ end
+
+ def test_TkOp_name
+ token = RDoc::RubyToken::TkOp.new 0, 0, 0, '&'
+
+ assert_equal '&', token.text
+ assert_equal '&', token.name
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_rubygems_hook.rb b/test/rdoc/test_rdoc_rubygems_hook.rb
index af6ffddf4a..fc2231965f 100644
--- a/test/rdoc/test_rdoc_rubygems_hook.rb
+++ b/test/rdoc/test_rdoc_rubygems_hook.rb
@@ -1,5 +1,5 @@
-require 'rubygems/test_case'
require 'rubygems'
+require 'rubygems/test_case'
require 'rdoc/rubygems_hook'
class TestRDocRubygemsHook < Gem::TestCase
@@ -7,6 +7,9 @@ class TestRDocRubygemsHook < Gem::TestCase
def setup
super
+ skip 'requires RubyGems 1.9+' unless
+ Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.9')
+
@a = quick_spec 'a'
@rdoc = RDoc::RubygemsHook.new @a
@@ -195,5 +198,5 @@ class TestRDocRubygemsHook < Gem::TestCase
FileUtils.chmod 0755, @a.doc_dir
end
-end if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.9')
+end
diff --git a/test/rdoc/test_rdoc_servlet.rb b/test/rdoc/test_rdoc_servlet.rb
new file mode 100644
index 0000000000..0234d33077
--- /dev/null
+++ b/test/rdoc/test_rdoc_servlet.rb
@@ -0,0 +1,408 @@
+require 'rdoc/test_case'
+class TestRDocServlet < RDoc::TestCase
+
+ def setup
+ super
+
+ @orig_gem_path = Gem.path
+
+ @tempdir = File.join Dir.tmpdir, "test_rdoc_servlet_#{$$}"
+ Gem.use_paths @tempdir
+ Gem.ensure_gem_subdirectories @tempdir
+
+ @spec = Gem::Specification.new 'spec', '1.0'
+ @spec.loaded_from = File.join @tempdir, @spec.spec_file
+
+ Gem::Specification.reset
+ Gem::Specification.all = [@spec]
+
+ server = {}
+ def server.mount(*) end
+
+ @stores = {}
+ @cache = Hash.new { |hash, store| hash[store] = {} }
+
+ @s = RDoc::Servlet.new server, @stores, @cache
+
+ @req = WEBrick::HTTPRequest.new :Logger => nil
+ @res = WEBrick::HTTPResponse.new :HTTPVersion => '1.0'
+
+ def @req.path= path
+ instance_variable_set :@path, path
+ end
+
+ @req.instance_variable_set :@header, Hash.new { |h, k| h[k] = [] }
+
+ @base = File.join @tempdir, 'base'
+ @system_dir = File.join @tempdir, 'base', 'system'
+
+ @orig_base = RDoc::RI::Paths::BASE
+ RDoc::RI::Paths::BASE.replace @base
+ @orig_ri_path_homedir = RDoc::RI::Paths::HOMEDIR
+ RDoc::RI::Paths::HOMEDIR.replace File.join @tempdir, 'home'
+
+ RDoc::RI::Paths.instance_variable_set \
+ :@gemdirs, %w[/nonexistent/gems/example-1.0/ri]
+ end
+
+ def teardown
+ super
+
+ Gem.use_paths(*@orig_gem_path)
+ Gem::Specification.reset
+
+ FileUtils.rm_rf @tempdir
+
+ RDoc::RI::Paths::BASE.replace @orig_base
+ RDoc::RI::Paths::HOMEDIR.replace @orig_ri_path_homedir
+ RDoc::RI::Paths.instance_variable_set :@gemdirs, nil
+ end
+
+ def test_asset
+ temp_dir do
+ now = Time.now
+
+ open 'rdoc.css', 'w' do |io| io.write 'h1 { color: red }' end
+ File.utime now, now, 'rdoc.css'
+
+ @s.asset_dirs[:darkfish] = '.'
+
+ @req.path = 'rdoc.css'
+
+ @s.asset :darkfish, @req, @res
+
+ assert_equal 'h1 { color: red }', @res.body
+ assert_equal 'text/css', @res.content_type
+ assert_equal now.httpdate, @res['last-modified']
+ end
+ end
+
+ def test_do_GET
+ touch_system_cache_path
+
+ @req.path = '/ruby/Missing.html'
+
+ @s.do_GET @req, @res
+
+ assert_equal 404, @res.status
+ end
+
+ def test_do_GET_asset_darkfish
+ temp_dir do
+ FileUtils.touch 'rdoc.css'
+
+ @s.asset_dirs[:darkfish] = '.'
+
+ @req.path = '/rdoc.css'
+
+ @s.do_GET @req, @res
+
+ assert_equal 'text/css', @res.content_type
+ end
+ end
+
+ def test_do_GET_asset_json_index
+ temp_dir do
+ FileUtils.mkdir 'js'
+ FileUtils.touch 'js/navigation.js'
+
+ @s.asset_dirs[:json_index] = '.'
+
+ @req.path = '/js/navigation.js'
+
+ @s.do_GET @req, @res
+
+ assert_equal 'application/javascript', @res.content_type
+ end
+ end
+
+ def test_do_GET_error
+ touch_system_cache_path
+
+ def @req.path() raise 'no' end
+
+ @s.do_GET @req, @res
+
+ assert_equal 500, @res.status
+ end
+
+ def test_do_GET_not_modified
+ touch_system_cache_path
+ @req.header['if-modified-since'] = [(Time.now + 10).httpdate]
+ @req.path = '/ruby/Missing.html'
+
+ assert_raises WEBrick::HTTPStatus::NotModified do
+ @s.do_GET @req, @res
+ end
+ end
+
+ def test_do_GET_root
+ touch_system_cache_path
+
+ @req.path = '/'
+
+ @s.do_GET @req, @res
+
+ assert_equal 'text/html', @res.content_type
+ assert_match %r%<title>Local RDoc Documentation</title>%, @res.body
+ end
+
+ def test_do_GET_root_search
+ touch_system_cache_path
+
+ @req.path = '/js/search_index.js'
+
+ @s.do_GET @req, @res
+
+ assert_equal 'application/javascript', @res.content_type
+ end
+
+ def test_documentation_page_class
+ store = RDoc::Store.new
+
+ generator = @s.generator_for store
+
+ file = store.add_file 'file.rb'
+ klass = file.add_class RDoc::NormalClass, 'Klass'
+ klass.add_class RDoc::NormalClass, 'Sub'
+
+ @s.documentation_page store, generator, 'Klass::Sub.html', @req, @res
+
+ assert_match %r%<title>class Klass::Sub - </title>%, @res.body
+ assert_match %r%<body id="top" class="class">%, @res.body
+ end
+
+ def test_documentation_page_not_found
+ store = RDoc::Store.new
+
+ generator = @s.generator_for store
+
+ @req.path = '/ruby/Missing.html'
+
+ @s.documentation_page store, generator, 'Missing.html', @req, @res
+
+ assert_equal 404, @res.status
+ end
+
+ def test_documentation_page_page
+ store = RDoc::Store.new
+
+ generator = @s.generator_for store
+
+ readme = store.add_file 'README.rdoc'
+ readme.parser = RDoc::Parser::Simple
+
+ @s.documentation_page store, generator, 'README_rdoc.html', @req, @res
+
+ assert_match %r%<title>README - </title>%, @res.body
+ assert_match %r%<body class="file">%, @res.body
+ end
+
+ def test_documentation_source
+ store, path = @s.documentation_source '/ruby/Object.html'
+
+ assert_equal @system_dir, store.path
+
+ assert_equal 'Object.html', path
+ end
+
+ def test_documentation_source_cached
+ cached_store = RDoc::Store.new
+
+ @stores['ruby'] = cached_store
+
+ store, path = @s.documentation_source '/ruby/Object.html'
+
+ assert_same cached_store, store
+
+ assert_equal 'Object.html', path
+ end
+
+ def test_error
+ e = RuntimeError.new 'foo'
+ e.set_backtrace caller
+
+ @s.error e, @req, @res
+
+ assert_equal 'text/html', @res.content_type
+ assert_equal 500, @res.status
+ assert_match %r%<title>Error%, @res.body
+ end
+
+ def test_generator_for
+ store = RDoc::Store.new
+ store.main = 'MAIN_PAGE.rdoc'
+ store.title = 'Title'
+
+ generator = @s.generator_for store
+
+ refute generator.file_output
+
+ assert_equal '..', generator.asset_rel_path
+
+ assert_equal 'MAIN_PAGE.rdoc', @s.options.main_page
+ assert_equal 'Title', @s.options.title
+
+ assert_kind_of RDoc::RDoc, store.rdoc
+ assert_same generator, store.rdoc.generator
+ end
+
+ def test_if_modified_since
+ temp_dir do
+ now = Time.now
+ File.utime now, now, '.'
+
+ @s.if_modified_since @req, @res, '.'
+
+ assert_equal now.to_i, Time.parse(@res['last-modified']).to_i
+ end
+ end
+
+ def test_if_modified_since_not_modified
+ temp_dir do
+ now = Time.now
+ File.utime now, now, '.'
+
+ @req.header['if-modified-since'] = [(now + 10).httpdate]
+
+ assert_raises WEBrick::HTTPStatus::NotModified do
+ @s.if_modified_since @req, @res, '.'
+ end
+
+ assert_equal now.to_i, Time.parse(@res['last-modified']).to_i
+ end
+ end
+
+ def test_installed_docs
+ touch_system_cache_path
+
+ expected = [
+ ['Ruby Documentation', 'ruby/', true, :system,
+ @system_dir],
+ ['Site Documentation', 'site/', false, :site,
+ File.join(@base, 'site')],
+ ['Home Documentation', 'home/', false, :home,
+ RDoc::RI::Paths::HOMEDIR],
+ ['spec-1.0', 'spec-1.0/', false, :gem,
+ File.join(@spec.doc_dir, 'ri')],
+ ]
+
+ assert_equal expected, @s.installed_docs
+ end
+
+ def test_not_found
+ generator = @s.generator_for RDoc::Store.new
+
+ @req.path = '/ruby/Missing.html'
+
+ @s.not_found generator, @req, @res
+
+ assert_equal 404, @res.status
+ assert_match %r%<title>Not Found</title>%, @res.body
+ assert_match %r%<kbd>/ruby/Missing\.html</kbd>%, @res.body
+ end
+
+ def test_ri_paths
+ paths = @s.ri_paths
+
+ expected = [
+ [@system_dir, :system],
+ [File.join(@base, 'site'), :site],
+ [RDoc::RI::Paths::HOMEDIR, :home],
+ [File.join(@spec.doc_dir, 'ri'), :gem],
+ ]
+
+ assert_equal expected, paths.to_a
+ end
+
+ def test_root
+ @s.root @req, @res
+
+ assert_equal 'text/html', @res.content_type
+ assert_match %r%<title>Local RDoc Documentation</title>%, @res.body
+ end
+
+ def test_root_search
+ touch_system_cache_path
+
+ @s.root_search @req, @res
+
+ assert_equal 'application/javascript', @res.content_type
+
+ @res.body =~ /\{.*\}/
+
+ index = JSON.parse $&
+
+ expected = {
+ 'index' => {
+ 'searchIndex' => %w[
+ Ruby\ Documentation
+ ],
+ 'longSearchIndex' => %w[
+ Ruby\ Documentation
+ ],
+ 'info' => [
+ ['Ruby Documentation', '', @system_dir, '',
+ 'Documentation for the Ruby standard library'],
+ ],
+ }
+ }
+
+ assert_equal expected, index
+ end
+
+ def test_show_documentation_index
+ touch_system_cache_path
+
+ @req.path = '/ruby'
+
+ @s.show_documentation @req, @res
+
+ assert_equal 'text/html', @res.content_type
+ assert_match %r%<title>Standard Library Documentation%, @res.body
+ end
+
+ def test_show_documentation_table_of_contents
+ touch_system_cache_path
+
+ @req.path = '/ruby/table_of_contents.html'
+
+ @s.show_documentation @req, @res
+
+ assert_equal 'text/html', @res.content_type
+ assert_match %r%<title>Table of Contents - Standard Library Documentation%,
+ @res.body
+ end
+
+ def test_show_documentation_page
+ touch_system_cache_path
+
+ @req.path = '/ruby/Missing.html'
+
+ @s.show_documentation @req, @res
+
+ assert_equal 404, @res.status
+ end
+
+ def test_show_documentation_search_index
+ touch_system_cache_path
+
+ @req.path = '/ruby/js/search_index.js'
+
+ @s.show_documentation @req, @res
+
+ assert_equal 'application/javascript', @res.content_type
+ assert_match %r%\Avar search_data =%, @res.body
+ end
+
+ def touch_system_cache_path
+ store = RDoc::Store.new @system_dir
+ store.title = 'Standard Library Documentation'
+
+ FileUtils.mkdir_p File.dirname store.cache_path
+
+ store.save
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_stats.rb b/test/rdoc/test_rdoc_stats.rb
index 0bf08334da..5073e53b7e 100644
--- a/test/rdoc/test_rdoc_stats.rb
+++ b/test/rdoc/test_rdoc_stats.rb
@@ -1,29 +1,46 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/stats'
-require 'rdoc/code_objects'
-require 'rdoc/markup'
-require 'rdoc/parser'
+require 'rdoc/test_case'
-class TestRDocStats < MiniTest::Unit::TestCase
+class TestRDocStats < RDoc::TestCase
def setup
- RDoc::TopLevel.reset
+ super
- @s = RDoc::Stats.new 0
+ @s = RDoc::Stats.new @store, 0
+
+ @tl = @store.add_file 'file.rb'
+ @tl.parser = RDoc::Parser::Ruby
+ end
+
+ def test_doc_stats
+ c = RDoc::CodeObject.new
+
+ assert_equal [1, 1], @s.doc_stats([c])
+ end
+
+ def test_doc_stats_documented
+ c = RDoc::CodeObject.new
+ c.comment = comment 'x'
+
+ assert_equal [1, 0], @s.doc_stats([c])
+ end
+
+ def test_doc_stats_display_eh
+ c = RDoc::CodeObject.new
+ c.ignore
+
+ assert_equal [0, 0], @s.doc_stats([c])
end
def test_report_attr
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
a = RDoc::Attr.new nil, 'a', 'RW', nil
- a.record_location tl
+ a.record_location @tl
c.add_attribute a
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -40,33 +57,46 @@ end
end
def test_report_attr_documented
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
a = RDoc::Attr.new nil, 'a', 'RW', 'a'
- a.record_location tl
+ a.record_location @tl
c.add_attribute a
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
assert_equal @s.great_job, report
end
+ def test_report_attr_line
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
+
+ a = RDoc::Attr.new nil, 'a', 'RW', nil
+ a.record_location @tl
+ a.line = 3
+ c.add_attribute a
+
+ @store.complete :public
+
+ assert_match '# in file file.rb:3', @s.report
+ end
+
def test_report_constant
- tl = RDoc::TopLevel.new 'file.rb'
- m = tl.add_module RDoc::NormalModule, 'M'
- m.record_location tl
- m.add_comment 'M', tl
+ m = @tl.add_module RDoc::NormalModule, 'M'
+ m.record_location @tl
+ m.add_comment 'M', @tl
c = RDoc::Constant.new 'C', nil, nil
- c.record_location tl
+ c.record_location @tl
m.add_constant c
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -84,18 +114,17 @@ end
end
def test_report_constant_alias
- tl = RDoc::TopLevel.new 'file.rb'
- mod = tl.add_module RDoc::NormalModule, 'M'
+ mod = @tl.add_module RDoc::NormalModule, 'M'
- c = tl.add_class RDoc::NormalClass, 'C'
+ c = @tl.add_class RDoc::NormalClass, 'C'
mod.add_constant c
ca = RDoc::Constant.new 'CA', nil, nil
ca.is_alias_for = c
- tl.add_constant ca
+ @tl.add_constant ca
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -105,33 +134,46 @@ end
end
def test_report_constant_documented
- tl = RDoc::TopLevel.new 'file.rb'
- m = tl.add_module RDoc::NormalModule, 'M'
- m.record_location tl
+ m = @tl.add_module RDoc::NormalModule, 'M'
+ m.record_location @tl
m.comment = 'M'
c = RDoc::Constant.new 'C', nil, 'C'
- c.record_location tl
+ c.record_location @tl
m.add_constant c
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
assert_equal @s.great_job, report
end
+ def test_report_constant_line
+ m = @tl.add_module RDoc::NormalModule, 'M'
+ m.record_location @tl
+ m.add_comment 'M', @tl
+
+ c = RDoc::Constant.new 'C', nil, nil
+ c.record_location @tl
+ c.line = 5
+ m.add_constant c
+
+ @store.complete :public
+
+ assert_match '# in file file.rb:5', @s.report
+ end
+
def test_report_class
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
m = RDoc::AnyMethod.new nil, 'm'
- m.record_location tl
+ m.record_location @tl
c.add_method m
m.comment = 'm'
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -148,18 +190,31 @@ end
assert_equal expected, report
end
+ def test_report_skip_object
+ c = @tl.add_class RDoc::NormalClass, 'Object'
+ c.record_location @tl
+
+ m = RDoc::AnyMethod.new nil, 'm'
+ m.record_location @tl
+ c.add_method m
+ m.comment = 'm'
+
+ @store.complete :public
+
+ refute_match %r%^class Object$%, @s.report
+ end
+
def test_report_class_documented
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
m = RDoc::AnyMethod.new nil, 'm'
- m.record_location tl
+ m.record_location @tl
c.add_method m
m.comment = 'm'
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -167,25 +222,24 @@ end
end
def test_report_class_documented_level_1
- tl = RDoc::TopLevel.new 'file.rb'
- c1 = tl.add_class RDoc::NormalClass, 'C1'
- c1.record_location tl
- c1.add_comment 'C1', tl
+ c1 = @tl.add_class RDoc::NormalClass, 'C1'
+ c1.record_location @tl
+ c1.add_comment 'C1', @tl
m1 = RDoc::AnyMethod.new nil, 'm1'
- m1.record_location tl
+ m1.record_location @tl
c1.add_method m1
m1.comment = 'm1'
- c2 = tl.add_class RDoc::NormalClass, 'C2'
- c2.record_location tl
+ c2 = @tl.add_class RDoc::NormalClass, 'C2'
+ c2.record_location @tl
m2 = RDoc::AnyMethod.new nil, 'm2'
- m2.record_location tl
+ m2.record_location @tl
c2.add_method m2
m2.comment = 'm2'
- RDoc::TopLevel.complete :public
+ @store.complete :public
@s.coverage_level = 1
@@ -206,10 +260,9 @@ end
end
def test_report_class_empty
- tl = RDoc::TopLevel.new 'file.rb'
- tl.add_class RDoc::NormalClass, 'C'
+ @tl.add_class RDoc::NormalClass, 'C'
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -225,15 +278,14 @@ The following items are not documented:
end
def test_report_class_empty_2
- tl = RDoc::TopLevel.new 'file.rb'
- c1 = tl.add_class RDoc::NormalClass, 'C1'
- c1.record_location tl
+ c1 = @tl.add_class RDoc::NormalClass, 'C1'
+ c1.record_location @tl
- c2 = tl.add_class RDoc::NormalClass, 'C2'
- c2.record_location tl
- c2.add_comment 'C2', tl
+ c2 = @tl.add_class RDoc::NormalClass, 'C2'
+ c2.record_location @tl
+ c2.add_comment 'C2', @tl
- RDoc::TopLevel.complete :public
+ @store.complete :public
@s.coverage_level = 1
report = @s.report
@@ -253,16 +305,15 @@ end
end
def test_report_class_method_documented
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
m = RDoc::AnyMethod.new nil, 'm'
- m.record_location tl
+ m.record_location @tl
c.add_method m
m.comment = 'm'
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -279,8 +330,19 @@ end
assert_equal expected, report
end
+ def test_report_class_module_ignore
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.ignore
+
+ @store.complete :public
+
+ report = @s.report_class_module c
+
+ assert_nil report
+ end
+
def test_report_empty
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -288,21 +350,20 @@ end
end
def test_report_method
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
m1 = RDoc::AnyMethod.new nil, 'm1'
- m1.record_location tl
+ m1.record_location @tl
c.add_method m1
m2 = RDoc::AnyMethod.new nil, 'm2'
- m2.record_location tl
+ m2.record_location @tl
c.add_method m2
m2.comment = 'm2'
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
@@ -320,42 +381,89 @@ end
assert_equal expected, report
end
+ def test_report_method_class
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
+
+ m1 = RDoc::AnyMethod.new nil, 'm1'
+ m1.record_location @tl
+ m1.singleton = true
+ c.add_method m1
+
+ m2 = RDoc::AnyMethod.new nil, 'm2'
+ m2.record_location @tl
+ m2.singleton = true
+ c.add_method m2
+ m2.comment = 'm2'
+
+ @store.complete :public
+
+ report = @s.report
+
+ expected = <<-EXPECTED
+The following items are not documented:
+
+class C # is documented
+
+ # in file file.rb
+ def self.m1; end
+
+end
+ EXPECTED
+
+ assert_equal expected, report
+ end
+
def test_report_method_documented
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
m = RDoc::AnyMethod.new nil, 'm'
- m.record_location tl
+ m.record_location @tl
c.add_method m
m.comment = 'm'
- RDoc::TopLevel.complete :public
+ @store.complete :public
report = @s.report
assert_equal @s.great_job, report
end
+ def test_report_method_line
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
+
+ m1 = RDoc::AnyMethod.new nil, 'm1'
+ m1.record_location @tl
+ m1.line = 4
+ c.add_method m1
+
+ @store.complete :public
+
+ assert_match '# in file file.rb:4', @s.report
+ end
+
def test_report_method_parameters
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
m1 = RDoc::AnyMethod.new nil, 'm1'
- m1.record_location tl
+ m1.record_location @tl
m1.params = '(p1, p2)'
m1.comment = 'Stuff with +p1+'
c.add_method m1
m2 = RDoc::AnyMethod.new nil, 'm2'
- m2.record_location tl
+ m2.record_location @tl
c.add_method m2
m2.comment = 'm2'
- RDoc::TopLevel.complete :public
+ @store.complete :public
@s.coverage_level = 1
report = @s.report
@@ -376,18 +484,18 @@ end
end
def test_report_method_parameters_documented
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ @tl.parser = RDoc::Parser::Ruby
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
m = RDoc::AnyMethod.new nil, 'm'
- m.record_location tl
+ m.record_location @tl
m.params = '(p1)'
m.comment = 'Stuff with +p1+'
c.add_method m
- RDoc::TopLevel.complete :public
+ @store.complete :public
@s.coverage_level = 1
report = @s.report
@@ -396,13 +504,12 @@ end
end
def test_report_method_parameters_yield
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
m = RDoc::AnyMethod.new nil, 'm'
- m.record_location tl
+ m.record_location @tl
m.call_seq = <<-SEQ
m(a) { |c| ... }
m(a, b) { |c, d| ... }
@@ -410,7 +517,7 @@ m(a, b) { |c, d| ... }
m.comment = 'Stuff with +a+, yields +c+ for you to do stuff with'
c.add_method m
- RDoc::TopLevel.complete :public
+ @store.complete :public
@s.coverage_level = 1
report = @s.report
@@ -431,26 +538,25 @@ end
end
def test_summary
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
- m = tl.add_module RDoc::NormalModule, 'M'
- m.record_location tl
+ m = @tl.add_module RDoc::NormalModule, 'M'
+ m.record_location @tl
a = RDoc::Attr.new nil, 'a', 'RW', nil
- a.record_location tl
+ a.record_location @tl
c.add_attribute a
c_c = RDoc::Constant.new 'C', nil, nil
- c_c.record_location tl
+ c_c.record_location @tl
c.add_constant c_c
m = RDoc::AnyMethod.new nil, 'm'
- m.record_location tl
+ m.record_location @tl
c.add_method m
- RDoc::TopLevel.complete :public
+ @store.complete :public
summary = @s.summary
summary.sub!(/Elapsed:.*/, '')
@@ -473,11 +579,10 @@ Total: 5 (5 undocumented)
end
def test_summary_level_false
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
- RDoc::TopLevel.complete :public
+ @store.complete :public
@s.coverage_level = false
@@ -502,18 +607,17 @@ Total: 1 (1 undocumented)
end
def test_summary_level_1
- tl = RDoc::TopLevel.new 'file.rb'
- c = tl.add_class RDoc::NormalClass, 'C'
- c.record_location tl
- c.add_comment 'C', tl
+ c = @tl.add_class RDoc::NormalClass, 'C'
+ c.record_location @tl
+ c.add_comment 'C', @tl
m = RDoc::AnyMethod.new nil, 'm'
- m.record_location tl
+ m.record_location @tl
m.params = '(p1, p2)'
m.comment = 'Stuff with +p1+'
c.add_method m
- RDoc::TopLevel.complete :public
+ @store.complete :public
@s.coverage_level = 1
@s.report
diff --git a/test/rdoc/test_rdoc_ri_store.rb b/test/rdoc/test_rdoc_store.rb
index 23e441b633..1b87ca6036 100644
--- a/test/rdoc/test_rdoc_ri_store.rb
+++ b/test/rdoc/test_rdoc_store.rb
@@ -1,23 +1,20 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/rdoc'
-require 'rdoc/ri'
-require 'rdoc/markup'
-require 'tmpdir'
-require 'fileutils'
-require 'pp'
+require File.expand_path '../xref_test_case', __FILE__
-class TestRDocRIStore < MiniTest::Unit::TestCase
+class TestRDocStore < XrefTestCase
OBJECT_ANCESTORS = defined?(::BasicObject) ? %w[BasicObject] : []
def setup
- RDoc::TopLevel.reset
+ super
@tmpdir = File.join Dir.tmpdir, "test_rdoc_ri_store_#{$$}"
@s = RDoc::RI::Store.new @tmpdir
- @top_level = RDoc::TopLevel.new 'file.rb'
+ @top_level = @s.add_file 'file.rb'
+
+ @page = @s.add_file 'README.txt'
+ @page.parser = RDoc::Parser::Simple
+ @page.comment = RDoc::Comment.new 'This is a page', @page
@klass = @top_level.add_class RDoc::NormalClass, 'Object'
@klass.add_comment 'original', @top_level
@@ -26,14 +23,27 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
@cmeth.singleton = true
@cmeth.record_location @top_level
+ @meth_comment = RDoc::Comment.new 'method comment'
+ @meth_comment.location = @top_level
+
@meth = RDoc::AnyMethod.new nil, 'method'
@meth.record_location @top_level
+ @meth.comment = @meth_comment
@meth_bang = RDoc::AnyMethod.new nil, 'method!'
@meth_bang.record_location @top_level
+ @meth_bang_alias = RDoc::Alias.new nil, 'method!', 'method_bang', ''
+ @meth_bang_alias.record_location @top_level
+
+ @meth_bang.add_alias @meth_bang_alias, @klass
+
+ @attr_comment = RDoc::Comment.new 'attribute comment'
+ @attr_comment.location = @top_level
+
@attr = RDoc::Attr.new nil, 'attr', 'RW', ''
@attr.record_location @top_level
+ @attr.comment = @attr_comment
@klass.add_method @cmeth
@klass.add_method @meth
@@ -50,10 +60,13 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
@nest_klass.add_method @nest_meth
@nest_klass.add_include @nest_incl
- @RM = RDoc::Markup
+ @mod = @top_level.add_module RDoc::NormalModule, 'Mod'
+ @mod.record_location @top_level
end
def teardown
+ super
+
FileUtils.rm_rf @tmpdir
end
@@ -64,8 +77,9 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
s.chomp
end
- def assert_cache imethods, cmethods, attrs, modules, ancestors = {}
- imethods ||= { 'Object' => %w[method method!] }
+ def assert_cache imethods, cmethods, attrs, modules,
+ ancestors = {}, pages = [], main = nil, title = nil
+ imethods ||= { 'Object' => %w[method method! method_bang] }
cmethods ||= { 'Object' => %w[cmethod] }
attrs ||= { 'Object' => ['attr_accessor attr'] }
@@ -79,6 +93,9 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
:encoding => nil,
:instance_methods => imethods,
:modules => modules,
+ :pages => pages,
+ :main => main,
+ :title => title,
}
@s.save_cache
@@ -98,6 +115,40 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
refute File.exist?(path), "#{path} exists"
end
+ def test_add_file
+ top_level = @store.add_file 'file.rb'
+
+ assert_kind_of RDoc::TopLevel, top_level
+ assert_equal @store, top_level.store
+ assert_equal 'file.rb', top_level.name
+ assert_includes @store.all_files, top_level
+
+ assert_same top_level, @store.add_file('file.rb')
+ refute_same top_level, @store.add_file('other.rb')
+ end
+
+ def test_all_classes_and_modules
+ expected = %w[
+ C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1
+ Child
+ M1 M1::M2
+ Parent
+ ]
+
+ assert_equal expected,
+ @store.all_classes_and_modules.map { |m| m.full_name }.sort
+ end
+
+ def test_all_files
+ assert_equal %w[xref_data.rb],
+ @store.all_files.map { |m| m.full_name }.sort
+ end
+
+ def test_all_modules
+ assert_equal %w[M1 M1::M2],
+ @store.all_modules.map { |m| m.full_name }.sort
+ end
+
def test_attributes
@s.cache[:attributes]['Object'] = %w[attr]
@@ -127,12 +178,63 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
@s.class_path('Object::SubClass')
end
- def test_dry_run
- refute @s.dry_run
+ def test_classes
+ expected = %w[
+ C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1
+ Child
+ Parent
+ ]
- @s.dry_run = true
+ assert_equal expected, @store.all_classes.map { |m| m.full_name }.sort
+ end
- assert @s.dry_run
+ def test_complete
+ @c2.add_module_alias @c2_c3, 'A1', @top_level
+
+ @store.complete :public
+
+ a1 = @xref_data.find_class_or_module 'C2::A1'
+
+ assert_equal 'C2::A1', a1.full_name
+ refute_empty a1.aliases
+ end
+
+ def test_find_class_named
+ assert_equal @c1, @store.find_class_named('C1')
+
+ assert_equal @c2_c3, @store.find_class_named('C2::C3')
+ end
+
+ def test_find_class_named_from
+ assert_equal @c5_c1, @store.find_class_named_from('C1', 'C5')
+
+ assert_equal @c1, @store.find_class_named_from('C1', 'C4')
+ end
+
+ def test_find_class_or_module
+ assert_equal @m1, @store.find_class_or_module('M1')
+ assert_equal @c1, @store.find_class_or_module('C1')
+
+ assert_equal @m1, @store.find_class_or_module('::M1')
+ assert_equal @c1, @store.find_class_or_module('::C1')
+ end
+
+ def test_find_file_named
+ assert_equal @xref_data, @store.find_file_named(@file_name)
+ end
+
+ def test_find_module_named
+ assert_equal @m1, @store.find_module_named('M1')
+ assert_equal @m1_m2, @store.find_module_named('M1::M2')
+ end
+
+ def test_find_text_page
+ page = @store.add_file 'PAGE.txt'
+ page.parser = RDoc::Parser::Simple
+
+ assert_nil @store.find_text_page 'no such page'
+
+ assert_equal page, @store.find_text_page('PAGE.txt')
end
def test_friendly_path
@@ -150,13 +252,21 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
assert_equal "ruby site", @s.friendly_path
@s.type = :home
- assert_equal "~/.ri", @s.friendly_path
+ assert_equal "~/.rdoc", @s.friendly_path
@s.type = :gem
@s.path = "#{@tmpdir}/gem_repository/doc/gem_name-1.0/ri"
assert_equal "gem gem_name-1.0", @s.friendly_path
end
+ def test_dry_run
+ refute @s.dry_run
+
+ @s.dry_run = true
+
+ assert @s.dry_run
+ end
+
def test_instance_methods
@s.cache[:instance_methods]['Object'] = %w[method]
@@ -165,11 +275,50 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
assert_equal expected, @s.instance_methods
end
+ def test_load_all
+ FileUtils.mkdir_p @tmpdir
+
+ @s.save
+
+ s = RDoc::Store.new @tmpdir
+
+ s.load_all
+
+ assert_equal [@klass, @nest_klass], s.all_classes.sort
+ assert_equal [@mod], s.all_modules.sort
+ assert_equal [@page, @top_level], s.all_files.sort
+
+ methods = s.all_classes_and_modules.map do |mod|
+ mod.method_list
+ end.flatten.sort
+
+ _meth_bang_alias = RDoc::AnyMethod.new nil, 'method_bang'
+ _meth_bang_alias.parent = @klass
+
+ assert_equal [@meth, @meth_bang, _meth_bang_alias, @nest_meth, @cmeth],
+ methods.sort_by { |m| m.full_name }
+
+ method = methods.find { |m| m == @meth }
+ assert_equal @meth_comment.parse, method.comment
+
+ assert_equal @klass, methods.last.parent
+
+ attributes = s.all_classes_and_modules.map do |mod|
+ mod.attributes
+ end.flatten.sort
+
+ assert_equal [@attr], attributes
+
+ assert_equal @attr_comment.parse, attributes.first.comment
+ end
+
def test_load_cache
cache = {
:encoding => :encoding_value,
- :methods => %w[Object#method],
+ :methods => { "Object" => %w[Object#method] },
+ :main => @page.full_name,
:modules => %w[Object],
+ :pages => [],
}
Dir.mkdir @tmpdir
@@ -183,6 +332,7 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
assert_equal cache, @s.cache
assert_equal :encoding_value, @s.encoding
+ assert_equal 'README.txt', @s.main
end
def test_load_cache_encoding_differs
@@ -190,8 +340,10 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
cache = {
:encoding => Encoding::ISO_8859_1,
- :methods => %w[Object#method],
+ :main => nil,
+ :methods => { "Object" => %w[Object#method] },
:modules => %w[Object],
+ :pages => [],
}
Dir.mkdir @tmpdir
@@ -216,7 +368,10 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
:class_methods => {},
:encoding => nil,
:instance_methods => {},
+ :main => nil,
:modules => [],
+ :pages => [],
+ :title => nil,
}
@s.load_cache
@@ -224,17 +379,96 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
assert_equal cache, @s.cache
end
+ def test_load_cache_legacy
+ cache = {
+ :ancestors => {},
+ :attributes => {},
+ :class_methods => {},
+ :encoding => :encoding_value,
+ :instance_methods => { "Object" => %w[Object#method] },
+ :modules => %w[Object],
+ # no :pages
+ # no :main
+ }
+
+ Dir.mkdir @tmpdir
+
+ open File.join(@tmpdir, 'cache.ri'), 'wb' do |io|
+ Marshal.dump cache, io
+ end
+
+ @s.load_cache
+
+ expected = {
+ :ancestors => {},
+ :attributes => {},
+ :class_methods => {},
+ :encoding => :encoding_value,
+ :instance_methods => { "Object" => %w[Object#method] },
+ :main => nil,
+ :modules => %w[Object],
+ :pages => [],
+ }
+
+ assert_equal expected, @s.cache
+
+ assert_equal :encoding_value, @s.encoding
+ assert_nil @s.main
+ end
+
def test_load_class
@s.save_class @klass
+ @s.classes_hash.clear
assert_equal @klass, @s.load_class('Object')
+
+ assert_includes @s.classes_hash, 'Object'
end
- def test_load_method_bang
+ def test_load_method
@s.save_method @klass, @meth_bang
meth = @s.load_method('Object', '#method!')
assert_equal @meth_bang, meth
+ assert_equal @klass, meth.parent
+ assert_equal @s, meth.store
+ end
+
+ def test_load_method_legacy
+ @s.save_method @klass, @meth
+
+ file = @s.method_file @klass.full_name, @meth.full_name
+
+ open file, 'wb' do |io|
+ io.write "\x04\bU:\x14RDoc::AnyMethod[\x0Fi\x00I" +
+ "\"\vmethod\x06:\x06EF\"\x11Klass#method0:\vpublic" +
+ "o:\eRDoc::Markup::Document\x06:\v@parts[\x06" +
+ "o:\x1CRDoc::Markup::Paragraph\x06;\t[\x06I" +
+ "\"\x16this is a comment\x06;\x06FI" +
+ "\"\rcall_seq\x06;\x06FI\"\x0Fsome_block\x06;\x06F" +
+ "[\x06[\aI\"\faliased\x06;\x06Fo;\b\x06;\t[\x06" +
+ "o;\n\x06;\t[\x06I\"\x12alias comment\x06;\x06FI" +
+ "\"\nparam\x06;\x06F"
+ end
+
+ meth = @s.load_method('Object', '#method')
+ assert_equal 'Klass#method', meth.full_name
+ assert_equal @klass, meth.parent
+ assert_equal @s, meth.store
+ end
+
+ def test_load_page
+ @s.save_page @page
+
+ assert_equal @page, @s.load_page('README.txt')
+ end
+
+ def test_main
+ assert_equal nil, @s.main
+
+ @s.main = 'README.txt'
+
+ assert_equal 'README.txt', @s.main
end
def test_method_file
@@ -251,29 +485,89 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
@s.method_file('Object', 'Object::method')
end
+ def test_module_names
+ @s.save_class @klass
+
+ assert_equal %w[Object], @s.module_names
+ end
+
+ def test_page
+ page = @store.add_file 'PAGE.txt'
+ page.parser = RDoc::Parser::Simple
+
+ assert_nil @store.page 'no such page'
+
+ assert_equal page, @store.page('PAGE')
+ end
+
+ def test_save
+ FileUtils.mkdir_p @tmpdir
+
+ @s.save
+
+ assert_directory File.join(@tmpdir, 'Object')
+
+ assert_file File.join(@tmpdir, 'Object', 'cdesc-Object.ri')
+ assert_file File.join(@tmpdir, 'Object', 'method-i.ri')
+ assert_file File.join(@tmpdir, 'page-README_txt.ri')
+
+ assert_file File.join(@tmpdir, 'cache.ri')
+
+ expected = {
+ :ancestors => {
+ 'Object::SubClass' => %w[Incl Object],
+ },
+ :attributes => { 'Object' => ['attr_accessor attr'] },
+ :class_methods => { 'Object' => %w[cmethod] },
+ :instance_methods => {
+ 'Object' => %w[attr method method! method_bang],
+ 'Object::SubClass' => %w[method],
+ },
+ :main => nil,
+ :modules => %w[Mod Object Object::SubClass],
+ :encoding => nil,
+ :pages => %w[README.txt],
+ :title => nil,
+ }
+
+ expected[:ancestors]['Object'] = %w[BasicObject] if defined?(::BasicObject)
+
+ open File.join(@tmpdir, 'cache.ri'), 'rb' do |io|
+ cache = Marshal.load io.read
+
+ assert_equal expected, cache
+ end
+ end
+
def test_save_cache
@s.save_class @klass
@s.save_method @klass, @meth
@s.save_method @klass, @cmeth
@s.save_class @nest_klass
+ @s.save_page @page
@s.encoding = :encoding_value
+ @s.main = @page.full_name
+ @s.title = 'title'
@s.save_cache
assert_file File.join(@tmpdir, 'cache.ri')
expected = {
+ :ancestors => {
+ 'Object::SubClass' => %w[Incl Object],
+ },
:attributes => { 'Object' => ['attr_accessor attr'] },
:class_methods => { 'Object' => %w[cmethod] },
:instance_methods => {
- 'Object' => %w[method method!],
+ 'Object' => %w[method method! method_bang],
'Object::SubClass' => %w[method],
},
+ :main => @page.full_name,
:modules => %w[Object Object::SubClass],
- :ancestors => {
- 'Object::SubClass' => %w[Incl Object],
- },
:encoding => :encoding_value,
+ :pages => %w[README.txt],
+ :title => 'title',
}
expected[:ancestors]['Object'] = %w[BasicObject] if defined?(::BasicObject)
@@ -307,6 +601,15 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
assert_cache({ 'Object' => %w[method] }, {}, {}, [])
end
+ def test_save_cache_duplicate_pages
+ @s.save_page @page
+ @s.save_page @page
+
+ @s.save_cache
+
+ assert_cache({}, {}, {}, [], {}, %w[README.txt])
+ end
+
def test_save_class
@s.save_class @klass
@@ -386,7 +689,7 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
s = RDoc::RI::Store.new @tmpdir
inner = @RM::Document.new @RM::Paragraph.new 'new comment'
- inner.file = @top_level.absolute_name
+ inner.file = @top_level
document = @RM::Document.new inner
@@ -395,8 +698,10 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
# This is a functional test
def test_save_class_merge_constant
- tl = RDoc::TopLevel.new 'file.rb'
- klass = RDoc::NormalClass.new 'C'
+ store = RDoc::Store.new
+ tl = store.add_file 'file.rb'
+
+ klass = tl.add_class RDoc::NormalClass, 'C'
klass.add_comment 'comment', tl
const = klass.add_constant RDoc::Constant.new('CONST', nil, nil)
@@ -404,14 +709,16 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
@s.save_class klass
- RDoc::RDoc.reset
-
- klass2 = RDoc::NormalClass.new 'C'
+ # separate parse run, independent store
+ store = RDoc::Store.new
+ tl = store.add_file 'file.rb'
+ klass2 = tl.add_class RDoc::NormalClass, 'C'
klass2.record_location tl
s = RDoc::RI::Store.new @tmpdir
s.save_class klass2
+ # separate `ri` run, independent store
s = RDoc::RI::Store.new @tmpdir
result = s.load_class 'C'
@@ -469,5 +776,49 @@ class TestRDocRIStore < MiniTest::Unit::TestCase
assert_cache({ 'Object::SubClass' => %w[method] }, {}, {}, [])
end
+ def test_save_page
+ @s.save_page @page
+
+ assert_file File.join(@tmpdir, 'page-README_txt.ri')
+
+ assert_cache({}, {}, {}, [], {}, %w[README.txt])
+ end
+
+ def test_save_page_file
+ @s.save_page @top_level
+
+ refute_file File.join(@tmpdir, 'page-file_rb.ri')
+ end
+
+ def test_source
+ @s.path = @tmpdir
+ @s.type = nil
+ assert_equal @s.path, @s.source
+
+ @s.type = :extra
+ assert_equal @s.path, @s.source
+
+ @s.type = :system
+ assert_equal "ruby", @s.source
+
+ @s.type = :site
+ assert_equal "site", @s.source
+
+ @s.type = :home
+ assert_equal "home", @s.source
+
+ @s.type = :gem
+ @s.path = "#{@tmpdir}/gem_repository/doc/gem_name-1.0/ri"
+ assert_equal "gem_name-1.0", @s.source
+ end
+
+ def test_title
+ assert_equal nil, @s.title
+
+ @s.title = 'rdoc'
+
+ assert_equal 'rdoc', @s.title
+ end
+
end
diff --git a/test/rdoc/test_rdoc_task.rb b/test/rdoc/test_rdoc_task.rb
index c17a5c8b38..dce02bc9b7 100644
--- a/test/rdoc/test_rdoc_task.rb
+++ b/test/rdoc/test_rdoc_task.rb
@@ -1,10 +1,11 @@
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc/task'
+require 'rdoc/test_case'
+require 'rake'
-class TestRDocTask < MiniTest::Unit::TestCase
+class TestRDocTask < RDoc::TestCase
def setup
+ super
+
Rake::Task.clear
@t = RDoc::Task.new
@@ -32,6 +33,14 @@ class TestRDocTask < MiniTest::Unit::TestCase
end
end
+ def test_markup_option
+ rdoc_task = RDoc::Task.new do |rd|
+ rd.markup = "tomdoc"
+ end
+
+ assert_equal %w[-o html --markup tomdoc], rdoc_task.option_list
+ end
+
def test_tasks_creation
RDoc::Task.new
assert Rake::Task[:rdoc]
diff --git a/test/rdoc/test_rdoc_text.rb b/test/rdoc/test_rdoc_text.rb
index e11c995e59..47eb4de906 100644
--- a/test/rdoc/test_rdoc_text.rb
+++ b/test/rdoc/test_rdoc_text.rb
@@ -1,16 +1,26 @@
# coding: utf-8
-require 'rubygems'
-require 'minitest/autorun'
-require 'rdoc'
-require 'rdoc/text'
-require 'rdoc/markup'
-require 'rdoc/markup/formatter'
+require 'rdoc/test_case'
-class TestRDocText < MiniTest::Unit::TestCase
+class TestRDocText < RDoc::TestCase
include RDoc::Text
+ def setup
+ super
+
+ @options = RDoc::Options.new
+
+ @top_level = @store.add_file 'file.rb'
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
def test_self_encode_fallback
skip "Encoding not implemented" unless Object.const_defined? :Encoding
@@ -110,13 +120,19 @@ The comments associated with
assert_equal Encoding::US_ASCII, result.encoding
end
- def test_markup
- def formatter() RDoc::Markup::ToHtml.new end
+ def test_markup_string
+ out = markup('hi').gsub("\n", '')
- assert_equal "<p>hi</p>", markup('hi').gsub("\n", '')
+ assert_equal '<p>hi</p>', out
end
- def test_normalize_comment
+ def test_markup_comment
+ out = markup(comment('hi')).gsub("\n", '')
+
+ assert_equal '<p>hi</p>', out
+ end
+
+ def test_normalize_comment_hash
text = <<-TEXT
##
# we don't worry too much.
@@ -133,10 +149,57 @@ The comments associated with
assert_equal expected, normalize_comment(text)
end
+ def test_normalize_comment_stars_single_space
+ text = <<-TEXT
+/*
+ * we don't worry too much.
+ *
+ * The comments associated with
+ */
+ TEXT
+
+ expected = <<-EXPECTED.rstrip
+we don't worry too much.
+
+The comments associated with
+ EXPECTED
+
+ assert_equal expected, normalize_comment(text)
+ end
+
+ def test_normalize_comment_stars_single_double_space
+ text = <<-TEXT
+/*
+ * we don't worry too much.
+ *
+ * The comments associated with
+ */
+ TEXT
+
+ expected = <<-EXPECTED.rstrip
+we don't worry too much.
+
+The comments associated with
+ EXPECTED
+
+ assert_equal expected, normalize_comment(text)
+ end
+
def test_parse
assert_kind_of RDoc::Markup::Document, parse('hi')
end
+ def test_parse_comment
+ expected = RDoc::Markup::Document.new
+ expected.file = @top_level
+
+ c = comment ''
+ parsed = parse c
+
+ assert_equal expected, parsed
+ assert_same parsed, parse(c)
+ end
+
def test_parse_document
assert_equal RDoc::Markup::Document.new, parse(RDoc::Markup::Document.new)
end
@@ -149,10 +212,92 @@ The comments associated with
assert_equal RDoc::Markup::Document.new, parse("#\n")
end
+ def test_parse_format_markdown
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('it _works_'))
+
+ parsed = parse 'it *works*', 'markdown'
+
+ assert_equal expected, parsed
+ end
+
+ def test_parse_format_rd
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('it <em>works</em>'))
+
+ parsed = parse 'it ((*works*))', 'rd'
+
+ assert_equal expected, parsed
+ end
+
+ def test_parse_format_tomdoc
+ code = verb('1 + 1')
+ code.format = :ruby
+
+ expected =
+ doc(
+ para('It does a thing'),
+ blank_line,
+ head(3, 'Examples'),
+ blank_line,
+ code)
+
+ text = <<-TOMDOC
+It does a thing
+
+Examples
+
+ 1 + 1
+ TOMDOC
+
+ parsed = parse text, 'tomdoc'
+
+ assert_equal expected, parsed
+ end
+
def test_parse_newline
assert_equal RDoc::Markup::Document.new, parse("\n")
end
+# def test_snippet
+# text = <<-TEXT
+#This is one-hundred characters or more of text in a single paragraph. This
+#paragraph will be cut off some point after the one-hundredth character.
+# TEXT
+#
+# expected = text.gsub(/\r?\n/, ' ').sub(/ some point.*/, '')
+#
+# assert_equal expected, snippet(text)
+# end
+#
+# def test_snippet_comment
+# c = comment 'This is a comment'
+#
+# assert_equal 'This is a comment', snippet(c)
+# end
+#
+# def test_snippet_no_space
+# text = <<-TEXT.strip
+#This is one-hundred characters or more of text in a single paragraph. This
+#paragraph will not be cut
+# TEXT
+#
+# expected = <<-EXPECTED.strip.gsub(/\r?\n/, ' ')
+#This is one-hundred characters or more of text in a single paragraph. This
+#paragraph will not be cut
+# EXPECTED
+#
+# assert_equal expected, snippet(text)
+# end
+#
+# def test_snippet_short
+# text = 'This is a comment'
+#
+# assert_equal text.dup, snippet(text)
+# end
+
def test_strip_hashes
text = <<-TEXT
##
@@ -309,6 +454,24 @@ The comments associated with
assert_equal Encoding::BINARY, result.encoding
end
+ def test_strip_stars_no_stars
+ text = <<-TEXT
+* we don't worry too much.
+
+The comments associated with
+
+ TEXT
+
+ expected = <<-EXPECTED
+* we don't worry too much.
+
+The comments associated with
+
+ EXPECTED
+
+ assert_equal expected, strip_stars(text)
+ end
+
def test_to_html_apostrophe
assert_equal '‘a', to_html("'a")
assert_equal 'a’', to_html("a'")
@@ -320,6 +483,10 @@ The comments associated with
assert_equal 'S', to_html('\\S')
end
+ def test_to_html_br
+ assert_equal '<br>', to_html('<br>')
+ end
+
def test_to_html_copyright
assert_equal '©', to_html('(c)')
end
@@ -393,5 +560,9 @@ The comments associated with
assert_equal "mismatched <tt> tag\n", err
end
+ def formatter()
+ RDoc::Markup::ToHtml.new @options
+ end
+
end
diff --git a/test/rdoc/test_rdoc_token_stream.rb b/test/rdoc/test_rdoc_token_stream.rb
new file mode 100644
index 0000000000..3c1a225c25
--- /dev/null
+++ b/test/rdoc/test_rdoc_token_stream.rb
@@ -0,0 +1,42 @@
+require 'rdoc/test_case'
+
+class TestRDocTokenStream < RDoc::TestCase
+
+ def test_class_to_html
+ tokens = [
+ RDoc::RubyToken::TkCONSTANT. new(0, 0, 0, 'CONSTANT'),
+ RDoc::RubyToken::TkDEF. new(0, 0, 0, 'KW'),
+ RDoc::RubyToken::TkIVAR. new(0, 0, 0, 'IVAR'),
+ RDoc::RubyToken::TkOp. new(0, 0, 0, 'Op'),
+ RDoc::RubyToken::TkId. new(0, 0, 0, 'Id'),
+ RDoc::RubyToken::TkNode. new(0, 0, 0, 'Node'),
+ RDoc::RubyToken::TkCOMMENT. new(0, 0, 0, 'COMMENT'),
+ RDoc::RubyToken::TkREGEXP. new(0, 0, 0, 'REGEXP'),
+ RDoc::RubyToken::TkSTRING. new(0, 0, 0, 'STRING'),
+ RDoc::RubyToken::TkVal. new(0, 0, 0, 'Val'),
+ RDoc::RubyToken::TkBACKSLASH.new(0, 0, 0, '\\'),
+ ]
+
+ expected = [
+ '<span class="ruby-constant">CONSTANT</span>',
+ '<span class="ruby-keyword">KW</span>',
+ '<span class="ruby-ivar">IVAR</span>',
+ '<span class="ruby-operator">Op</span>',
+ '<span class="ruby-identifier">Id</span>',
+ '<span class="ruby-node">Node</span>',
+ '<span class="ruby-comment">COMMENT</span>',
+ '<span class="ruby-regexp">REGEXP</span>',
+ '<span class="ruby-string">STRING</span>',
+ '<span class="ruby-value">Val</span>',
+ '\\'
+ ].join
+
+ assert_equal expected, RDoc::TokenStream.to_html(tokens)
+ end
+
+ def test_class_to_html_empty
+ assert_equal '', RDoc::TokenStream.to_html([])
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_tom_doc.rb b/test/rdoc/test_rdoc_tom_doc.rb
new file mode 100644
index 0000000000..08f30d1e53
--- /dev/null
+++ b/test/rdoc/test_rdoc_tom_doc.rb
@@ -0,0 +1,455 @@
+require 'rdoc/test_case'
+
+class TestRDocTomDoc < RDoc::TestCase
+
+ def setup
+ super
+
+ @top_level = @store.add_file 'file.rb'
+
+ @TD = RDoc::TomDoc
+ @td = @TD.new
+ end
+
+ def mu_pp obj
+ s = ''
+ s = PP.pp obj, s
+ s = s.force_encoding Encoding.default_external if defined? Encoding
+ s.chomp
+ end
+
+ def test_class_add_post_processor
+ RDoc::TomDoc.add_post_processor
+
+ pp = RDoc::Markup::PreProcess.new __FILE__, []
+
+ text = "# Public: Do some stuff\n"
+
+ comment = RDoc::Comment.new text, nil
+ comment.format = 'tomdoc'
+
+ parent = RDoc::Context.new
+
+ pp.handle comment, parent
+
+ method = parent.add_method RDoc::AnyMethod.new(nil, 'm')
+
+ assert_equal 'Public', method.section.title
+ assert_equal "# Do some stuff\n", comment.text
+ end
+
+ def test_class_signature
+ c = comment <<-COMMENT
+Signature
+
+ method_<here>(args)
+
+here - something
+ COMMENT
+ c.format = 'tomdoc'
+
+ signature = @TD.signature c
+
+ assert_equal "method_<here>(args)\n", signature
+ end
+
+ def test_class_signature_no_space
+ c = comment <<-COMMENT
+Signature
+ method_<here>(args)
+
+here - something
+ COMMENT
+ c.format = 'tomdoc'
+
+ signature = @TD.signature c
+
+ assert_equal "method_<here>(args)\n", signature
+
+ expected =
+ doc(
+ head(3, 'Signature'),
+ list(:NOTE,
+ item(%w[here],
+ para('something'))))
+ expected.file = @top_level
+
+ assert_equal expected, c.parse
+ end
+
+ def test_class_signature_none
+ c = comment ''
+ c.format = 'tomdoc'
+
+ assert_nil @TD.signature c
+ end
+
+ def test_class_rdoc
+ c = comment <<-COMMENT
+=== Signature
+
+ method_<here>(args)
+
+here - something
+ COMMENT
+ c.format = 'rdoc'
+
+ signature = @TD.signature c
+
+ assert_nil signature
+ end
+
+ def test_class_signature_two_space
+ c = comment <<-COMMENT
+Signature
+
+
+ method_<here>(args)
+
+here - something
+ COMMENT
+ c.format = 'tomdoc'
+
+ signature = @TD.signature c
+
+ assert_equal "method_<here>(args)\n", signature
+
+ expected =
+ doc(
+ head(3, 'Signature'),
+ list(:NOTE,
+ item(%w[here],
+ para('something'))))
+ expected.file = @top_level
+
+ assert_equal expected, c.parse
+ end
+
+ def test_parse_paragraph
+ text = "Public: Do some stuff\n"
+
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('Do some stuff'))
+
+ assert_equal expected, @TD.parse(text)
+ end
+
+ def test_parse_arguments
+ text = <<-TEXT
+Create new Arg object.
+
+name - name of argument
+description - arguments description
+ TEXT
+
+ expected =
+ doc(
+ para('Create new Arg object.'),
+ blank_line,
+ list(:NOTE,
+ item(%w[name],
+ para('name of argument')),
+ item(%w[description],
+ para('arguments description'))))
+
+ assert_equal expected, @TD.parse(text)
+ end
+
+ def test_parse_arguments_multiline
+ text = <<-TEXT
+Do some stuff
+
+foo - A comment goes here
+ and is more than one line
+ TEXT
+
+ expected =
+ doc(
+ para('Do some stuff'),
+ blank_line,
+ list(:NOTE,
+ item(%w[foo],
+ para('A comment goes here', 'and is more than one line'))))
+
+ assert_equal expected, @TD.parse(text)
+ end
+
+ def test_parse_arguments_nested
+ text = <<-TEXT
+Do some stuff
+
+foo - A comment goes here
+ :bar - bar documentation
+ TEXT
+
+ expected =
+ doc(
+ para('Do some stuff'),
+ blank_line,
+ list(:NOTE,
+ item(%w[foo],
+ para('A comment goes here'),
+ list(:NOTE,
+ item(%w[:bar],
+ para('bar documentation'))))))
+
+ assert_equal expected, @TD.parse(text)
+ end
+
+ def test_parse_examples
+ text = <<-TEXT
+Do some stuff
+
+Examples
+
+ 1 + 1
+ TEXT
+
+ code = verb("1 + 1\n")
+ code.format = :ruby
+
+ expected =
+ doc(
+ para('Do some stuff'),
+ blank_line,
+ head(3, 'Examples'),
+ blank_line,
+ code)
+
+ document = @TD.parse(text)
+ assert_equal expected, document
+ assert document.parts.last.ruby?
+ end
+
+ def test_parse_examples_signature
+ text = <<-TEXT
+Do some stuff
+
+Examples
+
+ 1 + 1
+
+Signature
+
+ foo(args)
+ TEXT
+
+ code1 = verb("1 + 1\n")
+ code1.format = :ruby
+
+ code2 = verb("foo(args)\n")
+
+ expected =
+ doc(
+ para('Do some stuff'),
+ blank_line,
+ head(3, 'Examples'),
+ blank_line,
+ code1,
+ head(3, 'Signature'),
+ blank_line,
+ code2)
+
+ document = @TD.parse text
+
+ assert_equal expected, document
+ end
+
+ def test_parse_returns
+ text = <<-TEXT
+Do some stuff
+
+Returns a thing
+ TEXT
+
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('Do some stuff'),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new('Returns a thing'))
+
+ assert_equal expected, @TD.parse(text)
+ end
+
+ def test_parse_returns_multiline
+ text = <<-TEXT
+Do some stuff
+
+Returns a thing
+ that is multiline
+ TEXT
+
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('Do some stuff'),
+ @RM::BlankLine.new,
+ @RM::Paragraph.new('Returns a thing', 'that is multiline'))
+
+ assert_equal expected, @TD.parse(text)
+ end
+
+ def test_parse_signature
+ text = <<-TEXT
+Do some stuff
+
+Signature
+
+ some_method(args)
+ TEXT
+
+ expected =
+ @RM::Document.new(
+ @RM::Paragraph.new('Do some stuff'),
+ @RM::BlankLine.new,
+ @RM::Heading.new(3, 'Signature'),
+ @RM::BlankLine.new,
+ @RM::Verbatim.new("some_method(args)\n"))
+
+ assert_equal expected, @TD.parse(text)
+ end
+
+ def test_tokenize_paragraph
+ @td.tokenize "Public: Do some stuff\n"
+
+ expected = [
+ [:TEXT, "Do some stuff", 0, 0],
+ [:NEWLINE, "\n", 13, 0],
+ ]
+
+ assert_equal expected, @td.tokens
+ end
+
+ def test_tokenize_arguments
+ @td.tokenize <<-TEXT
+Create new Arg object.
+
+name - name of argument
+description - arguments description
+ TEXT
+
+ expected = [
+ [:TEXT, "Create new Arg object.", 0, 0],
+ [:NEWLINE, "\n", 22, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:NOTE, "name", 0, 2],
+ [:TEXT, "name of argument", 14, 2],
+ [:NEWLINE, "\n", 30, 2],
+ [:NOTE, "description", 0, 3],
+ [:TEXT, "arguments description", 14, 3],
+ [:NEWLINE, "\n", 35, 3],
+ ]
+
+ assert_equal expected, @td.tokens
+ end
+
+ def test_tokenize_arguments_multiline
+ @td.tokenize <<-TEXT
+Do some stuff
+
+foo - A comment goes here
+ and is more than one line
+ TEXT
+
+ expected = [
+ [:TEXT, "Do some stuff", 0, 0],
+ [:NEWLINE, "\n", 13, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:NOTE, "foo", 0, 2],
+ [:TEXT, "A comment goes here", 6, 2],
+ [:NEWLINE, "\n", 25, 2],
+ [:TEXT, "and is more than one line", 2, 3],
+ [:NEWLINE, "\n", 27, 3],
+ ]
+
+ assert_equal expected, @td.tokens
+ end
+
+ def test_tokenize_arguments_nested
+ @td.tokenize <<-TEXT
+Do some stuff
+
+foo - A comment goes here
+ :bar - bar documentation
+ TEXT
+
+ expected = [
+ [:TEXT, "Do some stuff", 0, 0],
+ [:NEWLINE, "\n", 13, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:NOTE, "foo", 0, 2],
+ [:TEXT, "A comment goes here", 6, 2],
+ [:NEWLINE, "\n", 25, 2],
+ [:NOTE, ":bar", 6, 3],
+ [:TEXT, "bar documentation", 13, 3],
+ [:NEWLINE, "\n", 30, 3],
+ ]
+
+ assert_equal expected, @td.tokens
+ end
+
+ def test_tokenize_examples
+ @td.tokenize <<-TEXT
+Do some stuff
+
+Examples
+
+ 1 + 1
+ TEXT
+
+ expected = [
+ [:TEXT, "Do some stuff", 0, 0],
+ [:NEWLINE, "\n", 13, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:HEADER, 3, 0, 2],
+ [:TEXT, "Examples", 0, 2],
+ [:NEWLINE, "\n", 8, 2],
+ [:NEWLINE, "\n", 0, 3],
+ [:TEXT, "1 + 1", 2, 4],
+ [:NEWLINE, "\n", 7, 4],
+ ]
+
+ assert_equal expected, @td.tokens
+ end
+
+ def test_tokenize_returns
+ @td.tokenize <<-TEXT
+Do some stuff
+
+Returns a thing
+ TEXT
+
+ expected = [
+ [:TEXT, "Do some stuff", 0, 0],
+ [:NEWLINE, "\n", 13, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:TEXT, "Returns a thing", 0, 2],
+ [:NEWLINE, "\n", 15, 2],
+ ]
+
+ assert_equal expected, @td.tokens
+ end
+
+ def test_tokenize_returns_multiline
+ @td.tokenize <<-TEXT
+Do some stuff
+
+Returns a thing
+ that is multiline
+ TEXT
+
+ expected = [
+ [:TEXT, "Do some stuff", 0, 0],
+ [:NEWLINE, "\n", 13, 0],
+ [:NEWLINE, "\n", 0, 1],
+ [:TEXT, "Returns a thing", 0, 2],
+ [:NEWLINE, "\n", 15, 2],
+ [:TEXT, "that is multiline", 2, 3],
+ [:NEWLINE, "\n", 19, 3],
+ ]
+
+ assert_equal expected, @td.tokens
+ end
+
+end
+
diff --git a/test/rdoc/test_rdoc_top_level.rb b/test/rdoc/test_rdoc_top_level.rb
index 9e68bc4bdd..61f4362d09 100644
--- a/test/rdoc/test_rdoc_top_level.rb
+++ b/test/rdoc/test_rdoc_top_level.rb
@@ -1,5 +1,3 @@
-require 'rubygems'
-require 'minitest/autorun'
require File.expand_path '../xref_test_case', __FILE__
class TestRDocTopLevel < XrefTestCase
@@ -7,102 +5,15 @@ class TestRDocTopLevel < XrefTestCase
def setup
super
- @top_level = RDoc::TopLevel.new 'path/top_level.rb'
- end
-
- def test_class_all_classes_and_modules
- expected = %w[
- C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1
- Child
- M1 M1::M2
- Parent
- ]
-
- assert_equal expected,
- RDoc::TopLevel.all_classes_and_modules.map { |m| m.full_name }.sort
- end
-
- def test_class_classes
- expected = %w[
- C1 C2 C2::C3 C2::C3::H1 C3 C3::H1 C3::H2 C4 C4::C4 C5 C5::C1
- Child Parent
- ]
-
- assert_equal expected, RDoc::TopLevel.classes.map { |m| m.full_name }.sort
- end
-
- def test_class_complete
- @c2.add_module_alias @c2_c3, 'A1', @top_level
-
- RDoc::TopLevel.complete :public
-
- a1 = @xref_data.find_class_or_module 'C2::A1'
-
- assert_equal 'C2::A1', a1.full_name
- refute_empty a1.aliases
- end
-
- def test_class_files
- assert_equal %w[path/top_level.rb xref_data.rb],
- RDoc::TopLevel.files.map { |m| m.full_name }.sort
- end
-
- def test_class_find_class_named
- assert_equal @c1, RDoc::TopLevel.find_class_named('C1')
-
- assert_equal @c2_c3, RDoc::TopLevel.find_class_named('C2::C3')
- end
-
- def test_class_find_class_named_from
- assert_equal @c5_c1, RDoc::TopLevel.find_class_named_from('C1', 'C5')
-
- assert_equal @c1, RDoc::TopLevel.find_class_named_from('C1', 'C4')
- end
-
- def test_class_find_class_or_module
- assert_equal @m1, RDoc::TopLevel.find_class_or_module('M1')
- assert_equal @c1, RDoc::TopLevel.find_class_or_module('C1')
-
- assert_equal @m1, RDoc::TopLevel.find_class_or_module('::M1')
- assert_equal @c1, RDoc::TopLevel.find_class_or_module('::C1')
- end
-
- def test_class_find_file_named
- assert_equal @xref_data, RDoc::TopLevel.find_file_named(@file_name)
- end
-
- def test_class_find_module_named
- assert_equal @m1, RDoc::TopLevel.find_module_named('M1')
- assert_equal @m1_m2, RDoc::TopLevel.find_module_named('M1::M2')
- end
-
- def test_class_modules
- assert_equal %w[M1 M1::M2],
- RDoc::TopLevel.modules.map { |m| m.full_name }.sort
- end
-
- def test_class_new
- tl1 = RDoc::TopLevel.new 'file.rb'
- tl2 = RDoc::TopLevel.new 'file.rb'
- tl3 = RDoc::TopLevel.new 'other.rb'
-
- assert_same tl1, tl2
- refute_same tl1, tl3
- end
-
- def test_class_reset
- RDoc::TopLevel.reset
-
- assert_empty RDoc::TopLevel.classes
- assert_empty RDoc::TopLevel.modules
- assert_empty RDoc::TopLevel.files
+ @top_level = @store.add_file 'path/top_level.rb'
+ @top_level.parser = RDoc::Parser::Ruby
end
def test_add_alias
a = RDoc::Alias.new nil, 'old', 'new', nil
@top_level.add_alias a
- object = RDoc::TopLevel.find_class_named 'Object'
+ object = @store.find_class_named 'Object'
expected = { '#old' => [a] }
assert_equal expected, object.unmatched_alias_lists
assert_includes object.in_files, @top_level
@@ -114,7 +25,7 @@ class TestRDocTopLevel < XrefTestCase
a = RDoc::Alias.new nil, 'old', 'new', nil
@top_level.add_alias a
- object = RDoc::TopLevel.find_class_named('Object')
+ object = @store.find_class_named('Object')
assert_empty object.unmatched_alias_lists
assert_includes object.in_files, @top_level
end
@@ -123,7 +34,7 @@ class TestRDocTopLevel < XrefTestCase
const = RDoc::Constant.new 'C', nil, nil
@top_level.add_constant const
- object = RDoc::TopLevel.find_class_named 'Object'
+ object = @store.find_class_named 'Object'
assert_equal [const], object.constants
assert_includes object.in_files, @top_level
end
@@ -134,7 +45,7 @@ class TestRDocTopLevel < XrefTestCase
const = RDoc::Constant.new 'C', nil, nil
@top_level.add_constant const
- object = RDoc::TopLevel.find_class_named 'Object'
+ object = @store.find_class_named 'Object'
assert_empty object.constants
assert_includes object.in_files, @top_level
end
@@ -143,7 +54,7 @@ class TestRDocTopLevel < XrefTestCase
include = RDoc::Include.new 'C', nil
@top_level.add_include include
- object = RDoc::TopLevel.find_class_named 'Object'
+ object = @store.find_class_named 'Object'
assert_equal [include], object.includes
assert_includes object.in_files, @top_level
end
@@ -154,7 +65,7 @@ class TestRDocTopLevel < XrefTestCase
include = RDoc::Include.new 'C', nil
@top_level.add_include include
- object = RDoc::TopLevel.find_class_named('Object')
+ object = @store.find_class_named('Object')
assert_empty object.includes
assert_includes object.in_files, @top_level
end
@@ -163,7 +74,7 @@ class TestRDocTopLevel < XrefTestCase
method = RDoc::AnyMethod.new nil, 'm'
@top_level.add_method method
- object = RDoc::TopLevel.find_class_named 'Object'
+ object = @store.find_class_named 'Object'
assert_equal [method], object.method_list
assert_includes object.in_files, @top_level
end
@@ -174,7 +85,7 @@ class TestRDocTopLevel < XrefTestCase
method = RDoc::AnyMethod.new nil, 'm'
@top_level.add_method method
- object = RDoc::TopLevel.find_class_named('Object')
+ object = @store.find_class_named('Object')
assert_empty object.method_list
assert_includes object.in_files, @top_level
end
@@ -183,9 +94,18 @@ class TestRDocTopLevel < XrefTestCase
assert_equal 'top_level.rb', @top_level.base_name
end
+ def test_display_eh
+ refute @top_level.display?
+
+ page = @store.add_file 'README.txt'
+ page.parser = RDoc::Parser::Simple
+
+ assert page.display?
+ end
+
def test_eql_eh
- top_level2 = RDoc::TopLevel.new 'path/top_level.rb'
- other_level = RDoc::TopLevel.new 'path/other_level.rb'
+ top_level2 = @store.add_file 'path/top_level.rb'
+ other_level = @store.add_file 'path/other_level.rb'
assert_operator @top_level, :eql?, top_level2
@@ -193,8 +113,8 @@ class TestRDocTopLevel < XrefTestCase
end
def test_equals2
- top_level2 = RDoc::TopLevel.new 'path/top_level.rb'
- other_level = RDoc::TopLevel.new 'path/other_level.rb'
+ top_level2 = @store.add_file 'path/top_level.rb'
+ other_level = @store.add_file 'path/other_level.rb'
assert_equal @top_level, top_level2
@@ -213,8 +133,8 @@ class TestRDocTopLevel < XrefTestCase
end
def test_hash
- tl2 = RDoc::TopLevel.new 'path/top_level.rb'
- tl3 = RDoc::TopLevel.new 'other/top_level.rb'
+ tl2 = @store.add_file 'path/top_level.rb'
+ tl3 = @store.add_file 'other/top_level.rb'
assert_equal @top_level.hash, tl2.hash
refute_equal @top_level.hash, tl3.hash
@@ -232,9 +152,106 @@ class TestRDocTopLevel < XrefTestCase
assert_equal 0, @top_level.last_modified
end
+ def test_marshal_dump
+ page = @store.add_file 'README.txt'
+ page.parser = RDoc::Parser::Simple
+ page.comment = RDoc::Comment.new 'This is a page', page
+
+ loaded = Marshal.load Marshal.dump page
+
+ comment = RDoc::Markup::Document.new(
+ RDoc::Markup::Paragraph.new('This is a page'))
+ comment.file = loaded
+
+ assert_equal page, loaded
+
+ assert_equal 'README.txt', loaded.absolute_name
+ assert_equal 'README.txt', loaded.relative_name
+
+ assert_equal RDoc::Parser::Simple, loaded.parser
+
+ assert_equal comment, loaded.comment
+ end
+
+ def test_marshal_load_version_0
+ loaded = Marshal.load "\x04\bU:\x13RDoc::TopLevel" +
+ "[\ti\x00I\"\x0FREADME.txt\x06:\x06EF" +
+ "c\x19RDoc::Parser::Simple" +
+ "o:\eRDoc::Markup::Document\a:\v@parts" +
+ "[\x06o:\x1CRDoc::Markup::Paragraph\x06;\b" +
+ "[\x06I\"\x13This is a page\x06;\x06F:\n@file@\a"
+
+ comment = RDoc::Markup::Document.new(
+ RDoc::Markup::Paragraph.new('This is a page'))
+ comment.file = loaded
+
+ assert_equal 'README.txt', loaded.absolute_name
+ assert_equal 'README.txt', loaded.relative_name
+
+ assert_equal RDoc::Parser::Simple, loaded.parser
+
+ assert_equal comment, loaded.comment
+ end
+
def test_name
assert_equal 'top_level.rb', @top_level.name
end
+ def test_page_name
+ assert_equal 'top_level', @top_level.page_name
+
+ tl = @store.add_file 'README.ja.rdoc'
+
+ assert_equal 'README.ja', tl.page_name
+
+ tl = @store.add_file 'Rakefile'
+
+ assert_equal 'Rakefile', tl.page_name
+ end
+
+ def test_search_record
+ assert_nil @xref_data.search_record
+ end
+
+ def test_search_record_page
+ page = @store.add_file 'README.txt'
+ page.parser = RDoc::Parser::Simple
+ page.comment = 'This is a comment.'
+
+ expected = [
+ 'README',
+ '',
+ 'README',
+ '',
+ 'README_txt.html',
+ '',
+ "<p>This is a comment.\n",
+ ]
+
+ assert_equal expected, page.search_record
+ end
+
+ def test_text_eh
+ refute @xref_data.text?
+
+ rd = @store.add_file 'rd_format.rd'
+ rd.parser = RDoc::Parser::RD
+
+ assert rd.text?
+
+ simple = @store.add_file 'simple.txt'
+ simple.parser = RDoc::Parser::Simple
+
+ assert simple.text?
+ end
+
+ def test_text_eh_no_parser
+ refute @xref_data.text?
+
+ rd = @store.add_file 'rd_format.rd'
+
+ refute rd.text?
+ end
+
end
diff --git a/test/rdoc/xref_test_case.rb b/test/rdoc/xref_test_case.rb
index a001700d3b..29021a301c 100644
--- a/test/rdoc/xref_test_case.rb
+++ b/test/rdoc/xref_test_case.rb
@@ -1,26 +1,21 @@
ENV['RDOC_TEST'] = 'yes'
-require 'rubygems'
-require 'minitest/autorun'
require 'rdoc'
-require 'rdoc/stats'
-require 'rdoc/options'
-require 'rdoc/code_objects'
-require 'rdoc/parser/ruby'
require File.expand_path '../xref_data', __FILE__
-class XrefTestCase < MiniTest::Unit::TestCase
+class XrefTestCase < RDoc::TestCase
def setup
- RDoc::TopLevel.reset
-
- @file_name = 'xref_data.rb'
- @xref_data = RDoc::TopLevel.new @file_name
+ super
@options = RDoc::Options.new
@options.quiet = true
- stats = RDoc::Stats.new 0
+ @file_name = 'xref_data.rb'
+ @xref_data = @store.add_file @file_name
+ @top_level = @xref_data
+
+ stats = RDoc::Stats.new @store, 0
parser = RDoc::Parser::Ruby.new @xref_data, @file_name, XREF_DATA, @options,
stats
@@ -30,9 +25,8 @@ class XrefTestCase < MiniTest::Unit::TestCase
generator = Object.new
def generator.class_dir() nil end
def generator.file_dir() nil end
- rdoc = RDoc::RDoc.new
- RDoc::RDoc.current = rdoc
- rdoc.generator = generator
+ @rdoc.options = @options
+ @rdoc.generator = generator
@c1 = @xref_data.find_module_named 'C1'
@c1_m = @c1.method_list.last # C1#m