blob: 17df91af6cbd6b27c96bae93cc7c3bbbbfa325dd [file] [log] [blame]
/*
* 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);
}
}