JAL-2189 format tests
[jalview.git] / test / jalview / datamodel / HiddenSequencesTest.java
1 package jalview.datamodel;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertFalse;
5 import static org.testng.AssertJUnit.assertNotNull;
6 import static org.testng.AssertJUnit.assertNotSame;
7 import static org.testng.AssertJUnit.assertNull;
8 import static org.testng.AssertJUnit.assertSame;
9 import static org.testng.AssertJUnit.assertTrue;
10 import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
11
12 import jalview.gui.AlignViewport;
13
14 import java.util.List;
15
16 import org.testng.annotations.BeforeTest;
17 import org.testng.annotations.Test;
18
19 @Test(singleThreaded = true)
20 public class HiddenSequencesTest
21 {
22   static int SEQ_COUNT = 10;
23
24   SequenceI[] seqs;
25
26   /**
27    * Set up an alignment of 10 sequences
28    */
29   @BeforeTest(alwaysRun = true)
30   public void setUp()
31   {
32     seqs = new SequenceI[SEQ_COUNT];
33     for (int i = 0; i < SEQ_COUNT; i++)
34     {
35       // sequence lengths are 1, 2, ... 10
36       seqs[i] = new Sequence("Seq" + i, "abcdefghijk".substring(0, i + 1));
37     }
38   }
39
40   /**
41    * Test the method that converts sequence alignment index to what it would be
42    * if all sequences were unhidden
43    */
44   @Test(groups = "Functional")
45   public void testAdjustForHiddenSeqs()
46   {
47     AlignmentI al = new Alignment(seqs);
48     HiddenSequences hs = al.getHiddenSequences();
49     for (int i = 0; i < SEQ_COUNT; i++)
50     {
51       assertEquals(i, hs.adjustForHiddenSeqs(i));
52     }
53
54     // hide seq1 and seq5 and seq6
55     hs.hideSequence(seqs[1]);
56     hs.hideSequence(seqs[5]);
57     hs.hideSequence(seqs[6]);
58
59     /*
60      * alignment is now seq0/2/3/4/7/8/9
61      */
62     assertEquals(7, al.getHeight());
63     assertEquals(0, hs.adjustForHiddenSeqs(0));
64     assertEquals(2, hs.adjustForHiddenSeqs(1));
65     assertEquals(3, hs.adjustForHiddenSeqs(2));
66     assertEquals(4, hs.adjustForHiddenSeqs(3));
67     assertEquals(7, hs.adjustForHiddenSeqs(4));
68     assertEquals(8, hs.adjustForHiddenSeqs(5));
69     assertEquals(9, hs.adjustForHiddenSeqs(6));
70   }
71
72   /**
73    * Test the method that increments the internal array size if a sequence is
74    * added to the alignment (ugh this should not be exposed to the light of day)
75    */
76   @Test(groups = "Functional")
77   public void testAdjustHeightSequenceAdded()
78   {
79     AlignmentI al = new Alignment(seqs);
80     assertEquals(SEQ_COUNT, al.getHeight());
81
82     HiddenSequences hs = al.getHiddenSequences();
83     // initially does nothing
84     hs.adjustHeightSequenceAdded();
85     assertNull(hs.hiddenSequences);
86
87     // hide one sequence
88     hs.hideSequence(seqs[3]);
89     assertEquals(1, hs.getSize());
90     assertEquals(SEQ_COUNT - 1, al.getHeight());
91     assertEquals(SEQ_COUNT, hs.hiddenSequences.length);
92
93     /*
94      * add a sequence to the alignment
95      * - the safe way to call hs.adjustHeightSequenceAdded!
96      * (implementation depends on alignment height having
97      * been already updated for the added sequence)
98      */
99     al.addSequence(new Sequence("a", "b"));
100     assertEquals(1, hs.getSize());
101     assertEquals(SEQ_COUNT, al.getHeight());
102     assertEquals(SEQ_COUNT + 1, hs.hiddenSequences.length);
103   }
104
105   /**
106    * Test the method that decrements the internal array size if a sequence is
107    * deleted from the alignment (ugh this should not be exposed to the light of
108    * day)
109    */
110   @Test(groups = "Functional")
111   public void testAdjustHeightSequenceDeleted()
112   {
113     AlignmentI al = new Alignment(seqs);
114     assertEquals(SEQ_COUNT, al.getHeight());
115
116     HiddenSequences hs = al.getHiddenSequences();
117     // initially does nothing
118     hs.adjustHeightSequenceAdded();
119     assertNull(hs.hiddenSequences);
120
121     // hide two sequences
122     hs.hideSequence(seqs[3]);
123     hs.hideSequence(seqs[5]);
124     assertEquals(2, hs.getSize());
125     assertTrue(hs.isHidden(seqs[3]));
126     assertTrue(hs.isHidden(seqs[5]));
127     assertEquals(SEQ_COUNT - 2, al.getHeight());
128     assertEquals(SEQ_COUNT, hs.hiddenSequences.length);
129
130     /*
131      * delete a visible sequence from the alignment
132      * - the safe way to call hs.adjustHeightSequenceDeleted!
133      * (implementation depends on alignment height having
134      * been already updated for the removed sequence)
135      */
136     al.deleteSequence(seqs[2]);
137     assertEquals(2, hs.getSize());
138     // the visible alignment is unchanged:
139     assertEquals(SEQ_COUNT - 3, al.getHeight());
140     // sequences array size has decremented:
141     assertEquals(SEQ_COUNT - 1, hs.hiddenSequences.length);
142   }
143
144   /**
145    * Test the method that converts a 'full alignment' sequence index into the
146    * equivalent in the alignment with sequences hidden
147    */
148   @Test(groups = "Functional")
149   public void testFindIndexWithoutHiddenSeqs()
150   {
151     AlignmentI al = new Alignment(seqs);
152     HiddenSequences hs = al.getHiddenSequences();
153     for (int i = 0; i < SEQ_COUNT; i++)
154     {
155       assertEquals(i, hs.findIndexWithoutHiddenSeqs(i));
156     }
157
158     // hide seq1 and seq5 and seq6
159     hs.hideSequence(seqs[1]);
160     hs.hideSequence(seqs[5]);
161     hs.hideSequence(seqs[6]);
162
163     /*
164      * alignment is now seq0/2/3/4/7/8/9
165      */
166     assertEquals(7, al.getHeight());
167     assertEquals(0, hs.findIndexWithoutHiddenSeqs(0));
168     assertEquals(0, hs.findIndexWithoutHiddenSeqs(1));
169     assertEquals(1, hs.findIndexWithoutHiddenSeqs(2));
170     assertEquals(2, hs.findIndexWithoutHiddenSeqs(3));
171     assertEquals(3, hs.findIndexWithoutHiddenSeqs(4));
172     assertEquals(3, hs.findIndexWithoutHiddenSeqs(5));
173     assertEquals(3, hs.findIndexWithoutHiddenSeqs(6));
174     assertEquals(4, hs.findIndexWithoutHiddenSeqs(7));
175     assertEquals(5, hs.findIndexWithoutHiddenSeqs(8));
176     assertEquals(6, hs.findIndexWithoutHiddenSeqs(9));
177   }
178
179   /**
180    * Test the method that reconstructs (sort of) the full alignment including
181    * hidden sequences
182    */
183   @Test(groups = "Functional")
184   public void testGetFullAlignment()
185   {
186     AlignmentI al = new Alignment(seqs);
187     assertArrayEquals(seqs, al.getSequencesArray());
188     al.setProperty("a", "b");
189     al.addAnnotation(new AlignmentAnnotation("ann", "label", 12f));
190     al.setSeqrep(seqs[4]);
191     SequenceGroup sg = new SequenceGroup();
192     sg.addSequence(seqs[8], false);
193     al.addGroup(sg);
194     ((Alignment) al).hasRNAStructure = true;
195
196     HiddenSequences hs = al.getHiddenSequences();
197     AlignmentI al2 = hs.getFullAlignment();
198     // new alignment but with original sequences
199     assertNotSame(al, al2);
200     assertArrayEquals(al.getSequencesArray(), al2.getSequencesArray());
201
202     hs.hideSequence(seqs[4]);
203     hs.hideSequence(seqs[9]);
204     al2 = hs.getFullAlignment();
205     assertNotSame(al, al2);
206     assertArrayEquals(seqs, al2.getSequencesArray());
207     assertNotNull(al2.getProperties());
208     assertSame(al.getProperties(), al2.getProperties());
209     assertNotNull(al2.getAlignmentAnnotation());
210     assertSame(al.getAlignmentAnnotation(), al2.getAlignmentAnnotation());
211     assertSame(seqs[4], al2.getSeqrep());
212     assertNotNull(al2.getGroups());
213     assertSame(al.getGroups(), al2.getGroups());
214     assertTrue(al2.hasRNAStructure());
215   }
216
217   /**
218    * Test the method that returns the hidden sequence at a given index in the
219    * full alignment
220    * 
221    * @return either the sequence (if hidden) or null (if not hidden)
222    */
223   @Test(groups = "Functional")
224   public void testGetHiddenSequence()
225   {
226     AlignmentI al = new Alignment(seqs);
227     HiddenSequences hs = al.getHiddenSequences();
228     assertNull(hs.getHiddenSequence(0));
229     hs.hideSequence(seqs[3]);
230     assertSame(seqs[3], hs.getHiddenSequence(3));
231     assertNull(hs.getHiddenSequence(2));
232     assertNull(hs.getHiddenSequence(4));
233   }
234
235   @Test(groups = "Functional")
236   public void testGetSize()
237   {
238   }
239
240   @Test(groups = "Functional")
241   public void testGetWidth()
242   {
243     AlignmentI al = new Alignment(seqs);
244     HiddenSequences hs = al.getHiddenSequences();
245     assertEquals(0, hs.getWidth());
246     hs.hideSequence(seqs[6]);
247     hs.hideSequence(seqs[8]);
248     assertEquals(9, hs.getWidth());
249   }
250
251   /**
252    * Test the method that adds a sequence to the hidden sequences and deletes it
253    * from the alignment, and its converse
254    */
255   @Test(groups = "Functional")
256   public void testHideShowSequence()
257   {
258     AlignmentI al = new Alignment(seqs);
259     assertTrue(al.getSequences().contains(seqs[1]));
260     HiddenSequences hs = al.getHiddenSequences();
261     assertEquals(0, hs.getSize());
262     assertEquals(10, al.getHeight());
263
264     /*
265      * hide the second sequence in the alignment
266      */
267     hs.hideSequence(seqs[1]);
268     assertFalse(hs.isHidden(seqs[0]));
269     assertTrue(hs.isHidden(seqs[1]));
270     assertFalse(al.getSequences().contains(seqs[1]));
271     assertEquals(1, hs.getSize());
272     assertEquals(9, al.getHeight());
273     assertSame(seqs[2], al.getSequenceAt(1));
274
275     /*
276      * hide what is now the second sequence in the alignment
277      */
278     hs.hideSequence(seqs[2]);
279     assertFalse(hs.isHidden(seqs[0]));
280     assertTrue(hs.isHidden(seqs[1]));
281     assertTrue(hs.isHidden(seqs[2]));
282     assertFalse(al.getSequences().contains(seqs[1]));
283     assertFalse(al.getSequences().contains(seqs[2]));
284     assertEquals(2, hs.getSize());
285     assertEquals(8, al.getHeight());
286
287     /*
288      * perform 'reveal' on what is now the second sequence in the alignment
289      * this should unhide the two sequences that precede it
290      */
291     List<SequenceI> revealed = hs.showSequence(1, null);
292     assertEquals(2, revealed.size());
293     assertTrue(revealed.contains(seqs[1]));
294     assertTrue(revealed.contains(seqs[2]));
295     assertEquals(0, hs.getSize());
296     assertEquals(10, al.getHeight());
297   }
298
299   @Test(groups = "Functional")
300   public void testIsHidden()
301   {
302     AlignmentI al = new Alignment(seqs);
303     HiddenSequences hs = al.getHiddenSequences();
304     hs.hideSequence(seqs[7]);
305     hs.hideSequence(seqs[4]);
306     assertTrue(hs.isHidden(seqs[4]));
307     assertFalse(hs.isHidden(seqs[5]));
308     assertFalse(hs.isHidden(seqs[6]));
309     assertTrue(hs.isHidden(seqs[7]));
310     assertFalse(hs.isHidden(null));
311     assertFalse(hs.isHidden(new Sequence("", "")));
312   }
313
314   /**
315    * Test hiding and unhiding a group with a representative sequence. The
316    * representative should be left visible when the group is hidden, and
317    * included in the selected group when it is unhidden.
318    */
319   @Test(groups = "Functional")
320   public void testHideShowSequence_withHiddenRepSequence()
321   {
322     AlignmentI al = new Alignment(seqs);
323
324     /*
325      * represent seqs 2-4 with seq3
326      * this hides seq2 and seq4 but not seq3
327      */
328     AlignViewport av = new AlignViewport(al);
329     SequenceGroup sg = new SequenceGroup();
330     sg.addSequence(seqs[1], false);
331     sg.addSequence(seqs[2], false);
332     sg.addSequence(seqs[3], false);
333     av.setSelectionGroup(sg);
334
335     /*
336      * hiding group with reference sequence is done via AlignViewport
337      */
338     av.hideSequences(seqs[2], true);
339     HiddenSequences hs = al.getHiddenSequences();
340     assertEquals(2, hs.getSize());
341     assertTrue(hs.isHidden(seqs[1]));
342     assertFalse(hs.isHidden(seqs[2]));
343     assertTrue(hs.isHidden(seqs[3]));
344
345     /*
346      * should now be no sequences selected in the alignment
347      */
348     assertNull(av.getSelectionGroup());
349
350     /*
351      * visible alignment is now seq0/2/4/5/6/7/8/9
352      * 'reveal sequences' at the representative sequence (index = 1)
353      * this should unhide the one above i.e. seq1
354      * and return a selection list including seq2
355      * 
356      * note have to call via AlignViewport to get the expected
357      * resulting sequence selection
358      */
359     av.showSequence(1);
360
361     /*
362      * only seq3 is now hidden
363      */
364     assertEquals(1, hs.getSize());
365     assertTrue(hs.isHidden(seqs[3]));
366     assertEquals(SEQ_COUNT - 1, al.getHeight());
367     sg = av.getSelectionGroup();
368
369     /*
370      * unhidden and representative sequence selected
371      * (this behaviour may change! JAL-2133)
372      */
373     assertEquals(2, sg.getSize());
374     assertTrue(sg.getSequences().contains(seqs[1]));
375     assertTrue(sg.getSequences().contains(seqs[2]));
376     assertFalse(sg.getSequences().contains(seqs[3]));
377   }
378 }