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