(ns markdown.md-test (:require #?(:cljs [goog.string]) [clojure.test :refer [deftest is]] [markdown.core :as markdown] [markdown.tables :as tables])) (def entry-function #?(:clj markdown/md-to-html-string :cljs markdown/md->html)) (deftest heading1 (is (= "

Ticket #123

" (entry-function "# Ticket #123"))) (is (= "

Foo

" (entry-function " # Foo"))) (is (= "

foo

" (entry-function "#foo"))) (is (= "

foo

" (entry-function "foo\n==="))) (is (= "

foo

" (entry-function "#foo#"))) (is (= "

foo

" (entry-function "#foo#\n"))) (is (= "

some header with_an_underscore

" (entry-function "# some header `with_an_underscore`"))) (is (= "

heading1

" (entry-function "* one\n\nheading1\n========\n")))) (deftest heading2 (is (= "

foo

" (entry-function "##foo"))) (is (= "

foo

" (entry-function "foo\n---"))) (is (= "

foo

" (entry-function "##foo##"))) (is (= "

foo

" (entry-function "##foo##\n")))) (deftest heading-with-complex-anchor (is (= "

foo bar BAz

some text

" (entry-function "###foo bar BAz\nsome text" :heading-anchors true))) (is (= "

foo bar BAz

some text

" (entry-function "###foo bar BAz##\nsome text" :heading-anchors true)))) (deftest br (is (= "

foo

" (entry-function "foo ")))) (deftest hr (is (= "
" (entry-function "***"))) (is (= "
" (entry-function " * * * "))) (is (= "
" (entry-function " *****"))) (is (= "
" (entry-function "- - - ")))) (deftest em (is (= "

foo

" (entry-function "*foo*")))) (deftest italics (is (= "

foo

" (entry-function "_foo_")))) (deftest strong (is (= "

foo

" (entry-function "**foo**")))) (deftest bold-italics (is (= "

foo

" (entry-function "***foo***")))) (deftest bold (is (= "

foo

" (entry-function "__foo__")))) (deftest strong-inside-em (is (= "

foobarbaz

" (entry-function "*foo**bar**baz*")))) (deftest bold-inside-a-list (is (= "
  1. chickens.

See more: Cluck Cluck

" (entry-function "1. chickens. \n\n **See more: [Cluck Cluck](http://cluck.cluck.com)** \n\n")))) (deftest em-inside-strong (is (= "

foobarbaz

" (entry-function "**foo*bar*baz**")))) (deftest paragraph (is (= "

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore

" (entry-function "\nLorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore")))) (deftest paragraph-multiline (is (= "

Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore

" (entry-function "\nLorem ipsum dolor\nsit amet, consectetur adipisicing elit,\nsed do eiusmod tempor incididunt ut labore")))) (deftest paragraph-before-codeblock (is (= "

foo

bar\n

baz

" (entry-function "foo\n```\nbar\n```\nbaz"))) (is (= "
foo  \nbar
" (entry-function "```\nfoo \nbar```"))) (is (= "

" (entry-function "```\n```"))) (is (= "

" (entry-function "```go\n```"))) (is (= "
<html>\n</html>\n
" (entry-function "```\n\n\n``` ")))) (deftest paragraph-after-codeblock (is (= "
foo\n

bar baz

" (entry-function "```\nfoo\n```\nbar\nbaz")))) (deftest mulitple-paragraphs (is (= "

foo bar baz

foo bar baz

" (entry-function "\nfoo bar baz\n\n\nfoo bar baz")))) (deftest ul (is (= "" (entry-function "* foo\n* bar\n* baz"))) (is (= "" (entry-function "- foo\n- bar\n- baz"))) (is (= "" (entry-function "+ foo\n+ bar\n+ baz")))) (deftest list-in-a-codeblock (is (= "
list:\n- 1\n- 2\n
" (entry-function "```yaml\nlist:\n- 1\n- 2\n```")))) (deftest ul-followed-by-paragraph (is (= "

paragraph next line

" (entry-function "* foo\n* bar\n* baz\n\nparagraph\nnext line")))) (deftest ul-with-codeblock (is (= "" (entry-function "\n* foo\n* bar\n ```\n (defn foo []\n bar)\n ```\n* baz\n* more text\n"))) (is (= "" (entry-function "\n* foo\n* bar\n ```\n (defn foo []\n bar)\n ```\n text\n* baz\n* more text\n")))) (deftest ul-followed-by-multiline-paragraph (is (= "

paragraph

" (entry-function "* foo\n* bar\n* baz\n\nparagraph")))) (deftest ul-nested (is (= "" (entry-function "* first item\n * first sub-item\n * second sub-item\n * third sub-item\n* second item\n * first sub-item\n * second sub-item\n* third item"))) (is (= "" (entry-function "* first item\n - first sub-item\n - second sub-item\n - third sub-item\n* second item\n + first sub-item\n + second sub-item\n* third item"))) (is (= "" (entry-function " * abc\n\n+ def")))) (deftest ol (is (= "
  1. Foo
  2. Bar
  3. Baz
" (entry-function "1. Foo\n2. Bar\n3. Baz")))) (deftest ul-in-ol (is (= "
  1. Bar
    1. Subbar
      • foo
      • bar
      • baz
  2. Baz
" (entry-function "1. Bar\n 2. Subbar\n * foo\n * bar\n * baz\n3. Baz")))) (deftest ol-in-ul (is (= "" (entry-function "* Foo\n 1. Bar\n 1. Subbar\n* Baz"))) (is (= "" (entry-function "* Foo\n 1. Bar")))) (deftest multilist (is (= "" (entry-function "* foo * bar * baz 1. foo 2. bar * fuzz * blah * blue * brass")))) (deftest code (is (= "

foo bar baz x = y + z; foo

" (entry-function "foo bar baz `x = y + z;` foo"))) (is (= "

bar foo --- -- bar foo

" (entry-function "bar `foo --- -- bar` foo"))) (is (= "

<?xml version='1.0' encoding='UTF-8'?><channel></channel>

" (entry-function "``"))) (is (= "

foo bar baz (fn [x & xs] (str "x:" x)) foo

" (entry-function "foo bar baz `(fn [x & xs] (str \"x:\" x))` foo"))) (is (= "
```\nfoo\n```
" (entry-function " ```\n foo\n ```")))) (deftest multiline-code (is (= "
x = 5\ny = 6\nz = x + y
" (entry-function " x = 5\n y = 6\n z = x + y"))) (is (= "
x = 5\ny = 6\nz = x + y\n(fn [x & xs] (str "x"))
" (entry-function " x = 5\n y = 6\n z = x + y\n (fn [x & xs] (str \"x\"))")))) (deftest codeblock (is (= "
(defn- write^ [writer text]\n  (doseq [c text]\n    (.write writer (int c))))\n
" (entry-function "```\n(defn- write^ [writer text]\n (doseq [c text]\n (.write writer (int c))))\n```"))) (is (= "
(fn [x & xs]\n  (str "x"))\n
" (entry-function "```\n(fn [x & xs]\n (str \"x\"))\n```"))) (is (= "
(fn [x & xs]\n  (str "x"))\n
" (entry-function "```\n(fn [x & xs]\n (str \"x\"))\n```"))) (is (= "
(fn [x & xs]\n  (str "x"))\n
" (entry-function "```clojure\n(fn [x & xs]\n (str \"x\"))\n```"))) (is (= "
------------\n============\n    ------------\n    ============\n
" (entry-function " ```nohighlight ------------ ============ ------------ ============ ``` ")))) (deftest indented-codeblock (is (= "
foo
" (entry-function " foo"))) (is (= "
foo

bar

" (entry-function " foo\n\nbar"))) (is (= "
foo
bar" (entry-function " foo\nbar"))) (is (= "

baz foo

bar

" (entry-function "baz\n foo\n\nbar"))) (is (= "

Element #1

" (entry-function "
\n
\n

Element #1

\n
\n
")))) (deftest strikethrough (is (= "

foo

" (entry-function "~~foo~~")))) (deftest superscript (is (= "

foobar baz

" (entry-function "foo^bar baz")))) (deftest link (is (= "

underscoresarefine

" (entry-function "underscores_are_fine"))) (is (= "

github

" (entry-function "[github](http://github.com)"))) (is (= "

github

" (entry-function "[github](http://github.com/~)"))) (is (= "

github

" (entry-function "[github](http://github.com/^)"))) (is (= "

github

" (entry-function "[github](http://github.com/*)"))) (is (= "" (entry-function "* [github](http://github.com/*)"))) (is (= "

a link

" (entry-function "* hi\n\n[a link](https://see-here)"))) (is (= "

>!

" (entry-function "[>!](https://clojure.github.io/core.async/#clojure.core.async/>!)"))) (is (= "

" (entry-function "[github

" (entry-function "[*github*](http://github.com)"))) (is (= "

github

" (entry-function "[_github_](http://github.com)"))) (is (= "

github

" (entry-function "[__github__](http://github.com)"))) (is (= "

github

" (entry-function "[**github**](http://github.com)"))) (is (= "

github

" (entry-function "[~~github~~](http://github.com)")))) (deftest img (is (= "

\"Alt

" (entry-function "![Alt text](/path/to/img.jpg)"))) (is (= "

\"Alt

" (entry-function "![Alt text](/path/to/_img_.jpg \"Optional Title\")")))) (deftest img-link (is (= "

\"Continuous

" (entry-function "[![Continuous Integration status](https://secure.travis-ci.org/yogthos/markdown-clj.png)](http://travis-ci.org/yogthos/markdown-clj)"))) (is (= "

\"\"

" (entry-function "![](https://secure.travis-ci.org/yogthos/markdown-clj.png)")))) (deftest bad-link (is (= "

[github](http://github.comfooo

" (entry-function "[github](http://github.comfooo"))) (is (= "

[github] no way (http://github.com)

" (entry-function "[github] no way (http://github.com)")))) (deftest bad-link-title (is (= "

[github(http://github.comfooo)

" (entry-function "[github(http://github.comfooo)")))) (deftest blockquote (is (= "

Foo bar baz

" (entry-function ">Foo bar baz")))) (deftest blockquote-footer (is (= "

Foo bar baz

" (entry-function "> Foo bar baz\n>- Leo Tolstoy")))) (deftest blockquote-empty-footer (is (= "

Foo bar baz

" (entry-function "> Foo bar baz\n>-")))) (deftest blockquote-multiline-without-leading-angle-bracket (is (= "

Foo bar baz

" (entry-function "> Foo bar\nbaz")))) (deftest blockquote-multiple-paragraphs (is (= "

Foo bar

baz

" (entry-function "> Foo bar\n>\n> baz")))) (deftest blockquote-bullets (is (= "

list:

end.

" (entry-function "> list:\n>* foo\n>* bar\n\nend."))) (is (= "

" (entry-function ">* foo\n>* bar\n>* baz")))) (deftest blockquote-headings (is (= "

Foo

bar baz

" (entry-function "> ## Foo\n>bar baz"))) (is (= "

Foo

bar

baz

" (entry-function "> Foo\n>## bar\n> baz")))) (deftest escaped-characters (is (= "

^*‘_{}[]footestbar{x}[y]

" (entry-function "\\^\\*\\`\\_\\{\\}\\[\\]*foo*`test`_bar_{x}[y]")))) (deftest paragraph-after-list (is (= "
  1. a
  2. b

test bold and italic

" (entry-function "1. a\n2. b\n\ntest **bold** and *italic*")))) (deftest paragraph-close-before-list (is (= "

in paragraph

" (entry-function "in paragraph\n- list")))) (deftest autourl (is (= "

http://example.com/

" (entry-function ""))) (is (= "

Some content with a http://www.google.com/abc__123__efg link it in

" (entry-function "Some content with a link it in"))) (is (= "

http://foo https://bar/baz foo bar

" (entry-function " foo bar"))) #?(:bb nil :org.babashka/nbb nil :default (is (= "

abc@google.com

" (#?(:clj org.apache.commons.lang.StringEscapeUtils/unescapeHtml :cljs goog.string/unescapeEntities) (entry-function ""))))) #?(:bb nil :org.babashka/nbb nil :default (is (= "

abc_def_ghi@google.com

" (#?(:clj org.apache.commons.lang.StringEscapeUtils/unescapeHtml :cljs goog.string/unescapeEntities) (entry-function "")))))) (deftest not-a-list (is (= "

The fish was 192.8 lbs and was amazing to see.

" (entry-function "The fish was\n192.8 lbs and was amazing to see.")))) (deftest dont-encode-chars-in-hrefs (is (= "

example_link with tilde ~ and carat ^ and splat *

" (entry-function "[example_link with tilde ~ and carat ^ and splat *](http://www.google.com/example_link_foo~_^*)")))) (deftest complex-link-with-terminal-encoding-inside-header (is (= "

With a link the contents of the_link

" (entry-function "##With a link [the contents of the_link](http://a.com/under_score_in_the_link/)")))) (deftest two-links-tests-link-processing (is (= "

When you have a pair of links link1 and you want both Wow

" (entry-function "## When you have a pair of links [link1](http://123.com/1) and you want both [Wow](That%27s%20crazy)")))) (deftest link-then-image-processing (is (= "

You can have a link followed by an image \"\"

" (entry-function "You can have a [link](github.com) followed by an image ![](img.png)")))) (deftest image-then-link-processing (is (= "

You can have an image \"\" followed by a link

" (entry-function "You can have an image ![](img.png) followed by a [link](github.com)")))) (deftest link-with-optional-title (is (= "

Cryogens site

" (entry-function "[Cryogens site](https://github.com/cryogen-project/cryogen \"Cryogen Github\")")))) (deftest parse-table-row (is (= (tables/parse-table-row "| table cell contents |") [{:text "table cell contents"}])) (is (= (tables/parse-table-row "| contents 1 | contents 2 | contents 3 | contents 4 |") [{:text "contents 1"} {:text "contents 2"} {:text "contents 3"} {:text "contents 4"}]))) (deftest table-row->str (is (= (tables/table-row->str [{:text "contents 1"} {:text "contents 2"} {:text "contents 3"} {:text "contents 4"}] true) "contents 1contents 2contents 3contents 4")) (is (= (tables/table-row->str [{:text "contents 1"} {:text "contents 2"} {:text "contents 3"} {:text "contents 4"}] false) "contents 1contents 2contents 3contents 4")) (is (= (tables/table-row->str [{:text "contents 1" :alignment :left} {:text "contents 2" :alignment :center} {:text "contents 3" :alignment :right} {:text "contents 4"}] false) "contents 1contents 2contents 3contents 4"))) (deftest table->str (is (= (tables/table->str {:alignment-seq [{:alignment :left} {:alignment :center} {:alignment :right} {:alignment nil}] :data [[{:text "Header 1"} {:text "Header 2"} {:text "Header 3"} {:text "Header 4"}] [{:text "contents 1"} {:text "contents 2"} {:text "contents 3"} {:text "contents 4"}]]}) "
Header 1Header 2Header 3Header 4
contents 1contents 2contents 3contents 4
"))) (deftest divider-seq->alignment (is (= (tables/divider-seq->alignment [{:text "-----"} {:text ":-----"} {:text "-----:"} {:text ":-----:"}]) [nil {:alignment :left} {:alignment :right} {:alignment :center}]))) (deftest n-dash (is (= "

boo – bar

" (entry-function "boo -- bar")))) (deftest m-dash (is (= "

boo — bar

" (entry-function "boo --- bar")))) (deftest inhibit-simple (is (= "

_abc_

" (entry-function "$_abc_$" :inhibit-separator "$")))) (deftest inhibit-simple-seq (is (= "

_abc_

" (entry-function "$_abc_$" :inhibit-separator [\$])))) (deftest inhibit-inline-code (is (= "

`abc`

" (entry-function "$`abc`$" :inhibit-separator [\$])))) (deftest inhibit-inside-code (is (= "

a*b* & dc

" (entry-function "`a$*b* & d$c`" :inhibit-separator "$")))) (deftest inhibit-across-backticks (is (= "

one` `two

" (entry-function "`one$` `$two`" :inhibit-separator "$")))) (deftest inhibit-escape (is (= "

$

" (entry-function "$$" :inhibit-separator [\$])))) (deftest inhibit-escape-twice (is (= "

$$

" (entry-function "$$$$" :inhibit-separator "$")))) (deftest img-reprocess (is (= "

\"Text\" and Edit

" (entry-function "![Text](img.jpg) and [Edit](#)")))) (deftest dont-inhibit-text-within-escapes (is (= "

$abc$

" (entry-function "$$*abc*$$" :inhibit-separator "$")))) (deftest inhibit-escape-inside-code (is (= "

$

" (entry-function "`$$`" :inhibit-separator "$")))) (deftest whitespace-paragraphs (is (= "

foo

bar

" (entry-function "foo\n \nbar"))))