/*******************************************************************************
* Copyright (c) 2012 Original authors and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Original authors and others - initial API and implementation
******************************************************************************/
package org.eclipse.nebula.widgets.nattable.selection;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.eclipse.nebula.widgets.nattable.coordinate.Range;
import org.eclipse.nebula.widgets.nattable.selection.SelectionLayer;
import org.eclipse.nebula.widgets.nattable.selection.SelectionModel;
import org.eclipse.nebula.widgets.nattable.test.fixture.layer.DataLayerFixture;
import org.eclipse.nebula.widgets.nattable.util.ObjectUtils;
import org.eclipse.swt.graphics.Rectangle;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
public class SelectionModelTest {
private SelectionModel model;
@Before
public void before() {
SelectionLayer selectionLayer = new SelectionLayer(
new DataLayerFixture(100, 100, 100, 40));
this.model = new SelectionModel(selectionLayer);
}
@Test
public void isCellSelected() {
assertFalse("Empty model should have no selection.",
this.model.isCellPositionSelected(0, 0));
}
@Test
public void addCellSelection() {
this.model.addSelection(0, 0);
assertTrue("Failed to add selection.",
this.model.isCellPositionSelected(0, 0));
}
@Test
public void isColumnFullySelected() throws Exception {
this.model.addSelection(new Rectangle(3, 0, 10, 10));
assertFalse(this.model.isColumnPositionFullySelected(3, 11));
assertTrue(this.model.isColumnPositionFullySelected(3, 10));
this.model.clearSelection(3, 1);
assertFalse(this.model.isColumnPositionFullySelected(3, 10));
}
@Test
public void isColumnFullySelectedForContiguousRectangles() throws Exception {
this.model.addSelection(new Rectangle(0, 0, 10, 10));
this.model.addSelection(new Rectangle(5, 10, 10, 10));
assertTrue(this.model.isColumnPositionFullySelected(5, 20));
}
@Test
public void isColumnFullySelectedForNonContiguousRectangles()
throws Exception {
this.model.addSelection(new Rectangle(0, 0, 10, 10));
this.model.addSelection(new Rectangle(5, 5, 10, 8));
this.model.addSelection(new Rectangle(5, 15, 10, 5));
assertFalse(this.model.isColumnPositionFullySelected(5, 20));
}
@Test
public void isColumnFullySelectedForOverlapingRectangles() throws Exception {
this.model.addSelection(new Rectangle(0, 0, 10, 10));
this.model.addSelection(new Rectangle(5, 5, 10, 8));
assertTrue(this.model.isColumnPositionFullySelected(5, 13));
}
@Test
public void isColumnFullySelectedWhenIndividualCellsSelected()
throws Exception {
this.model.addSelection(new Rectangle(1, 5, 1, 1));
this.model.addSelection(new Rectangle(1, 10, 1, 1));
assertFalse(this.model.isColumnPositionFullySelected(1, 10));
}
@Test
public void isColumnFullySelectedWhenLastCellSelected() throws Exception {
this.model.addSelection(new Rectangle(1, 5, 1, 1));
assertFalse(this.model.isColumnPositionFullySelected(1, 6));
assertFalse(this.model.isColumnPositionFullySelected(1, 1000000));
}
@Test
public void isRowFullySelected() throws Exception {
this.model.addSelection(new Rectangle(0, 3, 10, 10));
assertTrue(this.model.isRowPositionFullySelected(3, 10));
}
@Test
public void isRowFullySelectedWhenMultipleRowsAndColumnsAreSelected()
throws Exception {
// Rows 3, 6 fully selected
this.model.addSelection(new Rectangle(0, 3, 10, 1));
this.model.addSelection(new Rectangle(0, 6, 10, 1));
// Column 2, 5 fully selected
this.model.addSelection(new Rectangle(2, 0, 1, 10));
this.model.addSelection(new Rectangle(5, 0, 1, 10));
assertTrue(this.model.isRowPositionFullySelected(6, 10));
assertTrue(this.model.isRowPositionFullySelected(3, 10));
// Remove Column 2
this.model.clearSelection(new Rectangle(2, 0, 1, 10));
assertFalse(this.model.isRowPositionFullySelected(6, 10));
assertFalse(this.model.isRowPositionFullySelected(3, 10));
// Add column 2 again
this.model.addSelection(new Rectangle(2, 0, 1, 10));
assertTrue(this.model.isRowPositionFullySelected(6, 10));
assertTrue(this.model.isRowPositionFullySelected(3, 10));
}
@Test
public void isRowNotFullySelected() throws Exception {
this.model.addSelection(new Rectangle(0, 3, 10, 10));
assertFalse(this.model.isRowPositionFullySelected(3, 11));
}
@Test
public void contains() throws Exception {
assertTrue(this.model.contains(new Rectangle(0, 0, 10, 10), new Rectangle(1,
1, 5, 5)));
assertTrue(this.model.contains(new Rectangle(0, 0, 10, 1), new Rectangle(5,
0, 1, 1)));
assertFalse(this.model.contains(new Rectangle(0, 6, 0, 0), new Rectangle(2,
6, 1, 1)));
}
@Test
public void isMltipleCol() throws Exception {
this.model.addSelection(new Rectangle(1, 0, 1, 20));
this.model.addSelection(new Rectangle(2, 0, 1, 20));
this.model.addSelection(new Rectangle(3, 0, 1, 20));
assertFalse(this.model.isColumnPositionFullySelected(1, 21));
assertTrue(this.model.isColumnPositionFullySelected(2, 20));
}
@Test
public void shouldReturnListOfFullySelectedColumns() throws Exception {
this.model.addSelection(new Rectangle(1, 0, 1, 20));
this.model.addSelection(new Rectangle(2, 10, 1, 4));
this.model.addSelection(new Rectangle(3, 0, 1, 20));
int[] fullySelectedColumns = this.model.getFullySelectedColumnPositions(20);
Assert.assertEquals(2, fullySelectedColumns.length);
Assert.assertEquals(1, fullySelectedColumns[0]);
Assert.assertEquals(3, fullySelectedColumns[1]);
}
@Test
public void shouldReturnListOfFullySelectedRows() throws Exception {
int[] fullySelectedRows = this.model.getFullySelectedRowPositions(20);
Assert.assertEquals(0, fullySelectedRows.length);
this.model.addSelection(new Rectangle(0, 1, 20, 1));
this.model.addSelection(new Rectangle(3, 2, 4, 1));
this.model.addSelection(new Rectangle(0, 3, 20, 1));
fullySelectedRows = this.model.getFullySelectedRowPositions(20);
Assert.assertEquals(2, fullySelectedRows.length);
Assert.assertEquals(1, fullySelectedRows[0]);
Assert.assertEquals(3, fullySelectedRows[1]);
}
@Test
public void addMultipleAdjacentCellSelection() {
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
this.model.addSelection(col, row);
}
}
for (int row = 0; row < 3; row++) {
for (int col = 0; col < 3; col++) {
assertTrue(
"Failed to add selection [" + row + ", " + col + "]",
this.model.isCellPositionSelected(col, row));
}
}
}
@Test
public void addMultipleDisjointCellSelection() {
this.model.addSelection(0, 0);
this.model.addSelection(2, 0);
this.model.addSelection(0, 2);
assertTrue("Failed to add selection [0, 0]",
this.model.isCellPositionSelected(0, 0));
assertTrue("Failed to add selection [0, 2]",
this.model.isCellPositionSelected(2, 0));
assertTrue("Failed to add selection [2, 0]",
this.model.isCellPositionSelected(0, 2));
assertFalse("Added too many cells to the range",
this.model.isCellPositionSelected(1, 0));
assertFalse("Added too many cells to the range",
this.model.isCellPositionSelected(0, 1));
assertFalse("Added too many cells to the range",
this.model.isCellPositionSelected(1, 1));
assertFalse("Added too many cells to the range",
this.model.isCellPositionSelected(2, 1));
assertFalse("Added too many cells to the range",
this.model.isCellPositionSelected(1, 2));
assertFalse("Added too many cells to the range",
this.model.isCellPositionSelected(2, 2));
assertFalse("Added too many cells to the range",
this.model.isCellPositionSelected(3, 3));
}
@Test
public void clearSelection() {
this.model.addSelection(0, 0);
this.model.clearSelection();
assertFalse("Failed to clear selection",
this.model.isCellPositionSelected(0, 0));
}
@Test
public void addRangeSelection() {
int col = 2;
int row = 3;
int numCols = 4;
int numRows = 5;
this.model.addSelection(new Rectangle(col, row, numCols, numRows));
for (int rowIndex = row; rowIndex < row + numRows; rowIndex++) {
for (int colIndex = col; colIndex < col + numCols; colIndex++) {
assertTrue("Failed to add range [" + rowIndex + ", " + colIndex
+ "]", this.model.isCellPositionSelected(colIndex, rowIndex));
}
}
assertFalse("Added too many cells from range",
this.model.isCellPositionSelected(col, row + numRows));
}
@Test
public void addNullRangeSelection() {
this.model.addSelection(null);
assertTrue(this.model.isEmpty());
}
@Test
public void removeSingleCell() {
this.model.addSelection(0, 0);
this.model.clearSelection(0, 0);
assertFalse("Failed to remove selection [0, 0].",
this.model.isCellPositionSelected(0, 0));
}
@Test
public void removeSingleCellAfterMultipleAdds() {
this.model.addSelection(0, 0);
this.model.addSelection(1, 1);
this.model.addSelection(2, 1);
this.model.addSelection(2, 3);
this.model.clearSelection(1, 1);
assertFalse("Failed to remove selection [1, 1].",
this.model.isCellPositionSelected(1, 1));
}
private void removeSingleCellFromRange(int col, int row, int numCols,
int numRows, int removedRow, int removedColumn) {
this.model.addSelection(new Rectangle(col, row, numCols, numRows));
this.model.clearSelection(removedColumn, removedRow);
assertFalse("Failed to remove selection [" + removedRow + ", "
+ removedColumn + "]",
this.model.isCellPositionSelected(removedColumn, removedRow));
for (int rowIndex = row; rowIndex < row + numRows; rowIndex++) {
for (int colIndex = col; colIndex < col + numCols; colIndex++) {
if (!(rowIndex == removedRow && colIndex == removedColumn))
assertTrue("Failed to add range [" + rowIndex + ", "
+ colIndex + "]",
this.model.isCellPositionSelected(colIndex, rowIndex));
}
}
}
private void removeRangeFromRange(int col, int row, int numCols,
int numRows, int removedRow, int removedColumn, int removedNumCols,
int removedNumRows) {
this.model.addSelection(new Rectangle(col, row, numCols, numRows));
Rectangle removedSelection = new Rectangle(removedColumn, removedRow,
removedNumCols, removedNumRows);
this.model.clearSelection(removedSelection);
for (int rowIndex = removedRow; rowIndex < removedRow + removedNumRows; rowIndex++) {
for (int colIndex = removedColumn; colIndex < removedColumn
+ removedNumCols; colIndex++) {
assertFalse("Failed to remove selection [" + rowIndex + ", "
+ colIndex + "]",
this.model.isCellPositionSelected(colIndex, rowIndex));
}
}
for (int rowIndex = row; rowIndex < row + numRows; rowIndex++) {
for (int colIndex = col; colIndex < col + numCols; colIndex++) {
if (!removedSelection.contains(colIndex, rowIndex))
assertTrue("Failed to add range [" + rowIndex + ", "
+ colIndex + "]",
this.model.isCellPositionSelected(colIndex, rowIndex));
}
}
}
@Test
public void removeSingleCellFrom1x1Range() {
int col = 2;
int row = 3;
int numCols = 1;
int numRows = 1;
int removedColumn = 2;
int removedRow = 3;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeSingleCellFromBeginning1x10Range() {
int col = 2;
int row = 3;
int numCols = 10;
int numRows = 1;
int removedColumn = 2;
int removedRow = 3;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeSingleCellFromEnd1x10Range() {
int col = 2;
int row = 3;
int numCols = 10;
int numRows = 1;
int removedColumn = 11;
int removedRow = 3;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeSingleCellFromMiddle1x10Range() {
int col = 2;
int row = 3;
int numCols = 10;
int numRows = 1;
int removedColumn = 8;
int removedRow = 3;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeSingleCellFromBeginning10x1Range() {
int col = 2;
int row = 3;
int numCols = 1;
int numRows = 10;
int removedColumn = 2;
int removedRow = 3;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeSingleCellFromEnd10x1Range() {
int col = 2;
int row = 3;
int numCols = 1;
int numRows = 10;
int removedColumn = 2;
int removedRow = 12;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeSingleCellFromMiddle10x1Range() {
int col = 2;
int row = 3;
int numCols = 1;
int numRows = 10;
int removedColumn = 2;
int removedRow = 7;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeTopLeftFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 2;
int removedRow = 3;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeTopRightFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 4;
int removedRow = 3;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeTopMiddleFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 3;
int removedRow = 3;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeBottomLeftFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 2;
int removedRow = 6;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeBottomRightFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 4;
int removedRow = 6;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeBottomMiddleFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 3;
int removedRow = 6;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeMidLeftFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 2;
int removedRow = 5;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeMidRightFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 4;
int removedRow = 5;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void removeMidMiddleFrom3x4Range() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 3;
int removedRow = 5;
removeSingleCellFromRange(col, row, numCols, numRows, removedRow,
removedColumn);
}
@Test
public void getSelectedRows() {
this.model.addSelection(10, 1);
this.model.addSelection(10, 2);
this.model.addSelection(10, 7);
this.model.addSelection(new Rectangle(10, 50, 5, 10));
List<Range> selectedRows = ObjectUtils.asList(this.model
.getSelectedRowPositions());
assertTrue(selectedRows.contains(new Range(1, 3)));
assertTrue(selectedRows.contains(new Range(7, 8)));
assertTrue(selectedRows.contains(new Range(50, 60)));
}
@Test
public void getSelectedRowsForOverlapingSelections() {
this.model.addSelection(new Rectangle(10, 3, 5, 2));
this.model.addSelection(new Rectangle(10, 4, 5, 10));
this.model.addSelection(new Rectangle(10, 20, 5, 10));
List<Range> selectedRows = ObjectUtils.asList(this.model
.getSelectedRowPositions());
assertEquals(2, selectedRows.size());
assertTrue(selectedRows.contains(new Range(3, 14)));
assertTrue(selectedRows.contains(new Range(20, 30)));
}
@Test
public void getSelectedRowsForLargeNumberOfSelections() {
this.model.addSelection(1, 10);
this.model.addSelection(new Rectangle(5, 1, 1, 100));
List<Range> selectedRows = ObjectUtils.asList(this.model
.getSelectedRowPositions());
assertEquals(1, selectedRows.size());
assertTrue(selectedRows.contains(new Range(1, 100)));
}
@Test
public void getSelectedRowCount() throws Exception {
this.model.addSelection(new Rectangle(10, 3, 1, 1));
this.model.addSelection(new Rectangle(10, 10, 1, 1));
this.model.addSelection(new Rectangle(10, 5, 1, 20));
assertEquals(21, this.model.getSelectedRowCount());
}
@Test
public void isRowPositionSelected() throws Exception {
this.model.addSelection(1, 10);
this.model.addSelection(new Rectangle(5, 1, 100, 10000000));
assertTrue(this.model.isRowPositionSelected(10));
assertTrue(this.model.isRowPositionSelected(99));
}
@Test
public void getSelectedColumns() {
int[] columns = new int[] { 1, 4, 3 };
for (int column : columns) {
this.model.addSelection(column, column % 3);
}
int[] selectedColumns = this.model.getSelectedColumnPositions();
Arrays.sort(columns);
assertEquals(Arrays.toString(columns), Arrays.toString(selectedColumns));
}
@Test
public void removeFromEmptySelection() {
Rectangle removedSelection = new Rectangle(0, 0, 10, 10);
this.model.clearSelection(removedSelection);
assertTrue("Removal from empty selection failed.", this.model.isEmpty());
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
assertFalse("Selection was not removed [" + i + ", " + j + "]",
this.model.isCellPositionSelected(j, i));
}
}
}
@Test
public void removeTopRange() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 4;
int removedColumn = 2;
int removedRow = 2;
int removedNumCols = 3;
int removedNumRows = 3;
removeRangeFromRange(col, row, numCols, numRows, removedRow,
removedColumn, removedNumCols, removedNumRows);
}
@Test
public void removeMidRange() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 10;
int removedColumn = 2;
int removedRow = 7;
int removedNumCols = 3;
int removedNumRows = 3;
removeRangeFromRange(col, row, numCols, numRows, removedRow,
removedColumn, removedNumCols, removedNumRows);
}
@Test
public void removeBottomRange() {
int col = 2;
int row = 3;
int numCols = 3;
int numRows = 10;
int removedColumn = 2;
int removedRow = 7;
int removedNumCols = 3;
int removedNumRows = 7;
removeRangeFromRange(col, row, numCols, numRows, removedRow,
removedColumn, removedNumCols, removedNumRows);
}
@Test
public void removeLeftRange() {
int col = 2;
int row = 3;
int numCols = 6;
int numRows = 4;
int removedColumn = 1;
int removedRow = 3;
int removedNumCols = 3;
int removedNumRows = 4;
removeRangeFromRange(col, row, numCols, numRows, removedRow,
removedColumn, removedNumCols, removedNumRows);
}
@Test
public void removeMiddleRange() {
int col = 2;
int row = 3;
int numCols = 6;
int numRows = 4;
int removedColumn = 4;
int removedRow = 3;
int removedNumCols = 2;
int removedNumRows = 4;
removeRangeFromRange(col, row, numCols, numRows, removedRow,
removedColumn, removedNumCols, removedNumRows);
}
@Test
public void removeRightRange() {
int col = 2;
int row = 3;
int numCols = 6;
int numRows = 4;
int removedColumn = 5;
int removedRow = 3;
int removedNumCols = 5;
int removedNumRows = 4;
removeRangeFromRange(col, row, numCols, numRows, removedRow,
removedColumn, removedNumCols, removedNumRows);
}
@Test
public void removeTopFromTwoRows() {
int col = 0;
int row = 0;
int numCols = 10;
int numRows = 2;
int removedColumn = col;
int removedRow = row;
int removedNumCols = numCols;
int removedNumRows = 1;
removeRangeFromRange(col, row, numCols, numRows, removedRow,
removedColumn, removedNumCols, removedNumRows);
}
@Test
public void sortByY() throws Exception {
List<Rectangle> rectangles = new ArrayList<Rectangle>();
rectangles.add(new Rectangle(0, 3, 1, 1));
rectangles.add(new Rectangle(0, 5, 1, 1));
rectangles.add(new Rectangle(0, 1, 1, 1));
rectangles.add(new Rectangle(0, 13, 1, 1));
this.model.sortByY(rectangles);
Assert.assertEquals(1, rectangles.get(0).y);
Assert.assertEquals(3, rectangles.get(1).y);
Assert.assertEquals(5, rectangles.get(2).y);
Assert.assertEquals(13, rectangles.get(3).y);
}
}