2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.datamodel;
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertTrue;
26 import static org.testng.AssertJUnit.fail;
28 import jalview.analysis.AlignmentGenerator;
29 import jalview.gui.JvOptionPane;
31 import java.util.Arrays;
32 import java.util.BitSet;
33 import java.util.Collections;
34 import java.util.ConcurrentModificationException;
35 import java.util.List;
37 import org.testng.annotations.BeforeClass;
38 import org.testng.annotations.Test;
40 public class ColumnSelectionTest
43 @BeforeClass(alwaysRun = true)
44 public void setUpJvOptionPane()
46 JvOptionPane.setInteractiveMode(false);
47 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
50 @Test(groups = { "Functional" })
51 public void testAddElement()
53 ColumnSelection cs = new ColumnSelection();
57 cs.addElement(5); // ignored
58 List<Integer> sel = cs.getSelected();
59 assertEquals("[2, 5, 3]", sel.toString());
63 * Test the remove method - in particular to verify that remove(int i) removes
64 * the element whose value is i, _NOT_ the i'th element.
66 @Test(groups = { "Functional" })
67 public void testRemoveElement()
69 ColumnSelection cs = new ColumnSelection();
73 // removing elements not in the list has no effect
76 List<Integer> sel = cs.getSelected();
77 assertEquals(2, sel.size());
78 assertEquals(new Integer(2), sel.get(0));
79 assertEquals(new Integer(5), sel.get(1));
81 // removing an element in the list removes it
83 // ...and also from the read-only view
84 assertEquals(1, sel.size());
85 sel = cs.getSelected();
86 assertEquals(1, sel.size());
87 assertEquals(new Integer(5), sel.get(0));
91 * Test the method that hides a specified column including any adjacent
92 * selected columns. This is a convenience method for the case where multiple
93 * column regions are selected and then hidden using menu option View | Hide |
96 @Test(groups = { "Functional" })
97 public void testHideColumns_withSelection()
99 // create random alignment
100 AlignmentGenerator gen = new AlignmentGenerator(false);
101 AlignmentI al = gen.generate(50, 20, 123, 5, 5);
103 ColumnSelection cs = new ColumnSelection();
104 // select columns 4-6
108 // hide column 5 (and adjacent):
109 cs.hideSelectedColumns(5, al);
111 List<int[]> hidden = al.getHiddenColumns().getListOfCols();
112 assertEquals(1, hidden.size());
113 assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
114 // none now selected:
115 assertTrue(cs.getSelected().isEmpty());
117 // repeat, hiding column 4 (5 and 6)
118 al = gen.generate(50, 20, 123, 5, 5);
119 cs = new ColumnSelection();
123 cs.hideSelectedColumns(4, al);
124 hidden = al.getHiddenColumns().getListOfCols();
125 assertEquals(1, hidden.size());
126 assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
127 assertTrue(cs.getSelected().isEmpty());
129 // repeat, hiding column (4, 5 and) 6
130 al = gen.generate(50, 20, 123, 5, 5);
131 cs = new ColumnSelection();
135 cs.hideSelectedColumns(6, al);
136 hidden = al.getHiddenColumns().getListOfCols();
137 assertEquals(1, hidden.size());
138 assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
139 assertTrue(cs.getSelected().isEmpty());
141 // repeat, with _only_ adjacent columns selected
142 al = gen.generate(50, 20, 123, 5, 5);
143 cs = new ColumnSelection();
146 cs.hideSelectedColumns(5, al);
147 hidden = al.getHiddenColumns().getListOfCols();
148 assertEquals(1, hidden.size());
149 assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
150 assertTrue(cs.getSelected().isEmpty());
154 * Test the method that hides all (possibly disjoint) selected column ranges
156 @Test(groups = { "Functional" })
157 public void testHideSelectedColumns()
159 // create random alignment
160 AlignmentGenerator gen = new AlignmentGenerator(false);
161 AlignmentI al = gen.generate(50, 20, 123, 5, 5);
163 ColumnSelection cs = new ColumnSelection();
164 int[] sel = { 2, 3, 4, 7, 8, 9, 20, 21, 22 };
170 HiddenColumns cols = al.getHiddenColumns();
171 cols.hideColumns(15, 18);
173 cs.hideSelectedColumns(al);
174 assertTrue(cs.getSelected().isEmpty());
175 List<int[]> hidden = cols.getListOfCols();
176 assertEquals(4, hidden.size());
177 assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
178 assertEquals("[7, 9]", Arrays.toString(hidden.get(1)));
179 assertEquals("[15, 18]", Arrays.toString(hidden.get(2)));
180 assertEquals("[20, 22]", Arrays.toString(hidden.get(3)));
184 * Test the method that gets runs of selected columns ordered by column. If
185 * this fails, HideSelectedColumns may also fail
187 @Test(groups = { "Functional" })
188 public void testGetSelectedRanges()
191 * getSelectedRanges returns ordered columns regardless
192 * of the order in which they are added
194 ColumnSelection cs = new ColumnSelection();
195 int[] sel = { 4, 3, 7, 21, 9, 20, 8, 22, 2 };
201 range = cs.getSelectedRanges();
202 assertEquals(3, range.size());
203 assertEquals("[2, 4]", Arrays.toString(range.get(0)));
204 assertEquals("[7, 9]", Arrays.toString(range.get(1)));
205 assertEquals("[20, 22]", Arrays.toString(range.get(2)));
208 range = cs.getSelectedRanges();
209 assertEquals(3, range.size());
210 assertEquals("[0, 4]", Arrays.toString(range.get(0)));
213 @Test(groups = { "Functional" })
214 public void testInvertColumnSelection()
216 // create random alignment
217 AlignmentGenerator gen = new AlignmentGenerator(false);
218 AlignmentI al = gen.generate(50, 20, 123, 5, 5);
220 ColumnSelection cs = new ColumnSelection();
225 HiddenColumns cols = al.getHiddenColumns();
226 cols.hideColumns(3, 3);
227 cols.hideColumns(6, 6);
229 // invert selection from start (inclusive) to end (exclusive)
230 cs.invertColumnSelection(2, 9, al);
231 assertEquals("[2, 5, 7]", cs.getSelected().toString());
233 cs.invertColumnSelection(1, 9, al);
234 assertEquals("[1, 4, 8]", cs.getSelected().toString());
237 @Test(groups = { "Functional" })
238 public void testMaxColumnSelection()
240 ColumnSelection cs = new ColumnSelection();
244 assertEquals(513, cs.getMax());
245 cs.removeElement(513);
246 assertEquals(1, cs.getMax());
248 assertEquals(0, cs.getMax());
251 assertEquals(513, cs.getMax());
255 @Test(groups = { "Functional" })
256 public void testMinColumnSelection()
258 ColumnSelection cs = new ColumnSelection();
262 assertEquals(0, cs.getMin());
264 assertEquals(1, cs.getMin());
266 assertEquals(0, cs.getMin());
269 @Test(groups = { "Functional" })
270 public void testEquals()
272 ColumnSelection cs = new ColumnSelection();
277 // same selections added in a different order
278 ColumnSelection cs2 = new ColumnSelection();
283 assertTrue(cs.equals(cs2));
284 assertTrue(cs.equals(cs));
285 assertTrue(cs2.equals(cs));
286 assertTrue(cs2.equals(cs2));
289 assertFalse(cs.equals(cs2));
290 assertFalse(cs2.equals(cs));
292 cs2.removeElement(12);
293 assertTrue(cs.equals(cs2));
297 cs2.hideSelectedColumns(88);
298 assertFalse(cs.equals(cs2));
300 * unhiding a column adds it to selection!
302 /* cs2.revealHiddenColumns(88);
303 assertFalse(cs.equals(cs2));
305 assertTrue(cs.equals(cs2));
309 * Test the method that returns selected columns, in the order in which they
312 @Test(groups = { "Functional" })
313 public void testGetSelected()
315 ColumnSelection cs = new ColumnSelection();
316 int[] sel = { 4, 3, 7, 21 };
322 List<Integer> selected = cs.getSelected();
323 assertEquals(4, selected.size());
324 assertEquals("[4, 3, 7, 21]", selected.toString());
327 * getSelected returns a read-only view of the list
328 * verify the view follows any changes in it
333 assertEquals("[3, 21, 1]", selected.toString());
337 * Test to verify that the list returned by getSelection cannot be modified
339 @Test(groups = { "Functional" })
340 public void testGetSelected_isReadOnly()
342 ColumnSelection cs = new ColumnSelection();
345 List<Integer> selected = cs.getSelected();
349 fail("expected exception");
350 } catch (UnsupportedOperationException e)
357 fail("expected exception");
358 } catch (UnsupportedOperationException e)
365 fail("expected exception");
366 } catch (UnsupportedOperationException e)
372 Collections.sort(selected);
373 fail("expected exception");
374 } catch (UnsupportedOperationException e)
381 * Test that demonstrates a ConcurrentModificationException is thrown if you
382 * change the selection while iterating over it
385 groups = "Functional",
386 expectedExceptions = { ConcurrentModificationException.class })
387 public void testGetSelected_concurrentModification()
389 ColumnSelection cs = new ColumnSelection();
395 * simulate changing the list under us (e.g. in a separate
396 * thread) while iterating over it -> ConcurrentModificationException
398 List<Integer> selected = cs.getSelected();
399 for (Integer col : selected)
401 if (col.intValue() == 0)
408 @Test(groups = "Functional")
409 public void testMarkColumns()
411 ColumnSelection cs = new ColumnSelection();
412 cs.addElement(5); // this will be cleared
413 BitSet toMark = new BitSet();
419 assertTrue(cs.markColumns(toMark, 3, 8, false, false, false));
420 List<Integer> selected = cs.getSelected();
421 assertEquals(2, selected.size());
422 assertTrue(selected.contains(3));
423 assertTrue(selected.contains(6));
426 @Test(groups = "Functional")
427 public void testMarkColumns_extend()
429 ColumnSelection cs = new ColumnSelection();
432 BitSet toMark = new BitSet();
439 * extending selection of {3, 6} should leave {1, 3, 5, 6} selected
441 assertTrue(cs.markColumns(toMark, 3, 8, false, true, false));
442 List<Integer> selected = cs.getSelected();
443 assertEquals(4, selected.size());
444 assertTrue(selected.contains(1));
445 assertTrue(selected.contains(3));
446 assertTrue(selected.contains(5));
447 assertTrue(selected.contains(6));
450 @Test(groups = "Functional")
451 public void testMarkColumns_invert()
453 ColumnSelection cs = new ColumnSelection();
454 cs.addElement(5); // this will be cleared
455 BitSet toMark = new BitSet();
462 * inverted selection of {3, 6} should select {4, 5, 7, 8}
464 assertTrue(cs.markColumns(toMark, 3, 8, true, false, false));
465 List<Integer> selected = cs.getSelected();
466 assertEquals(4, selected.size());
467 assertTrue(selected.contains(4));
468 assertTrue(selected.contains(5));
469 assertTrue(selected.contains(7));
470 assertTrue(selected.contains(8));
473 @Test(groups = "Functional")
474 public void testMarkColumns_toggle()
476 ColumnSelection cs = new ColumnSelection();
477 cs.addElement(1); // outside change range
480 cs.addElement(10); // outside change range
481 BitSet toMark = new BitSet();
488 * toggling state of {3, 6} should leave {1, 4, 6, 10} selected
490 assertTrue(cs.markColumns(toMark, 3, 8, false, false, true));
491 List<Integer> selected = cs.getSelected();
492 assertEquals(4, selected.size());
493 assertTrue(selected.contains(1));
494 assertTrue(selected.contains(4));
495 assertTrue(selected.contains(6));
496 assertTrue(selected.contains(10));
499 @Test(groups = "Functional")
500 public void testCopyConstructor()
502 ColumnSelection cs = new ColumnSelection();
506 ColumnSelection cs2 = new ColumnSelection(cs);
507 assertTrue(cs2.hasSelectedColumns());
509 // order of column selection is preserved
510 assertEquals("[3, 1]", cs2.getSelected().toString());
514 @Test(groups = { "Functional" })
515 public void testStretchGroup_expand()
518 * test that emulates clicking column 4 (selected)
519 * and dragging right to column 5 (all base 0)
521 ColumnSelection cs = new ColumnSelection();
523 SequenceGroup sg = new SequenceGroup();
526 cs.stretchGroup(5, sg, 4, 4);
527 assertEquals(cs.getSelected().size(), 2);
528 assertTrue(cs.contains(4));
529 assertTrue(cs.contains(5));
530 assertEquals(sg.getStartRes(), 4);
531 assertEquals(sg.getEndRes(), 5);
534 * emulate drag right with columns 10-20 already selected
537 for (int i = 10; i <= 20; i++)
541 assertEquals(cs.getSelected().size(), 11);
542 sg = new SequenceGroup();
545 cs.stretchGroup(21, sg, 10, 20);
546 assertEquals(cs.getSelected().size(), 12);
547 assertTrue(cs.contains(10));
548 assertTrue(cs.contains(21));
549 assertEquals(sg.getStartRes(), 10);
550 assertEquals(sg.getEndRes(), 21);
553 @Test(groups = { "Functional" })
554 public void testStretchGroup_shrink()
557 * emulate drag left to 19 with columns 10-20 already selected
559 ColumnSelection cs = new ColumnSelection();
560 for (int i = 10; i <= 20; i++)
564 assertEquals(cs.getSelected().size(), 11);
565 SequenceGroup sg = new SequenceGroup();
568 cs.stretchGroup(19, sg, 10, 20);
569 assertEquals(cs.getSelected().size(), 10);
570 assertTrue(cs.contains(10));
571 assertTrue(cs.contains(19));
572 assertFalse(cs.contains(20));
573 assertEquals(sg.getStartRes(), 10);
574 assertEquals(sg.getEndRes(), 19);