JAL-2573 Fixes for alignment < viewport width, and similarly height
[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.BeforeMethod;
18 import org.testng.annotations.Test;
19
20 public class ViewportRangesTest {
21
22   AlignmentGenerator gen = new AlignmentGenerator(false);
23
24   AlignmentI al = gen.generate(20, 30, 1, 5, 5);
25
26   AlignmentI smallAl = gen.generate(7, 2, 2, 5, 5);
27
28   @BeforeMethod
29   public void cleanUp()
30   {
31     ColumnSelection sel = new ColumnSelection();
32     al.getHiddenColumns().revealAllHiddenColumns(sel);
33     al.getHiddenSequences().showAll(null);
34   }
35
36   @Test(groups = { "Functional" })
37   public void testViewportRanges() 
38   {
39     ViewportRanges vr = new ViewportRanges(al);
40     
41     assertEquals(vr.getStartRes(),0);
42     assertEquals(vr.getEndRes(), al.getWidth()-1);
43     assertEquals(vr.getStartSeq(), 0);
44     assertEquals(vr.getEndSeq(), al.getHeight() - 1);
45   }
46
47   @Test(groups = { "Functional" })
48   public void testGetAbsoluteAlignmentHeight()
49   {
50     ViewportRanges vr = new ViewportRanges(al);
51
52     assertEquals(vr.getAbsoluteAlignmentHeight(), al.getHeight());
53
54     al.getHiddenSequences().hideSequence(al.getSequenceAt(3));
55     assertEquals(vr.getAbsoluteAlignmentHeight(), al.getHeight() + 1);
56   }
57
58   @Test(groups = { "Functional" })
59   public void testGetAbsoluteAlignmentWidth()
60   {
61     ViewportRanges vr = new ViewportRanges(al);
62     assertEquals(vr.getAbsoluteAlignmentWidth(), al.getWidth());
63   }
64
65   @Test(groups = { "Functional" })
66   public void testSetEndRes()
67   {
68     ViewportRanges vr = new ViewportRanges(al);
69     vr.setEndRes(-1);
70     assertEquals(vr.getEndRes(), 0);
71
72     vr.setEndRes(al.getWidth() - 1);
73     assertEquals(vr.getEndRes(), al.getWidth() - 1);
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     assertEquals(vr.getEndSeq(), al.getHeight() - 1);
88   }
89
90   @Test(groups = { "Functional" })
91   public void testSetStartRes()
92   {
93     ViewportRanges vr = new ViewportRanges(al);
94     vr.setStartRes(-1);
95     assertEquals(vr.getStartRes(), 0);
96
97     vr.setStartRes(al.getWidth());
98     assertEquals(vr.getStartRes(), al.getWidth() - 1);
99
100     vr.setStartRes(al.getWidth() - 1);
101     assertEquals(vr.getStartRes(), al.getWidth() - 1);
102   }
103
104   @Test(groups = { "Functional" })
105   public void testSetStartSeq()
106   {
107     ViewportRanges vr = new ViewportRanges(al);
108     vr.setStartSeq(-1);
109     assertEquals(vr.getStartSeq(), 0);
110
111     vr.setStartSeq(al.getHeight() - vr.getViewportHeight() + 1);
112     assertEquals(vr.getStartSeq(), al.getHeight() - vr.getViewportHeight());
113
114     vr.setStartSeq(al.getHeight() - vr.getViewportHeight());
115     assertEquals(vr.getStartSeq(), al.getHeight() - vr.getViewportHeight());
116   }
117
118   @Test(groups = { "Functional" })
119   public void testSetStartEndRes()
120   {
121     ViewportRanges vr = new ViewportRanges(al);
122     vr.setStartEndRes(-1, -1);
123     assertEquals(vr.getStartRes(), 0);
124     assertEquals(vr.getEndRes(), 0);
125
126     vr.setStartEndRes(5, 19);
127     assertEquals(vr.getStartRes(), 5);
128     assertEquals(vr.getEndRes(), 19);
129
130     vr.setStartEndRes(al.getWidth(), al.getWidth());
131     assertEquals(vr.getEndRes(), al.getWidth() - 1);
132
133     ViewportRanges vrsmall = new ViewportRanges(smallAl);
134     vrsmall.setStartEndRes(al.getWidth(), al.getWidth());
135     assertEquals(vrsmall.getEndRes(), 6);
136   }
137
138   @Test(groups = { "Functional" })
139   public void testSetStartEndSeq()
140   {
141     ViewportRanges vr = new ViewportRanges(al);
142     vr.setStartEndSeq(-1, -1);
143     assertEquals(vr.getStartSeq(), 0);
144     assertEquals(vr.getEndSeq(), 0);
145
146     vr.setStartEndSeq(5, 19);
147     assertEquals(vr.getStartSeq(), 5);
148     assertEquals(vr.getEndSeq(), 19);
149
150     vr.setStartEndSeq(al.getHeight(), al.getHeight());
151     assertEquals(vr.getEndSeq(), al.getHeight() - 1);
152   }
153
154   @Test(groups = { "Functional" })
155   public void testSetViewportHeight()
156   {
157     ViewportRanges vr = new ViewportRanges(al);
158     vr.setViewportHeight(13);
159     assertEquals(vr.getViewportHeight(), 13);
160   }
161
162   @Test(groups = { "Functional" })
163   public void testSetViewportWidth()
164   {
165     ViewportRanges vr = new ViewportRanges(al);
166     vr.setViewportWidth(13);
167     assertEquals(vr.getViewportWidth(), 13);
168   }
169
170   @Test(groups = { "Functional" })
171   public void testSetViewportStartAndHeight()
172   {
173     ViewportRanges vr = new ViewportRanges(al);
174     vr.setViewportStartAndHeight(2, 6);
175     assertEquals(vr.getViewportHeight(), 6);
176     assertEquals(vr.getStartSeq(), 2);
177
178     // reset -ve values of start to 0
179     vr.setViewportStartAndHeight(-1, 7);
180     assertEquals(vr.getViewportHeight(), 7);
181     assertEquals(vr.getStartSeq(), 0);
182
183     // reset out of bounds start values to within bounds
184     vr.setViewportStartAndHeight(35, 5);
185     assertEquals(vr.getViewportHeight(), 5);
186     assertEquals(vr.getStartSeq(), 24);
187   }
188
189   @Test(groups = { "Functional" })
190   public void testSetViewportStartAndWidth()
191   {
192     ViewportRanges vr = new ViewportRanges(al);
193     vr.setViewportStartAndWidth(2, 6);
194     assertEquals(vr.getViewportWidth(), 6);
195     assertEquals(vr.getStartRes(), 2);
196
197     // reset -ve values of start to 0
198     vr.setViewportStartAndWidth(-1, 7);
199     assertEquals(vr.getViewportWidth(), 7);
200     assertEquals(vr.getStartRes(), 0);
201
202     // reset out of bounds start values to within bounds
203     vr.setViewportStartAndWidth(35, 5);
204     assertEquals(vr.getViewportWidth(), 5);
205     assertEquals(vr.getStartRes(), 16);
206
207     // small alignment doesn't get bounds reset
208     ViewportRanges vrsmall = new ViewportRanges(smallAl);
209     vrsmall.setViewportStartAndWidth(0, 63);
210     assertEquals(vrsmall.getViewportWidth(), 7);
211     assertEquals(vrsmall.getStartRes(), 0);
212   }
213
214   @Test(groups = { "Functional" })
215   public void testPageUpDown()
216   {
217     ViewportRanges vr = new ViewportRanges(al);
218     vr.setViewportStartAndHeight(8, 6);
219     vr.pageDown();
220     assertEquals(vr.getStartSeq(), 13);
221
222     vr.pageUp();
223     assertEquals(vr.getStartSeq(), 8);
224
225     vr.pageUp();
226     assertEquals(vr.getStartSeq(), 3);
227
228     vr.pageUp();
229     // pageup does not go beyond 0, viewport height stays the same
230     assertEquals(vr.getStartSeq(), 0);
231     assertEquals(vr.getViewportHeight(), 6);
232
233     vr.pageDown();
234     vr.pageDown();
235     vr.pageDown();
236     vr.pageDown();
237     vr.pageDown();
238
239     // pagedown to bottom does not go beyond end, and height stays same
240     assertEquals(vr.getStartSeq(), 24);
241     assertEquals(vr.getViewportHeight(), 6);
242   }
243
244   @Test(groups = { "Functional" })
245   public void testScrollUp()
246   {
247     ViewportRanges vr = new ViewportRanges(al);
248     vr.setViewportStartAndHeight(1, 5);
249     vr.scrollUp(true);
250     assertEquals(vr.getStartSeq(), 0);
251     // can't scroll above top
252     vr.scrollUp(true);
253     assertEquals(vr.getStartSeq(), 0);
254
255     vr.setViewportStartAndHeight(24, 5);
256     vr.scrollUp(false);
257     assertEquals(vr.getStartSeq(), 25);
258     // can't scroll beyond bottom
259     vr.scrollUp(false);
260     assertEquals(vr.getStartSeq(), 25);
261   }
262
263   @Test(groups = { "Functional" })
264   public void testScrollUpWithHidden()
265   {
266     ViewportRanges vr = new ViewportRanges(al);
267
268     // hide last sequence
269     HiddenSequences hidden = new HiddenSequences(al);
270     hidden.hideSequence(al.getSequenceAt(29));
271
272     vr.setViewportStartAndHeight(1, 5);
273     vr.scrollUp(true);
274     assertEquals(vr.getStartSeq(), 0);
275     // can't scroll above top
276     vr.scrollUp(true);
277     assertEquals(vr.getStartSeq(), 0);
278
279     vr.setViewportStartAndHeight(23, 5);
280     vr.scrollUp(false);
281     assertEquals(vr.getStartSeq(), 24);
282     // can't scroll beyond bottom
283     vr.scrollUp(false);
284     assertEquals(vr.getStartSeq(), 24);
285   }
286
287   @Test(groups = { "Functional" })
288   public void testScrollRight()
289   {
290     ViewportRanges vr = new ViewportRanges(al);
291     vr.setViewportStartAndWidth(1, 5);
292     vr.scrollRight(false);
293     assertEquals(vr.getStartRes(), 0);
294     // can't scroll left past start
295     vr.scrollRight(false);
296     assertEquals(vr.getStartRes(), 0);
297
298     vr.setViewportStartAndWidth(15, 5);
299     vr.scrollRight(true);
300     assertEquals(vr.getStartRes(), 16);
301     // can't scroll right past end
302     vr.scrollRight(true);
303     assertEquals(vr.getStartRes(), 16);
304   }
305
306   @Test(groups = { "Functional" })
307   public void testScrollRightWithHidden()
308   {
309     ViewportRanges vr = new ViewportRanges(al);
310
311     // hide last 2 columns
312     HiddenColumns cols = new HiddenColumns();
313     cols.hideColumns(19, 20);
314     al.setHiddenColumns(cols);
315
316     vr.setViewportStartAndWidth(1, 5);
317     vr.scrollRight(false);
318     assertEquals(vr.getStartRes(), 0);
319     // can't scroll left past start
320     vr.scrollRight(false);
321     assertEquals(vr.getStartRes(), 0);
322
323     vr.setViewportStartAndWidth(13, 5);
324     vr.scrollRight(true);
325     assertEquals(vr.getStartRes(), 14);
326     // can't scroll right past last visible col
327     vr.scrollRight(true);
328     assertEquals(vr.getStartRes(), 14);
329   }
330
331   @Test(groups = { "Functional" })
332   public void testScrollToWrappedVisible()
333   {
334     ViewportRanges vr = new ViewportRanges(al);
335     vr.setViewportStartAndWidth(5, 10);
336
337     vr.scrollToWrappedVisible(0);
338     assertEquals(vr.getStartRes(), 0);
339
340     vr.scrollToWrappedVisible(10);
341     assertEquals(vr.getStartRes(), 10);
342
343     vr.scrollToWrappedVisible(15);
344     assertEquals(vr.getStartRes(), 10);
345   }
346
347   // leave until JAL-2388 is merged and we can do without viewport
348   /*@Test(groups = { "Functional" })
349   public void testScrollToVisible()
350   {
351     ViewportRanges vr = new ViewportRanges(al);
352     vr.setViewportStartAndWidth(12,5);
353     vr.setViewportStartAndHeight(10,6);
354     vr.scrollToVisible(13,14)
355     
356     // no change
357     assertEquals(vr.getStartRes(), 12);
358     assertEquals(vr.getStartSeq(), 10);
359     
360     vr.scrollToVisible(5,6);
361     assertEquals(vr.getStartRes(), 5);
362     assertEquals(vr.getStartSeq(), 6);
363     
364     // test for hidden columns too
365   }*/
366
367   @Test(groups = { "Functional" })
368   public void testEventFiring()
369   {
370     ViewportRanges vr = new ViewportRanges(al);
371     MockPropChangeListener l = new MockPropChangeListener(vr);
372     List<String> emptylist = new ArrayList<>();
373
374     vr.setViewportWidth(5);
375     vr.setViewportHeight(5);
376     l.reset();
377
378     // one event fired when startRes is called with new value
379     vr.setStartRes(4);
380     assertTrue(l.verify(1, Arrays.asList("startres")));
381     l.reset();
382
383     // no event fired for same value
384     vr.setStartRes(4);
385     assertTrue(l.verify(0, emptylist));
386     l.reset();
387
388     vr.setEndRes(10);
389     assertTrue(l.verify(1, Arrays.asList("startres")));
390     l.reset();
391
392     // no event fired for same value
393     vr.setEndRes(10);
394     assertTrue(l.verify(0, emptylist));
395     l.reset();
396
397     vr.setStartSeq(4);
398     assertTrue(l.verify(1, Arrays.asList("startseq")));
399     l.reset();
400
401     vr.setStartSeq(4);
402     assertTrue(l.verify(0, emptylist));
403     l.reset();
404
405     vr.setEndSeq(10);
406     assertTrue(l.verify(1, Arrays.asList("startseq")));
407     l.reset();
408
409     vr.setEndSeq(10);
410     assertTrue(l.verify(0, emptylist));
411     l.reset();
412
413     vr.setStartEndRes(2, 15);
414     assertTrue(l.verify(1, Arrays.asList("startres")));
415     l.reset();
416
417     vr.setStartEndRes(2, 15);
418     assertTrue(l.verify(0, emptylist));
419     l.reset();
420
421     // check new value fired by event is corrected startres
422     vr.setStartEndRes(-1, 5);
423     assertTrue(l.verify(1, Arrays.asList("startres"), Arrays.asList(0)));
424     l.reset();
425
426     // check new value fired by event is corrected endres
427     vr.setStartEndRes(0, -1);
428     assertTrue(l.verify(1, Arrays.asList("endres"), Arrays.asList(0)));
429     l.reset();
430
431     vr.setStartEndSeq(2, 15);
432     assertTrue(l.verify(1, Arrays.asList("startseq")));
433     l.reset();
434
435     vr.setStartEndSeq(2, 15);
436     assertTrue(l.verify(0, emptylist));
437     l.reset();
438
439     vr.setStartEndRes(2, 2); // so seq and res values should be different, in
440                              // case of transposing in code
441     l.reset();
442
443     // check new value fired by event is corrected startseq
444     vr.setStartEndSeq(-1, 5);
445     assertTrue(l.verify(1, Arrays.asList("startseq"), Arrays.asList(0)));
446     l.reset();
447
448     // check new value fired by event is corrected endseq
449     vr.setStartEndSeq(0, -1);
450     assertTrue(l.verify(1, Arrays.asList("endseq"), Arrays.asList(0)));
451     l.reset();
452
453     // reset for later tests
454     vr.setStartEndSeq(2, 15);
455     l.reset();
456
457     // test viewport height and width setting triggers event
458     vr.setViewportHeight(10);
459     assertTrue(l.verify(1, Arrays.asList("endseq")));
460     l.reset();
461
462     vr.setViewportWidth(18);
463     assertTrue(l.verify(1, Arrays.asList("endres")));
464     l.reset();
465
466     // already has seq start set to 2, so triggers endseq
467     vr.setViewportStartAndHeight(2, 16);
468     assertTrue(l.verify(1, Arrays.asList("endseq")));
469     l.reset();
470
471     vr.setViewportStartAndWidth(1, 14);
472     assertTrue(l.verify(1, Arrays.asList("startres")));
473     l.reset();
474
475     // test page up/down triggers event
476     vr.pageUp();
477     assertTrue(l.verify(1, Arrays.asList("startseq")));
478     l.reset();
479
480     vr.pageDown();
481     assertTrue(l.verify(1, Arrays.asList("startseq")));
482     l.reset();
483
484     // test scrolling triggers event
485     vr.scrollUp(true);
486     assertTrue(l.verify(1, Arrays.asList("startseq")));
487     l.reset();
488
489     vr.scrollUp(false);
490     assertTrue(l.verify(1, Arrays.asList("startseq")));
491     l.reset();
492
493     vr.scrollRight(true);
494     assertTrue(l.verify(1, Arrays.asList("startres")));
495     l.reset();
496
497     vr.scrollRight(false);
498     assertTrue(l.verify(1, Arrays.asList("startres")));
499     l.reset();
500
501     vr.scrollToVisible(10, 10);
502     assertTrue(l.verify(4,
503             Arrays.asList("startseq", "startseq", "startseq", "startseq")));
504     l.reset();
505
506     vr.scrollToWrappedVisible(5);
507     assertTrue(l.verify(1, Arrays.asList("startres")));
508     l.reset();
509   }
510 }
511
512 // mock listener for property change events
513 class MockPropChangeListener implements ViewportListenerI
514 {
515   private int firecount = 0;
516
517   private List<String> events = new ArrayList<>();
518
519   private List<Integer> newvalues = new ArrayList<>();
520
521   public MockPropChangeListener(ViewportRanges vr)
522   {
523     vr.addPropertyChangeListener(this);
524   }
525
526   @Override
527   public void propertyChange(PropertyChangeEvent evt)
528   {
529     firecount++;
530     events.add(evt.getPropertyName());
531     newvalues.add((Integer) evt.getNewValue());
532   }
533
534   public boolean verify(int count, List<String> eventslist,
535           List<Integer> valueslist)
536   {
537     return (count == firecount) && events.equals(eventslist)
538             && newvalues.equals(valueslist);
539   }
540
541   public boolean verify(int count, List<String> eventslist)
542   {
543     return (count == firecount) && events.equals(eventslist);
544   }
545
546   public void reset()
547   {
548     firecount = 0;
549     events.clear();
550     newvalues.clear();
551   }
552 }