diff --git a/tests/data/markdown/basic.toml b/tests/data/markdown/basic.toml index 1275157b5..78ff9d637 100644 --- a/tests/data/markdown/basic.toml +++ b/tests/data/markdown/basic.toml @@ -78,5 +78,123 @@ ___ profiles = [ "basic", "document",] [expected_output] -basic = "

Basic markup

\n

This is a sample paragraph that has asterisk bold, asterisk emphasized, underscore bold and underscore italic strings.

\n

This is a finalsample paragraph that has an asterisk bold italic string and an underscore bold italic string.
\nIt also has a newline break here!!!

\n

Here are examples of bold and emphasized text depending on the placement of underscores/asterisks:

\n

__Bold without closure does not work
\n**Bold without closure does not work
\n_Emphasis without closure does not work
\n*Emphasis without closure does not work

\n

Bold without closure
\non the same line
\ncarries forward to
\nthis is text that should strike off
\nmultiple consecutive lines

\n

Bold without closure
\non the same line
\ncarries forward to
\nmultiple consecutive lines

\n

Emphasis without closure
\non the same line
\ncarries forward to
\nmultiple consecutive lines

\n

Emphasis without closure
\non the same line
\ncarries forward to
\nmultiple consecutive lines

\n

Horizontal Rules

\n
\n

Above is a horizontal rule using hyphens.
\nThis is text that should strike off

\n
\n

Above is a horizontal rule using asterisks.
\nBelow is a horizontal rule using underscores.

\n
\n

Links

\n

Here is a link to hasgeek

\n

Link to funnel with the title 'Hasgeek'

\n

Autoconverted link https://github.com/hasgeek (will autoconvert if linkify is on)

\n
\n

Markdown-it typography

\n

The results of the below depend on the typographer options enabled by us in the markdown-it-py parser, if typographer=True has been passed to it.

\n

The below should convert if replacements has been enabled.

\n

(c) (C) (r) (R) (tm) (TM) (p) (P) +-
\ntest.. test... test..... test?..... test!....
\n!!!!!! ???? ,, -- ---

\n

The below should convert the quotes if smartquotes has been enabled.

\n

"Smartypants, double quotes" and 'single quotes'

\n
\n

Blockquotes

\n
\n

Blockquotes can also be nested...

\n
\n

...by using additional greater-than signs right next to each other...

\n
\n

...or with spaces between arrows.

\n
\n
\n
\n
" -document = "

Basic markup

\n

This is a sample paragraph that has asterisk bold, asterisk emphasized, underscore bold and underscore italic strings.

\n

This is a finalsample paragraph that has an asterisk bold italic string and an underscore bold italic string.
\nIt also has a newline break here!!!

\n

Here are examples of bold and emphasized text depending on the placement of underscores/asterisks:

\n

__Bold without closure does not work
\n**Bold without closure does not work
\n_Emphasis without closure does not work
\n*Emphasis without closure does not work

\n

Bold without closure
\non the same line
\ncarries forward to
\nthis is text that should strike off
\nmultiple consecutive lines

\n

Bold without closure
\non the same line
\ncarries forward to
\nmultiple consecutive lines

\n

Emphasis without closure
\non the same line
\ncarries forward to
\nmultiple consecutive lines

\n

Emphasis without closure
\non the same line
\ncarries forward to
\nmultiple consecutive lines

\n

Horizontal Rules

\n
\n

Above is a horizontal rule using hyphens.
\nThis is text that should strike off

\n
\n

Above is a horizontal rule using asterisks.
\nBelow is a horizontal rule using underscores.

\n
\n

Links

\n

Here is a link to hasgeek

\n

Link to funnel with the title 'Hasgeek'

\n

Autoconverted link https://github.com/hasgeek (will autoconvert if linkify is on)

\n
\n

Markdown-it typography

\n

The results of the below depend on the typographer options enabled by us in the markdown-it-py parser, if typographer=True has been passed to it.

\n

The below should convert if replacements has been enabled.

\n

(c) (C) (r) (R) (tm) (TM) (p) (P) +-
\ntest.. test... test..... test?..... test!....
\n!!!!!! ???? ,, -- ---

\n

The below should convert the quotes if smartquotes has been enabled.

\n

"Smartypants, double quotes" and 'single quotes'

\n
\n

Blockquotes

\n
\n

Blockquotes can also be nested...

\n
\n

...by using additional greater-than signs right next to each other...

\n
\n

...or with spaces between arrows.

\n
\n
\n
\n
" +basic = """

Basic markup

+

This is a sample paragraph that has asterisk bold, asterisk emphasized, underscore bold and underscore italic strings.

+

This is a finalsample paragraph that has an asterisk bold italic string and an underscore bold italic string.
+It also has a newline break here!!!

+

Here are examples of bold and emphasized text depending on the placement of underscores/asterisks:

+

__Bold without closure does not work
+**Bold without closure does not work
+_Emphasis without closure does not work
+*Emphasis without closure does not work

+

Bold without closure
+on the same line
+carries forward to
+this is text that should strike off
+multiple consecutive lines

+

Bold without closure
+on the same line
+carries forward to
+multiple consecutive lines

+

Emphasis without closure
+on the same line
+carries forward to
+multiple consecutive lines

+

Emphasis without closure
+on the same line
+carries forward to
+multiple consecutive lines

+

Horizontal Rules

+
+

Above is a horizontal rule using hyphens.
+This is text that should strike off

+
+

Above is a horizontal rule using asterisks.
+Below is a horizontal rule using underscores.

+
+

Links

+

Here is a link to hasgeek

+

Link to funnel with the title 'Hasgeek'

+

Autoconverted link https://github.com/hasgeek (will autoconvert if linkify is on)

+
+

Markdown-it typography

+

The results of the below depend on the typographer options enabled by us in the markdown-it-py parser, if typographer=True has been passed to it.

+

The below should convert if replacements has been enabled.

+

(c) (C) (r) (R) (tm) (TM) (p) (P) +-
+test.. test... test..... test?..... test!....
+!!!!!! ???? ,, -- ---

+

The below should convert the quotes if smartquotes has been enabled.

+

"Smartypants, double quotes" and 'single quotes'

+
+

Blockquotes

+
+

Blockquotes can also be nested...

+
+

...by using additional greater-than signs right next to each other...

+
+

...or with spaces between arrows.

+
+
+
+
+""" +document = """

Basic markup

+

This is a sample paragraph that has asterisk bold, asterisk emphasized, underscore bold and underscore italic strings.

+

This is a finalsample paragraph that has an asterisk bold italic string and an underscore bold italic string.
+It also has a newline break here!!!

+

Here are examples of bold and emphasized text depending on the placement of underscores/asterisks:

+

__Bold without closure does not work
+**Bold without closure does not work
+_Emphasis without closure does not work
+*Emphasis without closure does not work

+

Bold without closure
+on the same line
+carries forward to
+this is text that should strike off
+multiple consecutive lines

+

Bold without closure
+on the same line
+carries forward to
+multiple consecutive lines

+

Emphasis without closure
+on the same line
+carries forward to
+multiple consecutive lines

+

Emphasis without closure
+on the same line
+carries forward to
+multiple consecutive lines

+

Horizontal Rules

+
+

Above is a horizontal rule using hyphens.
+This is text that should strike off

+
+

Above is a horizontal rule using asterisks.
+Below is a horizontal rule using underscores.

+
+ +

Here is a link to hasgeek

+

Link to funnel with the title 'Hasgeek'

+

Autoconverted link https://github.com/hasgeek (will autoconvert if linkify is on)

+
+

Markdown-it typography

+

The results of the below depend on the typographer options enabled by us in the markdown-it-py parser, if typographer=True has been passed to it.

+

The below should convert if replacements has been enabled.

+

(c) (C) (r) (R) (tm) (TM) (p) (P) +-
+test.. test... test..... test?..... test!....
+!!!!!! ???? ,, -- ---

+

The below should convert the quotes if smartquotes has been enabled.

+

"Smartypants, double quotes" and 'single quotes'

+
+

Blockquotes

+
+

Blockquotes can also be nested...

+
+

...by using additional greater-than signs right next to each other...

+
+

...or with spaces between arrows.

+
+
+
+
+""" diff --git a/tests/data/markdown/code.toml b/tests/data/markdown/code.toml index efe078f56..3ebee0aff 100644 --- a/tests/data/markdown/code.toml +++ b/tests/data/markdown/code.toml @@ -63,5 +63,99 @@ Isn't that **fantastic**! profiles = [ "basic", "document",] [expected_output] -basic = "

Code

\n

Inline code

\n

Indented code

\n
// Some comments\nline 1 of code\nline 2 of code\nline 3 of code\n
\n

Block code "fences"

\n
Sample text here...\nIt is a sample text that has multiple lines\n
\n

Syntax highlighting

\n

Javascript

\n
var foo = function (bar) {\n  return bar++;\n};\n\nconsole.log(foo(5));\nconsole.log('`This should be printed`');\n
\n
\n

Javascript can be highlighted by using either of the two keywords js and javascript

\n
\n

Python

\n
import os\nfrom funnel.utils.markdown import DATAROOT, markdown\n\nif os.file.path.exists(\n    os.file.path.join(\n        DATAROOT,\n        'file',\n        'path'\n    )\n):\n    markdown('# I can output ``` also with a \\!')\n
\n

Markdown

\n
*I can also type markdown code blocks.*\nIsn't that **fantastic**!\n\n- This is a list\n  - Just testing\n  - this out\n\n[hasgeek](https://hasgeek.com)\n
" -document = "

Code

\n

Inline code

\n

Indented code

\n
// Some comments\nline 1 of code\nline 2 of code\nline 3 of code\n
\n

Block code "fences"

\n
Sample text here...\nIt is a sample text that has multiple lines\n
\n

Syntax highlighting

\n

Javascript

\n
var foo = function (bar) {\n  return bar++;\n};\n\nconsole.log(foo(5));\nconsole.log('`This should be printed`');\n
\n
\n

Javascript can be highlighted by using either of the two keywords js and javascript

\n
\n

Python

\n
import os\nfrom funnel.utils.markdown import DATAROOT, markdown\n\nif os.file.path.exists(\n    os.file.path.join(\n        DATAROOT,\n        'file',\n        'path'\n    )\n):\n    markdown('# I can output ``` also with a \\!')\n
\n

Markdown

\n
*I can also type markdown code blocks.*\nIsn't that **fantastic**!\n\n- This is a list\n  - Just testing\n  - this out\n\n[hasgeek](https://hasgeek.com)\n
" +basic = """

Code

+

Inline code

+

Indented code

+
// Some comments
+line 1 of code
+line 2 of code
+line 3 of code
+
+

Block code "fences"

+
Sample text here...
+It is a sample text that has multiple lines
+
+

Syntax highlighting

+

Javascript

+
var foo = function (bar) {
+  return bar++;
+};
+
+console.log(foo(5));
+console.log('`This should be printed`');
+
+
+

Javascript can be highlighted by using either of the two keywords js and javascript

+
+

Python

+
import os
+from funnel.utils.markdown import DATAROOT, markdown
+
+if os.file.path.exists(
+    os.file.path.join(
+        DATAROOT,
+        'file',
+        'path'
+    )
+):
+    markdown('# I can output ``` also with a \\!')
+
+

Markdown

+
*I can also type markdown code blocks.*
+Isn't that **fantastic**!
+
+- This is a list
+  - Just testing
+  - this out
+
+[hasgeek](https://hasgeek.com)
+
+""" +document = """

Code

+

Inline code

+

Indented code

+
// Some comments
+line 1 of code
+line 2 of code
+line 3 of code
+
+

Block code "fences"

+
Sample text here...
+It is a sample text that has multiple lines
+
+

Syntax highlighting

+

Javascript

+
var foo = function (bar) {
+  return bar++;
+};
+
+console.log(foo(5));
+console.log('`This should be printed`');
+
+
+

Javascript can be highlighted by using either of the two keywords js and javascript

+
+

Python

+
import os
+from funnel.utils.markdown import DATAROOT, markdown
+
+if os.file.path.exists(
+    os.file.path.join(
+        DATAROOT,
+        'file',
+        'path'
+    )
+):
+    markdown('# I can output ``` also with a \\!')
+
+

Markdown

+
*I can also type markdown code blocks.*
+Isn't that **fantastic**!
+
+- This is a list
+  - Just testing
+  - this out
+
+[hasgeek](https://hasgeek.com)
+
+""" diff --git a/tests/data/markdown/footnotes.toml b/tests/data/markdown/footnotes.toml index e2ad3fe09..728cdb474 100644 --- a/tests/data/markdown/footnotes.toml +++ b/tests/data/markdown/footnotes.toml @@ -26,10 +26,61 @@ profiles = [ "basic", "document",] [config.custom_profiles.footnotes] args_config = "default" -args_options = {html = false, linkify = true, typographer = true, breaks = true} plugins = ["footnote"] [expected_output] -basic = "

Footnotes

\n

Here is some random text!

\n

Footnote 1 link[^first].

\n

Footnote 2 link[^second].

\n

Inline footnote^[Text of inline footnote] definition.

\n

Duplicated footnote reference[^second].

\n

[^first]: Footnote can have markup

\n
and multiple paragraphs.\n
\n

[^second]: Footnote text.

\n
\n

This is some more random text to test whether the footnotes are placed after this text.

" -document = "

Footnotes

\n

Here is some random text!

\n

Footnote 1 link[1].

\n

Footnote 2 link[2].

\n

Inline footnote[3] definition.

\n

Duplicated footnote reference[2:1].

\n
\n

This is some more random text to test whether the footnotes are placed after this text.

\n
\n
\n
    \n
  1. Footnote can have markup

    \n

    and multiple paragraphs. ↩︎

    \n
  2. \n
  3. Footnote text. ↩︎ ↩︎

    \n
  4. \n
  5. Text of inline footnote ↩︎

    \n
  6. \n
\n
" -footnotes = "

Footnotes

\n

Here is some random text!

\n

Footnote 1 link[1].

\n

Footnote 2 link[2].

\n

Inline footnote[3] definition.

\n

Duplicated footnote reference[2:1].

\n
\n

This is some more random text to test whether the footnotes are placed after this text.

\n
\n
\n
    \n
  1. Footnote can have markup

    \n

    and multiple paragraphs. ↩︎

    \n
  2. \n
  3. Footnote text. ↩︎ ↩︎

    \n
  4. \n
  5. Text of inline footnote ↩︎

    \n
  6. \n
\n
" +basic = """

Footnotes

+

Here is some random text!

+

Footnote 1 link[^first].

+

Footnote 2 link[^second].

+

Inline footnote^[Text of inline footnote] definition.

+

Duplicated footnote reference[^second].

+

[^first]: Footnote can have markup

+
and multiple paragraphs.
+
+

[^second]: Footnote text.

+
+

This is some more random text to test whether the footnotes are placed after this text.

+""" +document = """

Footnotes

+

Here is some random text!

+

Footnote 1 link[1].

+

Footnote 2 link[2].

+

Inline footnote[3] definition.

+

Duplicated footnote reference[2:1].

+
+

This is some more random text to test whether the footnotes are placed after this text.

+
+
+
    +
  1. Footnote can have markup

    +

    and multiple paragraphs. ↩︎

    +
  2. +
  3. Footnote text. ↩︎ ↩︎

    +
  4. +
  5. Text of inline footnote ↩︎

    +
  6. +
+
+""" +footnotes = """

Footnotes

+

Here is some random text!

+

Footnote 1 link[1].

+

Footnote 2 link[2].

+

Inline footnote[3] definition.

+

Duplicated footnote reference[2:1].

+
+

This is some more random text to test whether the footnotes are placed after this text.

+
+
+
    +
  1. Footnote can have markup

    +

    and multiple paragraphs. ↩︎

    +
  2. +
  3. Footnote text. ↩︎ ↩︎

    +
  4. +
  5. Text of inline footnote ↩︎

    +
  6. +
+
+""" diff --git a/tests/data/markdown/headings.toml b/tests/data/markdown/headings.toml index 4b19d00e5..b4c962431 100644 --- a/tests/data/markdown/headings.toml +++ b/tests/data/markdown/headings.toml @@ -31,6 +31,60 @@ args_config = "default" plugins = [ "heading_anchors",] [expected_output] -basic = "

Using the heading-anchors plugin with it's default config:

\n

The below headings should convert and get linked.
\nOnly the specified headings in extension defaults should get linked.

\n

h1 Heading

\n

h2 Heading

\n

h3 Heading

\n

h4 Heading

\n
h5 Heading
\n
h6 Heading
\n
\n

The below headings should not convert due to lack of space between markup and text
\n#h1 Heading
\n##h2 Heading
\n###h3 Heading
\n####h4 Heading
\n#####h5 Heading
\n######h6 Heading

\n

Text with 2 or more hyphens below it converts to H2

" -document = "

Using the heading-anchors plugin with it's default config:

\n

The below headings should convert and get linked.
\nOnly the specified headings in extension defaults should get linked.

\n

h1 Heading

\n

h2 Heading

\n

h3 Heading

\n

h4 Heading

\n
h5 Heading
\n
h6 Heading
\n
\n

The below headings should not convert due to lack of space between markup and text
\n#h1 Heading
\n##h2 Heading
\n###h3 Heading
\n####h4 Heading
\n#####h5 Heading
\n######h6 Heading

\n

Text with 2 or more hyphens below it converts to H2

" -heading_anchors = "

Using the heading-anchors plugin with it’s default config:

\n

The below headings should convert and get linked.
\nOnly the specified headings in extension defaults should get linked.

\n

h1 Heading

\n

h2 Heading

\n

h3 Heading

\n

h4 Heading

\n
h5 Heading
\n
h6 Heading
\n
\n

The below headings should not convert due to lack of space between markup and text
\n#h1 Heading
\n##h2 Heading
\n###h3 Heading
\n####h4 Heading
\n#####h5 Heading
\n######h6 Heading

\n

Text with 2 or more hyphens below it converts to H2

" +basic = """

Using the heading-anchors plugin with it's default config:

+

The below headings should convert and get linked.
+Only the specified headings in extension defaults should get linked.

+

h1 Heading

+

h2 Heading

+

h3 Heading

+

h4 Heading

+
h5 Heading
+
h6 Heading
+
+

The below headings should not convert due to lack of space between markup and text
+#h1 Heading
+##h2 Heading
+###h3 Heading
+####h4 Heading
+#####h5 Heading
+######h6 Heading

+

Text with 2 or more hyphens below it converts to H2

+""" +document = """

Using the heading-anchors plugin with it's default config:

+

The below headings should convert and get linked.
+Only the specified headings in extension defaults should get linked.

+

h1 Heading

+

h2 Heading

+

h3 Heading

+

h4 Heading

+
h5 Heading
+
h6 Heading
+
+

The below headings should not convert due to lack of space between markup and text
+#h1 Heading
+##h2 Heading
+###h3 Heading
+####h4 Heading
+#####h5 Heading
+######h6 Heading

+

Text with 2 or more hyphens below it converts to H2

+""" +heading_anchors = """

Using the heading-anchors plugin with it’s default config:

+

The below headings should convert and get linked.
+Only the specified headings in extension defaults should get linked.

+

h1 Heading

+

h2 Heading

+

h3 Heading

+

h4 Heading

+
h5 Heading
+
h6 Heading
+
+

The below headings should not convert due to lack of space between markup and text
+#h1 Heading
+##h2 Heading
+###h3 Heading
+####h4 Heading
+#####h5 Heading
+######h6 Heading

+

Text with 2 or more hyphens below it converts to H2

+""" diff --git a/tests/data/markdown/images.toml b/tests/data/markdown/images.toml index dc8958180..fbcdb58c3 100644 --- a/tests/data/markdown/images.toml +++ b/tests/data/markdown/images.toml @@ -24,5 +24,23 @@ With a reference later in the document defining the URL location. profiles = [ "basic", "document",] [expected_output] -basic = "

Images

\n

\"Logo\"
\n\"Logo\" Images stay inline within the same block after a new line

\n

\"The

\n

Like links, images also have a footnote style syntax

\n

\"Alt:
\n\"Alt:
\n\"Alt:

\n

With a reference later in the document defining the URL location.

" -document = "

Images

\n

\"Logo\"
\n\"Logo\" Images stay inline within the same block after a new line

\n

\"The

\n

Like links, images also have a footnote style syntax

\n

\"Alt:
\n\"Alt:
\n\"Alt:

\n

With a reference later in the document defining the URL location.

" +basic = """

Images

+

Logo
+Logo Images stay inline within the same block after a new line

+

The past as a compass for the future

+

Like links, images also have a footnote style syntax

+

Alt: Find your peers
+Alt: Discover your community
+Alt: Sustain the conversations

+

With a reference later in the document defining the URL location.

+""" +document = """

Images

+

Logo
+Logo Images stay inline within the same block after a new line

+

The past as a compass for the future

+

Like links, images also have a footnote style syntax

+

Alt: Find your peers
+Alt: Discover your community
+Alt: Sustain the conversations

+

With a reference later in the document defining the URL location.

+""" diff --git a/tests/data/markdown/links.toml b/tests/data/markdown/links.toml index 011d62eb8..b1760c7c2 100644 --- a/tests/data/markdown/links.toml +++ b/tests/data/markdown/links.toml @@ -63,5 +63,105 @@ _http://danlec_@.1 style=background-image:url(data:image/png;base64,iVBORw0KGgoA profiles = [ "basic", "document",] [expected_output] -basic = "

Links

\n

Hasgeek
\nHasgeek TV

\n

Autoconverted links

\n

https://github.com/nodeca/pica
\nhttp://twitter.com/hasgeek

\n

Footnote style syntax

\n

Hasgeek

\n

Links can have a footnote style syntax, where the links can be defined later. This is helpful in the case of a repetitive URL that needs to be linked to.

\n

Unsafe links

\n

These are links that should not convert (source)

\n

[a](javascript:prompt(document.cookie))
\n[a](j a v a s c r i p t:prompt(document.cookie))
\n![a](javascript:prompt(document.cookie))
\n<javascript:prompt(document.cookie)>
\n<&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>
\n![a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
\n[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
\na
\n![a'"`onerror=prompt(document.cookie)](x)
\n[citelol]: (javascript:prompt(document.cookie))
\n[notmalicious](javascript:window.onerror=alert;throw%20document.cookie)
\n[test](javascript://%0d%0aprompt(1))
\n[test](javascript://%0d%0aprompt(1);com)
\n[notmalicious](javascript:window.onerror=alert;throw%20document.cookie)
\n[notmalicious](javascript://%0d%0awindow.onerror=alert;throw%20document.cookie)
\n[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
\n[clickme](vbscript:alert(document.domain))
\nhttp://danlec@.1 style=background-image:url(data:image/png;base64,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);background-repeat:no-repeat;display:block;width:100%;height:100px; onclick=alert(unescape(/Oh%20No!/.source));return(false);//
\ntext
\n[a](javascript:this;alert(1))
\n[a](javascript:this;alert(1))
\n[a](Javascript:alert(1))
\n[a](Javas%26%2399;ript:alert(1))
\n[a](javascript:alert�(1))
\n[a](javascript:confirm(1)
\n[a](javascript://www.google.com%0Aprompt(1))
\n[a](javascript://%0d%0aconfirm(1);com)
\n[a](javascript:window.onerror=confirm;throw%201)
\n[a](x01javascript:alert(document.domain))
\n[a](javascript://www.google.com%0Aalert(1))
\na
\n[a](JaVaScRiPt:alert(1))
\n\"a\"
\n\"a\"
\n</http://<?php><\\h1>script:scriptconfirm(2)
\nXSS
\n[ ](https://a.de?p=[[/data-x=. style=background-color:#000000;z-index:999;width:100%;position:fixed;top:0;left:0;right:0;bottom:0; data-y=.]])
\n[ ](http://a?p=[[/onclick=alert(0) .]])
\n[a](javascript:new%20Function`al\\ert`1``;)

" -document = "

Links

\n

Hasgeek
\nHasgeek TV

\n

Autoconverted links

\n

https://github.com/nodeca/pica
\nhttp://twitter.com/hasgeek

\n

Footnote style syntax

\n

Hasgeek

\n

Links can have a footnote style syntax, where the links can be defined later. This is helpful in the case of a repetitive URL that needs to be linked to.

\n

Unsafe links

\n

These are links that should not convert (source)

\n

[a](javascript:prompt(document.cookie))
\n[a](j a v a s c r i p t:prompt(document.cookie))
\n![a](javascript:prompt(document.cookie))
\n<javascript:prompt(document.cookie)>
\n<&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>
\n![a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
\n[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
\na
\n![a'"`onerror=prompt(document.cookie)](x)
\n[citelol]: (javascript:prompt(document.cookie))
\n[notmalicious](javascript:window.onerror=alert;throw%20document.cookie)
\n[test](javascript://%0d%0aprompt(1))
\n[test](javascript://%0d%0aprompt(1);com)
\n[notmalicious](javascript:window.onerror=alert;throw%20document.cookie)
\n[notmalicious](javascript://%0d%0awindow.onerror=alert;throw%20document.cookie)
\n[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
\n[clickme](vbscript:alert(document.domain))
\nhttp://danlec@.1 style=background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIAAAABACAMAAADlCI9NAAACcFBMVEX/AAD//////f3//v7/0tL/AQH/cHD/Cwv/+/v/CQn/EBD/FRX/+Pj/ISH/PDz/6Oj/CAj/FBT/DAz/Bgb/rq7/p6f/gID/mpr/oaH/NTX/5+f/mZn/wcH/ICD/ERH/Skr/3Nz/AgL/trb/QED/z8//6+v/BAT/i4v/9fX/ZWX/x8f/aGj/ysr/8/P/UlL/8vL/T0//dXX/hIT/eXn/bGz/iIj/XV3/jo7/W1v/wMD/Hh7/+vr/t7f/1dX/HBz/zc3/nJz/4eH/Zmb/Hx//RET/Njb/jIz/f3//Ojr/w8P/Ghr/8PD/Jyf/mJj/AwP/srL/Cgr/1NT/5ub/PT3/fHz/Dw//eHj/ra3/IiL/DQ3//Pz/9/f/Ly//+fn/UFD/MTH/vb3/7Oz/pKT/1tb/2tr/jY3/6en/QkL/5OT/ubn/JSX/MjL/Kyv/Fxf/Rkb/sbH/39//iYn/q6v/qqr/Y2P/Li7/wsL/uLj/4+P/yMj/S0v/GRn/cnL/hob/l5f/s7P/Tk7/WVn/ior/09P/hYX/bW3/GBj/XFz/aWn/Q0P/vLz/KCj/kZH/5eX/U1P/Wlr/cXH/7+//Kir/r6//LS3/vr7/lpb/lZX/WFj/ODj/a2v/TU3/urr/tbX/np7/BQX/SUn/Bwf/4uL/d3f/ExP/y8v/NDT/KSn/goL/8fH/qan/paX/2Nj/HR3/4OD/VFT/Z2f/SEj/bm7/v7//RUX/Fhb/ycn/V1f/m5v/IyP/xMT/rKz/oKD/7e3/dHT/h4f/Pj7/b2//fn7/oqL/7u7/2dn/TEz/Gxv/6ur/3d3/Nzf/k5P/EhL/Dg7/o6P/UVHe/LWIAAADf0lEQVR4Xu3UY7MraRRH8b26g2Pbtn1t27Zt37Ft27Zt6yvNpPqpPp3GneSeqZo3z3r5T1XXL6nOFnc6nU6n0+l046tPruw/+Vil/C8tvfscquuuOGTPT2ZnRySwWaFQqGG8Y6j6Zzgggd0XChWLf/U1OFoQaVJ7AayUwPYALHEM6UCWBDYJbhXfHjUBOHvVqz8YABxfnDCArrED7jSAs13Px4Zo1jmA7eGEAXvXjRVQuQE4USWqp5pNoCthALePFfAQ0OcchoCGBAEPgPGiE7AiacChDfBmjjg7DVztAKRtnJsXALj/Hpiy2B9wofqW9AQAg8Bd8VOpCR02YMVEE4xli/L8AOmtQMQHsP9IGUBZedq/AWJfIez+x4KZqgDtBlbzon6A8GnonOwBXNONavlmUS2Dx8XTjcCwe1wNvGQB2gxaKhbV7Ubx3QC5bRMUuAEvA9kFzzW3TQAeVoB5cFw8zQUGPH9M4LwFgML5IpL6BHCvH0DmAD3xgIUpUJcTmy7UQHaV/bteKZ6GgGr3eAq4QQEmWlNqJ1z0BeTvgGfz4gAFsDXfUmbeAeoAF0OfuLL8C91jHnCtBchYq7YzsMsXIFkmDDsBjwBfi2o6GM9IrOshIp5mA6vc42Sg1wJMEVUJlPgDpBzWb3EAVsMOm5m7Hg5KrAjcJJ5uRn3uLAvosgBrRPUgnAgApC2HjtpRwFTneZRpqLs6Ak+Lp5lAj9+LccoCzLYPZjBA3gIGRgHj4EuxewH6JdZhKBVPM4CL7rEIiKo7kMAvILIEXplvA/bCR2JXAYMSawtkiqfaDHjNtYVfhzJJBvBGJ3zmADhv6054W71ZrBNvHZDigr0DDCcFkHeB8wog70G/2LXA+xIrh03i02Zgavx0Blo+SA5Q+yEcrVSAYvjYBhwEPrEoDZ+KX20wIe7G1ZtwTJIDyMYU+FwBeuGLpaLqg91NcqnqgQU9Yre/ETpzkwXIIKAAmRnQruboUeiVS1cHmF8pcv70bqBVkgak1tgAaYbuw9bj9kFjVN28wsJvxK9VFQDGzjVF7d9+9z1ARJIHyMxRQNo2SDn2408HBsY5njZJPcFbTomJo59H5HIAUmIDpPQXVGS0igfg7detBqptv/0ulwfIbbQB8kchVtNmiQsQUO7Qru37jpQX7WmS/6YZPXP+LPprbVgC0ul0Op1Op9Pp/gYrAa7fWhG7QQAAAABJRU5ErkJggg==);background-repeat:no-repeat;display:block;width:100%;height:100px; onclick=alert(unescape(/Oh%20No!/.source));return(false);//
\ntext
\n[a](javascript:this;alert(1))
\n[a](javascript:this;alert(1))
\n[a](Javascript:alert(1))
\n[a](Javas%26%2399;ript:alert(1))
\n[a](javascript:alert�(1))
\n[a](javascript:confirm(1)
\n[a](javascript://www.google.com%0Aprompt(1))
\n[a](javascript://%0d%0aconfirm(1);com)
\n[a](javascript:window.onerror=confirm;throw%201)
\n[a](x01javascript:alert(document.domain))
\n[a](javascript://www.google.com%0Aalert(1))
\na
\n[a](JaVaScRiPt:alert(1))
\n\"a\"
\n\"a\"
\n</http://<?php><\\h1>script:scriptconfirm(2)
\nXSS
\n[ ](https://a.de?p=[[/data-x=. style=background-color:#000000;z-index:999;width:100%;position:fixed;top:0;left:0;right:0;bottom:0; data-y=.]])
\n[ ](http://a?p=[[/onclick=alert(0) .]])
\n[a](javascript:new%20Function`al\\ert`1``;)

" +basic = """

Links

+

Hasgeek
+Hasgeek TV

+

Autoconverted links

+

https://github.com/nodeca/pica
+http://twitter.com/hasgeek

+

Footnote style syntax

+

Hasgeek

+

Links can have a footnote style syntax, where the links can be defined later. This is helpful in the case of a repetitive URL that needs to be linked to.

+

Unsafe links

+

These are links that should not convert (source)

+

[a](javascript:prompt(document.cookie))
+[a](j a v a s c r i p t:prompt(document.cookie))
+![a](javascript:prompt(document.cookie))
+<javascript:prompt(document.cookie)>
+<&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>
+![a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
+[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
+a
+![a'"`onerror=prompt(document.cookie)](x)
+[citelol]: (javascript:prompt(document.cookie))
+[notmalicious](javascript:window.onerror=alert;throw%20document.cookie)
+[test](javascript://%0d%0aprompt(1))
+[test](javascript://%0d%0aprompt(1);com)
+[notmalicious](javascript:window.onerror=alert;throw%20document.cookie)
+[notmalicious](javascript://%0d%0awindow.onerror=alert;throw%20document.cookie)
+[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
+[clickme](vbscript:alert(document.domain))
+http://danlec@.1 style=background-image:url(data:image/png;base64,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);background-repeat:no-repeat;display:block;width:100%;height:100px; onclick=alert(unescape(/Oh%20No!/.source));return(false);//
+text
+[a](javascript:this;alert(1))
+[a](javascript:this;alert(1))
+[a](Javascript:alert(1))
+[a](Javas%26%2399;ript:alert(1))
+[a](javascript:alert�(1))
+[a](javascript:confirm(1)
+[a](javascript://www.google.com%0Aprompt(1))
+[a](javascript://%0d%0aconfirm(1);com)
+[a](javascript:window.onerror=confirm;throw%201)
+[a](x01javascript:alert(document.domain))
+[a](javascript://www.google.com%0Aalert(1))
+a
+[a](JaVaScRiPt:alert(1))
+a
+a
+</http://<?php><\\h1>script:scriptconfirm(2)
+XSS
+[ ](https://a.de?p=[[/data-x=. style=background-color:#000000;z-index:999;width:100%;position:fixed;top:0;left:0;right:0;bottom:0; data-y=.]])
+[ ](http://a?p=[[/onclick=alert(0) .]])
+[a](javascript:new%20Function`al\\ert`1``;)

+""" +document = """ +

Hasgeek
+Hasgeek TV

+ +

https://github.com/nodeca/pica
+http://twitter.com/hasgeek

+

Footnote style syntax

+

Hasgeek

+

Links can have a footnote style syntax, where the links can be defined later. This is helpful in the case of a repetitive URL that needs to be linked to.

+ +

These are links that should not convert (source)

+

[a](javascript:prompt(document.cookie))
+[a](j a v a s c r i p t:prompt(document.cookie))
+![a](javascript:prompt(document.cookie))
+<javascript:prompt(document.cookie)>
+<&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>
+![a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
+[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
+a
+![a'"`onerror=prompt(document.cookie)](x)
+[citelol]: (javascript:prompt(document.cookie))
+[notmalicious](javascript:window.onerror=alert;throw%20document.cookie)
+[test](javascript://%0d%0aprompt(1))
+[test](javascript://%0d%0aprompt(1);com)
+[notmalicious](javascript:window.onerror=alert;throw%20document.cookie)
+[notmalicious](javascript://%0d%0awindow.onerror=alert;throw%20document.cookie)
+[a](data:text/html;base64,PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K)
+[clickme](vbscript:alert(document.domain))
+http://danlec@.1 style=background-image:url(data:image/png;base64,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);background-repeat:no-repeat;display:block;width:100%;height:100px; onclick=alert(unescape(/Oh%20No!/.source));return(false);//
+text
+[a](javascript:this;alert(1))
+[a](javascript:this;alert(1))
+[a](Javascript:alert(1))
+[a](Javas%26%2399;ript:alert(1))
+[a](javascript:alert�(1))
+[a](javascript:confirm(1)
+[a](javascript://www.google.com%0Aprompt(1))
+[a](javascript://%0d%0aconfirm(1);com)
+[a](javascript:window.onerror=confirm;throw%201)
+[a](x01javascript:alert(document.domain))
+[a](javascript://www.google.com%0Aalert(1))
+a
+[a](JaVaScRiPt:alert(1))
+a
+a
+</http://<?php><\\h1>script:scriptconfirm(2)
+XSS
+[ ](https://a.de?p=[[/data-x=. style=background-color:#000000;z-index:999;width:100%;position:fixed;top:0;left:0;right:0;bottom:0; data-y=.]])
+[ ](http://a?p=[[/onclick=alert(0) .]])
+[a](javascript:new%20Function`al\\ert`1``;)

+""" diff --git a/tests/data/markdown/lists.toml b/tests/data/markdown/lists.toml index 057ef157b..53aee3185 100644 --- a/tests/data/markdown/lists.toml +++ b/tests/data/markdown/lists.toml @@ -36,5 +36,105 @@ Start numbering with offset: profiles = [ "basic", "document",] [expected_output] -basic = "

Lists

\n

Unordered

\n\n

Ordered

\n
    \n
  1. \n

    Lorem ipsum dolor sit amet

    \n
  2. \n
  3. \n

    Consectetur adipiscing elit

    \n
  4. \n
  5. \n

    Integer molestie lorem at massa

    \n
  6. \n
  7. \n

    You can use sequential numbers...

    \n
  8. \n
  9. \n

    ...or keep all the numbers as 1.

    \n
  10. \n
\n
    \n
  1. You can start a new list by switching between ) and .
  2. \n
  3. Skipping numbers does not have any effect.
  4. \n
\n

Start numbering with offset:

\n
    \n
  1. foo
  2. \n
  3. bar
  4. \n
\n
\n

2022. If you do not want to render a list, use \\ to escape the .

" -document = "

Lists

\n

Unordered

\n\n

Ordered

\n
    \n
  1. \n

    Lorem ipsum dolor sit amet

    \n
  2. \n
  3. \n

    Consectetur adipiscing elit

    \n
  4. \n
  5. \n

    Integer molestie lorem at massa

    \n
  6. \n
  7. \n

    You can use sequential numbers...

    \n
  8. \n
  9. \n

    ...or keep all the numbers as 1.

    \n
  10. \n
\n
    \n
  1. You can start a new list by switching between ) and .
  2. \n
  3. Skipping numbers does not have any effect.
  4. \n
\n

Start numbering with offset:

\n
    \n
  1. foo
  2. \n
  3. bar
  4. \n
\n
\n

2022. If you do not want to render a list, use \\ to escape the .

" +basic = """

Lists

+

Unordered

+ +

Ordered

+
    +
  1. +

    Lorem ipsum dolor sit amet

    +
  2. +
  3. +

    Consectetur adipiscing elit

    +
  4. +
  5. +

    Integer molestie lorem at massa

    +
  6. +
  7. +

    You can use sequential numbers...

    +
  8. +
  9. +

    ...or keep all the numbers as 1.

    +
  10. +
+
    +
  1. You can start a new list by switching between ) and .
  2. +
  3. Skipping numbers does not have any effect.
  4. +
+

Start numbering with offset:

+
    +
  1. foo
  2. +
  3. bar
  4. +
+
+

2022. If you do not want to render a list, use \\ to escape the .

+""" +document = """

Lists

+

Unordered

+ +

Ordered

+
    +
  1. +

    Lorem ipsum dolor sit amet

    +
  2. +
  3. +

    Consectetur adipiscing elit

    +
  4. +
  5. +

    Integer molestie lorem at massa

    +
  6. +
  7. +

    You can use sequential numbers...

    +
  8. +
  9. +

    ...or keep all the numbers as 1.

    +
  10. +
+
    +
  1. You can start a new list by switching between ) and .
  2. +
  3. Skipping numbers does not have any effect.
  4. +
+

Start numbering with offset:

+
    +
  1. foo
  2. +
  3. bar
  4. +
+
+

2022. If you do not want to render a list, use \\ to escape the .

+""" diff --git a/tests/data/markdown/tables.toml b/tests/data/markdown/tables.toml index 3e5f7db98..52eace6b8 100644 --- a/tests/data/markdown/tables.toml +++ b/tests/data/markdown/tables.toml @@ -20,5 +20,63 @@ markdown = """ profiles = [ "basic", "document",] [expected_output] -basic = "

Tables

\n

| Option | Description |
\n| ------ | ----------- |
\n| data | path to data files to supply the data that will be passed into templates. |
\n| engine | engine to be used for processing templates. Handlebars is the default. |
\n| ext | extension to be used for dest files. |

\n

Right aligned columns

\n

| Option | Description |
\n| ------:| -----------:|
\n| data | path to data files to supply the data that will be passed into templates. |
\n| engine | engine to be used for processing templates. Handlebars is the default. |
\n| ext | extension to be used for dest files. |

" -document = "

Tables

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
OptionDescription
datapath to data files to supply the data that will be passed into templates.
engineengine to be used for processing templates. Handlebars is the default.
extextension to be used for dest files.
\n

Right aligned columns

\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n
OptionDescription
datapath to data files to supply the data that will be passed into templates.
engineengine to be used for processing templates. Handlebars is the default.
extextension to be used for dest files.
" +basic = """

Tables

+

| Option | Description |
+| ------ | ----------- |
+| data | path to data files to supply the data that will be passed into templates. |
+| engine | engine to be used for processing templates. Handlebars is the default. |
+| ext | extension to be used for dest files. |

+

Right aligned columns

+

| Option | Description |
+| ------:| -----------:|
+| data | path to data files to supply the data that will be passed into templates. |
+| engine | engine to be used for processing templates. Handlebars is the default. |
+| ext | extension to be used for dest files. |

+""" +document = """

Tables

+ + + + + + + + + + + + + + + + + + + + + +
OptionDescription
datapath to data files to supply the data that will be passed into templates.
engineengine to be used for processing templates. Handlebars is the default.
extextension to be used for dest files.
+

Right aligned columns

+ + + + + + + + + + + + + + + + + + + + + +
OptionDescription
datapath to data files to supply the data that will be passed into templates.
engineengine to be used for processing templates. Handlebars is the default.
extextension to be used for dest files.
+""" diff --git a/tests/unit/utils/test_markdown.py b/tests/unit/utils/test_markdown.py index 34247be6e..c020f10ed 100644 --- a/tests/unit/utils/test_markdown.py +++ b/tests/unit/utils/test_markdown.py @@ -1,7 +1,7 @@ """Tests for markdown parser.""" from pathlib import Path -from typing import Dict, List, Optional, Type +from typing import Dict, List, Optional, Type, Union import warnings import pytest @@ -11,7 +11,7 @@ from funnel.utils.markdown.profiles import MarkdownProfile, profiles DATAROOT: Path = Path('tests/data/markdown') -DEBUG = True +DEBUG = False class MarkdownCase: @@ -69,38 +69,37 @@ def case_id(self) -> str: return f'{self.test_id}-{self.profile_id}' @property - def markdown_profile(self): + def markdown_profile(self) -> Union[str, Type[MarkdownProfile]]: return self.profile if self.profile is not None else self.profile_id @property - def output(self): - return ( - markdown(self.markdown, self.markdown_profile) - .__str__() - .lstrip('\n\r') - .rstrip(' \n\r') - ) + def output(self) -> str: + return markdown(self.markdown, self.markdown_profile) + + def update_expected_output(self) -> None: + self.expected_output = self.output class MarkdownTestRegistry: test_map: Optional[Dict[str, Dict[str, MarkdownCase]]] = None + test_files: Dict[str, tomlkit.TOMLDocument] @classmethod - def load(cls): + def load(cls) -> None: if cls.test_map is None: cls.test_map = {} - tests = { + cls.test_files = { file.name: tomlkit.loads(file.read_text()) for file in DATAROOT.iterdir() if file.suffix == '.toml' } - for test_id, test in tests.items(): - config = test['config'] - exp = test.get('expected_output', {}) + for test_id, test_data in cls.test_files.items(): + config = test_data['config'] + exp = test_data.get('expected_output', {}) cls.test_map[test_id] = { profile_id: MarkdownCase( test_id, - test['markdown'], + test_data['markdown'], profile_id, profile=profile, expected_output=exp.get(profile_id, None), @@ -111,6 +110,16 @@ def load(cls): }.items() } + @classmethod + def dump(cls) -> None: + if cls.test_map is not None: + for test_id, data in cls.test_files.items(): + data['expected_output'] = { + profile_id: tomlkit.api.string(case.output, multiline=True) + for profile_id, case in cls.test_map[test_id].items() + } + (DATAROOT / test_id).write_text(tomlkit.dumps(data)) + @classmethod def dataset(cls) -> List[MarkdownCase]: cls.load() @@ -120,6 +129,11 @@ def dataset(cls) -> List[MarkdownCase]: else [] ) + @classmethod + def update_output(cls) -> None: + cls.load() + cls.dump() + @pytest.mark.parametrize( 'case', @@ -134,3 +148,12 @@ def test_markdown_cases(case: MarkdownCase, unified_diff_output) -> None: unified_diff_output(case.expected_output, case.output) else: assert case.expected_output == case.output + + +@pytest.mark.update_markdown_data() +def test_markdown_update_output(pytestconfig): + has_mark = pytestconfig.getoption('-m', default=None) == 'update_markdown_data' + if not has_mark: + pytest.skip('Skipping update of expected output of markdown test cases') + # update_markdown_tests_data(debug=False) + MarkdownTestRegistry.update_output()