1 package jalview.viewmodel;
3 import static org.testng.Assert.assertEquals;
4 import static org.testng.Assert.assertTrue;
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;
12 import java.beans.PropertyChangeEvent;
13 import java.util.ArrayList;
14 import java.util.Arrays;
15 import java.util.List;
17 import org.testng.annotations.BeforeClass;
18 import org.testng.annotations.BeforeMethod;
19 import org.testng.annotations.Test;
21 public class ViewportRangesTest {
23 AlignmentGenerator gen = new AlignmentGenerator(false);
25 AlignmentI al = gen.generate(20, 30, 1, 5, 5);
27 AlignmentI smallAl = gen.generate(7, 2, 2, 5, 5);
29 @BeforeClass(alwaysRun = true)
32 gen = new AlignmentGenerator(false);
33 al = gen.generate(20, 30, 1, 5, 5);
34 smallAl = gen.generate(7, 2, 2, 5, 5);
37 @BeforeMethod(alwaysRun = true)
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);
47 @Test(groups = { "Functional" })
48 public void testViewportRanges()
50 ViewportRanges vr = new ViewportRanges(al);
52 assertEquals(vr.getStartRes(),0);
53 assertEquals(vr.getEndRes(), al.getWidth()-1);
54 assertEquals(vr.getStartSeq(), 0);
55 assertEquals(vr.getEndSeq(), al.getHeight() - 1);
58 @Test(groups = { "Functional" })
59 public void testGetAbsoluteAlignmentHeight()
61 ViewportRanges vr = new ViewportRanges(al);
63 assertEquals(vr.getAbsoluteAlignmentHeight(), al.getHeight());
65 al.getHiddenSequences().hideSequence(al.getSequenceAt(3));
66 assertEquals(vr.getAbsoluteAlignmentHeight(), al.getHeight() + 1);
69 @Test(groups = { "Functional" })
70 public void testGetAbsoluteAlignmentWidth()
72 ViewportRanges vr = new ViewportRanges(al);
73 assertEquals(vr.getAbsoluteAlignmentWidth(), al.getWidth());
76 @Test(groups = { "Functional" })
77 public void testSetEndSeq()
79 ViewportRanges vr = new ViewportRanges(al);
81 assertEquals(vr.getEndSeq(), 0);
83 vr.setEndSeq(al.getHeight());
84 assertEquals(vr.getEndSeq(), al.getHeight() - 1);
86 // vr.setEndRes(al.getHeight() - 1);
87 vr.setEndSeq(al.getHeight() - 1);
88 assertEquals(vr.getEndSeq(), al.getHeight() - 1);
91 @Test(groups = { "Functional" })
92 public void testSetStartRes()
94 ViewportRanges vr = new ViewportRanges(al);
96 assertEquals(vr.getStartRes(), 0);
98 vr.setStartRes(al.getWidth());
99 assertEquals(vr.getStartRes(), al.getWidth() - 1);
101 vr.setStartRes(al.getWidth() - 1);
102 assertEquals(vr.getStartRes(), al.getWidth() - 1);
105 @Test(groups = { "Functional" })
106 public void testSetStartSeq()
108 ViewportRanges vr = new ViewportRanges(al);
110 assertEquals(vr.getStartSeq(), 0);
112 vr.setStartSeq(al.getHeight() - vr.getViewportHeight() + 1);
113 assertEquals(vr.getStartSeq(), al.getHeight() - vr.getViewportHeight());
115 vr.setStartSeq(al.getHeight() - vr.getViewportHeight());
116 assertEquals(vr.getStartSeq(), al.getHeight() - vr.getViewportHeight());
119 @Test(groups = { "Functional" })
120 public void testSetStartEndRes()
122 ViewportRanges vr = new ViewportRanges(al);
123 vr.setStartEndRes(-1, -1);
124 assertEquals(vr.getStartRes(), 0);
125 assertEquals(vr.getEndRes(), 0);
127 vr.setStartEndRes(5, 19);
128 assertEquals(vr.getStartRes(), 5);
129 assertEquals(vr.getEndRes(), 19);
131 vr.setStartEndRes(al.getWidth(), al.getWidth());
132 assertEquals(vr.getEndRes(), al.getWidth() - 1);
134 ViewportRanges vrsmall = new ViewportRanges(smallAl);
135 vrsmall.setStartEndRes(al.getWidth(), al.getWidth());
136 assertEquals(vrsmall.getEndRes(), 6);
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);
145 @Test(groups = { "Functional" })
146 public void testSetStartEndSeq()
148 ViewportRanges vr = new ViewportRanges(al);
149 vr.setStartEndSeq(-1, -1);
150 assertEquals(vr.getStartSeq(), 0);
151 assertEquals(vr.getEndSeq(), 0);
153 vr.setStartEndSeq(5, 19);
154 assertEquals(vr.getStartSeq(), 5);
155 assertEquals(vr.getEndSeq(), 19);
157 vr.setStartEndSeq(al.getHeight(), al.getHeight());
158 assertEquals(vr.getEndSeq(), al.getHeight() - 1);
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);
169 @Test(groups = { "Functional" })
170 public void testSetViewportHeight()
172 ViewportRanges vr = new ViewportRanges(al);
173 vr.setViewportHeight(13);
174 assertEquals(vr.getViewportHeight(), 13);
177 @Test(groups = { "Functional" })
178 public void testSetViewportWidth()
180 ViewportRanges vr = new ViewportRanges(al);
181 vr.setViewportWidth(13);
182 assertEquals(vr.getViewportWidth(), 13);
185 @Test(groups = { "Functional" })
186 public void testSetViewportStartAndHeight()
188 ViewportRanges vr = new ViewportRanges(al);
189 vr.setViewportStartAndHeight(2, 6);
190 assertEquals(vr.getViewportHeight(), 6);
191 assertEquals(vr.getStartSeq(), 2);
193 // reset -ve values of start to 0
194 vr.setViewportStartAndHeight(-1, 7);
195 assertEquals(vr.getViewportHeight(), 7);
196 assertEquals(vr.getStartSeq(), 0);
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);
204 @Test(groups = { "Functional" })
205 public void testSetViewportStartAndWidth()
207 ViewportRanges vr = new ViewportRanges(al);
208 vr.setViewportStartAndWidth(2, 6);
209 assertEquals(vr.getViewportWidth(), 6);
210 assertEquals(vr.getStartRes(), 2);
212 // reset -ve values of start to 0
213 vr.setViewportStartAndWidth(-1, 7);
214 assertEquals(vr.getViewportWidth(), 7);
215 assertEquals(vr.getStartRes(), 0);
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);
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);
229 @Test(groups = { "Functional" })
230 public void testPageUpDown()
232 ViewportRanges vr = new ViewportRanges(al);
233 vr.setViewportStartAndHeight(8, 6);
235 assertEquals(vr.getStartSeq(), 13);
238 assertEquals(vr.getStartSeq(), 8);
241 assertEquals(vr.getStartSeq(), 3);
244 // pageup does not go beyond 0, viewport height stays the same
245 assertEquals(vr.getStartSeq(), 0);
246 assertEquals(vr.getViewportHeight(), 6);
254 // pagedown to bottom does not go beyond end, and height stays same
255 assertEquals(vr.getStartSeq(), 24);
256 assertEquals(vr.getViewportHeight(), 6);
259 @Test(groups = { "Functional" })
260 public void testScrollUp()
262 ViewportRanges vr = new ViewportRanges(al);
263 vr.setViewportStartAndHeight(1, 5);
265 assertEquals(vr.getStartSeq(), 0);
266 // can't scroll above top
268 assertEquals(vr.getStartSeq(), 0);
270 vr.setViewportStartAndHeight(24, 5);
272 assertEquals(vr.getStartSeq(), 25);
273 // can't scroll beyond bottom
275 assertEquals(vr.getStartSeq(), 25);
278 @Test(groups = { "Functional" })
279 public void testScrollUpWithHidden()
281 ViewportRanges vr = new ViewportRanges(al);
283 // hide last sequence
284 HiddenSequences hidden = new HiddenSequences(al);
285 hidden.hideSequence(al.getSequenceAt(29));
287 vr.setViewportStartAndHeight(1, 5);
289 assertEquals(vr.getStartSeq(), 0);
290 // can't scroll above top
292 assertEquals(vr.getStartSeq(), 0);
294 vr.setViewportStartAndHeight(23, 5);
296 assertEquals(vr.getStartSeq(), 24);
297 // can't scroll beyond bottom
299 assertEquals(vr.getStartSeq(), 24);
302 @Test(groups = { "Functional" })
303 public void testScrollRight()
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);
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);
321 @Test(groups = { "Functional" })
322 public void testScrollRightWithHidden()
324 ViewportRanges vr = new ViewportRanges(al);
326 // hide last 2 columns
327 HiddenColumns cols = new HiddenColumns();
328 cols.hideColumns(19, 20);
329 al.setHiddenColumns(cols);
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);
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);
346 @Test(groups = { "Functional" })
347 public void testScrollToWrappedVisible()
349 ViewportRanges vr = new ViewportRanges(al);
350 vr.setViewportStartAndWidth(5, 10);
352 vr.scrollToWrappedVisible(0);
353 assertEquals(vr.getStartRes(), 0);
355 vr.scrollToWrappedVisible(10);
356 assertEquals(vr.getStartRes(), 10);
358 vr.scrollToWrappedVisible(15);
359 assertEquals(vr.getStartRes(), 10);
362 // leave until JAL-2388 is merged and we can do without viewport
363 /*@Test(groups = { "Functional" })
364 public void testScrollToVisible()
366 ViewportRanges vr = new ViewportRanges(al);
367 vr.setViewportStartAndWidth(12,5);
368 vr.setViewportStartAndHeight(10,6);
369 vr.scrollToVisible(13,14)
372 assertEquals(vr.getStartRes(), 12);
373 assertEquals(vr.getStartSeq(), 10);
375 vr.scrollToVisible(5,6);
376 assertEquals(vr.getStartRes(), 5);
377 assertEquals(vr.getStartSeq(), 6);
379 // test for hidden columns too
382 @Test(groups = { "Functional" })
383 public void testEventFiring()
385 ViewportRanges vr = new ViewportRanges(al);
386 MockPropChangeListener l = new MockPropChangeListener(vr);
387 List<String> emptylist = new ArrayList<>();
389 vr.setViewportWidth(5);
390 vr.setViewportHeight(5);
393 // one event fired when startRes is called with new value
395 assertTrue(l.verify(1, Arrays.asList("startres")));
398 // no event fired for same value
400 assertTrue(l.verify(0, emptylist));
404 assertTrue(l.verify(1, Arrays.asList("startseq")));
408 assertTrue(l.verify(0, emptylist));
412 assertTrue(l.verify(1, Arrays.asList("startseq")));
416 assertTrue(l.verify(0, emptylist));
419 vr.setStartEndRes(2, 15);
420 assertTrue(l.verify(1, Arrays.asList("startres")));
423 vr.setStartEndRes(2, 15);
424 assertTrue(l.verify(0, emptylist));
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)));
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)));
437 vr.setStartEndSeq(2, 15);
438 assertTrue(l.verify(1, Arrays.asList("startseq")));
441 vr.setStartEndSeq(2, 15);
442 assertTrue(l.verify(0, emptylist));
445 vr.setStartEndRes(2, 2); // so seq and res values should be different, in
446 // case of transposing in code
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)));
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)));
459 // reset for later tests
460 vr.setStartEndSeq(2, 15);
463 // test viewport height and width setting triggers event
464 vr.setViewportHeight(10);
465 assertTrue(l.verify(1, Arrays.asList("endseq")));
468 vr.setViewportWidth(18);
469 assertTrue(l.verify(1, Arrays.asList("endres")));
472 // already has seq start set to 2, so triggers endseq
473 vr.setViewportStartAndHeight(2, 16);
474 assertTrue(l.verify(1, Arrays.asList("endseq")));
477 vr.setViewportStartAndWidth(1, 14);
478 assertTrue(l.verify(1, Arrays.asList("startres")));
481 // test page up/down triggers event
483 assertTrue(l.verify(1, Arrays.asList("startseq")));
487 assertTrue(l.verify(1, Arrays.asList("startseq")));
490 // test scrolling triggers event
492 assertTrue(l.verify(1, Arrays.asList("startseq")));
496 assertTrue(l.verify(1, Arrays.asList("startseq")));
499 vr.scrollRight(true);
500 assertTrue(l.verify(1, Arrays.asList("startres")));
503 vr.scrollRight(false);
504 assertTrue(l.verify(1, Arrays.asList("startres")));
507 vr.scrollToVisible(10, 10);
508 assertTrue(l.verify(4,
509 Arrays.asList("startseq", "startseq", "startseq", "startseq")));
512 vr.scrollToWrappedVisible(5);
513 assertTrue(l.verify(1, Arrays.asList("startres")));
517 @Test(groups = { "Functional" })
518 public void testGetWrappedScrollPosition()
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
526 * scroll is 0 at column 0 (only)
528 assertEquals(vr.getWrappedScrollPosition(0), 0);
531 * scroll is 1 at columns 1-40
537 assertEquals(1, vr.getWrappedScrollPosition(i));
541 * scroll is 2 at columns 41-80, etc
546 assertEquals(2, vr.getWrappedScrollPosition(i), "For " + i);
550 @Test(groups = { "Functional" })
551 public void testPageUpDownWrapped()
554 * 15 sequences, 110 residues wide (+gaps)
556 AlignmentI al2 = gen.generate(110, 15, 1, 5, 5);
558 ViewportRanges vr = new ViewportRanges(al2);
559 vr.setWrappedMode(true);
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);
572 assertEquals(vr.getStartRes(), 40);
573 assertEquals(vr.getEndRes(), 79);
574 assertEquals(vr.getStartSeq(), 0);
575 assertEquals(vr.getEndSeq(), 14);
577 // third and last row
578 // note endRes is nominal (>width) to preserve viewport width
580 assertEquals(vr.getStartRes(), 80);
581 assertEquals(vr.getEndRes(), 119);
582 assertEquals(vr.getStartSeq(), 0);
583 assertEquals(vr.getEndSeq(), 14);
585 // another pageDown should do nothing
587 assertEquals(vr.getStartRes(), 80);
588 assertEquals(vr.getEndRes(), 119);
589 assertEquals(vr.getStartSeq(), 0);
590 assertEquals(vr.getEndSeq(), 14);
592 // back to second row
594 assertEquals(vr.getStartRes(), 40);
595 assertEquals(vr.getEndRes(), 79);
596 assertEquals(vr.getStartSeq(), 0);
597 assertEquals(vr.getEndSeq(), 14);
601 assertEquals(vr.getStartRes(), 0);
602 assertEquals(vr.getEndRes(), 39);
603 assertEquals(vr.getStartSeq(), 0);
604 assertEquals(vr.getEndSeq(), 14);
606 // another pageUp should do nothing
608 assertEquals(vr.getStartRes(), 0);
609 assertEquals(vr.getEndRes(), 39);
610 assertEquals(vr.getStartSeq(), 0);
611 assertEquals(vr.getEndSeq(), 14);
614 * simulate scroll right a few positions
617 assertEquals(vr.getStartRes(), 5);
618 assertEquals(vr.getEndRes(), 5 + width - 1); // 44
620 vr.pageDown(); // 5-44 shifts to 45-84
621 assertEquals(vr.getStartRes(), 45);
622 assertEquals(vr.getEndRes(), 84);
624 vr.pageDown(); // 45-84 shifts to 85-124
625 assertEquals(vr.getStartRes(), 85);
626 assertEquals(vr.getEndRes(), 124);
628 vr.pageDown(); // no change - at end already
629 assertEquals(vr.getStartRes(), 85);
630 assertEquals(vr.getEndRes(), 124);
632 vr.pageUp(); // back we go
633 assertEquals(vr.getStartRes(), 45);
634 assertEquals(vr.getEndRes(), 84);
637 assertEquals(vr.getStartRes(), 5);
638 assertEquals(vr.getEndRes(), 44);
640 vr.pageUp(); // back to the start
641 assertEquals(vr.getStartRes(), 0);
642 assertEquals(vr.getEndRes(), 39);
645 @Test(groups = { "Functional" })
646 public void testSetStartEndResWrapped()
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);
654 vr.setStartEndRes(5, 19);
655 assertEquals(vr.getStartRes(), 5);
656 assertEquals(vr.getEndRes(), 19);
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);
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);
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);
677 @Test(groups = { "Functional" })
678 public void testSetViewportStartAndWidthWrapped()
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);
686 // reset -ve values of start to 0
687 vr.setViewportStartAndWidth(-1, 7);
688 assertEquals(vr.getViewportWidth(), 7);
689 assertEquals(vr.getStartRes(), 0);
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);
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);
703 @Test(groups = { "Functional" })
704 public void testGetWrappedMaxScroll()
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
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
720 for (int col = 0; col < alignmentWidth; col++)
722 int offset = col % width;
723 if (offset > 0 && offset < partWidth)
725 assertEquals(vr.getWrappedMaxScroll(col), 4, "col " + col);
729 assertEquals(vr.getWrappedMaxScroll(col), 3, "col " + col);
735 // mock listener for property change events
736 class MockPropChangeListener implements ViewportListenerI
738 private int firecount = 0;
740 private List<String> events = new ArrayList<>();
742 private List<Integer> newvalues = new ArrayList<>();
744 public MockPropChangeListener(ViewportRanges vr)
746 vr.addPropertyChangeListener(this);
750 public void propertyChange(PropertyChangeEvent evt)
753 events.add(evt.getPropertyName());
754 newvalues.add((Integer) evt.getNewValue());
757 public boolean verify(int count, List<String> eventslist,
758 List<Integer> valueslist)
760 return (count == firecount) && events.equals(eventslist)
761 && newvalues.equals(valueslist);
764 public boolean verify(int count, List<String> eventslist)
766 return (count == firecount) && events.equals(eventslist);