0f08ceb99f7f5c76814ea52a621da92d54cbd455
[jalview.git] / test / jalview / datamodel / ColumnSelectionTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
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.
11  *  
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.
16  * 
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.
20  */
21 package jalview.datamodel;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertSame;
26 import static org.testng.AssertJUnit.assertTrue;
27
28 import java.util.Arrays;
29 import java.util.List;
30
31 import org.testng.annotations.Test;
32
33 public class ColumnSelectionTest
34 {
35
36   @Test(groups = { "Functional" })
37   public void testAddElement()
38   {
39     ColumnSelection cs = new ColumnSelection();
40     cs.addElement(2);
41     cs.addElement(5);
42     cs.addElement(3);
43     cs.addElement(5); // ignored
44     List<Integer> sel = cs.getSelected();
45     assertEquals("[2, 5, 3]", sel.toString());
46   }
47
48   /**
49    * Test the remove method - in particular to verify that remove(int i) removes
50    * the element whose value is i, _NOT_ the i'th element.
51    */
52   @Test(groups = { "Functional" })
53   public void testRemoveElement()
54   {
55     ColumnSelection cs = new ColumnSelection();
56     cs.addElement(2);
57     cs.addElement(5);
58
59     // removing elements not in the list has no effect
60     cs.removeElement(0);
61     cs.removeElement(1);
62     List<Integer> sel = cs.getSelected();
63     assertEquals(2, sel.size());
64     assertEquals(new Integer(2), sel.get(0));
65     assertEquals(new Integer(5), sel.get(1));
66
67     // removing an element in the list removes it
68     cs.removeElement(2);
69     assertEquals(1, sel.size());
70     assertEquals(new Integer(5), sel.get(0));
71   }
72
73   /**
74    * Test the method that finds the visible column position of an alignment
75    * column, allowing for hidden columns.
76    */
77   @Test(groups = { "Functional" })
78   public void testFindColumnPosition()
79   {
80     ColumnSelection cs = new ColumnSelection();
81     assertEquals(5, cs.findColumnPosition(5));
82
83     // hiding column 6 makes no difference
84     cs.hideColumns(6, 6);
85     assertEquals(5, cs.findColumnPosition(5));
86
87     // hiding column 4 moves column 5 to column 4
88     cs.hideColumns(4, 4);
89     assertEquals(4, cs.findColumnPosition(5));
90
91     // hiding columns 1 and 2 moves column 5 to column 2
92     cs.hideColumns(1, 2);
93     assertEquals(2, cs.findColumnPosition(5));
94   }
95
96   @Test(groups = { "Functional" })
97   public void testHideColumns()
98   {
99     ColumnSelection cs = new ColumnSelection();
100     cs.hideColumns(5);
101     List<int[]> hidden = cs.getHiddenColumns();
102     assertEquals(1, hidden.size());
103     assertEquals("[5, 5]", Arrays.toString(hidden.get(0)));
104
105     cs.hideColumns(3);
106     assertEquals(2, hidden.size());
107     // two hidden ranges, in order:
108     assertSame(hidden, cs.getHiddenColumns());
109     assertEquals("[3, 3]", Arrays.toString(hidden.get(0)));
110     assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
111
112     // hiding column 4 expands [3, 3] to [3, 4]
113     // not fancy enough to coalesce this into [3, 5] though
114     cs.hideColumns(4);
115     hidden = cs.getHiddenColumns();
116     assertEquals(2, hidden.size());
117     assertEquals("[3, 4]", Arrays.toString(hidden.get(0)));
118     assertEquals("[5, 5]", Arrays.toString(hidden.get(1)));
119
120     // clear hidden columns (note they are added to selected)
121     cs.revealAllHiddenColumns();
122     // it is now actually null but getter returns an empty list
123     assertTrue(cs.getHiddenColumns().isEmpty());
124
125     cs.hideColumns(3, 6);
126     hidden = cs.getHiddenColumns();
127     int[] firstHiddenRange = hidden.get(0);
128     assertEquals("[3, 6]", Arrays.toString(firstHiddenRange));
129
130     // adding a subrange of already hidden should do nothing
131     cs.hideColumns(4, 5);
132     assertEquals(1, hidden.size());
133     assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
134     cs.hideColumns(3, 5);
135     assertEquals(1, hidden.size());
136     assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
137     cs.hideColumns(4, 6);
138     assertEquals(1, hidden.size());
139     assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
140     cs.hideColumns(3, 6);
141     assertEquals(1, hidden.size());
142     assertSame(firstHiddenRange, cs.getHiddenColumns().get(0));
143
144     cs.revealAllHiddenColumns();
145     cs.hideColumns(2, 4);
146     hidden = cs.getHiddenColumns();
147     assertEquals(1, hidden.size());
148     assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
149
150     // extend contiguous with 2 positions overlap
151     cs.hideColumns(3, 5);
152     assertEquals(1, hidden.size());
153     assertEquals("[2, 5]", Arrays.toString(hidden.get(0)));
154
155     // extend contiguous with 1 position overlap
156     cs.hideColumns(5, 6);
157     assertEquals(1, hidden.size());
158     assertEquals("[2, 6]", Arrays.toString(hidden.get(0)));
159
160     // extend contiguous with overlap both ends:
161     cs.hideColumns(1, 7);
162     assertEquals(1, hidden.size());
163     assertEquals("[1, 7]", Arrays.toString(hidden.get(0)));
164   }
165
166   /**
167    * Test the method that hides a specified column including any adjacent
168    * selected columns. This is a convenience method for the case where multiple
169    * column regions are selected and then hidden using menu option View | Hide |
170    * Selected Columns.
171    */
172   @Test(groups = { "Functional" })
173   public void testHideColumns_withSelection()
174   {
175     ColumnSelection cs = new ColumnSelection();
176     // select columns 4-6
177     cs.addElement(4);
178     cs.addElement(5);
179     cs.addElement(6);
180     // hide column 5 (and adjacent):
181     cs.hideColumns(5);
182     // 4,5,6 now hidden:
183     List<int[]> hidden = cs.getHiddenColumns();
184     assertEquals(1, hidden.size());
185     assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
186     // none now selected:
187     assertTrue(cs.getSelected().isEmpty());
188
189     // repeat, hiding column 4 (5 and 6)
190     cs = new ColumnSelection();
191     cs.addElement(4);
192     cs.addElement(5);
193     cs.addElement(6);
194     cs.hideColumns(4);
195     hidden = cs.getHiddenColumns();
196     assertEquals(1, hidden.size());
197     assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
198     assertTrue(cs.getSelected().isEmpty());
199
200     // repeat, hiding column (4, 5 and) 6
201     cs = new ColumnSelection();
202     cs.addElement(4);
203     cs.addElement(5);
204     cs.addElement(6);
205     cs.hideColumns(6);
206     hidden = cs.getHiddenColumns();
207     assertEquals(1, hidden.size());
208     assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
209     assertTrue(cs.getSelected().isEmpty());
210
211     // repeat, with _only_ adjacent columns selected
212     cs = new ColumnSelection();
213     cs.addElement(4);
214     cs.addElement(6);
215     cs.hideColumns(5);
216     hidden = cs.getHiddenColumns();
217     assertEquals(1, hidden.size());
218     assertEquals("[4, 6]", Arrays.toString(hidden.get(0)));
219     assertTrue(cs.getSelected().isEmpty());
220   }
221
222   /**
223    * Test the method that hides all (possibly disjoint) selected column ranges
224    */
225   @Test(groups = { "Functional" })
226   public void testHideSelectedColumns()
227   {
228     ColumnSelection cs = new ColumnSelection();
229     int[] sel = { 2, 3, 4, 7, 8, 9, 20, 21, 22 };
230     for (int col : sel)
231     {
232       cs.addElement(col);
233     }
234     cs.hideColumns(15, 18);
235
236     cs.hideSelectedColumns();
237     assertTrue(cs.getSelected().isEmpty());
238     List<int[]> hidden = cs.getHiddenColumns();
239     assertEquals(4, hidden.size());
240     assertEquals("[2, 4]", Arrays.toString(hidden.get(0)));
241     assertEquals("[7, 9]", Arrays.toString(hidden.get(1)));
242     assertEquals("[15, 18]", Arrays.toString(hidden.get(2)));
243     assertEquals("[20, 22]", Arrays.toString(hidden.get(3)));
244   }
245
246   /**
247    * Test the method that reveals a range of hidden columns given the start
248    * column of the range
249    */
250   @Test(groups = { "Functional" })
251   public void testRevealHiddenColumns()
252   {
253     ColumnSelection cs = new ColumnSelection();
254     cs.hideColumns(5, 8);
255     cs.addElement(10);
256     cs.revealHiddenColumns(5);
257     // hidden columns list now null but getter returns empty list:
258     assertTrue(cs.getHiddenColumns().isEmpty());
259     // revealed columns are marked as selected (added to selection):
260     assertEquals("[10, 5, 6, 7, 8]", cs.getSelected().toString());
261
262     // calling with a column other than the range start does nothing:
263     cs = new ColumnSelection();
264     cs.hideColumns(5, 8);
265     List<int[]> hidden = cs.getHiddenColumns();
266     cs.revealHiddenColumns(6);
267     assertSame(hidden, cs.getHiddenColumns());
268     assertTrue(cs.getSelected().isEmpty());
269   }
270
271   @Test(groups = { "Functional" })
272   public void testRevealAllHiddenColumns()
273   {
274     ColumnSelection cs = new ColumnSelection();
275     cs.hideColumns(5, 8);
276     cs.hideColumns(2, 3);
277     cs.addElement(11);
278     cs.addElement(1);
279     cs.revealAllHiddenColumns();
280
281     /*
282      * revealing hidden columns adds them (in order) to the (unordered)
283      * selection list
284      */
285     assertTrue(cs.getHiddenColumns().isEmpty());
286     assertEquals("[11, 1, 2, 3, 5, 6, 7, 8]", cs.getSelected().toString());
287   }
288
289   @Test(groups = { "Functional" })
290   public void testIsVisible()
291   {
292     ColumnSelection cs = new ColumnSelection();
293     cs.hideColumns(2, 4);
294     cs.hideColumns(6, 7);
295     assertTrue(cs.isVisible(0));
296     assertTrue(cs.isVisible(-99));
297     assertTrue(cs.isVisible(1));
298     assertFalse(cs.isVisible(2));
299     assertFalse(cs.isVisible(3));
300     assertFalse(cs.isVisible(4));
301     assertTrue(cs.isVisible(5));
302     assertFalse(cs.isVisible(6));
303     assertFalse(cs.isVisible(7));
304   }
305
306   @Test(groups = { "Functional" })
307   public void testGetVisibleContigs()
308   {
309     ColumnSelection cs = new ColumnSelection();
310     cs.hideColumns(3, 6);
311     cs.hideColumns(8, 9);
312     cs.hideColumns(12, 12);
313
314     // start position is inclusive, end position exclusive:
315     int[] visible = cs.getVisibleContigs(1, 13);
316     assertEquals("[1, 2, 7, 7, 10, 11]", Arrays.toString(visible));
317
318     visible = cs.getVisibleContigs(4, 14);
319     assertEquals("[7, 7, 10, 11, 13, 13]", Arrays.toString(visible));
320
321     visible = cs.getVisibleContigs(3, 10);
322     assertEquals("[7, 7]", Arrays.toString(visible));
323
324     visible = cs.getVisibleContigs(4, 6);
325     assertEquals("[]", Arrays.toString(visible));
326   }
327
328   @Test(groups = { "Functional" })
329   public void testInvertColumnSelection()
330   {
331     ColumnSelection cs = new ColumnSelection();
332     cs.addElement(4);
333     cs.addElement(6);
334     cs.addElement(8);
335     cs.hideColumns(3, 3);
336     cs.hideColumns(6, 6);
337
338     // invert selection from start (inclusive) to end (exclusive)
339     // hidden columns are _not_ changed
340     cs.invertColumnSelection(2, 9);
341     assertEquals("[2, 5, 7]", cs.getSelected().toString());
342
343     cs.invertColumnSelection(1, 9);
344     assertEquals("[1, 4, 8]", cs.getSelected().toString());
345   }
346
347   @Test(groups = { "Functional" })
348   public void testMaxColumnSelection()
349   {
350     ColumnSelection cs = new ColumnSelection();
351     cs.addElement(0);
352     cs.addElement(513);
353     cs.addElement(1);
354     assertEquals(513, cs.getMax());
355     cs.removeElement(513);
356     assertEquals(1, cs.getMax());
357     cs.removeElement(1);
358     assertEquals(0, cs.getMax());
359     cs.addElement(512);
360     cs.addElement(513);
361     assertEquals(513, cs.getMax());
362
363   }
364
365   @Test(groups = { "Functional" })
366   public void testMinColumnSelection()
367   {
368     ColumnSelection cs = new ColumnSelection();
369     cs.addElement(0);
370     cs.addElement(513);
371     cs.addElement(1);
372     assertEquals(0, cs.getMin());
373     cs.removeElement(0);
374     assertEquals(1, cs.getMin());
375     cs.addElement(0);
376     assertEquals(0, cs.getMin());
377   }
378 }