utest.markdown.htmlrender.pas 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372
  1. {
  2. This file is part of the Free Component Library (FCL)
  3. Copyright (c) 2025 by Michael Van Canneyt
  4. Markdown HTML renderer tests
  5. See the file COPYING.FPC, included in this distribution,
  6. for details about the copyright.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  10. **********************************************************************}
  11. unit UTest.Markdown.HTMLRender;
  12. {$mode ObjFPC}{$H+}
  13. interface
  14. uses
  15. Classes, SysUtils, fpcunit, testregistry,
  16. MarkDown.Elements,
  17. MarkDown.HtmlRender;
  18. type
  19. { TTestHTMLRender }
  20. TTestHTMLRender = Class(TTestCase)
  21. private
  22. FHTMLRenderer : TMarkDownHTMLRenderer;
  23. FDocument: TMarkDownDocument;
  24. Public
  25. Procedure SetUp; override;
  26. Procedure TearDown; override;
  27. function CreateTextBlock(aParent: TMarkdownBlock; const aText,aTextNode: string; aNodeStyle : TNodeStyles=[]): TMarkDownTextBlock;
  28. function CreateParagraphBlock(const aTextNode: string): TMarkdownBlock;
  29. function CreateQuotedBlock(const aTextNode: string): TMarkdownBlock;
  30. function CreateHeadingBlock(const aTextNode: string; aLevel : integer): TMarkdownBlock;
  31. function CreateListBlock(aOrdered : boolean; const aListItemText : string): TMarkDownListBlock;
  32. function CreateListItemBlock(aParent: TMarkDownContainerBlock; const aText: string): TMarkDownListItemBlock;
  33. function AppendTextNode(aBlock: TMarkDownTextBlock; const aText: string; aNodeStyle : TNodeStyles) : TMarkDownTextNode;
  34. procedure TestRender(const aHTML : string);
  35. Property Renderer : TMarkDownHTMLRenderer Read FHTMLRenderer;
  36. Property Document : TMarkDownDocument Read FDocument;
  37. Published
  38. procedure TestHookup;
  39. procedure TestEmpty;
  40. procedure TestEmptyNoEnvelope;
  41. procedure TestEmptyTitle;
  42. procedure TestEmptyHead;
  43. procedure TestTextBlockEmpty;
  44. procedure TestTextBlockText;
  45. procedure TestTextBlockTextStrong;
  46. procedure TestTextBlockTextEmph;
  47. procedure TestTextBlockTextDelete;
  48. procedure TestTextBlockTextStrongEmph;
  49. procedure TestTextBlockTextStrongEmphSplit1;
  50. procedure TestTextBlockTextStrongEmphSplit2;
  51. procedure TestPragraphBlockEmpty;
  52. procedure TestPragraphBlockText;
  53. procedure TestQuotedBlockEmpty;
  54. procedure TestQuotedBlockText;
  55. procedure TestHeadingBlockEmpty;
  56. procedure TestHeadingBlockText;
  57. procedure TestHeadingBlockTextLevel2;
  58. procedure TestUnorderedListEmpty;
  59. procedure TestUnorderedListOneItem;
  60. end;
  61. implementation
  62. { TTestHTMLRender }
  63. procedure TTestHTMLRender.SetUp;
  64. begin
  65. FHTMLRenderer:=TMarkDownHTMLRenderer.Create(Nil);
  66. FDocument:=TMarkDownDocument.Create(Nil,1);
  67. end;
  68. procedure TTestHTMLRender.TearDown;
  69. begin
  70. FreeAndNil(FDocument);
  71. FreeAndNil(FHTMLRenderer);
  72. end;
  73. function TTestHTMLRender.CreateTextBlock(aParent: TMarkdownBlock; const aText, aTextNode: string; aNodeStyle: TNodeStyles): TMarkDownTextBlock;
  74. begin
  75. Result:=TMarkDownTextBlock.Create(aParent,1,aText);
  76. if aTextNode<>'' then
  77. AppendTextNode(Result,aTextNode,aNodeStyle);
  78. end;
  79. function TTestHTMLRender.CreateParagraphBlock(const aTextNode: string): TMarkdownBlock;
  80. begin
  81. Result:=TMarkDownParagraphBlock.Create(FDocument,1);
  82. if aTextNode<>'' then
  83. CreateTextBlock(Result,aTextNode,aTextNode);
  84. end;
  85. function TTestHTMLRender.CreateQuotedBlock(const aTextNode: string): TMarkdownBlock;
  86. begin
  87. Result:=TMarkDownQuoteBlock.Create(FDocument,1);
  88. if aTextNode<>'' then
  89. CreateTextBlock(Result,aTextNode,aTextNode);
  90. end;
  91. function TTestHTMLRender.CreateHeadingBlock(const aTextNode: string; aLevel: integer): TMarkdownBlock;
  92. begin
  93. Result:=TMarkDownHeadingBlock.Create(FDocument,1,aLevel);
  94. if aTextNode<>'' then
  95. CreateTextBlock(Result,aTextNode,aTextNode);
  96. end;
  97. function TTestHTMLRender.CreateListItemBlock(aParent: TMarkDownContainerBlock; const aText: string): TMarkDownListItemBlock;
  98. var
  99. lPar : TMarkDownParagraphBlock;
  100. begin
  101. Result:=TMarkDownListItemBlock.Create(aParent,1);
  102. lPar:=TMarkDownParagraphBlock.Create(Result,1);
  103. CreateTextBlock(lPar,'',aText);
  104. end;
  105. function TTestHTMLRender.CreateListBlock(aOrdered: boolean; const aListItemText: string): TMarkDownListBlock;
  106. begin
  107. Result:=TMarkDownListBlock.Create(FDocument,1);
  108. Result.ordered:=aOrdered;
  109. if aListItemText<>'' then
  110. CreateListItemBlock(Result,aListItemText);
  111. end;
  112. function TTestHTMLRender.AppendTextNode(aBlock: TMarkDownTextBlock; const aText: string; aNodeStyle: TNodeStyles): TMarkDownTextNode;
  113. var
  114. p : TPosition;
  115. t : TMarkdownTextNode;
  116. begin
  117. if aBlock.Nodes=Nil then
  118. aBlock.Nodes:=TMarkDownTextNodeList.Create(True);
  119. p.col:=Length(aBlock.Text);
  120. p.line:=1;
  121. t:=TMarkDownTextNode.Create(p,nkText);
  122. t.addText(aText);
  123. t.active:=False;
  124. T.Styles:=aNodeStyle;
  125. aBlock.Nodes.Add(t);
  126. Result:=T;
  127. end;
  128. procedure TTestHTMLRender.TestRender(const aHTML: string);
  129. var
  130. L : TStrings;
  131. begin
  132. L:=TstringList.Create;
  133. try
  134. L.SkipLastLineBreak:=True;
  135. Renderer.RenderDocument(FDocument,L);
  136. assertEquals('Correct html: ',aHTML,L.Text);
  137. finally
  138. L.Free;
  139. end;
  140. end;
  141. procedure TTestHTMLRender.TestHookup;
  142. begin
  143. AssertNotNull('Have renderer',FHTMLRenderer);
  144. AssertNotNull('Have document',FDocument);
  145. AssertEquals('Have empty document',0,FDocument.blocks.Count);
  146. end;
  147. procedure TTestHTMLRender.TestEmpty;
  148. begin
  149. Renderer.Options:=[hoEnvelope];
  150. TestRender('<!DOCTYPE html>'+sLineBreak+'<html>'+sLineBreak+'<body>'+sLineBreak+'</body>'+sLineBreak+'</html>');
  151. end;
  152. procedure TTestHTMLRender.TestEmptyNoEnvelope;
  153. begin
  154. Renderer.Options:=[];
  155. TestRender('');
  156. end;
  157. procedure TTestHTMLRender.TestEmptyTitle;
  158. begin
  159. Renderer.Options:=[hoEnvelope,hoHead];
  160. Renderer.Title:='a';
  161. TestRender('<!DOCTYPE html>'+sLineBreak+'<html>'+sLineBreak
  162. +'<head>'+sLineBreak+'<title>a</title>'+sLineBreak+'</head>'+sLineBreak
  163. +'<body>'+sLineBreak+'</body>'+sLineBreak+'</html>');
  164. end;
  165. procedure TTestHTMLRender.TestEmptyHead;
  166. begin
  167. Renderer.Options:=[hoEnvelope,hoHead];
  168. Renderer.Head.Add('<meta charset="UTF8">');
  169. TestRender('<!DOCTYPE html>'+sLineBreak+'<html>'+sLineBreak
  170. +'<head>'+sLineBreak+'<meta charset="UTF8">'+sLineBreak+'</head>'+sLineBreak
  171. +'<body>'+sLineBreak+'</body>'+sLineBreak+'</html>');
  172. end;
  173. procedure TTestHTMLRender.TestTextBlockEmpty;
  174. begin
  175. CreateTextBlock(Document,'a','');
  176. TestRender('');
  177. end;
  178. procedure TTestHTMLRender.TestTextBlockText;
  179. begin
  180. CreateTextBlock(Document,'a','a');
  181. TestRender('a');
  182. end;
  183. procedure TTestHTMLRender.TestTextBlockTextStrong;
  184. begin
  185. CreateTextBlock(Document,'a','a',[nsStrong]);
  186. TestRender('<b>a</b>');
  187. end;
  188. procedure TTestHTMLRender.TestTextBlockTextEmph;
  189. begin
  190. CreateTextBlock(Document,'a','a',[nsEmph]);
  191. TestRender('<i>a</i>');
  192. end;
  193. procedure TTestHTMLRender.TestTextBlockTextDelete;
  194. begin
  195. CreateTextBlock(Document,'a','a',[nsDelete]);
  196. TestRender('<del>a</del>');
  197. end;
  198. procedure TTestHTMLRender.TestTextBlockTextStrongEmph;
  199. begin
  200. CreateTextBlock(Document,'a','a',[nsStrong,nsEmph]);
  201. TestRender('<b><i>a</i></b>');
  202. end;
  203. procedure TTestHTMLRender.TestTextBlockTextStrongEmphSplit1;
  204. var
  205. lBlock : TMarkDownTextBlock;
  206. begin
  207. lBlock:=CreateTextBlock(Document,'a','a ',[nsStrong]);
  208. AppendTextNode(lBlock,'b',[nsStrong,nsemph]);
  209. TestRender('<b>a <i>b</i></b>');
  210. end;
  211. procedure TTestHTMLRender.TestTextBlockTextStrongEmphSplit2;
  212. var
  213. lBlock : TMarkDownTextBlock;
  214. begin
  215. lBlock:=CreateTextBlock(Document,'a','a',[nsEmph,nsStrong]);
  216. AppendTextNode(lBlock,' b',[nsStrong]);
  217. TestRender('<b><i>a</i> b</b>');
  218. end;
  219. procedure TTestHTMLRender.TestPragraphBlockEmpty;
  220. begin
  221. CreateParagraphBlock('');
  222. TestRender('<p></p>');
  223. end;
  224. procedure TTestHTMLRender.TestPragraphBlockText;
  225. begin
  226. CreateParagraphBlock('a');
  227. TestRender('<p>a</p>');
  228. end;
  229. procedure TTestHTMLRender.TestQuotedBlockEmpty;
  230. begin
  231. CreateQuotedBlock('');
  232. TestRender('<blockquote>'+sLineBreak+'</blockquote>');
  233. end;
  234. procedure TTestHTMLRender.TestQuotedBlockText;
  235. begin
  236. CreateQuotedBlock('a');
  237. TestRender('<blockquote>'+sLineBreak+'a</blockquote>');
  238. end;
  239. procedure TTestHTMLRender.TestHeadingBlockEmpty;
  240. begin
  241. CreateHeadingBlock('',1);
  242. TestRender('<h1></h1>');
  243. end;
  244. procedure TTestHTMLRender.TestHeadingBlockText;
  245. begin
  246. CreateHeadingBlock('a',1);
  247. TestRender('<h1>a</h1>');
  248. end;
  249. procedure TTestHTMLRender.TestHeadingBlockTextLevel2;
  250. begin
  251. CreateHeadingBlock('a',2);
  252. TestRender('<h2>a</h2>');
  253. end;
  254. procedure TTestHTMLRender.TestUnorderedListEmpty;
  255. begin
  256. CreateListBlock(false,'');
  257. TestRender('<ul>'+sLineBreak+'</ul>');
  258. end;
  259. procedure TTestHTMLRender.TestUnorderedListOneItem;
  260. begin
  261. CreateListBlock(false,'a');
  262. TestRender('<ul>'+sLineBreak+'<li>a</li>'+sLineBreak+'</ul>');
  263. end;
  264. initialization
  265. Registertest(TTestHTMLRender);
  266. end.