You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

309 lines
12KB

  1. extern crate tera;
  2. extern crate front_matter;
  3. extern crate templates;
  4. extern crate rendering;
  5. use std::collections::HashMap;
  6. use tera::Tera;
  7. use front_matter::InsertAnchor;
  8. use templates::GUTENBERG_TERA;
  9. use rendering::{Context, markdown_to_html};
  10. #[test]
  11. fn can_do_markdown_to_html_simple() {
  12. let tera_ctx = Tera::default();
  13. let permalinks_ctx = HashMap::new();
  14. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  15. let res = markdown_to_html("hello", &context).unwrap();
  16. assert_eq!(res.0, "<p>hello</p>\n");
  17. }
  18. #[test]
  19. fn doesnt_highlight_code_block_with_highlighting_off() {
  20. let tera_ctx = Tera::default();
  21. let permalinks_ctx = HashMap::new();
  22. let mut context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  23. context.highlight_code = false;
  24. let res = markdown_to_html("```\n$ gutenberg server\n```", &context).unwrap();
  25. assert_eq!(
  26. res.0,
  27. "<pre><code>$ gutenberg server\n</code></pre>\n"
  28. );
  29. }
  30. #[test]
  31. fn can_highlight_code_block_no_lang() {
  32. let tera_ctx = Tera::default();
  33. let permalinks_ctx = HashMap::new();
  34. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  35. let res = markdown_to_html("```\n$ gutenberg server\n$ ping\n```", &context).unwrap();
  36. assert_eq!(
  37. res.0,
  38. "<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">$ gutenberg server\n</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">$ ping\n</span></pre>"
  39. );
  40. }
  41. #[test]
  42. fn can_highlight_code_block_with_lang() {
  43. let tera_ctx = Tera::default();
  44. let permalinks_ctx = HashMap::new();
  45. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  46. let res = markdown_to_html("```python\nlist.append(1)\n```", &context).unwrap();
  47. assert_eq!(
  48. res.0,
  49. "<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">list</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">.</span><span style=\"background-color:#2b303b;color:#bf616a;\">append</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">(</span><span style=\"background-color:#2b303b;color:#d08770;\">1</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">)</span><span style=\"background-color:#2b303b;color:#c0c5ce;\">\n</span></pre>"
  50. );
  51. }
  52. #[test]
  53. fn can_higlight_code_block_with_unknown_lang() {
  54. let tera_ctx = Tera::default();
  55. let permalinks_ctx = HashMap::new();
  56. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  57. let res = markdown_to_html("```yolo\nlist.append(1)\n```", &context).unwrap();
  58. // defaults to plain text
  59. assert_eq!(
  60. res.0,
  61. "<pre style=\"background-color:#2b303b\">\n<span style=\"background-color:#2b303b;color:#c0c5ce;\">list.append(1)\n</span></pre>"
  62. );
  63. }
  64. #[test]
  65. fn can_render_shortcode() {
  66. let permalinks_ctx = HashMap::new();
  67. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  68. let res = markdown_to_html(r#"
  69. Hello
  70. {{ youtube(id="ub36ffWAqgQ") }}
  71. "#, &context).unwrap();
  72. assert!(res.0.contains("<p>Hello</p>\n<div >"));
  73. assert!(res.0.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ""#));
  74. }
  75. #[test]
  76. fn can_render_several_shortcode_in_row() {
  77. let permalinks_ctx = HashMap::new();
  78. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  79. let res = markdown_to_html(r#"
  80. Hello
  81. {{ youtube(id="ub36ffWAqgQ") }}
  82. {{ youtube(id="ub36ffWAqgQ", autoplay=true) }}
  83. {{ vimeo(id="210073083") }}
  84. {{ streamable(id="c0ic") }}
  85. {{ gist(url="https://gist.github.com/Keats/32d26f699dcc13ebd41b") }}
  86. "#, &context).unwrap();
  87. assert!(res.0.contains("<p>Hello</p>\n<div >"));
  88. assert!(res.0.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ""#));
  89. assert!(res.0.contains(r#"<iframe src="https://www.youtube.com/embed/ub36ffWAqgQ?autoplay=1""#));
  90. assert!(res.0.contains(r#"<iframe src="https://www.streamable.com/e/c0ic""#));
  91. assert!(res.0.contains(r#"//player.vimeo.com/video/210073083""#));
  92. }
  93. #[test]
  94. fn doesnt_render_shortcode_in_code_block() {
  95. let permalinks_ctx = HashMap::new();
  96. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  97. let res = markdown_to_html(r#"```{{ youtube(id="w7Ft2ymGmfc") }}```"#, &context).unwrap();
  98. assert_eq!(res.0, "<p><code>{{ youtube(id=&quot;w7Ft2ymGmfc&quot;) }}</code></p>\n");
  99. }
  100. #[test]
  101. fn can_render_shortcode_with_body() {
  102. let mut tera = Tera::default();
  103. tera.extend(&GUTENBERG_TERA).unwrap();
  104. tera.add_raw_template("shortcodes/quote.html", "<blockquote>{{ body }} - {{ author}}</blockquote>").unwrap();
  105. let permalinks_ctx = HashMap::new();
  106. let context = Context::new(&tera, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  107. let res = markdown_to_html(r#"
  108. Hello
  109. {% quote(author="Keats") %}
  110. A quote
  111. {% end %}
  112. "#, &context).unwrap();
  113. assert_eq!(res.0, "<p>Hello\n</p><blockquote>A quote - Keats</blockquote>");
  114. }
  115. #[test]
  116. fn errors_rendering_unknown_shortcode() {
  117. let tera_ctx = Tera::default();
  118. let permalinks_ctx = HashMap::new();
  119. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  120. let res = markdown_to_html("{{ hello(flash=true) }}", &context);
  121. assert!(res.is_err());
  122. }
  123. #[test]
  124. fn can_make_valid_relative_link() {
  125. let mut permalinks = HashMap::new();
  126. permalinks.insert("pages/about.md".to_string(), "https://vincent.is/about".to_string());
  127. let tera_ctx = Tera::default();
  128. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks, InsertAnchor::None);
  129. let res = markdown_to_html(
  130. r#"[rel link](./pages/about.md), [abs link](https://vincent.is/about)"#,
  131. &context
  132. ).unwrap();
  133. assert!(
  134. res.0.contains(r#"<p><a href="https://vincent.is/about">rel link</a>, <a href="https://vincent.is/about">abs link</a></p>"#)
  135. );
  136. }
  137. #[test]
  138. fn can_make_relative_links_with_anchors() {
  139. let mut permalinks = HashMap::new();
  140. permalinks.insert("pages/about.md".to_string(), "https://vincent.is/about".to_string());
  141. let tera_ctx = Tera::default();
  142. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks, InsertAnchor::None);
  143. let res = markdown_to_html(r#"[rel link](./pages/about.md#cv)"#, &context).unwrap();
  144. assert!(
  145. res.0.contains(r#"<p><a href="https://vincent.is/about#cv">rel link</a></p>"#)
  146. );
  147. }
  148. #[test]
  149. fn errors_relative_link_inexistant() {
  150. let tera_ctx = Tera::default();
  151. let permalinks_ctx = HashMap::new();
  152. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  153. let res = markdown_to_html("[rel link](./pages/about.md)", &context);
  154. assert!(res.is_err());
  155. }
  156. #[test]
  157. fn can_add_id_to_headers() {
  158. let tera_ctx = Tera::default();
  159. let permalinks_ctx = HashMap::new();
  160. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  161. let res = markdown_to_html(r#"# Hello"#, &context).unwrap();
  162. assert_eq!(res.0, "<h1 id=\"hello\">Hello</h1>\n");
  163. }
  164. #[test]
  165. fn can_add_id_to_headers_same_slug() {
  166. let tera_ctx = Tera::default();
  167. let permalinks_ctx = HashMap::new();
  168. let context = Context::new(&tera_ctx, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  169. let res = markdown_to_html("# Hello\n# Hello", &context).unwrap();
  170. assert_eq!(res.0, "<h1 id=\"hello\">Hello</h1>\n<h1 id=\"hello-1\">Hello</h1>\n");
  171. }
  172. #[test]
  173. fn can_insert_anchor_left() {
  174. let permalinks_ctx = HashMap::new();
  175. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::Left);
  176. let res = markdown_to_html("# Hello", &context).unwrap();
  177. assert_eq!(
  178. res.0,
  179. "<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello</h1>\n"
  180. );
  181. }
  182. #[test]
  183. fn can_insert_anchor_right() {
  184. let permalinks_ctx = HashMap::new();
  185. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::Right);
  186. let res = markdown_to_html("# Hello", &context).unwrap();
  187. assert_eq!(
  188. res.0,
  189. "<h1 id=\"hello\">Hello<a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\n</h1>\n"
  190. );
  191. }
  192. // See https://github.com/Keats/gutenberg/issues/42
  193. #[test]
  194. fn can_insert_anchor_with_exclamation_mark() {
  195. let permalinks_ctx = HashMap::new();
  196. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::Left);
  197. let res = markdown_to_html("# Hello!", &context).unwrap();
  198. assert_eq!(
  199. res.0,
  200. "<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello!</h1>\n"
  201. );
  202. }
  203. // See https://github.com/Keats/gutenberg/issues/53
  204. #[test]
  205. fn can_insert_anchor_with_link() {
  206. let permalinks_ctx = HashMap::new();
  207. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::Left);
  208. let res = markdown_to_html("## [](#xresources)Xresources", &context).unwrap();
  209. assert_eq!(
  210. res.0,
  211. "<h2 id=\"xresources\"><a class=\"gutenberg-anchor\" href=\"#xresources\" aria-label=\"Anchor link for: xresources\">🔗</a>\nXresources</h2>\n"
  212. );
  213. }
  214. #[test]
  215. fn can_insert_anchor_with_other_special_chars() {
  216. let permalinks_ctx = HashMap::new();
  217. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::Left);
  218. let res = markdown_to_html("# Hello*_()", &context).unwrap();
  219. assert_eq!(
  220. res.0,
  221. "<h1 id=\"hello\"><a class=\"gutenberg-anchor\" href=\"#hello\" aria-label=\"Anchor link for: hello\">🔗</a>\nHello*_()</h1>\n"
  222. );
  223. }
  224. #[test]
  225. fn can_make_toc() {
  226. let permalinks_ctx = HashMap::new();
  227. let context = Context::new(
  228. &GUTENBERG_TERA,
  229. true,
  230. "base16-ocean-dark".to_string(),
  231. "https://mysite.com/something",
  232. &permalinks_ctx,
  233. InsertAnchor::Left
  234. );
  235. let res = markdown_to_html(r#"
  236. # Header 1
  237. ## Header 2
  238. ## Another Header 2
  239. ### Last one
  240. "#, &context).unwrap();
  241. let toc = res.1;
  242. assert_eq!(toc.len(), 1);
  243. assert_eq!(toc[0].children.len(), 2);
  244. assert_eq!(toc[0].children[1].children.len(), 1);
  245. }
  246. #[test]
  247. fn can_understand_backtick_in_titles() {
  248. let permalinks_ctx = HashMap::new();
  249. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  250. let res = markdown_to_html("# `Hello`", &context).unwrap();
  251. assert_eq!(
  252. res.0,
  253. "<h1 id=\"hello\"><code>Hello</code></h1>\n"
  254. );
  255. }
  256. #[test]
  257. fn can_understand_backtick_in_paragraphs() {
  258. let permalinks_ctx = HashMap::new();
  259. let context = Context::new(&GUTENBERG_TERA, true, "base16-ocean-dark".to_string(), "", &permalinks_ctx, InsertAnchor::None);
  260. let res = markdown_to_html("Hello `world`", &context).unwrap();
  261. assert_eq!(
  262. res.0,
  263. "<p>Hello <code>world</code></p>\n"
  264. );
  265. }