// $HeadURL$ // $Id$ // // Copyright © 2006, 2010, 2011, 2012 by the President and Fellows of Harvard College. // // Screensaver is an open-source project developed by the ICCB-L and NSRB labs // at Harvard Medical School. This software is distributed under the terms of // the GNU General Public License. package edu.harvard.med.screensaver.ui.arch.datatable; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import junit.framework.TestCase; import org.apache.log4j.Logger; import edu.harvard.med.screensaver.db.Criterion; import edu.harvard.med.screensaver.db.SortDirection; import edu.harvard.med.screensaver.db.Criterion.Operator; import edu.harvard.med.screensaver.db.datafetcher.DataFetcher; import edu.harvard.med.screensaver.db.hqlbuilder.HqlBuilder; import edu.harvard.med.screensaver.ui.arch.datatable.DataTable; import edu.harvard.med.screensaver.ui.arch.datatable.column.EnumColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.IntegerColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.RealColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.TableColumn; import edu.harvard.med.screensaver.ui.arch.datatable.column.TextColumn; import edu.harvard.med.screensaver.ui.arch.datatable.model.InMemoryDataModel; import edu.harvard.med.screensaver.ui.arch.util.UISelectOneBean; public class DataTableTest extends TestCase { // static members private static Logger log = Logger.getLogger(DataTableTest.class); // instance data members private DataTable<RowItem> _dataTable; private DataFetcher<RowItem,Integer,String> _dataFetcher; private int _fetchCount; private int _sortCount; private int _filterCount; private List<RowItem> _data; private List<TableColumn<RowItem,?>> _columns; private IntegerColumn<RowItem> _idCol; private TextColumn<RowItem> _nameCol; private EnumColumn<RowItem,Status> _statusCol; private RealColumn<RowItem> _valueCol; private TextColumn<RowItem> _urlCol; // public constructors and methods @Override public void setUp() { _columns = TableColumnManagerTest.makeColumns(); _idCol = (IntegerColumn<RowItem>) _columns.get(0); assertEquals("ID", _idCol.getName()); _nameCol = (TextColumn<RowItem>) _columns.get(1); assertEquals("Name", _nameCol.getName()); _statusCol = (EnumColumn<RowItem,Status>) _columns.get(2); assertEquals("Status", _statusCol.getName()); _valueCol = (RealColumn<RowItem>) _columns.get(3); assertEquals("Value", _valueCol.getName()); _urlCol = (TextColumn<RowItem>) _columns.get(4); assertEquals("URL", _urlCol.getName()); _data = new ArrayList<RowItem>(); try { _data.add(new RowItem(1, "a", Status.NEW, 1.00, new URL("http://1.com"))); _data.add(new RowItem(2, "b", Status.ACTIVE, 2.00, new URL("http://2.com"))); _data.add(new RowItem(3, "c", Status.DEAD, 3.00, new URL("http://3.com"))); } catch (MalformedURLException e) { fail(e.getMessage()); } _dataFetcher = new DataFetcher<RowItem,Integer,String>() { public List<RowItem> fetchAllData() { ++_fetchCount; return _data; } public Map<Integer,RowItem> fetchData(Set<Integer> keys) { Map<Integer,RowItem> result = new HashMap<Integer,RowItem>(); for (RowItem rowitem : _data) { if (keys.contains(rowitem.getId())) { result.put(rowitem.getId(), rowitem); } } return result; } public List<Integer> findAllKeys() { List<Integer> result = new ArrayList<Integer>(); for (RowItem rowitem : _data) { result.add(rowitem.getId()); } return result; } public void setFilteringCriteria(Map<String,List<? extends Criterion<?>>> criteria) { throw new UnsupportedOperationException("this DataFetcher expected to be used by InMemoryDataModel only"); } public void setOrderBy(List<String> orderByProperties) { throw new UnsupportedOperationException("this DataFetcher expected to be used by InMemoryDataModel only"); } @Override public void addDomainRestrictions(HqlBuilder hql) { } @Override public void setPropertiesToFetch(List<String> properties) { } }; _dataTable = new DataTable<RowItem>(); _dataTable.initialize(new InMemoryDataModel<RowItem>(_dataFetcher) { @Override public void sort(List<? extends TableColumn<RowItem,?>> sortColumns, SortDirection sortDirection) { ++_sortCount; super.sort(sortColumns, sortDirection); } @Override public void filter(List<? extends TableColumn<RowItem,?>> columns) { ++_filterCount; super.filter(columns); } }, _columns, new UISelectOneBean<Integer>(Arrays.asList(1, 2, 4), 2), false); } public void testRefetchOnColumnVisibilityChange() { _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); int prevFetchCount = _fetchCount; int prevSortCount = _sortCount; int prevFilterCount = _filterCount; _statusCol.setVisible(false); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("no data fetch after hiding column", prevFetchCount, _fetchCount); assertEquals("no data sort after hiding column", prevSortCount, _sortCount); assertEquals("no data filter after hiding column", prevFilterCount, _filterCount); _statusCol.setVisible(true); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("data fetch after unhiding column", prevFetchCount + 1, _fetchCount); // for InMemoryDatModel: // when "raw" data is re-fetched, sort and filter need to be reapplied assertEquals("data sort after unhiding column", prevSortCount + 1, _sortCount); assertEquals("data filter after unhiding column", prevFilterCount + 1, _filterCount); } public void testResortOnSortColumnChange() { _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); int prevFetchCount = _fetchCount; int prevSortCount = _sortCount; int prevFilterCount = _filterCount; _dataTable.getColumnManager().setSortColumn(_idCol); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("no data fetch after setting same sort column", prevFetchCount, _fetchCount); assertEquals("no data sort after setting same sort column", prevSortCount, _sortCount); assertEquals("no data filter after setting same sort column", prevFilterCount, _filterCount); _dataTable.getColumnManager().setSortColumn(_statusCol); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("no data fetch after setting different sort column", prevFetchCount, _fetchCount); assertEquals("data sort after setting different sort column", prevSortCount + 1, _sortCount); assertEquals("no data filter after setting different sort column", prevFilterCount, _filterCount); _dataTable.getColumnManager().setSortDirection(SortDirection.DESCENDING); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("no data fetch after setting different sort dir", prevFetchCount, _fetchCount); assertEquals("data sort after setting same different dir", prevSortCount + 2, _sortCount); assertEquals("no data filter after setting same different dir", prevFilterCount, _filterCount); _dataTable.getColumnManager().setSortColumn(_urlCol); _dataTable.getColumnManager().setSortDirection(SortDirection.ASCENDING); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("no data fetch after setting different sort col & dir", prevFetchCount, _fetchCount); assertEquals("(single) data sort after setting same different col & dir", prevSortCount + 3, _sortCount); assertEquals("no data filter after setting same different col & dir", prevFilterCount, _filterCount); } public void testRefilterOnCriterionChange() { _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); int prevFetchCount = _fetchCount; int prevSortCount = _sortCount; int prevFilterCount = _filterCount; _statusCol.clearCriteria().addCriterion(new Criterion<Status>(Operator.EQUAL, Status.DEAD)); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("no data fetch after adding criterion", prevFetchCount, _fetchCount); assertEquals("data filter after adding criterion", prevFilterCount + 1, _filterCount); // for InMemoryDataModel: sort must occur after filter occurs assertEquals("data sort after filter", prevSortCount + 1, _sortCount); _statusCol.getCriterion().setValue(Status.NEW); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("no data fetch after changing existing criterion value", prevFetchCount, _fetchCount); assertEquals("data filter after changing existing criterion value", prevFilterCount + 2, _filterCount); // for InMemoryDataModel: sort must occur after filter occurs assertEquals("data sort after changing existing criterion value", prevSortCount + 2, _sortCount); _statusCol.setVisible(false); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("no data fetch after criterion column hidden", prevFetchCount, _fetchCount); assertEquals("data filter after criterion column hidden", prevFilterCount + 3, _filterCount); // for InMemoryDataModel: sort must occur after filter occurs assertEquals("data sort after criterion column hidden", prevSortCount + 3, _sortCount); _statusCol.setVisible(true); _dataTable.getDataTableModel().setRowIndex(0); _dataTable.getRowData(); assertEquals("data fetch after criterion column unhidden", prevFetchCount + 1, _fetchCount); // for InMemoryDatModel: // when "raw" data is re-fetched, sort and filter need to be reapplied // re-filter also necessary since criterion column may have changed filter result assertEquals("data sort after criterion column unhidden", prevSortCount + 4, _sortCount); assertEquals("data filter after criterion column unhidden", prevFilterCount + 4, _filterCount); } public void testSortColumnChangedIfHidden() { _dataTable.getColumnManager().setSortColumn(_nameCol); _dataTable.getColumnManager().setSortDirection(SortDirection.DESCENDING); _dataTable.getDataTableModel().setRowIndex(0); RowItem rowData = _dataTable.getRowData(); assertEquals("originally sorted desc on name column", _nameCol, _dataTable.getColumnManager().getSortColumn()); assertEquals("originally sorted desc on name column", new Integer(3), rowData.getId()); _nameCol.setVisible(false); _dataTable.getDataTableModel().setRowIndex(0); rowData = _dataTable.getRowData(); assertEquals("sorted on id column after hiding original sort column", _idCol, _dataTable.getColumnManager().getSortColumn()); assertEquals("sorted on id column after hiding original sort column", new Integer(3), rowData.getId()); } public void testRowsPerPageSelector() { assertEquals(2, _dataTable.getRowsPerPage()); _dataTable.getRowsPerPageSelector().setSelection(1); assertEquals(1, _dataTable.getRowsPerPage()); assertTrue(_dataTable.isMultiPaged()); _dataTable.getRowsPerPageSelector().setSelection(4); assertEquals(4, _dataTable.getRowsPerPage()); assertFalse(_dataTable.isMultiPaged()); } public void testResetFilter() { _dataTable.getColumnManager().setSortColumn(_valueCol); _valueCol.getCriterion().setOperatorAndValue(Operator.GREATER_THAN_EQUAL, 2.0); assertEquals("filtered prior to reset", 2, _dataTable.getRowCount()); _dataTable.resetFilter(); assertEquals("filter reset", 3, _dataTable.getRowCount()); } // private methods }