Merge branch 'develop' into features/JAL-2446NCList
[jalview.git] / test / jalview / viewmodel / ViewportRangesTest.java
1 package jalview.viewmodel;
2
3 import static org.testng.Assert.assertEquals;
4 import static org.testng.Assert.assertFalse;
5 import static org.testng.Assert.assertTrue;
6
7 import jalview.analysis.AlignmentGenerator;
8 import jalview.datamodel.AlignmentI;
9 import jalview.datamodel.ColumnSelection;
10 import jalview.datamodel.HiddenColumns;
11 import jalview.datamodel.HiddenSequences;
12
13 import java.beans.PropertyChangeEvent;
14 import java.util.ArrayList;
15 import java.util.Arrays;
16 import java.util.List;
17
18 import org.testng.annotations.BeforeClass;
19 import org.testng.annotations.BeforeMethod;
20 import org.testng.annotations.Test;
21
22 public class ViewportRangesTest {
23
24   AlignmentGenerator gen = new AlignmentGenerator(false);
25
26   AlignmentI al = gen.generate(20, 30, 1, 5, 5);
27
28   AlignmentI smallAl = gen.generate(7, 2, 2, 5, 5);
29
30   @BeforeClass(alwaysRun = true)
31   public void setUp()
32   {
33     gen = new AlignmentGenerator(false);
34     al = gen.generate(20, 30, 1, 5, 5);
35     smallAl = gen.generate(7, 2, 2, 5, 5);
36   }
37
38   @BeforeMethod(alwaysRun = true)
39   public void cleanUp()
40   {
41     ColumnSelection sel = new ColumnSelection();
42     al.getHiddenColumns().revealAllHiddenColumns(sel);
43     al.getHiddenSequences().showAll(null);
44     smallAl.getHiddenColumns().revealAllHiddenColumns(sel);
45     smallAl.getHiddenSequences().showAll(null);
46   }
47
48   @Test(groups = { "Functional" })
49   public void testViewportRanges() 
50   {
51     ViewportRanges vr = new ViewportRanges(al);
52     
53     assertEquals(vr.getStartRes(),0);
54     assertEquals(vr.getEndRes(), al.getWidth()-1);
55     assertEquals(vr.getStartSeq(), 0);
56     assertEquals(vr.getEndSeq(), al.getHeight() - 1);
57   }
58
59   @Test(groups = { "Functional" })
60   public void testGetAbsoluteAlignmentHeight()
61   {
62     ViewportRanges vr = new ViewportRanges(al);
63
64     assertEquals(vr.getAbsoluteAlignmentHeight(), al.getHeight());
65
66     al.getHiddenSequences().hideSequence(al.getSequenceAt(3));
67     assertEquals(vr.getAbsoluteAlignmentHeight(), al.getHeight() + 1);
68   }
69
70   @Test(groups = { "Functional" })
71   public void testGetAbsoluteAlignmentWidth()
72   {
73     ViewportRanges vr = new ViewportRanges(al);
74     assertEquals(vr.getAbsoluteAlignmentWidth(), al.getWidth());
75   }
76
77   @Test(groups = { "Functional" })
78   public void testSetEndSeq()
79   {
80     ViewportRanges vr = new ViewportRanges(al);
81     vr.setEndSeq(-1);
82     assertEquals(vr.getEndSeq(), 0);
83
84     vr.setEndSeq(al.getHeight());
85     assertEquals(vr.getEndSeq(), al.getHeight() - 1);
86
87     // vr.setEndRes(al.getHeight() - 1);
88     vr.setEndSeq(al.getHeight() - 1);
89     assertEquals(vr.getEndSeq(), al.getHeight() - 1);
90   }
91
92   @Test(groups = { "Functional" })
93   public void testSetStartRes()
94   {
95     ViewportRanges vr = new ViewportRanges(al);
96     vr.setStartRes(-1);
97     assertEquals(vr.getStartRes(), 0);
98
99     vr.setStartRes(al.getWidth());
100     assertEquals(vr.getStartRes(), al.getWidth() - 1);
101
102     vr.setStartRes(al.getWidth() - 1);
103     assertEquals(vr.getStartRes(), al.getWidth() - 1);
104   }
105
106   @Test(groups = { "Functional" })
107   public void testSetStartSeq()
108   {
109     ViewportRanges vr = new ViewportRanges(al);
110     vr.setStartSeq(-1);
111     assertEquals(vr.getStartSeq(), 0);
112
113     vr.setStartSeq(al.getHeight() - vr.getViewportHeight() + 1);
114     assertEquals(vr.getStartSeq(), al.getHeight() - vr.getViewportHeight());
115
116     vr.setStartSeq(al.getHeight() - vr.getViewportHeight());
117     assertEquals(vr.getStartSeq(), al.getHeight() - vr.getViewportHeight());
118   }
119
120   @Test(groups = { "Functional" })
121   public void testSetStartEndRes()
122   {
123     ViewportRanges vr = new ViewportRanges(al);
124     vr.setStartEndRes(-1, -1);
125     assertEquals(vr.getStartRes(), 0);
126     assertEquals(vr.getEndRes(), 0);
127
128     vr.setStartEndRes(5, 19);
129     assertEquals(vr.getStartRes(), 5);
130     assertEquals(vr.getEndRes(), 19);
131
132     vr.setStartEndRes(al.getWidth(), al.getWidth());
133     assertEquals(vr.getEndRes(), al.getWidth() - 1);
134
135     ViewportRanges vrsmall = new ViewportRanges(smallAl);
136     vrsmall.setStartEndRes(al.getWidth(), al.getWidth());
137     assertEquals(vrsmall.getEndRes(), 6);
138
139     // make visible alignment width = 0
140     smallAl.getHiddenColumns().hideColumns(0, 6);
141     vrsmall.setStartEndRes(0, 4);
142     assertEquals(vrsmall.getStartRes(), 0);
143     assertEquals(vrsmall.getEndRes(), 0);
144   }
145
146   @Test(groups = { "Functional" })
147   public void testSetStartEndSeq()
148   {
149     ViewportRanges vr = new ViewportRanges(al);
150     vr.setStartEndSeq(-1, -1);
151     assertEquals(vr.getStartSeq(), 0);
152     assertEquals(vr.getEndSeq(), 0);
153
154     vr.setStartEndSeq(5, 19);
155     assertEquals(vr.getStartSeq(), 5);
156     assertEquals(vr.getEndSeq(), 19);
157
158     vr.setStartEndSeq(al.getHeight(), al.getHeight());
159     assertEquals(vr.getEndSeq(), al.getHeight() - 1);
160
161     // make visible alignment height = 0
162     smallAl.getHiddenSequences().hideSequence(smallAl.getSequenceAt(0));
163     smallAl.getHiddenSequences().hideSequence(smallAl.getSequenceAt(0));
164     ViewportRanges vrsmall = new ViewportRanges(smallAl);
165     vrsmall.setStartEndSeq(0, 3);
166     assertEquals(vrsmall.getStartSeq(), 0);
167     assertEquals(vrsmall.getEndSeq(), 0);
168   }
169
170   @Test(groups = { "Functional" })
171   public void testSetViewportHeight()
172   {
173     ViewportRanges vr = new ViewportRanges(al);
174     vr.setViewportHeight(13);
175     assertEquals(vr.getViewportHeight(), 13);
176   }
177
178   @Test(groups = { "Functional" })
179   public void testSetViewportWidth()
180   {
181     ViewportRanges vr = new ViewportRanges(al);
182     vr.setViewportWidth(13);
183     assertEquals(vr.getViewportWidth(), 13);
184   }
185
186   @Test(groups = { "Functional" })
187   public void testSetViewportStartAndHeight()
188   {
189     ViewportRanges vr = new ViewportRanges(al);
190     vr.setViewportStartAndHeight(2, 6);
191     assertEquals(vr.getViewportHeight(), 6);
192     assertEquals(vr.getStartSeq(), 2);
193
194     // reset -ve values of start to 0
195     vr.setViewportStartAndHeight(-1, 7);
196     assertEquals(vr.getViewportHeight(), 7);
197     assertEquals(vr.getStartSeq(), 0);
198
199     // reset out of bounds start values to within bounds
200     vr.setViewportStartAndHeight(35, 5);
201     assertEquals(vr.getViewportHeight(), 5);
202     assertEquals(vr.getStartSeq(), 24);
203   }
204
205   @Test(groups = { "Functional" })
206   public void testSetViewportStartAndWidth()
207   {
208     ViewportRanges vr = new ViewportRanges(al);
209     vr.setViewportStartAndWidth(2, 6);
210     assertEquals(vr.getViewportWidth(), 6);
211     assertEquals(vr.getStartRes(), 2);
212
213     // reset -ve values of start to 0
214     vr.setViewportStartAndWidth(-1, 7);
215     assertEquals(vr.getViewportWidth(), 7);
216     assertEquals(vr.getStartRes(), 0);
217
218     // reset out of bounds start values to within bounds
219     vr.setViewportStartAndWidth(35, 5);
220     assertEquals(vr.getViewportWidth(), 5);
221     assertEquals(vr.getStartRes(), 16);
222
223     // small alignment doesn't get bounds reset
224     ViewportRanges vrsmall = new ViewportRanges(smallAl);
225     vrsmall.setViewportStartAndWidth(0, 63);
226     assertEquals(vrsmall.getViewportWidth(), 7);
227     assertEquals(vrsmall.getStartRes(), 0);
228   }
229
230   @Test(groups = { "Functional" })
231   public void testPageUpDown()
232   {
233     ViewportRanges vr = new ViewportRanges(al);
234     vr.setViewportStartAndHeight(8, 6);
235     vr.pageDown();
236     assertEquals(vr.getStartSeq(), 13);
237
238     vr.pageUp();
239     assertEquals(vr.getStartSeq(), 8);
240
241     vr.pageUp();
242     assertEquals(vr.getStartSeq(), 3);
243
244     vr.pageUp();
245     // pageup does not go beyond 0, viewport height stays the same
246     assertEquals(vr.getStartSeq(), 0);
247     assertEquals(vr.getViewportHeight(), 6);
248
249     vr.pageDown();
250     vr.pageDown();
251     vr.pageDown();
252     vr.pageDown();
253     vr.pageDown();
254
255     // pagedown to bottom does not go beyond end, and height stays same
256     assertEquals(vr.getStartSeq(), 24);
257     assertEquals(vr.getViewportHeight(), 6);
258   }
259
260   @Test(groups = { "Functional" })
261   public void testScrollUp()
262   {
263     ViewportRanges vr = new ViewportRanges(al);
264     vr.setViewportStartAndHeight(1, 5);
265     vr.scrollUp(true);
266     assertEquals(vr.getStartSeq(), 0);
267     // can't scroll above top
268     vr.scrollUp(true);
269     assertEquals(vr.getStartSeq(), 0);
270
271     vr.setViewportStartAndHeight(24, 5);
272     vr.scrollUp(false);
273     assertEquals(vr.getStartSeq(), 25);
274     // can't scroll beyond bottom
275     vr.scrollUp(false);
276     assertEquals(vr.getStartSeq(), 25);
277   }
278
279   @Test(groups = { "Functional" })
280   public void testScrollUpWithHidden()
281   {
282     ViewportRanges vr = new ViewportRanges(al);
283
284     // hide last sequence
285     HiddenSequences hidden = new HiddenSequences(al);
286     hidden.hideSequence(al.getSequenceAt(29));
287
288     vr.setViewportStartAndHeight(1, 5);
289     vr.scrollUp(true);
290     assertEquals(vr.getStartSeq(), 0);
291     // can't scroll above top
292     vr.scrollUp(true);
293     assertEquals(vr.getStartSeq(), 0);
294
295     vr.setViewportStartAndHeight(23, 5);
296     vr.scrollUp(false);
297     assertEquals(vr.getStartSeq(), 24);
298     // can't scroll beyond bottom
299     vr.scrollUp(false);
300     assertEquals(vr.getStartSeq(), 24);
301   }
302
303   @Test(groups = { "Functional" })
304   public void testScrollRight()
305   {
306     ViewportRanges vr = new ViewportRanges(al);
307     vr.setViewportStartAndWidth(1, 5);
308     vr.scrollRight(false);
309     assertEquals(vr.getStartRes(), 0);
310     // can't scroll left past start
311     vr.scrollRight(false);
312     assertEquals(vr.getStartRes(), 0);
313
314     vr.setViewportStartAndWidth(15, 5);
315     vr.scrollRight(true);
316     assertEquals(vr.getStartRes(), 16);
317     // can't scroll right past end
318     vr.scrollRight(true);
319     assertEquals(vr.getStartRes(), 16);
320   }
321
322   @Test(groups = { "Functional" })
323   public void testScrollRightWithHidden()
324   {
325     ViewportRanges vr = new ViewportRanges(al);
326
327     // hide last 2 columns
328     HiddenColumns cols = new HiddenColumns();
329     cols.hideColumns(19, 20);
330     al.setHiddenColumns(cols);
331
332     vr.setViewportStartAndWidth(1, 5);
333     vr.scrollRight(false);
334     assertEquals(vr.getStartRes(), 0);
335     // can't scroll left past start
336     vr.scrollRight(false);
337     assertEquals(vr.getStartRes(), 0);
338
339     vr.setViewportStartAndWidth(13, 5);
340     vr.scrollRight(true);
341     assertEquals(vr.getStartRes(), 14);
342     // can't scroll right past last visible col
343     vr.scrollRight(true);
344     assertEquals(vr.getStartRes(), 14);
345   }
346
347   @Test(groups = { "Functional" })
348   public void testScrollToWrappedVisible()
349   {
350     AlignmentI al2 = gen.generate(60, 30, 1, 5, 5);
351
352     ViewportRanges vr = new ViewportRanges(al2);
353
354     // start with viewport on 5-14
355     vr.setViewportStartAndWidth(5, 10);
356     assertEquals(vr.getStartRes(), 5);
357     assertEquals(vr.getEndRes(), 14);
358
359     // scroll to 12 - no change
360     assertFalse(vr.scrollToWrappedVisible(12));
361     assertEquals(vr.getStartRes(), 5);
362
363     // scroll to 2 - back to 0-9
364     assertTrue(vr.scrollToWrappedVisible(2));
365     assertEquals(vr.getStartRes(), 0);
366     assertEquals(vr.getEndRes(), 9);
367
368     // scroll to 9 - no change
369     assertFalse(vr.scrollToWrappedVisible(9));
370     assertEquals(vr.getStartRes(), 0);
371
372     // scroll to 12 - moves to 10-19
373     assertTrue(vr.scrollToWrappedVisible(12));
374     assertEquals(vr.getStartRes(), 10);
375     assertEquals(vr.getEndRes(), 19);
376
377     vr.setStartRes(13);
378     assertEquals(vr.getStartRes(), 13);
379     assertEquals(vr.getEndRes(), 22);
380
381     // scroll to 45 - jumps to 43-52
382     assertTrue(vr.scrollToWrappedVisible(45));
383     assertEquals(vr.getStartRes(), 43);
384     assertEquals(vr.getEndRes(), 52);
385   }
386
387   // leave until JAL-2388 is merged and we can do without viewport
388   /*@Test(groups = { "Functional" })
389   public void testScrollToVisible()
390   {
391     ViewportRanges vr = new ViewportRanges(al);
392     vr.setViewportStartAndWidth(12,5);
393     vr.setViewportStartAndHeight(10,6);
394     vr.scrollToVisible(13,14)
395     
396     // no change
397     assertEquals(vr.getStartRes(), 12);
398     assertEquals(vr.getStartSeq(), 10);
399     
400     vr.scrollToVisible(5,6);
401     assertEquals(vr.getStartRes(), 5);
402     assertEquals(vr.getStartSeq(), 6);
403     
404     // test for hidden columns too
405   }*/
406
407   @Test(groups = { "Functional" })
408   public void testEventFiring()
409   {
410     ViewportRanges vr = new ViewportRanges(al);
411     MockPropChangeListener l = new MockPropChangeListener(vr);
412     List<String> emptylist = new ArrayList<>();
413
414     vr.setViewportWidth(5);
415     vr.setViewportHeight(5);
416     l.reset();
417
418     // one event fired when startRes is called with new value
419     vr.setStartRes(4);
420     assertTrue(l.verify(1, Arrays.asList("startres")));
421     l.reset();
422
423     // no event fired for same value
424     vr.setStartRes(4);
425     assertTrue(l.verify(0, emptylist));
426     l.reset();
427
428     vr.setStartSeq(4);
429     assertTrue(l.verify(1, Arrays.asList("startseq")));
430     l.reset();
431
432     vr.setStartSeq(4);
433     assertTrue(l.verify(0, emptylist));
434     l.reset();
435
436     vr.setEndSeq(10);
437     assertTrue(l.verify(1, Arrays.asList("startseq")));
438     l.reset();
439
440     vr.setEndSeq(10);
441     assertTrue(l.verify(0, emptylist));
442     l.reset();
443
444     vr.setStartEndRes(2, 15);
445     assertTrue(l.verify(1, Arrays.asList("startres")));
446     l.reset();
447
448     vr.setStartEndRes(2, 15);
449     assertTrue(l.verify(0, emptylist));
450     l.reset();
451
452     // check new value fired by event is corrected startres
453     vr.setStartEndRes(-1, 5);
454     assertTrue(l.verify(1, Arrays.asList("startres"), Arrays.asList(0)));
455     l.reset();
456
457     // check new value fired by event is corrected endres
458     vr.setStartEndRes(0, -1);
459     assertTrue(l.verify(1, Arrays.asList("endres"), Arrays.asList(0)));
460     l.reset();
461
462     vr.setStartEndSeq(2, 15);
463     assertTrue(l.verify(1, Arrays.asList("startseq")));
464     l.reset();
465
466     vr.setStartEndSeq(2, 15);
467     assertTrue(l.verify(0, emptylist));
468     l.reset();
469
470     vr.setStartEndRes(2, 2); // so seq and res values should be different, in
471                              // case of transposing in code
472     l.reset();
473
474     // check new value fired by event is corrected startseq
475     vr.setStartEndSeq(-1, 5);
476     assertTrue(l.verify(1, Arrays.asList("startseq"), Arrays.asList(0)));
477     l.reset();
478
479     // check new value fired by event is corrected endseq
480     vr.setStartEndSeq(0, -1);
481     assertTrue(l.verify(1, Arrays.asList("endseq"), Arrays.asList(0)));
482     l.reset();
483
484     // reset for later tests
485     vr.setStartEndSeq(2, 15);
486     l.reset();
487
488     // test viewport height and width setting triggers event
489     vr.setViewportHeight(10);
490     assertTrue(l.verify(1, Arrays.asList("endseq")));
491     l.reset();
492
493     vr.setViewportWidth(18);
494     assertTrue(l.verify(1, Arrays.asList("endres")));
495     l.reset();
496
497     // already has seq start set to 2, so triggers endseq
498     vr.setViewportStartAndHeight(2, 16);
499     assertTrue(l.verify(1, Arrays.asList("endseq")));
500     l.reset();
501
502     vr.setViewportStartAndWidth(1, 14);
503     assertTrue(l.verify(1, Arrays.asList("startres")));
504     l.reset();
505
506     // test page up/down triggers event
507     vr.pageUp();
508     assertTrue(l.verify(1, Arrays.asList("startseq")));
509     l.reset();
510
511     vr.pageDown();
512     assertTrue(l.verify(1, Arrays.asList("startseq")));
513     l.reset();
514
515     // test scrolling triggers event
516     vr.scrollUp(true);
517     assertTrue(l.verify(1, Arrays.asList("startseq")));
518     l.reset();
519
520     vr.scrollUp(false);
521     assertTrue(l.verify(1, Arrays.asList("startseq")));
522     l.reset();
523
524     vr.scrollRight(true);
525     assertTrue(l.verify(1, Arrays.asList("startres")));
526     l.reset();
527
528     vr.scrollRight(false);
529     assertTrue(l.verify(1, Arrays.asList("startres")));
530     l.reset();
531
532     vr.scrollToVisible(10, 10);
533     assertTrue(l.verify(4,
534             Arrays.asList("startseq", "startseq", "startseq", "startseq")));
535     l.reset();
536
537     vr.scrollToWrappedVisible(5);
538     assertTrue(l.verify(1, Arrays.asList("startres")));
539     l.reset();
540   }
541
542   @Test(groups = { "Functional" })
543   public void testGetWrappedScrollPosition()
544   {
545     AlignmentI al2 = gen.generate(157, 15, 1, 5, 5);
546     ViewportRanges vr = new ViewportRanges(al2);
547     vr.setStartEndRes(0, 39);
548     int width = vr.getViewportWidth(); // 40
549
550     /*
551      * scroll is 0 at column 0 (only)
552      */
553     assertEquals(vr.getWrappedScrollPosition(0), 0);
554
555     /*
556      * scroll is 1 at columns 1-40
557      */
558     int i = 1;
559     int j = width;
560     for (; i <= j; i++)
561     {
562       assertEquals(1, vr.getWrappedScrollPosition(i));
563     }
564
565     /*
566      * scroll is 2 at columns 41-80, etc
567      */
568     j += width;
569     for (; i <= j; i++)
570     {
571       assertEquals(2, vr.getWrappedScrollPosition(i), "For " + i);
572     }
573   }
574
575   @Test(groups = { "Functional" })
576   public void testPageUpDownWrapped()
577   {
578     /*
579      * 15 sequences, 110 residues wide (+gaps)
580      */
581     AlignmentI al2 = gen.generate(110, 15, 1, 5, 5);
582
583     ViewportRanges vr = new ViewportRanges(al2);
584     vr.setWrappedMode(true);
585
586     // first row
587     vr.setViewportStartAndWidth(0, 40);
588     int width = vr.getViewportWidth();
589     assertEquals(width, 40);
590     assertEquals(vr.getStartRes(), 0);
591     assertEquals(vr.getEndRes(), 39);
592     assertEquals(vr.getStartSeq(), 0);
593     assertEquals(vr.getEndSeq(), 14);
594
595     // second row
596     vr.pageDown();
597     assertEquals(vr.getStartRes(), 40);
598     assertEquals(vr.getEndRes(), 79);
599     assertEquals(vr.getStartSeq(), 0);
600     assertEquals(vr.getEndSeq(), 14);
601
602     // third and last row
603     // note endRes is nominal (>width) to preserve viewport width
604     vr.pageDown();
605     assertEquals(vr.getStartRes(), 80);
606     assertEquals(vr.getEndRes(), 119);
607     assertEquals(vr.getStartSeq(), 0);
608     assertEquals(vr.getEndSeq(), 14);
609
610     // another pageDown should do nothing
611     vr.pageDown();
612     assertEquals(vr.getStartRes(), 80);
613     assertEquals(vr.getEndRes(), 119);
614     assertEquals(vr.getStartSeq(), 0);
615     assertEquals(vr.getEndSeq(), 14);
616
617     // back to second row
618     vr.pageUp();
619     assertEquals(vr.getStartRes(), 40);
620     assertEquals(vr.getEndRes(), 79);
621     assertEquals(vr.getStartSeq(), 0);
622     assertEquals(vr.getEndSeq(), 14);
623
624     // back to first row
625     vr.pageUp();
626     assertEquals(vr.getStartRes(), 0);
627     assertEquals(vr.getEndRes(), 39);
628     assertEquals(vr.getStartSeq(), 0);
629     assertEquals(vr.getEndSeq(), 14);
630
631     // another pageUp should do nothing
632     vr.pageUp();
633     assertEquals(vr.getStartRes(), 0);
634     assertEquals(vr.getEndRes(), 39);
635     assertEquals(vr.getStartSeq(), 0);
636     assertEquals(vr.getEndSeq(), 14);
637
638     /*
639      * simulate scroll right a few positions
640      */
641     vr.setStartRes(5);
642     assertEquals(vr.getStartRes(), 5);
643     assertEquals(vr.getEndRes(), 5 + width - 1); // 44
644
645     vr.pageDown(); // 5-44 shifts to 45-84
646     assertEquals(vr.getStartRes(), 45);
647     assertEquals(vr.getEndRes(), 84);
648
649     vr.pageDown(); // 45-84 shifts to 85-124
650     assertEquals(vr.getStartRes(), 85);
651     assertEquals(vr.getEndRes(), 124);
652
653     vr.pageDown(); // no change - at end already
654     assertEquals(vr.getStartRes(), 85);
655     assertEquals(vr.getEndRes(), 124);
656
657     vr.pageUp(); // back we go
658     assertEquals(vr.getStartRes(), 45);
659     assertEquals(vr.getEndRes(), 84);
660
661     vr.pageUp();
662     assertEquals(vr.getStartRes(), 5);
663     assertEquals(vr.getEndRes(), 44);
664
665     vr.pageUp(); // back to the start
666     assertEquals(vr.getStartRes(), 0);
667     assertEquals(vr.getEndRes(), 39);
668   }
669
670   @Test(groups = { "Functional" })
671   public void testSetStartEndResWrapped()
672   {
673     ViewportRanges vr = new ViewportRanges(al);
674     vr.setWrappedMode(true);
675     vr.setStartEndRes(-1, -1);
676     assertEquals(vr.getStartRes(), 0);
677     assertEquals(vr.getEndRes(), 0);
678   
679     vr.setStartEndRes(5, 19);
680     assertEquals(vr.getStartRes(), 5);
681     assertEquals(vr.getEndRes(), 19);
682   
683     // bounds are not constrained to alignment width
684     // when in wrapped mode
685     vr.setStartEndRes(88, 888);
686     assertEquals(vr.getStartRes(), 88);
687     assertEquals(vr.getEndRes(), 888);
688   
689     ViewportRanges vrsmall = new ViewportRanges(smallAl);
690     vrsmall.setWrappedMode(true);
691     vrsmall.setStartEndRes(88, 888);
692     assertEquals(vrsmall.getStartRes(), 88);
693     assertEquals(vrsmall.getEndRes(), 888);
694   
695     // make visible alignment width = 0
696     smallAl.getHiddenColumns().hideColumns(0, 6);
697     vrsmall.setStartEndRes(0, 4);
698     assertEquals(vrsmall.getStartRes(), 0);
699     assertEquals(vrsmall.getEndRes(), 4);
700   }
701
702   @Test(groups = { "Functional" })
703   public void testSetViewportStartAndWidthWrapped()
704   {
705     ViewportRanges vr = new ViewportRanges(al);
706     vr.setWrappedMode(true);
707     vr.setViewportStartAndWidth(2, 6);
708     assertEquals(vr.getViewportWidth(), 6);
709     assertEquals(vr.getStartRes(), 2);
710   
711     // reset -ve values of start to 0
712     vr.setViewportStartAndWidth(-1, 7);
713     assertEquals(vr.getViewportWidth(), 7);
714     assertEquals(vr.getStartRes(), 0);
715   
716     // out of bounds values are not forced to within bounds
717     vr.setViewportStartAndWidth(35, 5);
718     assertEquals(vr.getViewportWidth(), 5);
719     assertEquals(vr.getStartRes(), 35);
720   
721     // small alignment doesn't get bounds reset
722     ViewportRanges vrsmall = new ViewportRanges(smallAl);
723     vrsmall.setViewportStartAndWidth(0, 63);
724     assertEquals(vrsmall.getViewportWidth(), 7);
725     assertEquals(vrsmall.getStartRes(), 0);
726   }
727
728   @Test(groups = { "Functional" })
729   public void testGetWrappedMaxScroll()
730   {
731     // generate an ungapped alignment of width 140
732     int alignmentWidth = 140;
733     AlignmentI al2 = gen.generate(alignmentWidth, 15, 1, 0, 5);
734     ViewportRanges vr = new ViewportRanges(al2);
735     vr.setStartEndRes(0, 39);
736     int width = vr.getViewportWidth(); // 40
737     int partWidth = alignmentWidth % width; // 20
738   
739     /*
740      * there are 3 * 40 remainder 20 residues
741      * number of widths depends on offset (scroll right)
742      * 4 widths (maxScroll = 3) if offset by 0 or more than 19 columns
743      * 5 widths (maxScroll = 4) if 1 <= offset <= 19
744      */
745     for (int col = 0; col < alignmentWidth; col++)
746     {
747       int offset = col % width;
748       if (offset > 0 && offset < partWidth)
749       {
750         assertEquals(vr.getWrappedMaxScroll(col), 4, "col " + col);
751       }
752       else
753       {
754         assertEquals(vr.getWrappedMaxScroll(col), 3, "col " + col);
755       }
756     }
757   }
758 }
759
760 // mock listener for property change events
761 class MockPropChangeListener implements ViewportListenerI
762 {
763   private int firecount = 0;
764
765   private List<String> events = new ArrayList<>();
766
767   private List<Integer> newvalues = new ArrayList<>();
768
769   public MockPropChangeListener(ViewportRanges vr)
770   {
771     vr.addPropertyChangeListener(this);
772   }
773
774   @Override
775   public void propertyChange(PropertyChangeEvent evt)
776   {
777     firecount++;
778     events.add(evt.getPropertyName());
779     newvalues.add((Integer) evt.getNewValue());
780   }
781
782   public boolean verify(int count, List<String> eventslist,
783           List<Integer> valueslist)
784   {
785     return (count == firecount) && events.equals(eventslist)
786             && newvalues.equals(valueslist);
787   }
788
789   public boolean verify(int count, List<String> eventslist)
790   {
791     return (count == firecount) && events.equals(eventslist);
792   }
793
794   public void reset()
795   {
796     firecount = 0;
797     events.clear();
798     newvalues.clear();
799   }
800 }