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.

GridTest.java 26KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785
  1. package com.vaadin.tests.server.component.grid;
  2. import static org.junit.Assert.assertArrayEquals;
  3. import static org.junit.Assert.assertEquals;
  4. import static org.junit.Assert.assertFalse;
  5. import static org.junit.Assert.assertNotNull;
  6. import static org.junit.Assert.assertSame;
  7. import static org.junit.Assert.assertTrue;
  8. import static org.junit.Assert.fail;
  9. import java.lang.reflect.InvocationTargetException;
  10. import java.lang.reflect.Method;
  11. import java.text.DecimalFormat;
  12. import java.text.DecimalFormatSymbols;
  13. import java.util.ArrayList;
  14. import java.util.Arrays;
  15. import java.util.Collections;
  16. import java.util.Date;
  17. import java.util.HashSet;
  18. import java.util.List;
  19. import java.util.Locale;
  20. import java.util.Optional;
  21. import java.util.Random;
  22. import java.util.Set;
  23. import java.util.concurrent.atomic.AtomicInteger;
  24. import java.util.concurrent.atomic.AtomicReference;
  25. import java.util.stream.Collectors;
  26. import java.util.stream.Stream;
  27. import org.easymock.Capture;
  28. import org.junit.Assert;
  29. import org.junit.Before;
  30. import org.junit.Rule;
  31. import org.junit.Test;
  32. import org.junit.rules.ExpectedException;
  33. import com.vaadin.data.Binder.Binding;
  34. import com.vaadin.data.ValidationException;
  35. import com.vaadin.data.ValueProvider;
  36. import com.vaadin.data.provider.DataCommunicator;
  37. import com.vaadin.data.provider.DataGenerator;
  38. import com.vaadin.data.provider.DataProvider;
  39. import com.vaadin.data.provider.GridSortOrder;
  40. import com.vaadin.data.provider.QuerySortOrder;
  41. import com.vaadin.data.provider.SortOrder;
  42. import com.vaadin.data.provider.bov.Person;
  43. import com.vaadin.event.selection.SelectionEvent;
  44. import com.vaadin.server.SerializableComparator;
  45. import com.vaadin.shared.data.sort.SortDirection;
  46. import com.vaadin.shared.ui.grid.HeightMode;
  47. import com.vaadin.tests.util.MockUI;
  48. import com.vaadin.ui.Grid;
  49. import com.vaadin.ui.Grid.Column;
  50. import com.vaadin.ui.Grid.SelectionMode;
  51. import com.vaadin.ui.TextField;
  52. import com.vaadin.ui.renderers.NumberRenderer;
  53. import elemental.json.Json;
  54. import elemental.json.JsonObject;
  55. import junit.framework.AssertionFailedError;
  56. public class GridTest {
  57. private Grid<String> grid;
  58. private Column<String, String> fooColumn;
  59. private Column<String, Integer> lengthColumn;
  60. private Column<String, Object> objectColumn;
  61. private Column<String, String> randomColumn;
  62. @Rule
  63. public ExpectedException thrown = ExpectedException.none();
  64. @Before
  65. public void setUp() {
  66. grid = new Grid<>();
  67. fooColumn = grid.addColumn(ValueProvider.identity()).setId("foo");
  68. lengthColumn = grid.addColumn(String::length, new NumberRenderer())
  69. .setId("length");
  70. objectColumn = grid.addColumn(string -> new Object());
  71. randomColumn = grid.addColumn(ValueProvider.identity())
  72. .setId("randomColumnId");
  73. }
  74. @Test
  75. public void testGridAssistiveCaption() {
  76. assertEquals(null, fooColumn.getAssistiveCaption());
  77. fooColumn.setAssistiveCaption("Press Enter to sort.");
  78. assertEquals("Press Enter to sort.", fooColumn.getAssistiveCaption());
  79. }
  80. @Test
  81. public void testCreateGridWithDataCommunicator() {
  82. DataCommunicator<String> specificDataCommunicator = new DataCommunicator<>();
  83. TestGrid<String> grid = new TestGrid<>(String.class,
  84. specificDataCommunicator);
  85. assertEquals(specificDataCommunicator, grid.getDataCommunicator());
  86. }
  87. @Test
  88. public void testGridHeightModeChange() {
  89. assertEquals("Initial height mode was not CSS", HeightMode.CSS,
  90. grid.getHeightMode());
  91. grid.setHeightByRows(13.24);
  92. assertEquals("Setting height by rows did not change height mode",
  93. HeightMode.ROW, grid.getHeightMode());
  94. grid.setHeight("100px");
  95. assertEquals("Setting height did not change height mode.",
  96. HeightMode.CSS, grid.getHeightMode());
  97. }
  98. @Test
  99. public void testFrozenColumnCountTooBig() {
  100. thrown.expect(IllegalArgumentException.class);
  101. thrown.expectMessage(
  102. "count must be between -1 and the current number of columns (4): 5");
  103. grid.setFrozenColumnCount(5);
  104. }
  105. @Test
  106. public void testFrozenColumnCountTooSmall() {
  107. thrown.expect(IllegalArgumentException.class);
  108. thrown.expectMessage(
  109. "count must be between -1 and the current number of columns (4): -2");
  110. grid.setFrozenColumnCount(-2);
  111. }
  112. @Test
  113. public void testSetFrozenColumnCount() {
  114. for (int i = -1; i < 2; ++i) {
  115. grid.setFrozenColumnCount(i);
  116. assertEquals("Frozen column count not updated", i,
  117. grid.getFrozenColumnCount());
  118. }
  119. }
  120. @Test
  121. public void testGridColumnIdentifier() {
  122. grid.getColumn("foo").setCaption("Bar");
  123. assertEquals("Column header not updated correctly", "Bar",
  124. grid.getHeaderRow(0).getCell("foo").getText());
  125. }
  126. @Test
  127. public void testGridMultipleColumnsWithSameIdentifier() {
  128. thrown.expect(IllegalArgumentException.class);
  129. thrown.expectMessage("Duplicate ID for columns");
  130. grid.addColumn(t -> t).setId("foo");
  131. }
  132. @Test
  133. public void testAddSelectionListener_singleSelectMode() {
  134. grid.setItems("foo", "bar", "baz");
  135. Capture<SelectionEvent<String>> eventCapture = new Capture<>();
  136. grid.addSelectionListener(event -> eventCapture.setValue(event));
  137. grid.getSelectionModel().select("foo");
  138. SelectionEvent<String> event = eventCapture.getValue();
  139. assertNotNull(event);
  140. assertFalse(event.isUserOriginated());
  141. assertEquals("foo", event.getFirstSelectedItem().get());
  142. assertEquals("foo",
  143. event.getAllSelectedItems().stream().findFirst().get());
  144. grid.getSelectionModel().select("bar");
  145. event = eventCapture.getValue();
  146. assertNotNull(event);
  147. assertFalse(event.isUserOriginated());
  148. assertEquals("bar", event.getFirstSelectedItem().get());
  149. assertEquals("bar",
  150. event.getAllSelectedItems().stream().findFirst().get());
  151. grid.getSelectionModel().deselect("bar");
  152. event = eventCapture.getValue();
  153. assertNotNull(event);
  154. assertFalse(event.isUserOriginated());
  155. assertEquals(Optional.empty(), event.getFirstSelectedItem());
  156. assertEquals(0, event.getAllSelectedItems().size());
  157. }
  158. @Test
  159. public void testAddSelectionListener_multiSelectMode() {
  160. grid.setItems("foo", "bar", "baz");
  161. grid.setSelectionMode(SelectionMode.MULTI);
  162. Capture<SelectionEvent<String>> eventCapture = new Capture<>();
  163. grid.addSelectionListener(event -> eventCapture.setValue(event));
  164. grid.getSelectionModel().select("foo");
  165. SelectionEvent<String> event = eventCapture.getValue();
  166. assertNotNull(event);
  167. assertFalse(event.isUserOriginated());
  168. assertEquals("foo", event.getFirstSelectedItem().get());
  169. assertEquals("foo",
  170. event.getAllSelectedItems().stream().findFirst().get());
  171. grid.getSelectionModel().select("bar");
  172. event = eventCapture.getValue();
  173. assertNotNull(event);
  174. assertFalse(event.isUserOriginated());
  175. assertEquals("foo", event.getFirstSelectedItem().get());
  176. assertEquals("foo",
  177. event.getAllSelectedItems().stream().findFirst().get());
  178. assertArrayEquals(new String[] { "foo", "bar" },
  179. event.getAllSelectedItems().toArray(new String[2]));
  180. grid.getSelectionModel().deselect("foo");
  181. event = eventCapture.getValue();
  182. assertNotNull(event);
  183. assertFalse(event.isUserOriginated());
  184. assertEquals("bar", event.getFirstSelectedItem().get());
  185. assertEquals("bar",
  186. event.getAllSelectedItems().stream().findFirst().get());
  187. assertArrayEquals(new String[] { "bar" },
  188. event.getAllSelectedItems().toArray(new String[1]));
  189. grid.getSelectionModel().deselectAll();
  190. event = eventCapture.getValue();
  191. assertNotNull(event);
  192. assertFalse(event.isUserOriginated());
  193. assertEquals(Optional.empty(), event.getFirstSelectedItem());
  194. assertEquals(0, event.getAllSelectedItems().size());
  195. }
  196. @Test
  197. public void testAddSelectionListener_noSelectionMode() {
  198. thrown.expect(UnsupportedOperationException.class);
  199. thrown.expectMessage(
  200. "This selection model doesn't allow selection, cannot add selection listeners to it");
  201. grid.setSelectionMode(SelectionMode.NONE);
  202. grid.addSelectionListener(event -> fail("never ever happens (tm)"));
  203. }
  204. @Test
  205. public void sortByColumn_sortOrderIsAscendingOneColumn() {
  206. Column<String, ?> column = grid.getColumns().get(1);
  207. grid.sort(column);
  208. GridSortOrder<String> sortOrder = grid.getSortOrder().get(0);
  209. assertEquals(column, sortOrder.getSorted());
  210. assertEquals(SortDirection.ASCENDING, sortOrder.getDirection());
  211. }
  212. @Test
  213. public void sortByColumnDesc_sortOrderIsDescendingOneColumn() {
  214. Column<String, ?> column = grid.getColumns().get(1);
  215. grid.sort(column, SortDirection.DESCENDING);
  216. GridSortOrder<String> sortOrder = grid.getSortOrder().get(0);
  217. assertEquals(column, sortOrder.getSorted());
  218. assertEquals(SortDirection.DESCENDING, sortOrder.getDirection());
  219. }
  220. @Test
  221. public void setSortOrder() {
  222. Column<String, ?> column1 = grid.getColumns().get(1);
  223. Column<String, ?> column2 = grid.getColumns().get(2);
  224. List<GridSortOrder<String>> order = Arrays.asList(
  225. new GridSortOrder<>(column2, SortDirection.DESCENDING),
  226. new GridSortOrder<>(column1, SortDirection.ASCENDING));
  227. grid.setSortOrder(order);
  228. List<GridSortOrder<String>> sortOrder = grid.getSortOrder();
  229. assertEquals(column2, sortOrder.get(0).getSorted());
  230. assertEquals(SortDirection.DESCENDING, sortOrder.get(0).getDirection());
  231. assertEquals(column1, sortOrder.get(1).getSorted());
  232. assertEquals(SortDirection.ASCENDING, sortOrder.get(1).getDirection());
  233. }
  234. @Test
  235. public void clearSortOrder() {
  236. Column<String, ?> column = grid.getColumns().get(1);
  237. grid.sort(column);
  238. grid.clearSortOrder();
  239. assertEquals(0, grid.getSortOrder().size());
  240. }
  241. @Test
  242. public void sortListener_eventIsFired() {
  243. Column<String, ?> column1 = grid.getColumns().get(1);
  244. Column<String, ?> column2 = grid.getColumns().get(2);
  245. List<GridSortOrder<String>> list = new ArrayList<>();
  246. AtomicReference<Boolean> fired = new AtomicReference<>();
  247. grid.addSortListener(event -> {
  248. assertTrue(list.isEmpty());
  249. fired.set(true);
  250. list.addAll(event.getSortOrder());
  251. });
  252. grid.sort(column1, SortDirection.DESCENDING);
  253. assertEquals(column1, list.get(0).getSorted());
  254. assertEquals(SortDirection.DESCENDING, list.get(0).getDirection());
  255. List<GridSortOrder<String>> order = Arrays.asList(
  256. new GridSortOrder<>(column2, SortDirection.DESCENDING),
  257. new GridSortOrder<>(column1, SortDirection.ASCENDING));
  258. list.clear();
  259. grid.setSortOrder(order);
  260. assertEquals(column2, list.get(0).getSorted());
  261. assertEquals(SortDirection.DESCENDING, list.get(0).getDirection());
  262. assertEquals(column1, list.get(1).getSorted());
  263. assertEquals(SortDirection.ASCENDING, list.get(1).getDirection());
  264. list.clear();
  265. fired.set(false);
  266. grid.clearSortOrder();
  267. assertEquals(0, list.size());
  268. assertTrue(fired.get());
  269. }
  270. @Test
  271. public void beanGrid() {
  272. Grid<Person> grid = new Grid<>(Person.class);
  273. Column<Person, ?> nameColumn = grid.getColumn("name");
  274. Column<Person, ?> bornColumn = grid.getColumn("born");
  275. assertNotNull(nameColumn);
  276. assertNotNull(bornColumn);
  277. assertEquals("Name", nameColumn.getCaption());
  278. assertEquals("Born", bornColumn.getCaption());
  279. JsonObject json = getRowData(grid, new Person("Lorem", 2000));
  280. Set<String> values = Stream.of(json.keys()).map(json::getString)
  281. .collect(Collectors.toSet());
  282. assertEquals(new HashSet<>(Arrays.asList("Lorem", "2000")), values);
  283. assertSingleSortProperty(nameColumn, "name");
  284. assertSingleSortProperty(bornColumn, "born");
  285. }
  286. @Test
  287. public void beanGrid_editor() throws ValidationException {
  288. Grid<Person> grid = new Grid<>(Person.class);
  289. Column<Person, ?> nameColumn = grid.getColumn("name");
  290. TextField nameField = new TextField();
  291. nameColumn.setEditorComponent(nameField);
  292. Optional<Binding<Person, ?>> maybeBinding = grid.getEditor().getBinder()
  293. .getBinding("name");
  294. assertTrue(maybeBinding.isPresent());
  295. Binding<Person, ?> binding = maybeBinding.get();
  296. assertSame(nameField, binding.getField());
  297. Person person = new Person("Lorem", 2000);
  298. grid.getEditor().getBinder().setBean(person);
  299. assertEquals("Lorem", nameField.getValue());
  300. nameField.setValue("Ipsum");
  301. assertEquals("Ipsum", person.getName());
  302. }
  303. @Test
  304. public void oneArgSetEditor_nonBeanGrid() {
  305. thrown.expect(IllegalStateException.class);
  306. thrown.expectMessage(
  307. "A Grid created without a bean type class literal or a custom property set"
  308. + " doesn't support finding properties by name.");
  309. Grid<Person> grid = new Grid<>();
  310. Column<Person, String> nameCol = grid.addColumn(Person::getName)
  311. .setId("name");
  312. nameCol.setEditorComponent(new TextField());
  313. }
  314. @Test
  315. public void addExistingColumnById_throws() {
  316. thrown.expect(IllegalStateException.class);
  317. thrown.expectMessage("There is already a column for name");
  318. Grid<Person> grid = new Grid<>(Person.class);
  319. grid.addColumn("name");
  320. }
  321. @Test
  322. public void removeByColumn_readdById() {
  323. Grid<Person> grid = new Grid<>(Person.class);
  324. grid.removeColumn(grid.getColumn("name"));
  325. grid.addColumn("name");
  326. List<Column<Person, ?>> columns = grid.getColumns();
  327. assertEquals(2, columns.size());
  328. assertEquals("born", columns.get(0).getId());
  329. assertEquals("name", columns.get(1).getId());
  330. }
  331. @Test
  332. public void removeColumnByColumn() {
  333. grid.removeColumn(fooColumn);
  334. assertEquals(Arrays.asList(lengthColumn, objectColumn, randomColumn),
  335. grid.getColumns());
  336. }
  337. @Test
  338. public void removeColumnByColumn_alreadyRemoved() {
  339. thrown.expect(IllegalArgumentException.class);
  340. thrown.expectMessage(
  341. "Column with id foo cannot be removed from the grid");
  342. grid.removeColumn(fooColumn);
  343. grid.removeColumn(fooColumn);
  344. assertEquals(Arrays.asList(lengthColumn, objectColumn, randomColumn),
  345. grid.getColumns());
  346. }
  347. @Test
  348. public void removeColumnById_alreadyRemoved() {
  349. thrown.expect(IllegalStateException.class);
  350. thrown.expectMessage("There is no column with the id foo");
  351. grid.removeColumn("foo");
  352. grid.removeColumn("foo");
  353. }
  354. @Test
  355. public void removeColumnById() {
  356. grid.removeColumn("foo");
  357. assertEquals(Arrays.asList(lengthColumn, objectColumn, randomColumn),
  358. grid.getColumns());
  359. }
  360. @Test
  361. public void removeAllColumns() {
  362. grid.removeAllColumns();
  363. assertEquals(Collections.emptyList(), grid.getColumns());
  364. }
  365. @Test
  366. public void removeAllColumnsInGridWithoutColumns() {
  367. grid.removeAllColumns();
  368. grid.removeAllColumns();
  369. assertEquals(Collections.emptyList(), grid.getColumns());
  370. }
  371. @Test
  372. public void removeFrozenColumn() {
  373. grid.setFrozenColumnCount(3);
  374. grid.removeColumn(fooColumn);
  375. assertEquals(2, grid.getFrozenColumnCount());
  376. }
  377. @Test
  378. public void removeHiddenFrozenColumn() {
  379. lengthColumn.setHidden(true);
  380. grid.setFrozenColumnCount(3);
  381. grid.removeColumn(lengthColumn);
  382. assertEquals(2, grid.getFrozenColumnCount());
  383. }
  384. @Test
  385. public void removeNonFrozenColumn() {
  386. grid.setFrozenColumnCount(3);
  387. grid.removeColumn(randomColumn);
  388. assertEquals(3, grid.getFrozenColumnCount());
  389. }
  390. @Test
  391. public void testFrozenColumnRemoveColumn() {
  392. assertEquals("Grid should not start with a frozen column", 0,
  393. grid.getFrozenColumnCount());
  394. int columnCount = grid.getColumns().size();
  395. grid.setFrozenColumnCount(columnCount);
  396. grid.removeColumn(grid.getColumns().get(0));
  397. assertEquals(
  398. "Frozen column count should be updated when removing a frozen column",
  399. columnCount - 1, grid.getFrozenColumnCount());
  400. }
  401. @Test
  402. public void setColumns_reorder() {
  403. // Will remove other columns
  404. grid.setColumns("length", "foo");
  405. List<Column<String, ?>> columns = grid.getColumns();
  406. assertEquals(2, columns.size());
  407. assertEquals("length", columns.get(0).getId());
  408. assertEquals("foo", columns.get(1).getId());
  409. }
  410. @Test
  411. public void setColumns_addColumn_notBeangrid() {
  412. thrown.expect(IllegalStateException.class);
  413. thrown.expectMessage(
  414. "A Grid created without a bean type class literal or a custom property set"
  415. + " doesn't support finding properties by name.");
  416. // Not possible to add a column in a grid that cannot add columns based
  417. // on a string
  418. grid.setColumns("notHere");
  419. }
  420. @Test
  421. public void setColumns_addColumns_beangrid() {
  422. Grid<Person> grid = new Grid<>(Person.class);
  423. // Remove so we can add it back
  424. grid.removeColumn("name");
  425. grid.setColumns("born", "name");
  426. List<Column<Person, ?>> columns = grid.getColumns();
  427. assertEquals(2, columns.size());
  428. assertEquals("born", columns.get(0).getId());
  429. assertEquals("name", columns.get(1).getId());
  430. }
  431. @Test
  432. public void setColumnOrder_byColumn() {
  433. grid.setColumnOrder(randomColumn, lengthColumn);
  434. assertEquals(Arrays.asList(randomColumn, lengthColumn, fooColumn,
  435. objectColumn), grid.getColumns());
  436. }
  437. @Test
  438. public void setColumnOrder_byColumn_removedColumn() {
  439. thrown.expect(IllegalStateException.class);
  440. thrown.expectMessage("setColumnOrder should not be called "
  441. + "with columns that are not in the grid.");
  442. grid.removeColumn(randomColumn);
  443. grid.setColumnOrder(randomColumn, lengthColumn);
  444. }
  445. @Test
  446. public void setColumnOrder_byString() {
  447. grid.setColumnOrder("randomColumnId", "length");
  448. assertEquals(Arrays.asList(randomColumn, lengthColumn, fooColumn,
  449. objectColumn), grid.getColumns());
  450. }
  451. @Test
  452. public void setColumnOrder_byString_removedColumn() {
  453. thrown.expect(IllegalStateException.class);
  454. thrown.expectMessage("There is no column with the id randomColumnId");
  455. grid.removeColumn("randomColumnId");
  456. grid.setColumnOrder("randomColumnId", "length");
  457. }
  458. @Test
  459. public void defaultSorting_comparableTypes() {
  460. testValueProviderSorting(1, 2, 3);
  461. }
  462. @Test
  463. public void defaultSorting_strings() {
  464. testValueProviderSorting("a", "b", "c");
  465. }
  466. @Test
  467. public void defaultSorting_notComparable() {
  468. assert !Comparable.class.isAssignableFrom(AtomicInteger.class);
  469. testValueProviderSorting(new AtomicInteger(10), new AtomicInteger(8),
  470. new AtomicInteger(9));
  471. }
  472. @Test
  473. public void defaultSorting_differentComparables() {
  474. testValueProviderSorting(10.1, 200, 3000.1, 4000);
  475. }
  476. @Test
  477. public void defaultSorting_mutuallyComparableTypes() {
  478. testValueProviderSorting(new Date(10), new java.sql.Date(1000000),
  479. new Date(100000000));
  480. }
  481. private static void testValueProviderSorting(Object... expectedOrder) {
  482. SerializableComparator<Object> comparator = new Grid<>()
  483. .addColumn(ValueProvider.identity())
  484. .getComparator(SortDirection.ASCENDING);
  485. assertNotNull(comparator);
  486. List<Object> values = new ArrayList<>(Arrays.asList(expectedOrder));
  487. Collections.shuffle(values, new Random(42));
  488. assertArrayEquals(expectedOrder,
  489. values.stream().sorted(comparator).toArray());
  490. }
  491. @Test
  492. public void addBeanColumn_validRenderer() {
  493. Grid<Person> grid = new Grid<>(Person.class);
  494. grid.removeColumn("born");
  495. grid.addColumn("born", new NumberRenderer(new DecimalFormat("#,###",
  496. DecimalFormatSymbols.getInstance(Locale.US))));
  497. Person person = new Person("Name", 2017);
  498. JsonObject rowData = getRowData(grid, person);
  499. String formattedValue = Stream.of(rowData.keys())
  500. .map(rowData::getString).filter(value -> !value.equals("Name"))
  501. .findFirst().orElse(null);
  502. assertEquals(formattedValue, "2,017");
  503. }
  504. @Test
  505. public void addBeanColumn_invalidRenderer() {
  506. thrown.expect(IllegalArgumentException.class);
  507. thrown.expectMessage("NumberRenderer");
  508. thrown.expectMessage(
  509. " cannot be used with a property of type java.lang.String");
  510. Grid<Person> grid = new Grid<>(Person.class);
  511. grid.removeColumn("name");
  512. grid.addColumn("name", new NumberRenderer());
  513. }
  514. @Test
  515. public void columnId_sortProperty() {
  516. assertSingleSortProperty(lengthColumn, "length");
  517. }
  518. @Test
  519. public void columnId_sortProperty_noId() {
  520. assertEquals(0,
  521. objectColumn.getSortOrder(SortDirection.ASCENDING).count());
  522. }
  523. @Test
  524. public void sortProperty_setId_doesntOverride() {
  525. objectColumn.setSortProperty("foo");
  526. objectColumn.setId("bar");
  527. assertSingleSortProperty(objectColumn, "foo");
  528. }
  529. private static void assertSingleSortProperty(Column<?, ?> column,
  530. String expectedProperty) {
  531. QuerySortOrder[] sortOrders = column
  532. .getSortOrder(SortDirection.ASCENDING)
  533. .toArray(QuerySortOrder[]::new);
  534. assertEquals(1, sortOrders.length);
  535. assertEquals(SortDirection.ASCENDING, sortOrders[0].getDirection());
  536. assertEquals(expectedProperty, sortOrders[0].getSorted());
  537. }
  538. private static <T> JsonObject getRowData(Grid<T> grid, T row) {
  539. JsonObject json = Json.createObject();
  540. if (grid.getColumns().isEmpty()) {
  541. return json;
  542. }
  543. // generateData only works if Grid is attached
  544. new MockUI().setContent(grid);
  545. Method getter = findDataGeneratorGetterMethod();
  546. grid.getColumns().forEach(column -> {
  547. DataGenerator<T> dataGenerator;
  548. try {
  549. dataGenerator = (DataGenerator<T>) getter.invoke(column,
  550. new Object[] {});
  551. dataGenerator.generateData(row, json);
  552. } catch (IllegalAccessException | IllegalArgumentException
  553. | InvocationTargetException e) {
  554. throw new AssertionFailedError(
  555. "Cannot get DataGenerator from Column");
  556. }
  557. });
  558. // Detach again
  559. grid.getUI().setContent(null);
  560. return json.getObject("d");
  561. }
  562. private static Method findDataGeneratorGetterMethod() {
  563. try {
  564. Method getter = Column.class.getDeclaredMethod("getDataGenerator",
  565. new Class<?>[] {});
  566. getter.setAccessible(true);
  567. return getter;
  568. } catch (NoSuchMethodException | SecurityException e) {
  569. throw new AssertionFailedError(
  570. "Cannot get DataGenerator from Column");
  571. }
  572. }
  573. @Test
  574. public void removeColumnToThrowForInvalidColumn() {
  575. thrown.expect(IllegalArgumentException.class);
  576. thrown.expectMessage(
  577. "Column with id null cannot be removed from the grid");
  578. Grid<Person> grid1 = new Grid<>();
  579. Grid<Person> grid2 = new Grid<>();
  580. Column<Person, ?> column1 = grid1.addColumn(ValueProvider.identity());
  581. grid2.removeColumn(column1);
  582. }
  583. @Test
  584. public void testColumnSortable() {
  585. Column<String, String> column = grid.addColumn(String::toString);
  586. // Use in-memory data provider
  587. grid.setItems(Collections.emptyList());
  588. Assert.assertTrue("Column should be initially sortable",
  589. column.isSortable());
  590. Assert.assertTrue("User should be able to sort the column",
  591. column.isSortableByUser());
  592. column.setSortable(false);
  593. Assert.assertFalse("Column should not be sortable",
  594. column.isSortable());
  595. Assert.assertFalse(
  596. "User should not be able to sort the column with in-memory data",
  597. column.isSortableByUser());
  598. // Use CallBackDataProvider
  599. grid.setDataProvider(
  600. DataProvider.fromCallbacks(q -> Stream.of(), q -> 0));
  601. Assert.assertFalse("Column should not be sortable",
  602. column.isSortable());
  603. Assert.assertFalse("User should not be able to sort the column",
  604. column.isSortableByUser());
  605. column.setSortable(true);
  606. Assert.assertTrue("Column should be marked sortable",
  607. column.isSortable());
  608. Assert.assertFalse(
  609. "User should not be able to sort the column since no sort order is provided",
  610. column.isSortableByUser());
  611. column.setSortProperty("toString");
  612. Assert.assertTrue("Column should be marked sortable",
  613. column.isSortable());
  614. Assert.assertFalse(
  615. "User should be able to sort the column with the sort order",
  616. column.isSortableByUser());
  617. }
  618. }