| /* |
| * Copyright 2010 Google Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| * use this file except in compliance with the License. You may obtain a copy of |
| * the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| * License for the specific language governing permissions and limitations under |
| * the License. |
| */ |
| package com.google.gwt.user.cellview.client; |
| |
| import com.google.gwt.cell.client.TextCell; |
| import com.google.gwt.core.client.GWT; |
| import com.google.gwt.dom.client.Element; |
| import com.google.gwt.dom.client.Style.Unit; |
| import com.google.gwt.dom.client.TableCellElement; |
| import com.google.gwt.dom.client.TableElement; |
| import com.google.gwt.dom.client.TableRowElement; |
| import com.google.gwt.dom.client.TableSectionElement; |
| import com.google.gwt.resources.client.ImageResource; |
| import com.google.gwt.user.cellview.client.AbstractHasData.RedrawEvent.Handler; |
| import com.google.gwt.user.cellview.client.CellTable.Resources; |
| import com.google.gwt.user.cellview.client.CellTable.Style; |
| import com.google.gwt.user.client.DOM; |
| import com.google.gwt.user.client.ui.RootPanel; |
| import com.google.gwt.user.client.ui.Widget; |
| |
| import java.util.Locale; |
| |
| /** |
| * Tests for {@link CellTable}. |
| */ |
| public class CellTableTest extends AbstractCellTableTestBase<CellTable<String>> { |
| |
| /** |
| * Test headers that span multiple columns. |
| */ |
| public void testMultiColumnHeader() { |
| Resources res = GWT.create(Resources.class); |
| CellTable<String> table = new CellTable<String>(10, res); |
| TextHeader header = new TextHeader("Hello"); |
| |
| // Get the style information. |
| Style style = res.cellTableStyle(); |
| String styleHeader = style.cellTableHeader(); |
| String styleFirstColumn = style.cellTableFirstColumnHeader(); |
| String styleLastColumn = style.cellTableLastColumnHeader(); |
| |
| // No header. |
| table.redraw(); |
| table.getPresenter().flush(); |
| assertEquals(0, getHeaderCount(table)); |
| |
| // Single column. |
| table.addColumn(new TextColumn<String>() { |
| @Override |
| public String getValue(String object) { |
| return null; |
| } |
| }, header); |
| table.getPresenter().flush(); |
| assertEquals(1, getHeaderCount(table)); |
| assertEquals(1, getHeaderElement(table, 0).getColSpan()); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleHeader)); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleFirstColumn)); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleLastColumn)); |
| |
| // Header spans both columns. |
| table.addColumn(new TextColumn<String>() { |
| @Override |
| public String getValue(String object) { |
| return null; |
| } |
| }, header); |
| table.getPresenter().flush(); |
| assertEquals(1, getHeaderCount(table)); |
| assertEquals(2, getHeaderElement(table, 0).getColSpan()); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleHeader)); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleFirstColumn)); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleLastColumn)); |
| |
| // Header spans all three columns. |
| table.addColumn(new TextColumn<String>() { |
| @Override |
| public String getValue(String object) { |
| return null; |
| } |
| }, header); |
| table.getPresenter().flush(); |
| assertEquals(1, getHeaderCount(table)); |
| assertEquals(3, getHeaderElement(table, 0).getColSpan()); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleHeader)); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleFirstColumn)); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleLastColumn)); |
| |
| // New header at fourth column. |
| table.addColumn(new TextColumn<String>() { |
| @Override |
| public String getValue(String object) { |
| return null; |
| } |
| }, "New Header"); |
| table.getPresenter().flush(); |
| assertEquals(2, getHeaderCount(table)); |
| assertEquals(3, getHeaderElement(table, 0).getColSpan()); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleHeader)); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleFirstColumn)); |
| assertEquals(1, getHeaderElement(table, 1).getColSpan()); |
| assertTrue(getHeaderElement(table, 1).getClassName().contains(styleHeader)); |
| assertTrue(getHeaderElement(table, 1).getClassName().contains(styleLastColumn)); |
| |
| // Two separate spans of same header: HHHXHH. |
| table.addColumn(new TextColumn<String>() { |
| @Override |
| public String getValue(String object) { |
| return null; |
| } |
| }, header); |
| table.addColumn(new TextColumn<String>() { |
| @Override |
| public String getValue(String object) { |
| return null; |
| } |
| }, header); |
| table.getPresenter().flush(); |
| assertEquals(3, getHeaderCount(table)); |
| assertEquals(3, getHeaderElement(table, 0).getColSpan()); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleHeader)); |
| assertTrue(getHeaderElement(table, 0).getClassName().contains(styleFirstColumn)); |
| assertEquals(1, getHeaderElement(table, 1).getColSpan()); |
| assertTrue(getHeaderElement(table, 1).getClassName().contains(styleHeader)); |
| assertEquals(2, getHeaderElement(table, 2).getColSpan()); |
| assertTrue(getHeaderElement(table, 2).getClassName().contains(styleHeader)); |
| assertTrue(getHeaderElement(table, 2).getClassName().contains(styleLastColumn)); |
| } |
| |
| public void testNullLoadingImage() { |
| // Create a Resources instance that does not include a loading image. |
| CellTable.Resources resources = new CellTable.Resources() { |
| private final CellTable.Resources defaultRes = GWT.create(CellTable.Resources.class); |
| |
| @Override |
| public ImageResource cellTableFooterBackground() { |
| return defaultRes.cellTableFooterBackground(); |
| } |
| |
| @Override |
| public ImageResource cellTableHeaderBackground() { |
| return defaultRes.cellTableHeaderBackground(); |
| } |
| |
| @Override |
| public ImageResource cellTableLoading() { |
| return null; |
| } |
| |
| @Override |
| public ImageResource cellTableSelectedBackground() { |
| return defaultRes.cellTableSelectedBackground(); |
| } |
| |
| @Override |
| public ImageResource cellTableSortAscending() { |
| return defaultRes.cellTableSortAscending(); |
| } |
| |
| @Override |
| public ImageResource cellTableSortDescending() { |
| return defaultRes.cellTableSortDescending(); |
| } |
| |
| @Override |
| public Style cellTableStyle() { |
| return defaultRes.cellTableStyle(); |
| } |
| }; |
| |
| CellTable<String> table = new CellTable<String>(25, resources); |
| assertNull(table.getLoadingIndicator()); |
| } |
| |
| /** |
| * Using a null sort icon should not cause any errors if none of the columns |
| * are sortable. |
| */ |
| public void testNullSortIcons() { |
| // Create a Resources instance that does not include sort images. |
| CellTable.Resources resources = new CellTable.Resources() { |
| private final CellTable.Resources defaultRes = GWT.create(CellTable.Resources.class); |
| |
| @Override |
| public ImageResource cellTableFooterBackground() { |
| return defaultRes.cellTableFooterBackground(); |
| } |
| |
| @Override |
| public ImageResource cellTableHeaderBackground() { |
| return defaultRes.cellTableHeaderBackground(); |
| } |
| |
| @Override |
| public ImageResource cellTableLoading() { |
| return defaultRes.cellTableLoading(); |
| } |
| |
| @Override |
| public ImageResource cellTableSelectedBackground() { |
| return defaultRes.cellTableSelectedBackground(); |
| } |
| |
| @Override |
| public ImageResource cellTableSortAscending() { |
| return null; |
| } |
| |
| @Override |
| public ImageResource cellTableSortDescending() { |
| return null; |
| } |
| |
| @Override |
| public Style cellTableStyle() { |
| return defaultRes.cellTableStyle(); |
| } |
| }; |
| |
| CellTable<String> table = new CellTable<String>(10, resources); |
| populateData(table); |
| table.getPresenter().flush(); |
| } |
| |
| /** |
| * CellTable should not throw any errors if all of the icons are null. |
| * |
| * Sort icons are only used if a column is sorted. Background icons are not |
| * used in the default styles, and are optional. The sorting icon is specially |
| * handled. |
| */ |
| public void testNullIcons() { |
| // Create a Resources instance that does not include sort images. |
| CellTable.Resources resources = new CellTable.Resources() { |
| private final CellTable.Resources defaultRes = GWT.create(CellTable.Resources.class); |
| |
| @Override |
| public ImageResource cellTableFooterBackground() { |
| return null; |
| } |
| |
| @Override |
| public ImageResource cellTableHeaderBackground() { |
| return null; |
| } |
| |
| @Override |
| public ImageResource cellTableLoading() { |
| return null; |
| } |
| |
| @Override |
| public ImageResource cellTableSelectedBackground() { |
| return null; |
| } |
| |
| @Override |
| public ImageResource cellTableSortAscending() { |
| return null; |
| } |
| |
| @Override |
| public ImageResource cellTableSortDescending() { |
| return null; |
| } |
| |
| @Override |
| public Style cellTableStyle() { |
| return defaultRes.cellTableStyle(); |
| } |
| }; |
| |
| CellTable<String> table = new CellTable<String>(10, resources); |
| populateData(table); |
| table.getPresenter().flush(); |
| } |
| |
| /** |
| * Test that removing a column sets its width to zero and the display to none. |
| */ |
| public void testRemoveColumnWithWidth_withRemoveColumnsOnHideEnabled() { |
| CellTable<String> table = createAbstractHasData(new TextCell()); |
| table.setRemoveColumnsOnHide(true); |
| Column<String, ?> column1 = table.getColumn(1); |
| table.setColumnWidth(column1, "100px"); |
| Element col0 = table.colgroup.getFirstChildElement(); |
| Element col1 = col0.getNextSiblingElement(); |
| assertEquals("100px", col1.getStyle().getWidth().toLowerCase(Locale.ROOT)); |
| assertEquals(2, table.colgroup.getChildCount()); |
| |
| // Remove column 1. |
| table.removeColumn(column1); |
| table.getPresenter().flush(); |
| |
| assertNull(col0.getNextSiblingElement()); |
| assertEquals(1, table.colgroup.getChildCount()); |
| } |
| |
| public void testRemoveColumnWithWidth_withRemoveColumnsOnHideDisabled() { |
| CellTable<String> table = createAbstractHasData(new TextCell()); |
| table.setRemoveColumnsOnHide(false); |
| Column<String, ?> column1 = table.getColumn(1); |
| table.setColumnWidth(column1, "100px"); |
| Element col0 = table.colgroup.getFirstChildElement(); |
| Element col1 = col0.getNextSiblingElement(); |
| assertEquals("100px", col1.getStyle().getWidth().toLowerCase(Locale.ROOT)); |
| assertEquals(2, table.colgroup.getChildCount()); |
| |
| // Remove column 1. |
| table.removeColumn(column1); |
| table.getPresenter().flush(); |
| |
| assertEquals("0px", col1.getStyle().getWidth()); |
| assertEquals("none", col1.getStyle().getDisplay().toLowerCase(Locale.ROOT)); |
| } |
| |
| public void testEmptyTableWidgetAttachDetach() { |
| class AttachDetachAwareWidget extends Widget { |
| int attachCount = 0; |
| int detachCount = 0; |
| |
| public AttachDetachAwareWidget() { |
| setElement(DOM.createAnchor()); |
| } |
| |
| @Override |
| protected void onAttach() { |
| attachCount++; |
| } |
| |
| @Override |
| protected void onDetach() { |
| detachCount++; |
| } |
| } |
| |
| AttachDetachAwareWidget widget = new AttachDetachAwareWidget(); |
| CellTable<String> table = createAbstractHasData(new TextCell()); |
| table.setEmptyTableWidget(widget); |
| assertEquals(0, widget.attachCount); |
| RootPanel.get().add(table); |
| RootPanel.get().remove(table); |
| RootPanel.get().add(table); |
| assertEquals(2, widget.attachCount); |
| assertEquals(1, widget.detachCount); |
| } |
| |
| @Override |
| public void testSetColumnWidth() { |
| CellTable<String> table = createAbstractHasData(new TextCell()); |
| Column<String, ?> column0 = table.getColumn(0); |
| Column<String, ?> column1 = table.getColumn(1); |
| |
| // Set the width. |
| table.setColumnWidth(column1, "100px"); |
| Element col0 = table.colgroup.getFirstChildElement(); |
| Element col1 = col0.getNextSiblingElement(); |
| assertEquals("", col0.getStyle().getWidth()); |
| assertEquals("100px", col1.getStyle().getWidth().toLowerCase(Locale.ROOT)); |
| |
| // Clear the width. |
| table.clearColumnWidth(column1); |
| assertEquals("", col0.getStyle().getWidth()); |
| assertEquals("", col1.getStyle().getWidth()); |
| |
| // Set the width again. |
| table.setColumnWidth(column0, 30.1, Unit.PCT); |
| assertEquals("30.1%", col0.getStyle().getWidth().toLowerCase(Locale.ROOT)); |
| assertEquals("", col1.getStyle().getWidth()); |
| } |
| |
| public void testSetTableLayoutFixed() { |
| CellTable<String> table = createAbstractHasData(new TextCell()); |
| assertNotSame("fixed", table.getElement().getStyle().getTableLayout()); |
| |
| table.setTableLayoutFixed(true); |
| assertEquals("fixed", table.getElement().getStyle().getTableLayout()); |
| |
| table.setTableLayoutFixed(false); |
| assertNotSame("fixed", table.getElement().getStyle().getTableLayout()); |
| } |
| |
| /** |
| * Test if the tableWidget style is applied. |
| */ |
| public void testTableWidgetStyle() { |
| Resources res = GWT.create(Resources.class); |
| CellTable<String> table = new CellTable<String>(10, res); |
| |
| String tableWidgetStyle = res.cellTableStyle().cellTableWidget(); |
| |
| TableElement tableElem = table.getElement().cast(); |
| assertTrue(tableElem.getClassName().contains(tableWidgetStyle)); |
| } |
| |
| public void testTableRenderedEvent() { |
| final Counter counter = new Counter(); |
| CellTable<String> table = createAbstractHasData(new TextCell()); |
| table.addRedrawHandler(new Handler() { |
| @Override |
| public void onRedraw() { |
| counter.increment(); |
| } |
| }); |
| |
| // Cause table to redraw by removing a column. |
| Column<String, ?> column1 = table.getColumn(1); |
| table.removeColumn(column1); |
| table.getPresenter().flush(); |
| assertEquals(1, counter.getCount()); |
| |
| // Cause the table to redraw by resetting the {@link CellTableBuilder}. |
| table.setTableBuilder(new DefaultCellTableBuilder<String>(table)); |
| table.getPresenter().flush(); |
| assertEquals(2, counter.getCount()); |
| } |
| |
| @Override |
| protected CellTable<String> createAbstractHasData() { |
| return new CellTable<String>(); |
| } |
| |
| @Override |
| protected TableCellElement getBodyElement(CellTable<String> table, int row, int column) { |
| TableElement tableElem = table.getElement().cast(); |
| TableSectionElement tbody = tableElem.getTBodies().getItem(0); |
| TableRowElement tr = tbody.getRows().getItem(row); |
| return tr.getCells().getItem(column); |
| } |
| |
| @Override |
| protected int getHeaderCount(CellTable<String> table) { |
| TableElement tableElem = table.getElement().cast(); |
| TableSectionElement thead = tableElem.getTHead(); |
| if (thead.getRows().getLength() == 0) { |
| return 0; |
| } |
| TableRowElement tr = thead.getRows().getItem(0); |
| return tr.getCells().getLength(); |
| } |
| |
| @Override |
| protected TableCellElement getHeaderElement(CellTable<String> table, int column) { |
| TableElement tableElem = table.getElement().cast(); |
| TableSectionElement thead = tableElem.getTHead(); |
| TableRowElement tr = thead.getRows().getItem(0); |
| return tr.getCells().getItem(column); |
| } |
| } |