JAL-2759 Various minor HiddenColumns updates after review
[jalview.git] / test / jalview / datamodel / HiddenColumnsTest.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.Assert.assertNull;
24 import static org.testng.AssertJUnit.assertEquals;
25 import static org.testng.AssertJUnit.assertFalse;
26 import static org.testng.AssertJUnit.assertTrue;
27
28 import jalview.analysis.AlignmentGenerator;
29
30 import java.util.Arrays;
31 import java.util.BitSet;
32 import java.util.Iterator;
33
34 import org.testng.annotations.Test;
35
36 public class HiddenColumnsTest
37 {
38   /**
39    * Test the method which counts the number of hidden columns
40    */
41   @Test(groups = { "Functional" })
42   public void testGetSize()
43   {
44     HiddenColumns hidden = new HiddenColumns();
45     assertEquals(0, hidden.getSize());
46
47     hidden.hideColumns(3, 5);
48     assertEquals(3, hidden.getSize());
49
50     hidden.hideColumns(8, 8);
51     assertEquals(4, hidden.getSize());
52
53     hidden.hideColumns(9, 14);
54     assertEquals(10, hidden.getSize());
55
56     ColumnSelection cs = new ColumnSelection();
57     hidden.revealAllHiddenColumns(cs);
58     assertEquals(0, hidden.getSize());
59   }
60
61   /**
62    * Test the method that finds the visible column position of an alignment
63    * column, allowing for hidden columns.
64    */
65   @Test(groups = { "Functional" })
66   public void testFindColumnPosition()
67   {
68     HiddenColumns cs = new HiddenColumns();
69     assertEquals(5, cs.absoluteToVisibleColumn(5));
70
71     // hiding column 6 makes no difference
72     cs.hideColumns(6, 6);
73     assertEquals(5, cs.absoluteToVisibleColumn(5));
74
75     // hiding column 4 moves column 5 to column 4
76     cs.hideColumns(4, 4);
77     assertEquals(4, cs.absoluteToVisibleColumn(5));
78
79     // hiding column 4 moves column 4 to position 3
80     assertEquals(3, cs.absoluteToVisibleColumn(4));
81
82     // hiding columns 1 and 2 moves column 5 to column 2
83     cs.hideColumns(1, 2);
84     assertEquals(2, cs.absoluteToVisibleColumn(5));
85
86     // check with > 1 hidden column regions
87     // where some columns are in the hidden regions
88     HiddenColumns cs2 = new HiddenColumns();
89     cs2.hideColumns(5, 10);
90     cs2.hideColumns(20, 27);
91     cs2.hideColumns(40, 44);
92
93     // hiding columns 5-10 and 20-27 moves column 8 to column 4
94     assertEquals(4, cs2.absoluteToVisibleColumn(8));
95
96     // and moves column 24 to 13
97     assertEquals(13, cs2.absoluteToVisibleColumn(24));
98
99     // and moves column 28 to 14
100     assertEquals(14, cs2.absoluteToVisibleColumn(28));
101
102     // and moves column 40 to 25
103     assertEquals(25, cs2.absoluteToVisibleColumn(40));
104
105     // check when hidden columns start at 0 that the visible column
106     // is returned as 0
107     HiddenColumns cs3 = new HiddenColumns();
108     cs3.hideColumns(0, 4);
109     assertEquals(0, cs3.absoluteToVisibleColumn(2));
110
111     // check that column after the last hidden region doesn't crash
112     assertEquals(46, cs2.absoluteToVisibleColumn(65));
113   }
114
115   @Test(groups = { "Functional" })
116   public void testVisibleContigsIterator()
117   {
118     HiddenColumns cs = new HiddenColumns();
119
120     Iterator<int[]> visible = cs.getVisContigsIterator(3, 10, false);
121     int[] region = visible.next();
122     assertEquals("[3, 9]", Arrays.toString(region));
123     assertFalse(visible.hasNext());
124
125     cs.hideColumns(3, 6);
126     cs.hideColumns(8, 9);
127     cs.hideColumns(12, 12);
128
129     // Test both ends visible region
130
131     // start position is inclusive, end position exclusive
132     visible = cs.getVisContigsIterator(1, 13, false);
133     region = visible.next();
134     assertEquals("[1, 2]", Arrays.toString(region));
135     region = visible.next();
136     assertEquals("[7, 7]", Arrays.toString(region));
137     region = visible.next();
138     assertEquals("[10, 11]", Arrays.toString(region));
139     assertFalse(visible.hasNext());
140
141     // Test start hidden, end visible
142     visible = cs.getVisContigsIterator(4, 14, false);
143     region = visible.next();
144     assertEquals("[7, 7]", Arrays.toString(region));
145     region = visible.next();
146     assertEquals("[10, 11]", Arrays.toString(region));
147     region = visible.next();
148     assertEquals("[13, 13]", Arrays.toString(region));
149     assertFalse(visible.hasNext());
150
151     // Test start hidden, end hidden
152     visible = cs.getVisContigsIterator(3, 10, false);
153     region = visible.next();
154     assertEquals("[7, 7]", Arrays.toString(region));
155     assertFalse(visible.hasNext());
156
157     // Test start visible, end hidden
158     visible = cs.getVisContigsIterator(0, 13, false);
159     region = visible.next();
160     assertEquals("[0, 2]", Arrays.toString(region));
161     region = visible.next();
162     assertEquals("[7, 7]", Arrays.toString(region));
163     region = visible.next();
164     assertEquals("[10, 11]", Arrays.toString(region));
165     assertFalse(visible.hasNext());
166
167     // Test empty result
168     visible = cs.getVisContigsIterator(4, 6, false);
169     assertFalse(visible.hasNext());
170   }
171
172   @Test(groups = { "Functional" })
173   public void testEquals()
174   {
175     HiddenColumns cs = new HiddenColumns();
176     cs.hideColumns(5, 9);
177
178     // a different set of hidden columns
179     HiddenColumns cs2 = new HiddenColumns();
180
181     // with no hidden columns
182     assertFalse(cs.equals(cs2));
183     assertFalse(cs2.equals(cs));
184
185     // with the wrong kind of object
186     assertFalse(cs.equals(new HiddenColumnsCursor()));
187
188     // with a different hiddenColumns object - by size
189     HiddenColumns cs3 = new HiddenColumns();
190     cs3.hideColumns(2, 3);
191     assertFalse(cs.equals(cs3));
192
193     // with hidden columns added in a different order
194     cs2.hideColumns(6, 9);
195     assertFalse(cs.equals(cs2));
196     assertFalse(cs2.equals(cs));
197
198     cs2.hideColumns(5, 8);
199
200     assertTrue(cs.equals(cs2));
201     assertTrue(cs.equals(cs));
202     assertTrue(cs2.equals(cs));
203     assertTrue(cs2.equals(cs2));
204
205     // different ranges, same size
206     cs.hideColumns(10, 12);
207     cs2.hideColumns(10, 15);
208     assertFalse(cs.equals(cs2));
209
210   }
211
212   @Test(groups = "Functional")
213   public void testCopyConstructor()
214   {
215     HiddenColumns cs = new HiddenColumns();
216     cs.hideColumns(10, 11);
217     cs.hideColumns(5, 7);
218     Iterator<int[]> regions = cs.iterator();
219     assertEquals("[5, 7]",
220             Arrays.toString(regions.next()));
221
222     HiddenColumns cs2 = new HiddenColumns(cs);
223     regions = cs2.iterator();
224     assertTrue(cs2.hasHiddenColumns());
225     assertEquals(2, cs2.getNumberOfRegions());
226     // hidden columns are held in column order
227     assertEquals("[5, 7]",
228             Arrays.toString(regions.next()));
229     assertEquals("[10, 11]",
230             Arrays.toString(regions.next()));
231   }
232
233   @Test(groups = "Functional")
234   public void testCopyConstructor2()
235   {
236     HiddenColumns cs = new HiddenColumns();
237     cs.hideColumns(10, 11);
238     cs.hideColumns(5, 7);
239
240     HiddenColumns cs2 = new HiddenColumns(cs, 3, 9, 1);
241     assertTrue(cs2.hasHiddenColumns());
242     Iterator<int[]> regions = cs2.iterator();
243
244     // only [5,7] returned, offset by 1
245     assertEquals("[4, 6]",
246             Arrays.toString(regions.next()));
247     assertEquals(3, cs2.getSize());
248
249     cs2 = new HiddenColumns(cs, 8, 15, 4);
250     regions = cs2.iterator();
251     assertTrue(cs2.hasHiddenColumns());
252
253     // only [10,11] returned, offset by 4
254     assertEquals("[6, 7]",
255             Arrays.toString(regions.next()));
256     assertEquals(2, cs2.getSize());
257
258     cs2 = new HiddenColumns(cs, 6, 10, 4);
259     assertFalse(cs2.hasHiddenColumns());
260   }
261
262   /**
263    * Test the code used to locate the reference sequence ruler origin
264    */
265   @Test(groups = { "Functional" })
266   public void testLocateVisibleStartofSequence()
267   {
268     // create random alignment
269     AlignmentGenerator gen = new AlignmentGenerator(false);
270     AlignmentI al = gen.generate(50, 20, 123, 5, 5);
271
272     HiddenColumns cs = al.getHiddenColumns();
273     ColumnSelection colsel = new ColumnSelection();
274
275     SequenceI seq = new Sequence("RefSeq", "-A-SD-ASD--E---");
276     assertEquals(2, seq.findIndex(seq.getStart()));
277
278     // no hidden columns
279     assertEquals(seq.findIndex(seq.getStart()) - 1, cs.locateVisibleStartOfSequence(seq));
280
281     // hidden column on gap after end of sequence - should not affect bounds
282     colsel.hideSelectedColumns(13, al.getHiddenColumns());
283     assertEquals(seq.findIndex(seq.getStart()) - 1,cs.locateVisibleStartOfSequence(seq));
284
285     cs.revealAllHiddenColumns(colsel);
286     // hidden column on gap before beginning of sequence - should vis bounds by
287     // one
288     colsel.hideSelectedColumns(0, al.getHiddenColumns());
289     assertEquals(seq.findIndex(seq.getStart()) - 2,cs.locateVisibleStartOfSequence(seq));
290
291     cs.revealAllHiddenColumns(colsel);
292     // hide columns around most of sequence - leave one residue remaining
293     cs.hideColumns(1, 3);
294     cs.hideColumns(6, 11);
295
296     Iterator<int[]> it = cs.getVisContigsIterator(0, 6, false);
297
298     assertEquals("-D", seq.getSequenceStringFromIterator(it));
299     // cs.getVisibleSequenceStrings(0, 5, new SequenceI[]
300     // { seq })[0]);
301
302     assertEquals(1, cs.locateVisibleStartOfSequence(seq));
303     cs.revealAllHiddenColumns(colsel);
304
305     // hide whole sequence - should just get location of hidden region
306     // containing sequence
307     cs.hideColumns(1, 11);
308     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
309
310     cs.revealAllHiddenColumns(colsel);
311     cs.hideColumns(0, 15);
312     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
313
314     SequenceI seq2 = new Sequence("RefSeq2", "-------A-SD-ASD--E---");
315
316     cs.revealAllHiddenColumns(colsel);
317     cs.hideColumns(7, 17);
318     assertEquals(0,cs.locateVisibleStartOfSequence(seq2));
319
320     cs.revealAllHiddenColumns(colsel);
321     cs.hideColumns(3, 17);
322     assertEquals(0,cs.locateVisibleStartOfSequence(seq2));
323
324     cs.revealAllHiddenColumns(colsel);
325     cs.hideColumns(3, 19);
326     assertEquals(0,cs.locateVisibleStartOfSequence(seq2));
327
328     cs.revealAllHiddenColumns(colsel);
329     cs.hideColumns(0, 0);
330     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
331
332     cs.revealAllHiddenColumns(colsel);
333     cs.hideColumns(0, 1);
334     assertEquals(1,cs.locateVisibleStartOfSequence(seq));
335
336     cs.revealAllHiddenColumns(colsel);
337     cs.hideColumns(0, 2);
338     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
339
340     cs.revealAllHiddenColumns(colsel);
341     cs.hideColumns(1, 1);
342     assertEquals(2,cs.locateVisibleStartOfSequence(seq));
343
344     cs.revealAllHiddenColumns(colsel);
345     cs.hideColumns(1, 2);
346     assertEquals(1,cs.locateVisibleStartOfSequence(seq));
347
348     cs.revealAllHiddenColumns(colsel);
349     cs.hideColumns(1, 3);
350     assertEquals(1,cs.locateVisibleStartOfSequence(seq));
351
352     cs.revealAllHiddenColumns(colsel);
353     cs.hideColumns(0, 2);
354     cs.hideColumns(5, 6);
355     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
356
357     cs.revealAllHiddenColumns(colsel);
358     cs.hideColumns(0, 2);
359     cs.hideColumns(5, 6);
360     cs.hideColumns(9, 10);
361     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
362
363     cs.revealAllHiddenColumns(colsel);
364     cs.hideColumns(0, 2);
365     cs.hideColumns(7, 11);
366     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
367
368     cs.revealAllHiddenColumns(colsel);
369     cs.hideColumns(2, 4);
370     cs.hideColumns(7, 11);
371     assertEquals(1,cs.locateVisibleStartOfSequence(seq));
372
373     cs.revealAllHiddenColumns(colsel);
374     cs.hideColumns(2, 4);
375     cs.hideColumns(7, 12);
376     assertEquals(1,cs.locateVisibleStartOfSequence(seq));
377
378     cs.revealAllHiddenColumns(colsel);
379     cs.hideColumns(1, 11);
380     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
381
382     cs.revealAllHiddenColumns(colsel);
383     cs.hideColumns(0, 12);
384     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
385
386     cs.revealAllHiddenColumns(colsel);
387     cs.hideColumns(0, 4);
388     cs.hideColumns(6, 12);
389     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
390
391     cs.revealAllHiddenColumns(colsel);
392     cs.hideColumns(0, 1);
393     cs.hideColumns(3, 12);
394     assertEquals(0,cs.locateVisibleStartOfSequence(seq));
395
396     cs.revealAllHiddenColumns(colsel);
397     cs.hideColumns(3, 14);
398     cs.hideColumns(17, 19);
399     assertEquals(3,cs.locateVisibleStartOfSequence(seq2));
400
401     cs.revealAllHiddenColumns(colsel);
402     cs.hideColumns(3, 7);
403     cs.hideColumns(9, 14);
404     cs.hideColumns(17, 19);
405     assertEquals(9,cs.locateVisibleStartOfSequence(seq2));
406
407     cs.revealAllHiddenColumns(colsel);
408     cs.hideColumns(0, 1);
409     cs.hideColumns(3, 4);
410     cs.hideColumns(6, 8);
411     cs.hideColumns(10, 12);
412     assertEquals(6, cs.locateVisibleStartOfSequence(seq));
413
414   }
415
416   @Test(groups = { "Functional" })
417   public void testLocateVisibleStartPathologicals()
418   {
419     // test some pathological cases we missed
420     AlignmentI al = new Alignment(
421             new SequenceI[]
422     { new Sequence("refseqGaptest", "KTDVTI----------NFI-----G----L") });
423     HiddenColumns cs = new HiddenColumns();
424     cs.hideList(al.getSequenceAt(0).getInsertions());
425     assertEquals("G", ""
426             + al.getSequenceAt(0).getCharAt(cs.visibleToAbsoluteColumn(9)));
427
428     // KM: no idea what this is meant to be testing... seems to be an unfinished
429     // test
430   }
431
432   @Test(groups = { "Functional" })
433   public void testHideColumns()
434   {
435     // create random alignment
436     AlignmentGenerator gen = new AlignmentGenerator(false);
437     AlignmentI al = gen.generate(50, 20, 123, 5, 5);
438
439     ColumnSelection colsel = new ColumnSelection();
440     HiddenColumns cs = al.getHiddenColumns();
441     colsel.hideSelectedColumns(5, al.getHiddenColumns());
442     Iterator<int[]> regions = cs.iterator();
443     assertEquals(1, cs.getNumberOfRegions());
444     assertEquals("[5, 5]", Arrays.toString(regions.next()));
445
446     colsel.hideSelectedColumns(3, al.getHiddenColumns());
447     regions = cs.iterator();
448     assertEquals(2, cs.getNumberOfRegions());
449     // two hidden ranges, in order:
450     assertEquals("[3, 3]", Arrays.toString(regions.next()));
451     assertEquals("[5, 5]", Arrays.toString(regions.next()));
452
453     // hiding column 4 expands [3, 3] to [3, 4]
454     // and merges to [5, 5] to make [3, 5]
455     colsel.hideSelectedColumns(4, al.getHiddenColumns());
456     regions = cs.iterator();
457     assertEquals(1, cs.getNumberOfRegions());
458     assertEquals("[3, 5]", Arrays.toString(regions.next()));
459
460     // clear hidden columns (note they are added to selected)
461     cs.revealAllHiddenColumns(colsel);
462     // it is now actually null but getter returns an empty list
463     assertEquals(0, cs.getNumberOfRegions());
464
465     cs.hideColumns(3, 6);
466     regions = cs.iterator();
467     int[] firstHiddenRange = regions.next();
468     assertEquals("[3, 6]", Arrays.toString(firstHiddenRange));
469
470     // adding a subrange of already hidden should do nothing
471     cs.hideColumns(4, 5);
472     regions = cs.iterator();
473     assertEquals(1, cs.getNumberOfRegions());
474     assertEquals("[3, 6]",
475             Arrays.toString(regions.next()));
476     cs.hideColumns(3, 5);
477     regions = cs.iterator();
478     assertEquals(1, cs.getNumberOfRegions());
479     assertEquals("[3, 6]",
480             Arrays.toString(regions.next()));
481     cs.hideColumns(4, 6);
482     regions = cs.iterator();
483     assertEquals(1, cs.getNumberOfRegions());
484     assertEquals("[3, 6]",
485             Arrays.toString(regions.next()));
486     cs.hideColumns(3, 6);
487     regions = cs.iterator();
488     assertEquals(1, cs.getNumberOfRegions());
489     assertEquals("[3, 6]",
490             Arrays.toString(regions.next()));
491
492     cs.revealAllHiddenColumns(colsel);
493     cs.hideColumns(2, 4);
494     regions = cs.iterator();
495     assertEquals(1, cs.getNumberOfRegions());
496     assertEquals("[2, 4]", Arrays.toString(regions.next()));
497
498     // extend contiguous with 2 positions overlap
499     cs.hideColumns(3, 5);
500     regions = cs.iterator();
501     assertEquals(1, cs.getNumberOfRegions());
502     assertEquals("[2, 5]", Arrays.toString(regions.next()));
503
504     // extend contiguous with 1 position overlap
505     cs.hideColumns(5, 6);
506     regions = cs.iterator();
507     assertEquals(1, cs.getNumberOfRegions());
508     assertEquals("[2, 6]", Arrays.toString(regions.next()));
509
510     // extend contiguous with overlap both ends:
511     cs.hideColumns(1, 7);
512     regions = cs.iterator();
513     assertEquals(1, cs.getNumberOfRegions());
514     assertEquals("[1, 7]", Arrays.toString(regions.next()));
515
516     cs.revealAllHiddenColumns(colsel);
517     cs.hideColumns(15, 18);
518     cs.hideColumns(2, 4);
519     cs.hideColumns(7, 9);
520     regions = cs.iterator();
521     assertEquals(3, cs.getNumberOfRegions());
522     assertEquals("[2, 4]", Arrays.toString(regions.next()));
523     assertEquals("[7, 9]", Arrays.toString(regions.next()));
524     assertEquals("[15, 18]", Arrays.toString(regions.next()));
525   }
526
527   /**
528    * Test the method that reveals a range of hidden columns given the start
529    * column of the range
530    */
531   @Test(groups = { "Functional" })
532   public void testRevealHiddenColumns()
533   {
534     ColumnSelection colsel = new ColumnSelection();
535     HiddenColumns cs = new HiddenColumns();
536
537     // test with null hidden columns
538     cs.revealHiddenColumns(5, colsel);
539     assertTrue(colsel.getSelected().isEmpty());
540
541     cs.hideColumns(5, 8);
542     colsel.addElement(10);
543     cs.revealHiddenColumns(5, colsel);
544
545     // hiddenColumns now empty
546     assertEquals(0, cs.getSize());
547
548     // revealed columns are marked as selected (added to selection):
549     assertEquals("[10, 5, 6, 7, 8]", colsel.getSelected().toString());
550
551     // calling with a column other than the range start does nothing:
552     colsel = new ColumnSelection();
553     cs = new HiddenColumns();
554     cs.hideColumns(5, 8);
555
556     int prevSize = cs.getSize();
557     cs.revealHiddenColumns(6, colsel);
558     assertEquals(prevSize, cs.getSize());
559     assertTrue(colsel.getSelected().isEmpty());
560
561     // reveal hidden columns when there is more than one region
562     cs.hideColumns(20, 23);
563     // now there are 2 hidden regions
564     assertEquals(2, cs.getNumberOfRegions());
565
566     cs.revealHiddenColumns(20, colsel);
567
568     // hiddenColumns now has one region
569     assertEquals(1, cs.getNumberOfRegions());
570
571     // revealed columns are marked as selected (added to selection):
572     assertEquals("[20, 21, 22, 23]", colsel.getSelected().toString());
573
574     // call with a column past the end of the hidden column ranges
575     colsel.clear();
576     cs.revealHiddenColumns(20, colsel);
577     // hiddenColumns still has 1 region
578     assertEquals(1, cs.getNumberOfRegions());
579     assertTrue(colsel.getSelected().isEmpty());
580   }
581
582   @Test(groups = { "Functional" })
583   public void testRevealAllHiddenColumns()
584   {
585     HiddenColumns hidden = new HiddenColumns();
586     ColumnSelection colsel = new ColumnSelection();
587
588     // test with null hidden columns
589     hidden.revealAllHiddenColumns(colsel);
590     assertTrue(colsel.getSelected().isEmpty());
591
592     hidden.hideColumns(5, 8);
593     hidden.hideColumns(2, 3);
594     colsel.addElement(11);
595     colsel.addElement(1);
596     hidden.revealAllHiddenColumns(colsel);
597
598     /*
599      * revealing hidden columns adds them (in order) to the (unordered)
600      * selection list
601      */
602
603     // hiddenColumns now empty
604     assertEquals(0, hidden.getSize());
605
606     assertEquals("[11, 1, 2, 3, 5, 6, 7, 8]",
607             colsel.getSelected().toString());
608   }
609
610   @Test(groups = { "Functional" })
611   public void testIsVisible()
612   {
613     HiddenColumns cs = new HiddenColumns();
614     cs.hideColumns(2, 4);
615     cs.hideColumns(6, 7);
616     assertTrue(cs.isVisible(0));
617     assertTrue(cs.isVisible(-99));
618     assertTrue(cs.isVisible(1));
619     assertFalse(cs.isVisible(2));
620     assertFalse(cs.isVisible(3));
621     assertFalse(cs.isVisible(4));
622     assertTrue(cs.isVisible(5));
623     assertFalse(cs.isVisible(6));
624     assertFalse(cs.isVisible(7));
625     assertTrue(cs.isVisible(8));
626   }
627
628   /**
629    * Test for the case when a hidden range encloses more one already hidden
630    * range
631    */
632   @Test(groups = { "Functional" })
633   public void testHideColumns_subsumingHidden()
634   {
635     /*
636      * JAL-2370 bug scenario:
637      * two hidden ranges subsumed by a third
638      */
639     HiddenColumns cs = new HiddenColumns();
640     cs.hideColumns(49, 59);
641     cs.hideColumns(69, 79);
642     Iterator<int[]> regions = cs.iterator();
643     assertEquals(2, cs.getNumberOfRegions());
644     assertEquals("[49, 59]", Arrays.toString(regions.next()));
645     assertEquals("[69, 79]", Arrays.toString(regions.next()));
646
647     cs.hideColumns(48, 80);
648     regions = cs.iterator();
649     assertEquals(1, cs.getNumberOfRegions());
650     assertEquals("[48, 80]", Arrays.toString(regions.next()));
651
652     /*
653      * another...joining hidden ranges
654      */
655     cs = new HiddenColumns();
656     cs.hideColumns(10, 20);
657     cs.hideColumns(30, 40);
658     cs.hideColumns(50, 60);
659     // hiding 21-49 should merge to one range
660     cs.hideColumns(21, 49);
661     regions = cs.iterator();
662     assertEquals(1, cs.getNumberOfRegions());
663     assertEquals("[10, 60]", Arrays.toString(regions.next()));
664
665     /*
666      * another...left overlap, subsumption, right overlap,
667      * no overlap of existing hidden ranges
668      */
669     cs = new HiddenColumns();
670     cs.hideColumns(10, 20);
671     cs.hideColumns(10, 20);
672     cs.hideColumns(30, 35);
673     cs.hideColumns(40, 50);
674     cs.hideColumns(60, 70);
675
676     cs.hideColumns(15, 45);
677     regions = cs.iterator();
678     assertEquals(2, cs.getNumberOfRegions());
679     assertEquals("[10, 50]", Arrays.toString(regions.next()));
680     assertEquals("[60, 70]", Arrays.toString(regions.next()));
681   }
682
683   @Test(groups = { "Functional" })
684   public void testHideColumns_BitSet()
685   {
686     HiddenColumns cs;
687
688     BitSet one = new BitSet();
689
690     // one hidden range
691     one.set(1);
692     cs = new HiddenColumns();
693     cs.hideColumns(one);
694     assertEquals(1, cs.getNumberOfRegions());
695
696     one.set(2);
697     cs = new HiddenColumns();
698     cs.hideColumns(one);
699     assertEquals(1, cs.getNumberOfRegions());
700
701     one.set(3);
702     cs = new HiddenColumns();
703     cs.hideColumns(one);
704     assertEquals(1, cs.getNumberOfRegions());
705
706     // split
707     one.clear(2);
708     cs = new HiddenColumns();
709     cs.hideColumns(one);
710     assertEquals(2, cs.getNumberOfRegions());
711
712     assertEquals(0, cs.visibleToAbsoluteColumn(0));
713     assertEquals(2, cs.visibleToAbsoluteColumn(1));
714     assertEquals(4, cs.visibleToAbsoluteColumn(2));
715
716     // one again
717     one.clear(1);
718     cs = new HiddenColumns();
719     cs.hideColumns(one);
720
721     assertEquals(1, cs.getNumberOfRegions());
722
723     assertEquals(0, cs.visibleToAbsoluteColumn(0));
724     assertEquals(1, cs.visibleToAbsoluteColumn(1));
725     assertEquals(2, cs.visibleToAbsoluteColumn(2));
726     assertEquals(4, cs.visibleToAbsoluteColumn(3));
727   }
728
729   @Test(groups = { "Functional" })
730   public void hideColumns_BitSetAndRange()
731   {
732     HiddenColumns hc = new HiddenColumns();
733     hc.hideColumns(3, 5);
734     hc.hideColumns(15, 20);
735     hc.hideColumns(45, 60);
736
737     BitSet tohide = new BitSet();
738
739     // all unhidden if tohide is empty and range covers hidden
740     hc.hideColumns(tohide, 1, 70);
741     assertTrue(!hc.hasHiddenColumns());
742
743     hc.hideColumns(3, 5);
744     hc.hideColumns(15, 20);
745     hc.hideColumns(45, 60);
746
747     // but not if range does not cover hidden
748     hc.hideColumns(tohide, 23, 40);
749     assertTrue(hc.hasHiddenColumns());
750
751     // and partial unhide if range partially covers
752     hc.hideColumns(tohide, 1, 17);
753     Iterator<int[]> it = hc.iterator();
754     assertTrue(it.hasNext());
755     int[] region = it.next();
756
757     assertEquals(18, region[0]);
758     assertEquals(20, region[1]);
759
760     assertTrue(it.hasNext());
761     region = it.next();
762
763     assertEquals(45, region[0]);
764     assertEquals(60, region[1]);
765
766     assertFalse(it.hasNext());
767   }
768
769   @Test(groups = { "Functional" })
770   public void testRegionsToString()
771   {
772     HiddenColumns hc = new HiddenColumns();
773
774     String result = hc.regionsToString(",", "--");
775     assertEquals("", result);
776
777     hc.hideColumns(3, 7);
778     hc.hideColumns(10, 10);
779     hc.hideColumns(14, 15);
780
781     result = hc.regionsToString(",", "--");
782     assertEquals("3--7,10--10,14--15", result);
783   }
784
785   @Test(groups = "Functional")
786   public void testGetVisibleStartAndEndIndex()
787   {
788     Sequence seq = new Sequence("testSeq", "ABCDEFGHIJKLMNOPQRSTUVWXYZ");
789     AlignmentI align = new Alignment(new SequenceI[] { seq });
790     HiddenColumns hc = new HiddenColumns();
791
792     int[] startEnd = hc.getVisibleStartAndEndIndex(align.getWidth());
793     assertEquals(0, startEnd[0]);
794     assertEquals(25, startEnd[1]);
795
796     hc.hideColumns(0, 0);
797     startEnd = hc.getVisibleStartAndEndIndex(align.getWidth());
798     assertEquals(1, startEnd[0]);
799     assertEquals(25, startEnd[1]);
800
801     hc.hideColumns(6, 9);
802     hc.hideColumns(11, 12);
803     startEnd = hc.getVisibleStartAndEndIndex(align.getWidth());
804     assertEquals(1, startEnd[0]);
805     assertEquals(25, startEnd[1]);
806
807     hc.hideColumns(24, 25);
808     startEnd = hc.getVisibleStartAndEndIndex(align.getWidth());
809     System.out.println(startEnd[0] + " : " + startEnd[1]);
810     assertEquals(1, startEnd[0]);
811     assertEquals(23, startEnd[1]);
812
813     // force lowest range to start of alignment
814     hc = new HiddenColumns();
815     hc.hideColumns(3, 4);
816     startEnd = hc.getVisibleStartAndEndIndex(align.getWidth());
817     assertEquals(0, startEnd[0]);
818     assertEquals(25, startEnd[1]);
819   }
820
821   @Test(groups = "Functional")
822   public void testGetRegionWithEdgeAtRes()
823   {
824     HiddenColumns hc = new HiddenColumns();
825
826     int[] result = hc.getRegionWithEdgeAtRes(5);
827     assertNull(result);
828
829     hc.hideColumns(3, 7);
830     hc.hideColumns(10, 10);
831     hc.hideColumns(14, 15);
832
833     result = hc.getRegionWithEdgeAtRes(2);
834     assertEquals(3, result[0]);
835     assertEquals(7, result[1]);
836
837     result = hc.getRegionWithEdgeAtRes(4);
838     assertEquals(10, result[0]);
839     assertEquals(10, result[1]);
840
841     result = hc.getRegionWithEdgeAtRes(5);
842     assertEquals(10, result[0]);
843     assertEquals(10, result[1]);
844
845     result = hc.getRegionWithEdgeAtRes(6);
846     assertNull(result);
847
848     result = hc.getRegionWithEdgeAtRes(0);
849     assertNull(result);
850
851     result = hc.getRegionWithEdgeAtRes(7);
852     assertEquals(14, result[0]);
853     assertEquals(15, result[1]);
854
855     result = hc.getRegionWithEdgeAtRes(8);
856     assertEquals(14, result[0]);
857     assertEquals(15, result[1]);
858
859     result = hc.getRegionWithEdgeAtRes(16);
860     assertNull(result);
861   }
862
863   @Test(groups = "Functional")
864   public void testHasHiddenColumns()
865   {
866     HiddenColumns h = new HiddenColumns();
867
868     // new HiddenColumns2 has no hidden cols
869     assertFalse(h.hasHiddenColumns());
870
871     // some columns hidden, returns true
872     h.hideColumns(5, 10);
873     assertTrue(h.hasHiddenColumns());
874
875     // reveal columns, no hidden cols again
876     ColumnSelection sel = new ColumnSelection();
877     h.revealAllHiddenColumns(sel);
878     assertFalse(h.hasHiddenColumns());
879   }
880
881   @Test(groups = "Functional")
882   public void testHasManyHiddenColumns()
883   {
884     HiddenColumns h = new HiddenColumns();
885
886     // h has no hidden cols
887     assertFalse(h.hasMultiHiddenColumnRegions());
888
889     // one set of columns hidden, returns false
890     h.hideColumns(5, 10);
891     assertFalse(h.hasMultiHiddenColumnRegions());
892
893     // two sets hidden, returns true
894     h.hideColumns(15, 17);
895     assertTrue(h.hasMultiHiddenColumnRegions());
896
897     // back to one block, asserts false
898     h.hideColumns(11, 14);
899     assertFalse(h.hasMultiHiddenColumnRegions());
900   }
901
902   @Test(groups = "Functional")
903   public void testAdjustForHiddenColumns()
904   {
905     HiddenColumns h = new HiddenColumns();
906     // returns input value when there are no hidden columns
907     assertEquals(10, h.visibleToAbsoluteColumn(10));
908
909     h.hideColumns(20, 30);
910     assertEquals(10, h.visibleToAbsoluteColumn(10));
911     assertEquals(20 + 11, h.visibleToAbsoluteColumn(20));
912     assertEquals(35 + 11, h.visibleToAbsoluteColumn(35));
913
914     h.hideColumns(5, 7);
915     assertEquals(10 + 3, h.visibleToAbsoluteColumn(10));
916     assertEquals(20 + 14, h.visibleToAbsoluteColumn(20));
917     assertEquals(35 + 14, h.visibleToAbsoluteColumn(35));
918
919     ColumnSelection sel = new ColumnSelection();
920     h.revealAllHiddenColumns(sel);
921     h.hideColumns(0, 1);
922     assertEquals(4, h.visibleToAbsoluteColumn(2));
923   }
924
925   @Test(groups = "Functional")
926   public void testGetHiddenBoundaryLeft()
927   {
928     HiddenColumns h = new HiddenColumns();
929
930     // returns same value if no hidden cols
931     assertEquals(3, h.getNextHiddenBoundary(true, 3));
932
933     h.hideColumns(5, 10);
934     assertEquals(10, h.getNextHiddenBoundary(true, 15));
935     assertEquals(3, h.getNextHiddenBoundary(true, 3));
936     assertEquals(7, h.getNextHiddenBoundary(true, 7));
937
938     h.hideColumns(15, 20);
939     assertEquals(10, h.getNextHiddenBoundary(true, 15));
940     assertEquals(20, h.getNextHiddenBoundary(true, 21));
941   }
942
943   @Test(groups = "Functional")
944   public void testGetNextHiddenBoundary()
945   {
946     HiddenColumns h = new HiddenColumns();
947
948     // returns same value if no hidden cols
949     assertEquals(3, h.getNextHiddenBoundary(false, 3));
950
951     h.hideColumns(5, 10);
952     assertEquals(5, h.getNextHiddenBoundary(false, 3));
953     assertEquals(15, h.getNextHiddenBoundary(false, 15));
954     assertEquals(7, h.getNextHiddenBoundary(false, 7));
955
956     h.hideColumns(15, 20);
957     assertEquals(15, h.getNextHiddenBoundary(false, 7));
958     assertEquals(15, h.getNextHiddenBoundary(false, 14));
959
960     // returns same value if there is no next hidden column
961     assertEquals(22, h.getNextHiddenBoundary(false, 22));
962   }
963
964   @Test(groups = "Functional")
965   public void testIterator()
966   {
967     HiddenColumns h = new HiddenColumns();
968     Iterator<int[]> result = h.iterator();
969     assertFalse(result.hasNext());
970
971     h.hideColumns(5, 10);
972     result = h.iterator();
973     int[] next = result.next();
974     assertEquals(5, next[0]);
975     assertEquals(10, next[1]);
976     assertFalse(result.hasNext());
977
978     h.hideColumns(22, 23);
979     result = h.iterator();
980     next = result.next();
981     assertEquals(5, next[0]);
982     assertEquals(10, next[1]);
983     next = result.next();
984     assertEquals(22, next[0]);
985     assertEquals(23, next[1]);
986     assertFalse(result.hasNext());
987
988     // test for only one hidden region at start of alignment
989     ColumnSelection sel = new ColumnSelection();
990     h.revealAllHiddenColumns(sel);
991     h.hideColumns(0, 1);
992     result = h.iterator();
993     next = result.next();
994     assertEquals(0, next[0]);
995     assertEquals(1, next[1]);
996     assertFalse(result.hasNext());
997   }
998
999   /* @Test(groups = "Functional")
1000   public void testGetVisibleSequenceStrings()
1001   {
1002     HiddenColumns h = new HiddenColumns();
1003     SequenceI seq1 = new Sequence("TEST1", "GALMFWKQESPVICYHRNDT");
1004     SequenceI seq2 = new Sequence("TEST2", "VICYHRNDTGA");
1005     SequenceI[] seqs = new SequenceI[2];
1006     seqs[0] = seq1;
1007     seqs[1] = seq2;
1008     String[] result = h.getVisibleSequenceStrings(5, 10, seqs);
1009     assertEquals(2, result.length);
1010     assertEquals("WKQES", result[0]);
1011     assertEquals("RNDTG", result[1]);
1012   
1013     h.hideColumns(6, 8);
1014     result = h.getVisibleSequenceStrings(5, 10, seqs);
1015     assertEquals(2, result.length);
1016     assertEquals("WS", result[0]);
1017     assertEquals("RG", result[1]);
1018   
1019     SequenceI seq = new Sequence("RefSeq", "-A-SD-ASD--E---");
1020     ColumnSelection sel = new ColumnSelection();
1021     h.revealAllHiddenColumns(sel);
1022     h.hideColumns(1, 3);
1023     h.hideColumns(6, 11);
1024     assertEquals("-D",
1025             h.getVisibleSequenceStrings(0, 5, new SequenceI[]
1026     { seq })[0]);
1027   }*/
1028
1029   @Test(groups = "Functional")
1030   public void testHideInsertionsFor()
1031   {
1032     HiddenColumns h = new HiddenColumns();
1033     HiddenColumns h2 = new HiddenColumns();
1034     SequenceI seq1 = new Sequence("TEST1", "GAL---MFW-KQESPVICY--HRNDT");
1035     SequenceI seq2 = new Sequence("TEST1", "GALMFWKQESPVICYHRNDT");
1036
1037     h.hideList(seq2.getInsertions());
1038     assertTrue(h.equals(h2));
1039
1040     h.hideList(seq1.getInsertions());
1041     h2.hideColumns(3, 5);
1042     h2.hideColumns(9, 9);
1043     h2.hideColumns(19, 20);
1044     assertTrue(h.equals(h2));
1045   }
1046
1047   @Test(groups = "Functional")
1048   public void testHideColumns_BitSet_range()
1049   {
1050     HiddenColumns h = new HiddenColumns();
1051     HiddenColumns h2 = new HiddenColumns();
1052
1053     BitSet tohide = new BitSet(21);
1054     h.hideColumns(tohide);
1055     assertTrue(h.equals(h2));
1056
1057     // when setting bitset, first param is invlusive, second exclusive
1058     tohide.set(3, 6);
1059     tohide.set(9);
1060     tohide.set(15, 21);
1061     h.hideColumns(tohide, 5, 23);
1062
1063     h2.hideColumns(5, 5);
1064     h2.hideColumns(9, 9);
1065     h2.hideColumns(15, 20);
1066     assertTrue(h.equals(h2));
1067
1068     tohide.clear();
1069     tohide.set(41);
1070     h.hideColumns(tohide, 23, 30);
1071     assertTrue(h.equals(h2));
1072
1073     tohide.set(41);
1074     h.hideColumns(tohide, 30, 45);
1075     h2.hideColumns(41, 41);
1076     assertTrue(h.equals(h2));
1077
1078     tohide.clear();
1079     tohide.set(25, 28);
1080     h.hideColumns(tohide, 17, 50);
1081     h2 = new HiddenColumns();
1082     h2.hideColumns(17, 20);
1083     h2.hideColumns(25, 27);
1084     h2.hideColumns(41, 41);
1085   }
1086
1087   @Test(groups = "Functional")
1088   public void testOffsetByVisibleColumns()
1089   {
1090     HiddenColumns h = new HiddenColumns();
1091     int result = h.offsetByVisibleColumns(-1, 10);
1092     assertEquals(9, result);
1093
1094     h.hideColumns(7, 9);
1095     result = h.offsetByVisibleColumns(-4, 10);
1096     assertEquals(3, result);
1097
1098     h.hideColumns(14, 15);
1099     result = h.offsetByVisibleColumns(-4, 10);
1100     assertEquals(3, result);
1101
1102     result = h.offsetByVisibleColumns(-10, 17);
1103     assertEquals(2, result);
1104
1105     result = h.offsetByVisibleColumns(-1, 7);
1106     assertEquals(5, result);
1107
1108     result = h.offsetByVisibleColumns(-1, 8);
1109     assertEquals(5, result);
1110
1111     result = h.offsetByVisibleColumns(-3, 15);
1112     assertEquals(10, result);
1113
1114     ColumnSelection sel = new ColumnSelection();
1115     h.revealAllHiddenColumns(sel);
1116     h.hideColumns(0, 30);
1117     result = h.offsetByVisibleColumns(-31, 0);
1118     assertEquals(-31, result);
1119
1120     HiddenColumns cs = new HiddenColumns();
1121
1122     // test that without hidden columns, offsetByVisibleColumns returns
1123     // position n to left of provided position
1124     long pos = cs.offsetByVisibleColumns(-3, 10);
1125     assertEquals(7, pos);
1126
1127     // 0 returns same position
1128     pos = cs.offsetByVisibleColumns(0, 10);
1129     assertEquals(10, pos);
1130
1131     // overflow to left returns negative number
1132     pos = cs.offsetByVisibleColumns(-3, 0);
1133     assertEquals(-3, pos);
1134
1135     // test that with hidden columns to left of result column
1136     // behaviour is the same as above
1137     cs.hideColumns(1, 3);
1138
1139     // position n to left of provided position
1140     pos = cs.offsetByVisibleColumns(-3, 10);
1141     assertEquals(7, pos);
1142
1143     // 0 returns same position
1144     pos = cs.offsetByVisibleColumns(0, 10);
1145     assertEquals(10, pos);
1146
1147     // test with one set of hidden columns between start and required position
1148     cs.hideColumns(12, 15);
1149     pos = cs.offsetByVisibleColumns(-8, 17);
1150     assertEquals(5, pos);
1151
1152     // test with two sets of hidden columns between start and required position
1153     cs.hideColumns(20, 21);
1154     pos = cs.offsetByVisibleColumns(-8, 23);
1155     assertEquals(9, pos);
1156
1157     // repeat last 2 tests with no hidden columns to left of required position
1158     ColumnSelection colsel = new ColumnSelection();
1159     cs.revealAllHiddenColumns(colsel);
1160
1161     // test with one set of hidden columns between start and required position
1162     cs.hideColumns(12, 15);
1163     pos = cs.offsetByVisibleColumns(-8, 17);
1164     assertEquals(5, pos);
1165
1166     // test with two sets of hidden columns between start and required position
1167     cs.hideColumns(20, 21);
1168     pos = cs.offsetByVisibleColumns(-8, 23);
1169     assertEquals(9, pos);
1170
1171     // test with right (positive) offsets
1172
1173     // test that without hidden columns, offsetByVisibleColumns returns
1174     // position n to right of provided position
1175     pos = cs.offsetByVisibleColumns(3, 7);
1176     assertEquals(10, pos);
1177
1178     // test that with hidden columns to left of result column
1179     // behaviour is the same as above
1180     cs.hideColumns(1, 3);
1181
1182     // test with one set of hidden columns between start and required position
1183     cs.hideColumns(12, 15);
1184     pos = cs.offsetByVisibleColumns(8, 5);
1185     assertEquals(17, pos);
1186
1187     // test with two sets of hidden columns between start and required position
1188     cs.hideColumns(20, 21);
1189     pos = cs.offsetByVisibleColumns(8, 9);
1190     assertEquals(23, pos);
1191
1192     // repeat last 2 tests with no hidden columns to left of required position
1193     colsel = new ColumnSelection();
1194     cs.revealAllHiddenColumns(colsel);
1195
1196     // test with one set of hidden columns between start and required position
1197     cs.hideColumns(12, 15);
1198     pos = cs.offsetByVisibleColumns(8, 5);
1199     assertEquals(17, pos);
1200
1201     // test with two sets of hidden columns between start and required position
1202     cs.hideColumns(20, 21);
1203     pos = cs.offsetByVisibleColumns(8, 9);
1204     assertEquals(23, pos);
1205   }
1206
1207   @Test(groups = "Functional")
1208   public void testBoundedIterator()
1209   {
1210     HiddenColumns h = new HiddenColumns();
1211     Iterator<int[]> it = h.getBoundedIterator(0, 10);
1212
1213     // no hidden columns = nothing to iterate over
1214     assertFalse(it.hasNext());
1215
1216     // [start,end] contains all hidden columns
1217     // all regions are returned
1218     h.hideColumns(3, 10);
1219     h.hideColumns(14, 16);
1220     it = h.getBoundedIterator(0, 20);
1221     assertTrue(it.hasNext());
1222     int[] next = it.next();
1223     assertEquals(3, next[0]);
1224     assertEquals(10, next[1]);
1225     next = it.next();
1226     assertEquals(14, next[0]);
1227     assertEquals(16, next[1]);
1228     assertFalse(it.hasNext());
1229
1230     // [start,end] overlaps a region
1231     // 1 region returned
1232     it = h.getBoundedIterator(5, 7);
1233     assertTrue(it.hasNext());
1234     next = it.next();
1235     assertEquals(3, next[0]);
1236     assertEquals(10, next[1]);
1237     assertFalse(it.hasNext());
1238
1239     // [start,end] fully contains 1 region and start of last
1240     // - 2 regions returned
1241     it = h.getBoundedIterator(3, 15);
1242     assertTrue(it.hasNext());
1243     next = it.next();
1244     assertEquals(3, next[0]);
1245     assertEquals(10, next[1]);
1246     next = it.next();
1247     assertEquals(14, next[0]);
1248     assertEquals(16, next[1]);
1249     assertFalse(it.hasNext());
1250
1251     // [start,end] contains end of first region and whole of last region
1252     // - 2 regions returned
1253     it = h.getBoundedIterator(4, 20);
1254     assertTrue(it.hasNext());
1255     next = it.next();
1256     assertEquals(3, next[0]);
1257     assertEquals(10, next[1]);
1258     next = it.next();
1259     assertEquals(14, next[0]);
1260     assertEquals(16, next[1]);
1261     assertFalse(it.hasNext());
1262   }
1263
1264   @Test(groups = "Functional")
1265   public void testBoundedStartIterator()
1266   {
1267     HiddenColumns h = new HiddenColumns();
1268     Iterator<Integer> it = h.getBoundedStartIterator(0, 10);
1269
1270     // no hidden columns = nothing to iterate over
1271     assertFalse(it.hasNext());
1272
1273     // [start,end] contains all hidden columns
1274     // all regions are returned
1275     h.hideColumns(3, 10);
1276     h.hideColumns(14, 16);
1277     it = h.getBoundedStartIterator(0, 20);
1278     assertTrue(it.hasNext());
1279     int next = it.next();
1280     assertEquals(3, next);
1281     next = it.next();
1282     assertEquals(6, next);
1283     assertFalse(it.hasNext());
1284
1285     // [start,end] does not contain a start of a region
1286     // no regions to iterate over
1287     it = h.getBoundedStartIterator(4, 5);
1288     assertFalse(it.hasNext());
1289
1290     // [start,end] fully contains 1 region and start of last
1291     // - 2 regions returned
1292     it = h.getBoundedStartIterator(3, 7);
1293     assertTrue(it.hasNext());
1294     next = it.next();
1295     assertEquals(3, next);
1296     next = it.next();
1297     assertEquals(6, next);
1298     assertFalse(it.hasNext());
1299
1300     // [start,end] contains whole of last region
1301     // - 1 region returned
1302     it = h.getBoundedStartIterator(4, 20);
1303     assertTrue(it.hasNext());
1304     next = it.next();
1305     assertEquals(6, next);
1306     assertFalse(it.hasNext());
1307   }
1308
1309   @Test(groups = "Functional")
1310   public void testVisibleBlocksVisBoundsIterator()
1311   {
1312     HiddenColumns h = new HiddenColumns();
1313     Iterator<int[]> regions = h.getVisContigsIterator(0, 31, true);
1314
1315     // only 1 visible region spanning 0-30 if nothing is hidden
1316     assertTrue(regions.hasNext());
1317     int[] region = regions.next();
1318     assertEquals(0, region[0]);
1319     assertEquals(30, region[1]);
1320     assertFalse(regions.hasNext());
1321
1322     // hide 1 region in middle
1323     // 2 regions one on either side
1324     // second region boundary accounts for hidden columns
1325     h.hideColumns(10, 15);
1326     regions = h.getVisContigsIterator(0, 31, true);
1327
1328     assertTrue(regions.hasNext());
1329     region = regions.next();
1330     assertEquals(0, region[0]);
1331     assertEquals(9, region[1]);
1332     region = regions.next();
1333     assertEquals(16, region[0]);
1334     assertEquals(36, region[1]);
1335     assertFalse(regions.hasNext());
1336
1337     // single hidden region at left
1338     h = new HiddenColumns();
1339     h.hideColumns(0, 5);
1340     regions = h.getVisContigsIterator(0, 31, true);
1341
1342     assertTrue(regions.hasNext());
1343     region = regions.next();
1344     assertEquals(6, region[0]);
1345     assertEquals(36, region[1]);
1346     assertFalse(regions.hasNext());
1347
1348     // single hidden region at right
1349     h = new HiddenColumns();
1350     h.hideColumns(27, 30);
1351     regions = h.getVisContigsIterator(0, 31, true);
1352
1353     assertTrue(regions.hasNext());
1354     region = regions.next();
1355     assertEquals(0, region[0]);
1356     assertEquals(26, region[1]);
1357     region = regions.next();
1358     assertEquals(31, region[0]);
1359     assertEquals(34, region[1]);
1360     assertFalse(regions.hasNext());
1361
1362     // hidden region at left + hidden region in middle
1363     h = new HiddenColumns();
1364     h.hideColumns(0, 5);
1365     h.hideColumns(23, 25);
1366     regions = h.getVisContigsIterator(0, 31, true);
1367
1368     assertTrue(regions.hasNext());
1369     region = regions.next();
1370     assertEquals(6, region[0]);
1371     assertEquals(22, region[1]);
1372     region = regions.next();
1373     assertEquals(26, region[0]);
1374     assertEquals(39, region[1]);
1375     assertFalse(regions.hasNext());
1376
1377     // hidden region at right + hidden region in middle
1378     h = new HiddenColumns();
1379     h.hideColumns(27, 30);
1380     h.hideColumns(11, 14);
1381     regions = h.getVisContigsIterator(0, 31, true);
1382
1383     assertTrue(regions.hasNext());
1384     region = regions.next();
1385     assertEquals(0, region[0]);
1386     assertEquals(10, region[1]);
1387     region = regions.next();
1388     assertEquals(15, region[0]);
1389     assertEquals(26, region[1]);
1390     region = regions.next();
1391     assertEquals(31, region[0]);
1392     assertEquals(38, region[1]);
1393     assertFalse(regions.hasNext());
1394
1395     // hidden region at left and right
1396     h = new HiddenColumns();
1397     h.hideColumns(27, 35);
1398     h.hideColumns(0, 4);
1399     regions = h.getVisContigsIterator(0, 31, true);
1400
1401     assertTrue(regions.hasNext());
1402     region = regions.next();
1403     assertEquals(5, region[0]);
1404     assertEquals(26, region[1]);
1405     region = regions.next();
1406     assertEquals(36, region[0]);
1407     assertEquals(44, region[1]);
1408     assertFalse(regions.hasNext());
1409
1410     // multiple hidden regions
1411     h = new HiddenColumns();
1412     h.hideColumns(1, 1);
1413     h.hideColumns(3, 5);
1414     h.hideColumns(9, 11);
1415     h.hideColumns(22, 26);
1416
1417     regions = h.getVisContigsIterator(0, 31, true);
1418
1419     assertTrue(regions.hasNext());
1420     region = regions.next();
1421     assertEquals(0, region[0]);
1422     assertEquals(0, region[1]);
1423     region = regions.next();
1424     assertEquals(2, region[0]);
1425     assertEquals(2, region[1]);
1426     region = regions.next();
1427     assertEquals(6, region[0]);
1428     assertEquals(8, region[1]);
1429     region = regions.next();
1430     assertEquals(12, region[0]);
1431     assertEquals(21, region[1]);
1432     region = regions.next();
1433     assertEquals(27, region[0]);
1434     assertEquals(42, region[1]);
1435     assertFalse(regions.hasNext());
1436   }
1437
1438   /*
1439    * the VisibleColsIterator is tested elsewhere, this just tests that 
1440    * it can be retrieved from HiddenColumns
1441    */
1442   @Test(groups = "Functional")
1443   public void testGetVisibleColsIterator()
1444   {
1445     HiddenColumns h = new HiddenColumns();
1446     Iterator<Integer> it = h.getVisibleColsIterator(0, 10);
1447
1448     assertTrue(it instanceof VisibleColsIterator);
1449   }
1450
1451   @Test(groups = "Functional")
1452   public void testHashCode()
1453   {
1454     HiddenColumns h = new HiddenColumns();
1455     h.hideColumns(0, 25);
1456
1457     int result = h.hashCode();
1458     assertTrue(result > 0);
1459
1460     h.hideColumns(30, 50);
1461     assertTrue(h.hashCode() > 0);
1462     assertTrue(result != h.hashCode());
1463   }
1464 }