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.

GridDeclarativeTest.java 35KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886
  1. /*
  2. * Copyright 2000-2016 Vaadin Ltd.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License"); you may not
  5. * use this file except in compliance with the License. You may obtain a copy of
  6. * the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. * License for the specific language governing permissions and limitations under
  14. * the License.
  15. */
  16. package com.vaadin.tests.server.component.grid;
  17. import static org.junit.Assert.assertNull;
  18. import java.lang.reflect.InvocationTargetException;
  19. import java.lang.reflect.Method;
  20. import java.util.List;
  21. import java.util.Locale;
  22. import org.jsoup.Jsoup;
  23. import org.jsoup.nodes.Document;
  24. import org.jsoup.nodes.Element;
  25. import org.jsoup.parser.Tag;
  26. import org.jsoup.select.Elements;
  27. import org.jsoup.select.Selector;
  28. import org.junit.Test;
  29. import com.vaadin.data.SelectionModel.Multi;
  30. import com.vaadin.data.SelectionModel.Single;
  31. import com.vaadin.data.provider.DataProvider;
  32. import com.vaadin.data.provider.Query;
  33. import com.vaadin.shared.ui.ContentMode;
  34. import com.vaadin.shared.ui.grid.HeightMode;
  35. import com.vaadin.tests.data.bean.Address;
  36. import com.vaadin.tests.data.bean.Country;
  37. import com.vaadin.tests.data.bean.Person;
  38. import com.vaadin.tests.data.bean.Sex;
  39. import com.vaadin.tests.server.component.abstractlisting.AbstractListingDeclarativeTest;
  40. import com.vaadin.ui.Grid;
  41. import com.vaadin.ui.Grid.Column;
  42. import com.vaadin.ui.Grid.SelectionMode;
  43. import com.vaadin.ui.Label;
  44. import com.vaadin.ui.TextField;
  45. import com.vaadin.ui.components.grid.FooterCell;
  46. import com.vaadin.ui.components.grid.FooterRow;
  47. import com.vaadin.ui.components.grid.HeaderCell;
  48. import com.vaadin.ui.components.grid.HeaderRow;
  49. import com.vaadin.ui.declarative.DesignContext;
  50. import com.vaadin.ui.declarative.DesignException;
  51. /**
  52. * @author Vaadin Ltd
  53. *
  54. */
  55. public class GridDeclarativeTest extends AbstractListingDeclarativeTest<Grid> {
  56. @Test
  57. public void gridAttributes() {
  58. Grid<Person> grid = new Grid<>();
  59. int frozenColumns = 1;
  60. HeightMode heightMode = HeightMode.ROW;
  61. double heightByRows = 13.7d;
  62. grid.addColumn(Person::getFirstName).setCaption("First Name");
  63. grid.addColumn(Person::getLastName).setId("id").setCaption("Id");
  64. grid.setFrozenColumnCount(frozenColumns);
  65. grid.setSelectionMode(SelectionMode.MULTI);
  66. grid.setHeightMode(heightMode);
  67. grid.setHeightByRows(heightByRows);
  68. String design = String.format(
  69. "<%s height-mode='%s' frozen-columns='%d' rows='%s' selection-mode='%s'><table><colgroup>"
  70. + "<col column-id='column0' sortable>"
  71. + "<col column-id='id' sortable>" + "</colgroup><thead>"
  72. + "<tr default><th plain-text column-ids='column0'>First Name</th>"
  73. + "<th plain-text column-ids='id'>Id</th></tr>"
  74. + "</thead></table></%s>",
  75. getComponentTag(),
  76. heightMode.toString().toLowerCase(Locale.ROOT), frozenColumns,
  77. heightByRows,
  78. SelectionMode.MULTI.toString().toLowerCase(Locale.ROOT),
  79. getComponentTag());
  80. testRead(design, grid);
  81. testWrite(design, grid);
  82. }
  83. @Test
  84. public void mergedHeaderCells() {
  85. Grid<Person> grid = new Grid<>();
  86. Column<Person, String> column1 = grid.addColumn(Person::getFirstName)
  87. .setCaption("First Name");
  88. Column<Person, String> column2 = grid.addColumn(Person::getLastName)
  89. .setId("id").setCaption("Id");
  90. Column<Person, String> column3 = grid.addColumn(Person::getEmail)
  91. .setId("mail").setCaption("Mail");
  92. HeaderRow header = grid.addHeaderRowAt(1);
  93. String headerRowText1 = "foo";
  94. header.getCell(column1).setText(headerRowText1);
  95. HeaderCell cell2 = header.getCell(column2);
  96. HeaderCell join = header.join(cell2, header.getCell(column3));
  97. String headerRowText3 = "foobar";
  98. join.setText(headerRowText3);
  99. String design = String.format("<%s><table><colgroup>"
  100. + "<col column-id='column0' sortable>"
  101. + "<col column-id='id' sortable>"
  102. + "<col column-id='mail' sortable>" + "</colgroup><thead>"
  103. + "<tr default><th plain-text column-ids='column0'>First Name</th>"
  104. + "<th plain-text column-ids='id'>Id</th>"
  105. + "<th plain-text column-ids='mail'>Mail</th></tr>"
  106. + "<tr><th plain-text column-ids='column0'>%s</th>"
  107. + "<th colspan='2' plain-text column-ids='id,mail'>foobar</th></tr>"
  108. + "</thead></table></%s>", getComponentTag(), headerRowText1,
  109. headerRowText3, getComponentTag());
  110. testRead(design, grid);
  111. testWrite(design, grid);
  112. }
  113. @Test
  114. public void mergedFooterCells() {
  115. Grid<Person> grid = new Grid<>();
  116. Column<Person, String> column1 = grid.addColumn(Person::getFirstName)
  117. .setCaption("First Name");
  118. Column<Person, String> column2 = grid.addColumn(Person::getLastName)
  119. .setId("id").setCaption("Id");
  120. Column<Person, String> column3 = grid.addColumn(Person::getEmail)
  121. .setId("mail").setCaption("Mail");
  122. FooterRow footer = grid.addFooterRowAt(0);
  123. FooterCell cell1 = footer.getCell(column1);
  124. String footerRowText1 = "foo";
  125. cell1.setText(footerRowText1);
  126. FooterCell cell2 = footer.getCell(column2);
  127. FooterCell cell3 = footer.getCell(column3);
  128. String footerRowText2 = "foobar";
  129. footer.join(cell2, cell3).setHtml(footerRowText2);
  130. String design = String.format("<%s><table><colgroup>"
  131. + "<col column-id='column0' sortable>"
  132. + "<col column-id='id' sortable>"
  133. + "<col column-id='mail' sortable>" + "</colgroup><thead>"
  134. + "<tr default><th plain-text column-ids='column0'>First Name</th>"
  135. + "<th plain-text column-ids='id'>Id</th>"
  136. + "<th plain-text column-ids='mail'>Mail</th></tr></thead>"
  137. + "<tfoot><tr><td plain-text column-ids='column0'>%s</td>"
  138. + "<td colspan='2' column-ids='id,mail'>%s</td></tr></tfoot>"
  139. + "</table></%s>", getComponentTag(), footerRowText1,
  140. footerRowText2, getComponentTag());
  141. testRead(design, grid);
  142. testWrite(design, grid);
  143. }
  144. @Test
  145. public void columnAttributes() {
  146. Grid<Person> grid = new Grid<>();
  147. String secondColumnId = "sortableColumn";
  148. Column<Person, String> notSortableColumn = grid
  149. .addColumn(Person::getFirstName).setCaption("First Name");
  150. Column<Person, String> column2 = grid.addColumn(Person::getLastName)
  151. .setId(secondColumnId).setCaption("Id");
  152. String caption = "not-sortable-column";
  153. notSortableColumn.setCaption(caption);
  154. boolean sortable = false;
  155. notSortableColumn.setSortable(sortable);
  156. boolean editable = true;
  157. notSortableColumn.setEditorComponent(new TextField(),
  158. Person::setLastName);
  159. notSortableColumn.setEditable(editable);
  160. boolean resizable = false;
  161. notSortableColumn.setResizable(resizable);
  162. boolean hidable = true;
  163. notSortableColumn.setHidable(hidable);
  164. boolean hidden = true;
  165. notSortableColumn.setHidden(hidden);
  166. String hidingToggleCaption = "sortable-toggle-caption";
  167. column2.setHidingToggleCaption(hidingToggleCaption);
  168. double width = 17.3;
  169. column2.setWidth(width);
  170. double minWidth = 37.3;
  171. column2.setMinimumWidth(minWidth);
  172. double maxWidth = 63.4;
  173. column2.setMaximumWidth(maxWidth);
  174. int expandRatio = 83;
  175. column2.setExpandRatio(expandRatio);
  176. String design = String.format("<%s><table><colgroup>"
  177. + "<col column-id='column0' sortable='%s' editable resizable='%s' hidable hidden>"
  178. + "<col column-id='sortableColumn' sortable hiding-toggle-caption='%s' width='%s' min-width='%s' max-width='%s' expand='%s'>"
  179. + "</colgroup><thead>"
  180. + "<tr default><th plain-text column-ids='column0'>%s</th>"
  181. + "<th plain-text column-ids='sortableColumn'>%s</th>"
  182. + "</tr></thead>" + "</table></%s>", getComponentTag(),
  183. sortable, resizable, hidingToggleCaption, width, minWidth,
  184. maxWidth, expandRatio, caption, "Id", getComponentTag());
  185. testRead(design, grid, true);
  186. testWrite(design, grid);
  187. }
  188. @Test
  189. public void headerFooterSerialization() {
  190. Grid<Person> grid = new Grid<>();
  191. Column<Person, String> column1 = grid.addColumn(Person::getFirstName)
  192. .setCaption("First Name");
  193. Column<Person, String> column2 = grid.addColumn(Person::getLastName)
  194. .setId("id").setCaption("Id");
  195. FooterRow footerRow = grid.addFooterRowAt(0);
  196. footerRow.getCell(column1).setText("x");
  197. footerRow.getCell(column2).setHtml("y");
  198. String design = String.format("<%s><table><colgroup>"
  199. + "<col column-id='column0' sortable>"
  200. + "<col column-id='id' sortable></colgroup><thead>"
  201. + "<tr default><th plain-text column-ids='column0'>First Name</th>"
  202. + "<th plain-text column-ids='id'>Id</th></tr>"
  203. + "</thead><tbody></tbody>"
  204. + "<tfoot><tr><td plain-text column-ids='column0'>x</td>"
  205. + "<td column-ids='id'>y</td></tr></tfoot>" + "</table></%s>",
  206. getComponentTag(), getComponentTag());
  207. testRead(design, grid);
  208. testWrite(design, grid, true);
  209. }
  210. @Override
  211. public void dataSerialization() throws InstantiationException,
  212. IllegalAccessException, InvocationTargetException {
  213. Grid<Person> grid = new Grid<>();
  214. Person person1 = createPerson("foo", "bar");
  215. Person person2 = createPerson("name", "last-name");
  216. grid.setItems(person1, person2);
  217. grid.addColumn(Person::getFirstName).setCaption("First Name");
  218. grid.addColumn(Person::getLastName).setId("id").setCaption("Id");
  219. String design = String.format("<%s><table><colgroup>"
  220. + "<col column-id='column0' sortable>"
  221. + "<col column-id='id' sortable></colgroup><thead>"
  222. + "<tr default><th plain-text column-ids='column0'>First Name</th>"
  223. + "<th plain-text column-ids='id'>Id</th></tr>"
  224. + "</thead><tbody>"
  225. + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
  226. + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
  227. + "</tbody></table></%s>", getComponentTag(),
  228. person1.toString(), person1.getFirstName(),
  229. person1.getLastName(), person2.toString(),
  230. person2.getFirstName(), person2.getLastName(),
  231. getComponentTag());
  232. Grid<?> readGrid = testRead(design, grid, true, true);
  233. assertEquals(2, readGrid.getDataProvider().size(new Query<>()));
  234. testWrite(design, grid, true);
  235. }
  236. /**
  237. * Value for single select
  238. */
  239. @Override
  240. @Test
  241. public void valueSerialization() throws InstantiationException,
  242. IllegalAccessException, InvocationTargetException {
  243. valueSingleSelectSerialization();
  244. }
  245. @SuppressWarnings("unchecked")
  246. @Test
  247. public void valueMultiSelectSerialization() throws InstantiationException,
  248. IllegalAccessException, InvocationTargetException {
  249. Grid<Person> grid = new Grid<>();
  250. Person person1 = createPerson("foo", "bar");
  251. Person person2 = createPerson("name", "last-name");
  252. Person person3 = createPerson("foo", "last-name");
  253. grid.setItems(person1, person2, person3);
  254. grid.addColumn(Person::getFirstName).setCaption("First Name");
  255. grid.addColumn(Person::getLastName).setId("id").setCaption("Id");
  256. Multi<Person> model = (Multi<Person>) grid
  257. .setSelectionMode(SelectionMode.MULTI);
  258. model.selectItems(person1, person3);
  259. String design = String.format(
  260. "<%s selection-mode='multi'><table><colgroup>"
  261. + "<col column-id='column0' sortable>"
  262. + "<col column-id='id' sortable></colgroup><thead>"
  263. + "<tr default><th plain-text column-ids='column0'>First Name</th>"
  264. + "<th plain-text column-ids='id'>Id</th></tr>"
  265. + "</thead><tbody>"
  266. + "<tr item='%s' selected><td>%s</td><td>%s</td></tr>"
  267. + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
  268. + "<tr item='%s' selected><td>%s</td><td>%s</td></tr>"
  269. + "</tbody></table></%s>",
  270. getComponentTag(), person1.toString(), person1.getFirstName(),
  271. person1.getLastName(), person2.toString(),
  272. person2.getFirstName(), person2.getLastName(),
  273. person3.toString(), person3.getFirstName(),
  274. person3.getLastName(), getComponentTag());
  275. Grid<?> readGrid = testRead(design, grid, true, true);
  276. assertEquals(3, readGrid.getDataProvider().size(new Query<>()));
  277. testWrite(design, grid, true);
  278. }
  279. @SuppressWarnings("unchecked")
  280. private void valueSingleSelectSerialization() throws InstantiationException,
  281. IllegalAccessException, InvocationTargetException {
  282. Grid<Person> grid = new Grid<>();
  283. Person person1 = createPerson("foo", "bar");
  284. Person person2 = createPerson("name", "last-name");
  285. grid.setItems(person1, person2);
  286. grid.addColumn(Person::getFirstName).setCaption("First Name");
  287. grid.addColumn(Person::getLastName).setId("id").setCaption("Id");
  288. Single<Person> model = (Single<Person>) grid
  289. .setSelectionMode(SelectionMode.SINGLE);
  290. model.select(person2);
  291. String design = String.format("<%s><table><colgroup>"
  292. + "<col column-id='column0' sortable>"
  293. + "<col column-id='id' sortable></colgroup><thead>"
  294. + "<tr default><th plain-text column-ids='column0'>First Name</th>"
  295. + "<th plain-text column-ids='id'>Id</th></tr>"
  296. + "</thead><tbody>"
  297. + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
  298. + "<tr item='%s' selected><td>%s</td><td>%s</td></tr>"
  299. + "</tbody></table></%s>", getComponentTag(),
  300. person1.toString(), person1.getFirstName(),
  301. person1.getLastName(), person2.toString(),
  302. person2.getFirstName(), person2.getLastName(),
  303. getComponentTag());
  304. Grid<?> readGrid = testRead(design, grid, true, true);
  305. assertEquals(2, readGrid.getDataProvider().size(new Query<>()));
  306. testWrite(design, grid, true);
  307. }
  308. @Override
  309. public void readOnlySelection() throws InstantiationException,
  310. IllegalAccessException, InvocationTargetException {
  311. Grid<Person> grid = new Grid<>();
  312. Person person1 = createPerson("foo", "bar");
  313. Person person2 = createPerson("name", "last-name");
  314. grid.setItems(person1, person2);
  315. grid.addColumn(Person::getFirstName).setCaption("First Name");
  316. grid.addColumn(Person::getLastName).setId("id").setCaption("Id");
  317. grid.setSelectionMode(SelectionMode.MULTI);
  318. grid.asMultiSelect().setReadOnly(true);
  319. String formatString = "<%s %s selection-allowed><table><colgroup>"
  320. + "<col column-id='column0' sortable>"
  321. + "<col column-id='id' sortable>" + "</colgroup><thead>"
  322. + "<tr default><th plain-text column-ids='column0'>First Name</th>"
  323. + "<th plain-text column-ids='id'>Id</th></tr>"
  324. + "</thead><tbody>"
  325. + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
  326. + "<tr item='%s'><td>%s</td><td>%s</td></tr>"
  327. + "</tbody></table></%s>";
  328. String design = String.format(formatString, getComponentTag(),
  329. "selection-mode='multi'", person1.toString(),
  330. person1.getFirstName(), person1.getLastName(),
  331. person2.toString(), person2.getFirstName(),
  332. person2.getLastName(), getComponentTag());
  333. Grid<?> readGrid = testRead(design, grid, true, true);
  334. assertEquals(2, readGrid.getDataProvider().size(new Query<>()));
  335. testWrite(design, grid, true);
  336. grid.setSelectionMode(SelectionMode.SINGLE);
  337. grid.asSingleSelect().setReadOnly(true);
  338. design = String.format(formatString, getComponentTag(), "",
  339. person1.toString(), person1.getFirstName(),
  340. person1.getLastName(), person2.toString(),
  341. person2.getFirstName(), person2.getLastName(),
  342. getComponentTag());
  343. readGrid = testRead(design, grid, true, true);
  344. assertEquals(2, readGrid.getDataProvider().size(new Query<>()));
  345. testWrite(design, grid, true);
  346. }
  347. @Test
  348. public void testComponentInGridHeader() {
  349. Grid<Person> grid = new Grid<>();
  350. Column<Person, String> column = grid.addColumn(Person::getFirstName)
  351. .setCaption("First Name");
  352. String html = "<b>Foo</b>";
  353. Label component = new Label(html);
  354. component.setContentMode(ContentMode.HTML);
  355. //@formatter:off
  356. String design = String.format( "<%s><table>"
  357. + "<colgroup>"
  358. + " <col sortable column-id='column0'>"
  359. + "</colgroup>"
  360. + "<thead>"
  361. + "<tr default><th column-ids='column0'><vaadin-label>%s</vaadin-label></th></tr>"
  362. + "</thead>"
  363. + "</table></%s>", getComponentTag(), html, getComponentTag());
  364. //@formatter:on
  365. grid.getDefaultHeaderRow().getCell(column).setComponent(component);
  366. testRead(design, grid, true);
  367. testWrite(design, grid);
  368. }
  369. @Test
  370. public void testComponentInGridFooter() {
  371. Grid<Person> grid = new Grid<>();
  372. Column<Person, String> column = grid.addColumn(Person::getFirstName)
  373. .setCaption("First Name");
  374. String html = "<b>Foo</b>";
  375. Label component = new Label(html);
  376. component.setContentMode(ContentMode.HTML);
  377. grid.prependFooterRow().getCell(column).setComponent(component);
  378. grid.removeHeaderRow(grid.getDefaultHeaderRow());
  379. //@formatter:off
  380. String design = String.format( "<%s><table>"
  381. + "<colgroup>"
  382. + " <col sortable column-id='column0'>"
  383. + "</colgroup>"
  384. + "<thead>"
  385. +"<tfoot>"
  386. + "<tr><td column-ids='column0'><vaadin-label>%s</vaadin-label></td></tr>"
  387. + "</tfoot>"
  388. + "</table>"
  389. + "</%s>", getComponentTag(), html, getComponentTag());
  390. //@formatter:on
  391. testRead(design, grid, true);
  392. testWrite(design, grid);
  393. }
  394. @Test
  395. public void testNoHeaderRows() {
  396. //@formatter:off
  397. String design = "<vaadin-grid><table>"
  398. + "<colgroup>"
  399. + " <col sortable column-id='column0'>"
  400. + "</colgroup>"
  401. + "<thead />"
  402. + "</table>"
  403. + "</vaadin-grid>";
  404. //@formatter:on
  405. Grid<Person> grid = new Grid<>();
  406. grid.addColumn(Person::getFirstName).setCaption("First Name");
  407. grid.removeHeaderRow(grid.getDefaultHeaderRow());
  408. testWrite(design, grid);
  409. testRead(design, grid, true);
  410. }
  411. @Test
  412. public void testReadEmptyGrid() {
  413. String design = "<vaadin-grid />";
  414. testRead(design, new Grid<String>(), false);
  415. }
  416. @Test
  417. public void testEmptyGrid() {
  418. String design = "<vaadin-grid></vaadin-grid>";
  419. Grid<String> expected = new Grid<>();
  420. testWrite(design, expected);
  421. testRead(design, expected, true);
  422. }
  423. @Test(expected = DesignException.class)
  424. public void testMalformedGrid() {
  425. String design = "<vaadin-grid><vaadin-label /></vaadin-grid>";
  426. testRead(design, new Grid<String>());
  427. }
  428. @Test(expected = DesignException.class)
  429. public void testGridWithNoColGroup() {
  430. String design = "<vaadin-grid><table><thead><tr><th>Foo</tr></thead></table></vaadin-grid>";
  431. testRead(design, new Grid<String>());
  432. }
  433. @Test
  434. @SuppressWarnings("unchecked")
  435. public void testHtmlEntitiesinGridHeaderFooter() {
  436. String id = "> id";
  437. String plainText = "plain-text";
  438. //@formatter:off
  439. String design = String.format( "<%s><table>"
  440. + "<colgroup>"
  441. + " <col sortable column-id='%s'>"
  442. + "</colgroup>"
  443. + "<thead>"
  444. +" <tr default><th %s column-ids='%s'>&gt; Test</th>"
  445. + "</thead>"
  446. + "<tfoot>"
  447. + "<tr><td %s column-ids='%s'>&gt; Test</td></tr>"
  448. + "</tfoot>"
  449. + "<tbody />"
  450. + "</table></%s>",
  451. getComponentTag() , id, plainText, id, plainText, id, getComponentTag());
  452. //@formatter:on
  453. Grid<Person> grid = read(design);
  454. String actualHeader = grid.getHeaderRow(0).getCell(id).getText();
  455. String actualFooter = grid.getFooterRow(0).getCell(id).getText();
  456. String expected = "> Test";
  457. assertEquals(expected, actualHeader);
  458. assertEquals(expected, actualFooter);
  459. design = design.replace(plainText, "");
  460. grid = read(design);
  461. actualHeader = grid.getHeaderRow(0).getCell(id).getHtml();
  462. actualFooter = grid.getFooterRow(0).getCell(id).getHtml();
  463. expected = "&gt; Test";
  464. assertEquals(expected, actualHeader);
  465. assertEquals(expected, actualFooter);
  466. grid = new Grid<>();
  467. Column<Person, String> column = grid.addColumn(Person::getFirstName)
  468. .setId(id);
  469. HeaderRow header = grid.addHeaderRowAt(0);
  470. FooterRow footer = grid.addFooterRowAt(0);
  471. grid.removeHeaderRow(grid.getDefaultHeaderRow());
  472. // entities should be encoded when writing back, not interpreted as HTML
  473. header.getCell(column).setText("&amp; Test");
  474. footer.getCell(column).setText("&amp; Test");
  475. Element root = new Element(Tag.valueOf(getComponentTag()), "");
  476. grid.writeDesign(root, new DesignContext());
  477. assertEquals("&amp;amp; Test",
  478. root.getElementsByTag("th").get(0).html());
  479. assertEquals("&amp;amp; Test",
  480. root.getElementsByTag("td").get(0).html());
  481. header = grid.addHeaderRowAt(0);
  482. footer = grid.addFooterRowAt(0);
  483. // entities should not be encoded, this is already given as HTML
  484. header.getCell(id).setHtml("&amp; Test");
  485. footer.getCell(id).setHtml("&amp; Test");
  486. root = new Element(Tag.valueOf(getComponentTag()), "");
  487. grid.writeDesign(root, new DesignContext());
  488. assertEquals("&amp; Test", root.getElementsByTag("th").get(0).html());
  489. assertEquals("&amp; Test", root.getElementsByTag("td").get(0).html());
  490. }
  491. @SuppressWarnings("rawtypes")
  492. @Override
  493. public Grid<?> testRead(String design, Grid expected) {
  494. return testRead(design, expected, false);
  495. }
  496. @Override
  497. @SuppressWarnings("rawtypes")
  498. public Grid<?> testRead(String design, Grid expected, boolean retestWrite) {
  499. return testRead(design, expected, retestWrite, false);
  500. }
  501. @SuppressWarnings("rawtypes")
  502. public Grid<?> testRead(String design, Grid expected, boolean retestWrite,
  503. boolean writeData) {
  504. Grid<?> actual = super.testRead(design, expected);
  505. compareGridColumns(expected, actual);
  506. compareHeaders(expected, actual);
  507. compareFooters(expected, actual);
  508. if (retestWrite) {
  509. testWrite(design, actual, writeData);
  510. }
  511. return actual;
  512. }
  513. private void compareHeaders(Grid<?> expected, Grid<?> actual) {
  514. assertEquals("Different header row count", expected.getHeaderRowCount(),
  515. actual.getHeaderRowCount());
  516. for (int i = 0; i < expected.getHeaderRowCount(); ++i) {
  517. HeaderRow expectedRow = expected.getHeaderRow(i);
  518. HeaderRow actualRow = actual.getHeaderRow(i);
  519. if (expectedRow.equals(expected.getDefaultHeaderRow())) {
  520. assertEquals("Different index for default header row",
  521. actual.getDefaultHeaderRow(), actualRow);
  522. }
  523. for (Column<?, ?> column : expected.getColumns()) {
  524. String baseError = "Difference when comparing cell for "
  525. + column.toString() + " on header row " + i + ": ";
  526. HeaderCell expectedCell = expectedRow.getCell(column);
  527. HeaderCell actualCell = actualRow.getCell(column);
  528. switch (expectedCell.getCellType()) {
  529. case TEXT:
  530. assertEquals(baseError + "Text content",
  531. expectedCell.getText(), actualCell.getText());
  532. break;
  533. case HTML:
  534. assertEquals(baseError + "HTML content",
  535. expectedCell.getHtml(), actualCell.getHtml());
  536. break;
  537. case WIDGET:
  538. assertEquals(baseError + "Component content",
  539. expectedCell.getComponent(),
  540. actualCell.getComponent());
  541. break;
  542. }
  543. }
  544. }
  545. }
  546. private void compareFooters(Grid<?> expected, Grid<?> actual) {
  547. assertEquals("Different footer row count", expected.getFooterRowCount(),
  548. actual.getFooterRowCount());
  549. for (int i = 0; i < expected.getFooterRowCount(); ++i) {
  550. FooterRow expectedRow = expected.getFooterRow(i);
  551. FooterRow actualRow = actual.getFooterRow(i);
  552. for (Column<?, ?> column : expected.getColumns()) {
  553. String baseError = "Difference when comparing cell for "
  554. + column.toString() + " on footer row " + i + ": ";
  555. FooterCell expectedCell = expectedRow.getCell(column);
  556. FooterCell actualCell = actualRow.getCell(column);
  557. switch (expectedCell.getCellType()) {
  558. case TEXT:
  559. assertEquals(baseError + "Text content",
  560. expectedCell.getText(), actualCell.getText());
  561. break;
  562. case HTML:
  563. assertEquals(baseError + "HTML content",
  564. expectedCell.getHtml(), actualCell.getHtml());
  565. break;
  566. case WIDGET:
  567. assertEquals(baseError + "Component content",
  568. expectedCell.getComponent(),
  569. actualCell.getComponent());
  570. break;
  571. }
  572. }
  573. }
  574. }
  575. private void compareGridColumns(Grid<?> expected, Grid<?> actual) {
  576. List<?> columns = expected.getColumns();
  577. List<?> actualColumns = actual.getColumns();
  578. assertEquals("Different amount of columns", columns.size(),
  579. actualColumns.size());
  580. for (int i = 0; i < columns.size(); ++i) {
  581. Column<?, ?> col1 = (Column<?, ?>) columns.get(i);
  582. Column<?, ?> col2 = (Column<?, ?>) actualColumns.get(i);
  583. String baseError = "Error when comparing columns for property "
  584. + col1.getId() + ": ";
  585. assertEquals(baseError + "Width", col1.getWidth(), col2.getWidth());
  586. assertEquals(baseError + "Maximum width", col1.getMaximumWidth(),
  587. col2.getMaximumWidth());
  588. assertEquals(baseError + "Minimum width", col1.getMinimumWidth(),
  589. col2.getMinimumWidth());
  590. assertEquals(baseError + "Expand ratio", col1.getExpandRatio(),
  591. col2.getExpandRatio());
  592. String id1 = col1.getId();
  593. String id2 = col2.getId();
  594. // column.getId() affects .isSortable()
  595. if ((id1 != null && id2 != null) || (id1 == null && id2 == null)) {
  596. assertEquals(baseError + "Sortable", col1.isSortable(),
  597. col2.isSortable());
  598. }
  599. assertEquals(baseError + "Editable", col1.isEditable(),
  600. col2.isEditable());
  601. assertEquals(baseError + "Hidable", col1.isHidable(),
  602. col2.isHidable());
  603. assertEquals(baseError + "Hidden", col1.isHidden(),
  604. col2.isHidden());
  605. assertEquals(baseError + "HidingToggleCaption",
  606. col1.getHidingToggleCaption(),
  607. col2.getHidingToggleCaption());
  608. }
  609. }
  610. @Override
  611. protected String getComponentTag() {
  612. return "vaadin-grid";
  613. }
  614. @Override
  615. protected Class<? extends Grid> getComponentClass() {
  616. return Grid.class;
  617. }
  618. @Override
  619. protected boolean acceptProperty(Class<?> clazz, Method readMethod,
  620. Method writeMethod) {
  621. if (readMethod != null) {
  622. Class<?> returnType = readMethod.getReturnType();
  623. if (HeaderRow.class.equals(returnType)
  624. || DataProvider.class.equals(returnType)) {
  625. return false;
  626. }
  627. }
  628. return super.acceptProperty(clazz, readMethod, writeMethod);
  629. }
  630. private Person createPerson(String name, String lastName) {
  631. Person person = new Person() {
  632. @Override
  633. public String toString() {
  634. return getFirstName() + " " + getLastName();
  635. }
  636. };
  637. person.setFirstName(name);
  638. person.setLastName(lastName);
  639. return person;
  640. }
  641. @Test
  642. public void beanItemType() throws Exception {
  643. Class<Person> beanClass = Person.class;
  644. String beanClassName = beanClass.getName();
  645. //@formatter:off
  646. String design = String.format( "<%s data-item-type=\"%s\"></%s>",
  647. getComponentTag() , beanClassName, getComponentTag());
  648. //@formatter:on
  649. @SuppressWarnings("unchecked")
  650. Grid<Person> grid = read(design);
  651. assertEquals(beanClass, grid.getBeanType());
  652. testWrite(design, grid);
  653. }
  654. @Test
  655. public void beanGridDefaultColumns() {
  656. Grid<Person> grid = new Grid<>(Person.class);
  657. String design = write(grid, false);
  658. assertDeclarativeColumnCount(11, design);
  659. Person testPerson = new Person("the first", "the last", "The email", 64,
  660. Sex.MALE, new Address("the street", 12313, "The city",
  661. Country.SOUTH_AFRICA));
  662. @SuppressWarnings("unchecked")
  663. Grid<Person> readGrid = read(design);
  664. assertColumns(11, grid.getColumns(), readGrid.getColumns(), testPerson);
  665. }
  666. private void assertDeclarativeColumnCount(int i, String design) {
  667. Document html = Jsoup.parse(design);
  668. Elements cols = Selector.select("vaadin-grid", html)
  669. .select("colgroup > col");
  670. assertEquals("Number of columns in the design file", i, cols.size());
  671. }
  672. private void assertColumns(int expectedCount,
  673. List<Column<Person, ?>> expectedColumns,
  674. List<Column<Person, ?>> columns, Person testPerson) {
  675. assertEquals(expectedCount, expectedColumns.size());
  676. assertEquals(expectedCount, columns.size());
  677. for (int i = 0; i < expectedColumns.size(); i++) {
  678. Column<Person, ?> expectedColumn = expectedColumns.get(i);
  679. Column<Person, ?> column = columns.get(i);
  680. // Property mapping
  681. assertEquals(expectedColumn.getId(), column.getId());
  682. // Header caption
  683. assertEquals(expectedColumn.getCaption(), column.getCaption());
  684. // Value providers are not stored in the declarative file
  685. // so this only works for bean properties
  686. if (column.getId() != null
  687. && !column.getId().equals("column" + i)) {
  688. assertEquals(
  689. expectedColumn.getValueProvider().apply(testPerson),
  690. column.getValueProvider().apply(testPerson));
  691. }
  692. }
  693. }
  694. @Test
  695. public void beanGridNoColumns() {
  696. Grid<Person> grid = new Grid<>(Person.class);
  697. grid.setColumns();
  698. String design = write(grid, false);
  699. assertDeclarativeColumnCount(0, design);
  700. Person testPerson = new Person("the first", "the last", "The email", 64,
  701. Sex.MALE, new Address("the street", 12313, "The city",
  702. Country.SOUTH_AFRICA));
  703. @SuppressWarnings("unchecked")
  704. Grid<Person> readGrid = read(design);
  705. assertColumns(0, grid.getColumns(), readGrid.getColumns(), testPerson);
  706. // Can add a mapped property
  707. assertEquals("The email", readGrid.addColumn("email").getValueProvider()
  708. .apply(testPerson));
  709. }
  710. @Test
  711. public void beanGridOnlyCustomColumns() {
  712. // Writes columns without propertyId even though name matches, reads
  713. // columns without propertyId mapping, can add new columns using
  714. // propertyId
  715. Grid<Person> grid = new Grid<>(Person.class);
  716. grid.setColumns();
  717. grid.addColumn(Person::getFirstName).setCaption("First Name");
  718. String design = write(grid, false);
  719. assertDeclarativeColumnCount(1, design);
  720. Person testPerson = new Person("the first", "the last", "The email", 64,
  721. Sex.MALE, new Address("the street", 12313, "The city",
  722. Country.SOUTH_AFRICA));
  723. @SuppressWarnings("unchecked")
  724. Grid<Person> readGrid = read(design);
  725. assertColumns(1, grid.getColumns(), readGrid.getColumns(), testPerson);
  726. // First name should not be mapped to the property
  727. assertNull(readGrid.getColumns().get(0).getValueProvider()
  728. .apply(testPerson));
  729. // Can add a mapped property
  730. assertEquals("the last", readGrid.addColumn("lastName")
  731. .getValueProvider().apply(testPerson));
  732. }
  733. @Test
  734. public void beanGridOneCustomizedColumn() {
  735. // Writes columns with propertyId except one without
  736. // Reads columns to match initial setup
  737. Grid<Person> grid = new Grid<>(Person.class);
  738. grid.addColumn(
  739. person -> person.getFirstName() + " " + person.getLastName())
  740. .setCaption("First and Last");
  741. String design = write(grid, false);
  742. assertDeclarativeColumnCount(12, design);
  743. Person testPerson = new Person("the first", "the last", "The email", 64,
  744. Sex.MALE, new Address("the street", 12313, "The city",
  745. Country.SOUTH_AFRICA));
  746. @SuppressWarnings("unchecked")
  747. Grid<Person> readGrid = read(design);
  748. assertColumns(12, grid.getColumns(), readGrid.getColumns(), testPerson);
  749. // First and last name should not be mapped to anything but should exist
  750. assertNull(readGrid.getColumns().get(11).getValueProvider()
  751. .apply(testPerson));
  752. }
  753. }