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