TCFlexLayout.pas 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349
  1. unit TCFlexLayout;
  2. {$mode ObjFPC}{$H+}
  3. interface
  4. uses
  5. Classes, SysUtils, testregistry, TCFresnelCSS, Fresnel.Controls, Fresnel.DOM;
  6. type
  7. { TTestFlexLayout }
  8. TTestFlexLayout = class(TCustomTestFresnelCSS)
  9. published
  10. procedure TestFlexLayout_Empty;
  11. procedure TestFlexLayout_Empty_FlexInline;
  12. procedure TestFlexLayout_Row_OneItem;
  13. procedure TestFlexLayout_Row_OneItem_NoGrow;
  14. procedure TestFlexLayout_Row_OneItem_Grow;
  15. procedure TestFlexLayout_Row_OneItem_Shrink;
  16. procedure TestFlexLayout_Row_TwoItems_Grow;
  17. procedure TestFlexLayout_Row_TwoItems_JustifyCenter;
  18. // todo: test flex-direction:row, flex-wrap:nowrap
  19. // todo: test flex-direction:row-reverse, flex-wrap:nowrap
  20. // todo: test flex-direction:row, flex-wrap:wrap
  21. // todo: test flex-direction:row-reverse, flex-wrap:wrap
  22. // todo: test flex-direction:row, flex-wrap:wrap-reverse
  23. // todo: test flex-direction:row-reverse, flex-wrap:wrap-reverse
  24. // todo: test flex-direction:column, flex-wrap:nowrap
  25. // todo: test flex-direction:column-reverse, flex-wrap:nowrap
  26. // todo: test flex-direction:column, flex-wrap:wrap
  27. // todo: test flex-direction:column-reverse, flex-wrap:wrap
  28. // todo: test flex-direction:column, flex-wrap:wrap-reverse
  29. // todo: test flex-direction:column-reverse, flex-wrap:wrap-reverse
  30. // todo: test child visibility:collapse
  31. // todo: test child visibility:hidden
  32. // todo: test child position:relative
  33. // todo: test child position:absolute
  34. // todo: test child position:fixed
  35. // todo: test child position:sticky
  36. // todo: test justify-content: left, right, start, end, flex-start, flex-end, center, space-around, space-between, space-evenly
  37. // todo: test align-items: stretch, normal, left, right, start, end, flex-start, flex-end, center, baseline, first baseline, last baseline
  38. // todo: test column-gap, row-gap
  39. // todo: test padding-left,right,top,bottom percentage uses container's width
  40. // todo: test margin-left,right,top,bottom percentage uses container's width
  41. end;
  42. implementation
  43. { TTestFlexLayout }
  44. procedure TTestFlexLayout.TestFlexLayout_Empty;
  45. var
  46. FlexDiv: TDiv;
  47. begin
  48. FlexDiv:=TDiv.Create(Viewport);
  49. FlexDiv.Name:='FlexDiv';
  50. FlexDiv.Parent:=Viewport;
  51. Viewport.Stylesheet.Text:=LinesToStr([
  52. '#FlexDiv { width: 100px; height: 100px; display: flex; }'
  53. ]);
  54. Viewport.Draw;
  55. AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
  56. AssertEquals('FlexDiv.GetComputedString(fcaWidth)','100px',FlexDiv.GetComputedString(fcaWidth));
  57. AssertEquals('FlexDiv.GetComputedString(fcaDisplay)','flex',FlexDiv.GetComputedString(fcaDisplay));
  58. AssertEquals('FlexDiv.ComputedDisplayInside',CSSRegistry.Keywords[CSSRegistry.kwFlex],CSSRegistry.Keywords[FlexDiv.ComputedDisplayInside]);
  59. AssertEquals('FlexDiv.ComputedDisplayOutside',CSSRegistry.Keywords[CSSRegistry.kwBlock],CSSRegistry.Keywords[FlexDiv.ComputedDisplayOutside]);
  60. end;
  61. procedure TTestFlexLayout.TestFlexLayout_Empty_FlexInline;
  62. var
  63. FlexDiv: TDiv;
  64. begin
  65. FlexDiv:=TDiv.Create(Viewport);
  66. FlexDiv.Name:='FlexDiv';
  67. FlexDiv.Parent:=Viewport;
  68. Viewport.Stylesheet.Text:=LinesToStr([
  69. '#FlexDiv { width: 100px; height: 100px; display: inline flex; }'
  70. ]);
  71. Viewport.Draw;
  72. AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
  73. AssertEquals('FlexDiv.GetComputedString(fcaWidth)','100px',FlexDiv.GetComputedString(fcaWidth));
  74. AssertEquals('FlexDiv.GetComputedString(fcaDisplay)','inline flex',FlexDiv.GetComputedString(fcaDisplay));
  75. AssertEquals('FlexDiv.ComputedDisplayInside',CSSRegistry.Keywords[CSSRegistry.kwFlex],CSSRegistry.Keywords[FlexDiv.ComputedDisplayInside]);
  76. AssertEquals('FlexDiv.ComputedDisplayOutside',CSSRegistry.Keywords[CSSRegistry.kwInline],CSSRegistry.Keywords[FlexDiv.ComputedDisplayOutside]);
  77. end;
  78. procedure TTestFlexLayout.TestFlexLayout_Row_OneItem;
  79. var
  80. FlexDiv, Div1: TDiv;
  81. Body: TBody;
  82. begin
  83. Body:=TBody.Create(Viewport);
  84. Body.Name:='Body';
  85. Body.Parent:=Viewport;
  86. FlexDiv:=TDiv.Create(Viewport);
  87. FlexDiv.Name:='FlexDiv';
  88. FlexDiv.Parent:=Body;
  89. Div1:=TDiv.Create(Viewport);
  90. Div1.Name:='Div1';
  91. Div1.Parent:=FlexDiv;
  92. Viewport.Stylesheet.Text:=LinesToStr([
  93. 'body { margin: 0; }',
  94. '#FlexDiv { display: flex; }',
  95. '#Div1 { width: 30px; height: 20px; }'
  96. ]);
  97. Viewport.Draw;
  98. AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
  99. AssertEquals('FlexDiv.GetComputedString(fcaDisplay)','flex',FlexDiv.GetComputedString(fcaDisplay));
  100. AssertEquals('Div1.UsedContentBox.Left',0,Div1.UsedContentBox.Left);
  101. AssertEquals('Div1.UsedContentBox.Top',0,Div1.UsedContentBox.Top);
  102. AssertEquals('Div1.UsedContentBox.Width',30,Div1.UsedContentBox.Width);
  103. AssertEquals('Div1.UsedContentBox.Height',20,Div1.UsedContentBox.Height);
  104. AssertEquals('FlexDiv.UsedContentBox.Left',0,FlexDiv.UsedContentBox.Left);
  105. AssertEquals('FlexDiv.UsedContentBox.Top',0,FlexDiv.UsedContentBox.Top);
  106. AssertEquals('FlexDiv.UsedContentBox.Width',800,FlexDiv.UsedContentBox.Width);
  107. AssertEquals('FlexDiv.UsedContentBox.Height',20,FlexDiv.UsedContentBox.Height);
  108. end;
  109. procedure TTestFlexLayout.TestFlexLayout_Row_OneItem_NoGrow;
  110. var
  111. FlexDiv, Div1: TDiv;
  112. Body: TBody;
  113. begin
  114. Body:=TBody.Create(Viewport);
  115. Body.Name:='Body';
  116. Body.Parent:=Viewport;
  117. FlexDiv:=TDiv.Create(Viewport);
  118. FlexDiv.Name:='FlexDiv';
  119. FlexDiv.Parent:=Body;
  120. Div1:=TDiv.Create(Viewport);
  121. Div1.Name:='Div1';
  122. Div1.Parent:=FlexDiv;
  123. Viewport.Stylesheet.Text:=LinesToStr([
  124. 'body { margin: 0; }',
  125. '#FlexDiv { display: flex; width: 200px; }',
  126. '#Div1 { width: 30px; height: 20px; }'
  127. ]);
  128. Viewport.Draw;
  129. AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
  130. AssertEquals('FlexDiv.GetComputedString(fcaDisplay)','flex',FlexDiv.GetComputedString(fcaDisplay));
  131. AssertEquals('Div1.GetComputedString(fcaFlexGrow)','0',Div1.GetComputedString(fcaFlexGrow));
  132. AssertEquals('Div1.UsedContentBox.Left',0,Div1.UsedContentBox.Left);
  133. AssertEquals('Div1.UsedContentBox.Top',0,Div1.UsedContentBox.Top);
  134. AssertEquals('Div1.UsedContentBox.Width',30,Div1.UsedContentBox.Width);
  135. AssertEquals('Div1.UsedContentBox.Height',20,Div1.UsedContentBox.Height);
  136. AssertEquals('FlexDiv.UsedContentBox.Left',0,FlexDiv.UsedContentBox.Left);
  137. AssertEquals('FlexDiv.UsedContentBox.Top',0,FlexDiv.UsedContentBox.Top);
  138. AssertEquals('FlexDiv.UsedContentBox.Width',200,FlexDiv.UsedContentBox.Width);
  139. AssertEquals('FlexDiv.UsedContentBox.Height',20,FlexDiv.UsedContentBox.Height);
  140. end;
  141. procedure TTestFlexLayout.TestFlexLayout_Row_OneItem_Grow;
  142. var
  143. FlexDiv, Div1: TDiv;
  144. Body: TBody;
  145. begin
  146. Body:=TBody.Create(Viewport);
  147. Body.Name:='Body';
  148. Body.Parent:=Viewport;
  149. FlexDiv:=TDiv.Create(Viewport);
  150. FlexDiv.Name:='FlexDiv';
  151. FlexDiv.Parent:=Body;
  152. Div1:=TDiv.Create(Viewport);
  153. Div1.Name:='Div1';
  154. Div1.Parent:=FlexDiv;
  155. Viewport.Stylesheet.Text:=LinesToStr([
  156. 'body { margin: 0; }',
  157. '#FlexDiv { display: flex; width: 200px; }',
  158. '#Div1 { width: 30px; height: 20px; flex-grow: 1; }'
  159. ]);
  160. Viewport.Draw;
  161. AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
  162. AssertEquals('FlexDiv.GetComputedString(fcaDisplay)','flex',FlexDiv.GetComputedString(fcaDisplay));
  163. AssertEquals('Div1.GetComputedString(fcaFlexGrow)','1',Div1.GetComputedString(fcaFlexGrow));
  164. AssertEquals('Div1.UsedContentBox.Left',0,Div1.UsedContentBox.Left);
  165. AssertEquals('Div1.UsedContentBox.Top',0,Div1.UsedContentBox.Top);
  166. AssertEquals('Div1.UsedContentBox.Width',200,Div1.UsedContentBox.Width);
  167. AssertEquals('Div1.UsedContentBox.Height',20,Div1.UsedContentBox.Height);
  168. AssertEquals('FlexDiv.UsedContentBox.Left',0,FlexDiv.UsedContentBox.Left);
  169. AssertEquals('FlexDiv.UsedContentBox.Top',0,FlexDiv.UsedContentBox.Top);
  170. AssertEquals('FlexDiv.UsedContentBox.Width',200,FlexDiv.UsedContentBox.Width);
  171. AssertEquals('FlexDiv.UsedContentBox.Height',20,FlexDiv.UsedContentBox.Height);
  172. end;
  173. procedure TTestFlexLayout.TestFlexLayout_Row_OneItem_Shrink;
  174. var
  175. FlexDiv, Div1: TDiv;
  176. Body: TBody;
  177. begin
  178. Body:=TBody.Create(Viewport);
  179. Body.Name:='Body';
  180. Body.Parent:=Viewport;
  181. FlexDiv:=TDiv.Create(Viewport);
  182. FlexDiv.Name:='FlexDiv';
  183. FlexDiv.Parent:=Body;
  184. Div1:=TDiv.Create(Viewport);
  185. Div1.Name:='Div1';
  186. Div1.Parent:=FlexDiv;
  187. Viewport.Stylesheet.Text:=LinesToStr([
  188. 'body { margin: 0; }',
  189. '#FlexDiv { display: flex; width: 10px; }',
  190. '#Div1 { width: 30px; height: 20px; }'
  191. ]);
  192. Viewport.Draw;
  193. AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
  194. AssertEquals('FlexDiv.GetComputedString(fcaDisplay)','flex',FlexDiv.GetComputedString(fcaDisplay));
  195. AssertEquals('Div1.UsedContentBox.Left',0,Div1.UsedContentBox.Left);
  196. AssertEquals('Div1.UsedContentBox.Top',0,Div1.UsedContentBox.Top);
  197. AssertEquals('Div1.UsedContentBox.Width',10,Div1.UsedContentBox.Width);
  198. AssertEquals('Div1.UsedContentBox.Height',20,Div1.UsedContentBox.Height);
  199. AssertEquals('FlexDiv.UsedContentBox.Left',0,FlexDiv.UsedContentBox.Left);
  200. AssertEquals('FlexDiv.UsedContentBox.Top',0,FlexDiv.UsedContentBox.Top);
  201. AssertEquals('FlexDiv.UsedContentBox.Width',10,FlexDiv.UsedContentBox.Width);
  202. AssertEquals('FlexDiv.UsedContentBox.Height',20,FlexDiv.UsedContentBox.Height);
  203. end;
  204. procedure TTestFlexLayout.TestFlexLayout_Row_TwoItems_Grow;
  205. var
  206. FlexDiv, Div1, Div2: TDiv;
  207. Body: TBody;
  208. begin
  209. Body:=TBody.Create(Viewport);
  210. Body.Name:='Body';
  211. Body.Parent:=Viewport;
  212. FlexDiv:=TDiv.Create(Viewport);
  213. FlexDiv.Name:='FlexDiv';
  214. FlexDiv.Parent:=Body;
  215. Div1:=TDiv.Create(Viewport);
  216. Div1.Name:='Div1';
  217. Div1.Parent:=FlexDiv;
  218. Div2:=TDiv.Create(Viewport);
  219. Div2.Name:='Div2';
  220. Div2.Parent:=FlexDiv;
  221. Viewport.Stylesheet.Text:=LinesToStr([
  222. 'body { margin: 0; }',
  223. '#FlexDiv { display: flex; width: 200px; }',
  224. '#Div1 { width: 30px; height: 20px; flex-grow: 3; }',
  225. '#Div2 { width: 70px; height: 20px; flex-grow: 2; }'
  226. ]);
  227. Viewport.Draw;
  228. AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
  229. AssertEquals('FlexDiv.GetComputedString(fcaDisplay)','flex',FlexDiv.GetComputedString(fcaDisplay));
  230. AssertEquals('Div1.GetComputedString(fcaFlexGrow)','3',Div1.GetComputedString(fcaFlexGrow));
  231. AssertEquals('Div2.GetComputedString(fcaFlexGrow)','2',Div2.GetComputedString(fcaFlexGrow));
  232. AssertEquals('FlexDiv.UsedContentBox.Left',0,FlexDiv.UsedContentBox.Left);
  233. AssertEquals('FlexDiv.UsedContentBox.Top',0,FlexDiv.UsedContentBox.Top);
  234. AssertEquals('FlexDiv.UsedContentBox.Width',200,FlexDiv.UsedContentBox.Width);
  235. AssertEquals('FlexDiv.UsedContentBox.Height',20,FlexDiv.UsedContentBox.Height);
  236. AssertEquals('Div1.UsedContentBox.Left',0,Div1.UsedContentBox.Left);
  237. AssertEquals('Div1.UsedContentBox.Top',0,Div1.UsedContentBox.Top);
  238. AssertEquals('Div1.UsedContentBox.Width',90,Div1.UsedContentBox.Width);
  239. AssertEquals('Div1.UsedContentBox.Height',20,Div1.UsedContentBox.Height);
  240. AssertEquals('Div2.UsedContentBox.Left',90,Div2.UsedContentBox.Left);
  241. AssertEquals('Div2.UsedContentBox.Top',0,Div2.UsedContentBox.Top);
  242. AssertEquals('Div2.UsedContentBox.Width',110,Div2.UsedContentBox.Width);
  243. AssertEquals('Div2.UsedContentBox.Height',20,Div2.UsedContentBox.Height);
  244. end;
  245. procedure TTestFlexLayout.TestFlexLayout_Row_TwoItems_JustifyCenter;
  246. var
  247. FlexDiv, Div1, Div2: TDiv;
  248. Body: TBody;
  249. begin
  250. Body:=TBody.Create(Viewport);
  251. Body.Name:='Body';
  252. Body.Parent:=Viewport;
  253. FlexDiv:=TDiv.Create(Viewport);
  254. FlexDiv.Name:='FlexDiv';
  255. FlexDiv.Parent:=Body;
  256. Div1:=TDiv.Create(Viewport);
  257. Div1.Name:='Div1';
  258. Div1.Parent:=FlexDiv;
  259. Div2:=TDiv.Create(Viewport);
  260. Div2.Name:='Div2';
  261. Div2.Parent:=FlexDiv;
  262. Viewport.Stylesheet.Text:=LinesToStr([
  263. 'body { margin: 0; }',
  264. '#FlexDiv { display: flex; width: 200px; justify-content: center; }',
  265. '#Div1 { width: 30px; height: 20px; }',
  266. '#Div2 { width: 70px; height: 20px; }'
  267. ]);
  268. Viewport.Draw;
  269. AssertEquals('FlexDiv.Rendered',true,FlexDiv.Rendered);
  270. AssertEquals('FlexDiv.GetComputedString(fcaDisplay)','flex',FlexDiv.GetComputedString(fcaDisplay));
  271. AssertEquals('FlexDiv.GetComputedString(fcaJustifyContent)','center',FlexDiv.GetComputedString(fcaJustifyContent));
  272. AssertEquals('FlexDiv.UsedContentBox.Left',0,FlexDiv.UsedContentBox.Left);
  273. AssertEquals('FlexDiv.UsedContentBox.Top',0,FlexDiv.UsedContentBox.Top);
  274. AssertEquals('FlexDiv.UsedContentBox.Width',200,FlexDiv.UsedContentBox.Width);
  275. AssertEquals('FlexDiv.UsedContentBox.Height',20,FlexDiv.UsedContentBox.Height);
  276. AssertEquals('Div1.UsedContentBox.Left',50,Div1.UsedContentBox.Left);
  277. AssertEquals('Div1.UsedContentBox.Top',0,Div1.UsedContentBox.Top);
  278. AssertEquals('Div1.UsedContentBox.Width',30,Div1.UsedContentBox.Width);
  279. AssertEquals('Div1.UsedContentBox.Height',20,Div1.UsedContentBox.Height);
  280. AssertEquals('Div2.UsedContentBox.Left',80,Div2.UsedContentBox.Left);
  281. AssertEquals('Div2.UsedContentBox.Top',0,Div2.UsedContentBox.Top);
  282. AssertEquals('Div2.UsedContentBox.Width',70,Div2.UsedContentBox.Width);
  283. AssertEquals('Div2.UsedContentBox.Height',20,Div2.UsedContentBox.Height);
  284. end;
  285. Initialization
  286. RegisterTests([TTestFlexLayout]);
  287. end.