Merge branch 'develop' of http://source.jalview.org/git/jalview into develop
[jalview.git] / test / jalview / datamodel / ColumnSelectionTest.java
index e59719c..a943e7c 100644 (file)
@@ -22,12 +22,14 @@ package jalview.datamodel;
 
 import static org.testng.AssertJUnit.assertEquals;
 import static org.testng.AssertJUnit.assertFalse;
-import static org.testng.AssertJUnit.assertNotSame;
 import static org.testng.AssertJUnit.assertSame;
 import static org.testng.AssertJUnit.assertTrue;
+import static org.testng.AssertJUnit.fail;
 
 import java.util.Arrays;
 import java.util.BitSet;
+import java.util.Collections;
+import java.util.ConcurrentModificationException;
 import java.util.List;
 
 import org.testng.annotations.Test;
@@ -68,8 +70,8 @@ public class ColumnSelectionTest
 
     // removing an element in the list removes it
     cs.removeElement(2);
-    // ...but not from the copy list!
-    assertEquals(2, sel.size());
+    // ...and also from the read-only view
+    assertEquals(1, sel.size());
     sel = cs.getSelected();
     assertEquals(1, sel.size());
     assertEquals(new Integer(5), sel.get(0));
@@ -542,7 +544,7 @@ public class ColumnSelectionTest
    * were added
    */
   @Test(groups = { "Functional" })
-  public void testGetSelection()
+  public void testGetSelected()
   {
     ColumnSelection cs = new ColumnSelection();
     int[] sel = { 4, 3, 7, 21 };
@@ -551,32 +553,90 @@ public class ColumnSelectionTest
       cs.addElement(col);
     }
 
-    List<Integer> selected1 = cs.getSelected();
-    assertEquals(4, selected1.size());
+    List<Integer> selected = cs.getSelected();
+    assertEquals(4, selected.size());
+    assertEquals("[4, 3, 7, 21]", selected.toString());
 
     /*
-     * getSelected returns a copy, verify the list
-     * is externally immutable
+     * getSelected returns a read-only view of the list
+     * verify the view follows any changes in it
      */
-    selected1.clear();
-    List<Integer> selected2 = cs.getSelected();
-    assertNotSame(selected1, selected2);
-    assertEquals(4, selected2.size());
-    int i = 0;
-    for (int col : sel)
+    cs.removeElement(7);
+    cs.addElement(1);
+    cs.removeElement(4);
+    assertEquals("[3, 21, 1]", selected.toString());
+  }
+
+  /**
+   * Test to verify that the list returned by getSelection cannot be modified
+   */
+  @Test(groups = { "Functional" })
+  public void testGetSelected_isReadOnly()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(3);
+
+    List<Integer> selected = cs.getSelected();
+    try
+    {
+      selected.clear();
+      fail("expected exception");
+    } catch (UnsupportedOperationException e)
+    {
+      // expected
+    }
+    try
+    {
+      selected.add(1);
+      fail("expected exception");
+    } catch (UnsupportedOperationException e)
+    {
+      // expected
+    }
+    try
+    {
+      selected.remove(3);
+      fail("expected exception");
+    } catch (UnsupportedOperationException e)
     {
-      assertEquals(col, selected2.get(i++).intValue());
+      // expected
     }
+    try
+    {
+      Collections.sort(selected);
+      fail("expected exception");
+    } catch (UnsupportedOperationException e)
+    {
+      // expected
+    }
+  }
 
-    cs.removeElement(7);
+  /**
+   * Test that demonstrates a ConcurrentModificationException is thrown if you
+   * change the selection while iterating over it
+   */
+  @Test(
+    groups = "Functional",
+    expectedExceptions = { ConcurrentModificationException.class })
+  public void testGetSelected_concurrentModification()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(0);
     cs.addElement(1);
-    cs.removeElement(4);
+    cs.addElement(2);
 
-    List<Integer> selected3 = cs.getSelected();
-    assertEquals(3, selected3.size());
-    assertEquals(3, selected3.get(0).intValue());
-    assertEquals(21, selected3.get(1).intValue());
-    assertEquals(1, selected3.get(2).intValue());
+    /*
+     * simulate changing the list under us (e.g. in a separate
+     * thread) while iterating over it -> ConcurrentModificationException
+     */
+    List<Integer> selected = cs.getSelected();
+    for (Integer col : selected)
+    {
+      if (col.intValue() == 0)
+      {
+        cs.removeElement(1);
+      }
+    }
   }
 
   @Test(groups = "Functional")
@@ -669,4 +729,25 @@ public class ColumnSelectionTest
     assertTrue(selected.contains(6));
     assertTrue(selected.contains(10));
   }
+
+  @Test(groups = "Functional")
+  public void testCopyConstructor()
+  {
+    ColumnSelection cs = new ColumnSelection();
+    cs.addElement(3);
+    cs.addElement(1);
+    cs.hideColumns(10, 11);
+    cs.hideColumns(5, 7);
+    assertEquals("[5, 7]", Arrays.toString(cs.getHiddenColumns().get(0)));
+
+    ColumnSelection cs2 = new ColumnSelection(cs);
+    assertTrue(cs2.hasSelectedColumns());
+    assertTrue(cs2.hasHiddenColumns());
+    // order of column selection is preserved
+    assertEquals("[3, 1]", cs2.getSelected().toString());
+    assertEquals(2, cs2.getHiddenColumns().size());
+    // hidden columns are held in column order
+    assertEquals("[5, 7]", Arrays.toString(cs2.getHiddenColumns().get(0)));
+    assertEquals("[10, 11]", Arrays.toString(cs2.getHiddenColumns().get(1)));
+  }
 }