{"fileId":"664d362ac4aa0dc46f5f868d795c6aa0e75acc9cf7c351fc7445bbb7cc28c841","type":"Contented","path":"/jest/pipelines/jest-markdown","modifiedDate":1696943516077,"sections":["Pipelines"],"fields":{"title":"Jest Markdown Pipeline","description":"\"Nothing is better than documentation with examples. But nothing is worse than examples that don't work because the code has changed since the documentation was written.\" - rustbook"},"headings":[{"depth":1,"headingId":"jest-markdown-pipeline","title":"Jest Markdown Pipeline","children":[{"depth":2,"headingId":"comments-parsing","title":"Comments Parsing","children":[{"depth":3,"headingId":"this-section-is-generated-by-the-code-snippet-below","title":"This section is generated by the code snippet below.","children":[]}]},{"depth":2,"headingId":"including-codeblocks","title":"Including Codeblocks","children":[]}]}],"html":"<nav class=\"toc\"><ol class=\"toc-level toc-level-1\"><li class=\"toc-item toc-item-h1\"><a class=\"toc-link toc-link-h1\" href=\"#jest-markdown-pipeline\">Jest Markdown Pipeline</a><ol class=\"toc-level toc-level-2\"><li class=\"toc-item toc-item-h2\"><a class=\"toc-link toc-link-h2\" href=\"#comments-parsing\">Comments Parsing</a><ol class=\"toc-level toc-level-3\"><li class=\"toc-item toc-item-h3\"><a class=\"toc-link toc-link-h3\" href=\"#this-section-is-generated-by-the-code-snippet-below\">This section is generated by the code snippet below.</a></li></ol></li><li class=\"toc-item toc-item-h2\"><a class=\"toc-link toc-link-h2\" href=\"#including-codeblocks\">Including Codeblocks</a></li></ol></li></ol></nav><h1 id=\"jest-markdown-pipeline\"><a aria-hidden=\"true\" tabindex=\"-1\" href=\"#jest-markdown-pipeline\"><span class=\"icon icon-link\"></span></a>Jest Markdown Pipeline</h1>\n<p>\"Nothing is better than documentation with examples. But nothing is worse than examples that\ndon't work because the code has changed since the documentation was written.\" - rustbook</p>\n<p>Example code blocks in our markdown or inline documentation comments can be useful to quickly\ndemonstrate how one can use our software. As they are part of our living standards, each example\ncode should be functional code that can be asserted and tested. Documentation example code should be\nautomated, tested and linted as part of our workflow.</p>\n<p>Initially, we were thinking of creating a <code>md-jest</code> for parsing code blocks in markdown and transforming them into\njest tests. Similar to how <code>ts-jest</code> transform TS to CommonJS, but using <code>contented-processor</code> to transform MD files.</p>\n<p><a href=\"https://github.com/eli-lim\" target=\"_blank\" rel=\"nofollow\">@eli-lim</a> suggested we transform jest files <code>*.test.ts</code> into Markdown instead. We\nget the DX of writing test with Jest and IDE support (without having to support write our own runner). It is much\neasier to transform comments to markdown than transform markdown to code (although not much harder, the focus here is\non the DX). Further, you get the natural flow of writing narrative and writing tests as a narrative.</p>\n<blockquote>\n<p>This page, is written in a jest test file. <code>JestMarkdown.spec.ts</code></p>\n</blockquote>\n<h2 id=\"comments-parsing\"><a aria-hidden=\"true\" tabindex=\"-1\" href=\"#comments-parsing\"><span class=\"icon icon-link\"></span></a>Comments Parsing</h2>\n<p>All comments are automatically picked up as Markdown with indent stripped. Indent are stripped using\n<code>strip-indent</code>, <code>*</code> are also stripped. For bullet points, you should use <code>-</code> and avoid using <code>*</code> to prevent\nunintentional stripping.</p>\n<ul>\n<li><code>//</code> - Line Comment</li>\n<li><code>/*</code> - Block Comment</li>\n<li><code>/**</code> - Block Comment</li>\n</ul>\n<hr>\n<h3 id=\"this-section-is-generated-by-the-code-snippet-below\"><a aria-hidden=\"true\" tabindex=\"-1\" href=\"#this-section-is-generated-by-the-code-snippet-below\"><span class=\"icon icon-link\"></span></a>This section is generated by the code snippet below.</h3>\n<p>This is a multi line with <code>*</code> stripped from each line.</p>\n<p>This is a <code>Line Comment</code></p>\n<p>This is a <code>Block Comment</code></p>\n<p>This is a <code>Multi Line</code>\n<code>Block Comment</code> without <code>*</code>.</p>\n<div class=\"rehype-shiki\"><pre class=\"shiki css-variable\" style=\"background-color: var(--shiki-color-background)\"><code><span class=\"line\"><span style=\"color: var(--shiki-token-comment)\">/**</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-token-comment)\"> * ### This section is generated by the code snippet below.</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-token-comment)\"> *</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-token-comment)\"> * This is a multi line with `*` stripped from each line.</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-token-comment)\"> */</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-token-comment)\">// This is a `Line Comment`</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-token-comment)\">/* This is a `Block Comment` */</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-token-comment)\">/* This is a `Multi Line`</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-token-comment)\"> `Block Comment` without `*`. */</span></span></code></pre></div>\n<h2 id=\"including-codeblocks\"><a aria-hidden=\"true\" tabindex=\"-1\" href=\"#including-codeblocks\"><span class=\"icon icon-link\"></span></a>Including Codeblocks</h2>\n<p><code>JestMarkdown</code> has the ability to \"pickup\" codes and add them into a codeblock. Codeblock is parsed line by line,\n<code>@contented codeblock:start</code> indicate the starting line and <code>@contented codeblock:end</code> indicate the ending line.\nEverything between will be included into a codeblock. Although not recommended, you can nest multiple\n<code>@contented codeblock</code> between.</p>\n<div class=\"rehype-shiki\"><pre class=\"shiki css-variable\" style=\"background-color: var(--shiki-color-background)\"><code><span class=\"line\"><span style=\"color: var(--shiki-token-string-expression)\">'@contented codeblock:start'</span><span style=\"color: var(--shiki-token-punctuation)\">,</span></span></code></pre></div>\n<div class=\"rehype-shiki\"><pre class=\"shiki css-variable\" style=\"background-color: var(--shiki-color-background)\"><code><span class=\"line\"><span style=\"color: var(--shiki-token-string-expression)\">'@contented codeblock:end'</span><span style=\"color: var(--shiki-token-punctuation)\">,</span></span></code></pre></div>\n<div class=\"rehype-shiki\"><pre class=\"shiki css-variable\" style=\"background-color: var(--shiki-color-background)\"><code><span class=\"line\"><span style=\"color: var(--shiki-token-function)\">it</span><span style=\"color: var(--shiki-color-text)\">(</span><span style=\"color: var(--shiki-token-string-expression)\">'this it statement is in a codeblock with nested codeblock'</span><span style=\"color: var(--shiki-token-punctuation)\">,</span><span style=\"color: var(--shiki-color-text)\"> () </span><span style=\"color: var(--shiki-token-keyword)\">=></span><span style=\"color: var(--shiki-color-text)\"> {</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">  </span><span style=\"color: var(--shiki-token-keyword)\">const</span><span style=\"color: var(--shiki-color-text)\"> </span><span style=\"color: var(--shiki-token-constant)\">symbols</span><span style=\"color: var(--shiki-color-text)\"> </span><span style=\"color: var(--shiki-token-keyword)\">=</span><span style=\"color: var(--shiki-color-text)\"> [</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">    </span><span style=\"color: var(--shiki-token-comment)\">// @contented codeblock:start</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">    </span><span style=\"color: var(--shiki-token-string-expression)\">'@contented codeblock:start'</span><span style=\"color: var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">    </span><span style=\"color: var(--shiki-token-comment)\">// @contented codeblock:end</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">    </span><span style=\"color: var(--shiki-token-string-expression)\">'everything in between will be included as a TypeScript codeblock ```ts\\n```'</span><span style=\"color: var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">    </span><span style=\"color: var(--shiki-token-comment)\">// @contented codeblock:start</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">    </span><span style=\"color: var(--shiki-token-string-expression)\">'@contented codeblock:end'</span><span style=\"color: var(--shiki-token-punctuation)\">,</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">    </span><span style=\"color: var(--shiki-token-comment)\">// @contented codeblock:end</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">  ];</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">  </span><span style=\"color: var(--shiki-token-function)\">expect</span><span style=\"color: var(--shiki-color-text)\">(</span><span style=\"color: var(--shiki-token-function)\">join</span><span style=\"color: var(--shiki-color-text)\">(</span><span style=\"color: var(--shiki-token-keyword)\">...</span><span style=\"color: var(--shiki-color-text)\">symbols))</span><span style=\"color: var(--shiki-token-function)\">.toBeDefined</span><span style=\"color: var(--shiki-color-text)\">();</span></span>\n<span class=\"line\"><span style=\"color: var(--shiki-color-text)\">});</span></span></code></pre></div>"}