JAL-2326 added setup method for JvOptionPane in all Jalveiw test classes to enable...
[jalview.git] / test / jalview / datamodel / ResidueCountTest.java
1 package jalview.datamodel;
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.datamodel.ResidueCount.SymbolCounts;
8 import jalview.gui.JvOptionPane;
9
10 import org.junit.Assert;
11 import org.testng.annotations.BeforeClass;
12 import org.testng.annotations.Test;
13
14 public class ResidueCountTest
15 {
16
17   @BeforeClass(alwaysRun = true)
18   public void setUpJvOptionPane()
19   {
20     JvOptionPane.setInteractiveMode(false);
21     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
22   }
23
24   /**
25    * Test a mix of add and put for nucleotide counting
26    */
27   @Test(groups = "Functional")
28   public void test_countNucleotide()
29   {
30     ResidueCount rc = new ResidueCount(true);
31     assertEquals(rc.getCount('A'), 0);
32     assertEquals(rc.getGapCount(), 0);
33     // add then add
34     assertEquals(rc.add('A'), 1);
35     assertEquals(rc.add('a'), 2);
36     // put then add
37     rc.put('g', 3);
38     assertEquals(rc.add('G'), 4);
39     // add then put
40     assertEquals(rc.add('c'), 1);
41     rc.put('C', 4);
42     assertEquals(rc.add('N'), 1);
43
44     assertEquals(rc.getCount('a'), 2);
45     assertEquals(rc.getCount('A'), 2);
46     assertEquals(rc.getCount('G'), 4);
47     assertEquals(rc.getCount('c'), 4);
48     assertEquals(rc.getCount('T'), 0); // never seen
49     assertEquals(rc.getCount('N'), 1);
50     assertEquals(rc.getCount('?'), 0);
51     assertEquals(rc.getCount('-'), 0);
52
53     assertFalse(rc.isCountingInts());
54     assertFalse(rc.isUsingOtherData());
55   }
56
57   /**
58    * Test adding to gap count (either using addGap or add)
59    */
60   @Test(groups = "Functional")
61   public void testAddGap()
62   {
63     ResidueCount rc = new ResidueCount(true);
64     rc.addGap();
65     rc.add('-');
66     rc.add('.');
67     rc.add(' ');
68     
69     assertEquals(rc.getGapCount(), 4);
70     assertEquals(rc.getCount(' '), 4);
71     assertEquals(rc.getCount('-'), 4);
72     assertEquals(rc.getCount('.'), 4);
73     assertFalse(rc.isUsingOtherData());
74     assertFalse(rc.isCountingInts());
75   }
76
77   @Test(groups = "Functional")
78   public void testOverflow()
79   {
80     /*
81      * overflow from add
82      */
83     ResidueCount rc = new ResidueCount(true);
84     rc.addGap();
85     rc.put('A', Short.MAX_VALUE - 1);
86     assertFalse(rc.isCountingInts());
87     rc.add('A');
88     assertFalse(rc.isCountingInts());
89     rc.add('A');
90     assertTrue(rc.isCountingInts());
91     assertEquals(rc.getCount('a'), Short.MAX_VALUE + 1);
92     rc.add('A');
93     assertTrue(rc.isCountingInts());
94     assertEquals(rc.getCount('a'), Short.MAX_VALUE + 2);
95     assertEquals(rc.getGapCount(), 1);
96     rc.addGap();
97     assertEquals(rc.getGapCount(), 2);
98
99     /*
100      * overflow from put
101      */
102     rc = new ResidueCount(true);
103     rc.put('G', Short.MAX_VALUE + 1);
104     assertTrue(rc.isCountingInts());
105     assertEquals(rc.getCount('g'), Short.MAX_VALUE + 1);
106     rc.put('G', 1);
107     assertTrue(rc.isCountingInts());
108     assertEquals(rc.getCount('g'), 1);
109
110     /*
111      * underflow from put
112      */
113     rc = new ResidueCount(true);
114     rc.put('G', Short.MIN_VALUE - 1);
115     assertTrue(rc.isCountingInts());
116     assertEquals(rc.getCount('g'), Short.MIN_VALUE - 1);
117   }
118
119   /**
120    * Test a mix of add and put for peptide counting
121    */
122   @Test(groups = "Functional")
123   public void test_countPeptide()
124   {
125     ResidueCount rc = new ResidueCount(false);
126     rc.put('q', 4);
127     rc.add('Q');
128     rc.add('X');
129     rc.add('x');
130     rc.add('W');
131     rc.put('w', 7);
132     rc.put('m', 12);
133     rc.put('M', 13);
134
135     assertEquals(rc.getCount('q'), 5);
136     assertEquals(rc.getCount('X'), 2);
137     assertEquals(rc.getCount('W'), 7);
138     assertEquals(rc.getCount('m'), 13);
139     assertEquals(rc.getCount('G'), 0);
140     assertEquals(rc.getCount('-'), 0);
141
142     assertFalse(rc.isCountingInts());
143     assertFalse(rc.isUsingOtherData());
144   }
145
146   @Test(groups = "Functional")
147   public void test_unexpectedPeptide()
148   {
149     ResidueCount rc = new ResidueCount(false);
150     // expected characters (upper or lower case):
151     String aas = "ACDEFGHIKLMNPQRSTVWXY";
152     String lower = aas.toLowerCase();
153     for (int i = 0; i < aas.length(); i++)
154     {
155       rc.put(aas.charAt(i), i);
156       rc.add(lower.charAt(i));
157     }
158     for (int i = 0; i < aas.length(); i++)
159     {
160       assertEquals(rc.getCount(aas.charAt(i)), i + 1);
161     }
162     assertFalse(rc.isUsingOtherData());
163
164     rc.put('J', 4);
165     assertTrue(rc.isUsingOtherData());
166     assertEquals(rc.getCount('J'), 4);
167     rc.add('j');
168     assertEquals(rc.getCount('J'), 5);
169   }
170
171   @Test(groups = "Functional")
172   public void test_unexpectedNucleotide()
173   {
174     ResidueCount rc = new ResidueCount(true);
175     // expected characters (upper or lower case):
176     String nucs = "ACGTUN";
177     String lower = nucs.toLowerCase();
178     for (int i = 0; i < nucs.length(); i++)
179     {
180       rc.put(nucs.charAt(i), i);
181       rc.add(lower.charAt(i));
182     }
183     for (int i = 0; i < nucs.length(); i++)
184     {
185       assertEquals(rc.getCount(nucs.charAt(i)), i + 1);
186     }
187     assertFalse(rc.isUsingOtherData());
188
189     rc.add('J');
190     assertTrue(rc.isUsingOtherData());
191   }
192
193   @Test(groups = "Functional")
194   public void testGetModalCount()
195   {
196     ResidueCount rc = new ResidueCount(true);
197     rc.add('c');
198     rc.add('g');
199     rc.add('c');
200     assertEquals(rc.getModalCount(), 2);
201
202     // modal count is in the 'short overflow' counts
203     rc = new ResidueCount();
204     rc.add('c');
205     rc.put('g', Short.MAX_VALUE);
206     rc.add('G');
207     assertEquals(rc.getModalCount(), Short.MAX_VALUE + 1);
208
209     // modal count is in the 'other data' counts
210     rc = new ResidueCount(false);
211     rc.add('Q');
212     rc.add('{');
213     rc.add('{');
214     assertEquals(rc.getModalCount(), 2);
215
216     // verify modal count excludes gap
217     rc = new ResidueCount();
218     rc.add('Q');
219     rc.add('P');
220     rc.add('Q');
221     rc.addGap();
222     rc.addGap();
223     rc.addGap();
224     assertEquals(rc.getModalCount(), 2);
225   }
226
227   @Test(groups = "Functional")
228   public void testGetResiduesForCount()
229   {
230     ResidueCount rc = new ResidueCount(true);
231     rc.add('c');
232     rc.add('g');
233     rc.add('c');
234     assertEquals(rc.getResiduesForCount(2), "C");
235     assertEquals(rc.getResiduesForCount(1), "G");
236     assertEquals(rc.getResiduesForCount(3), "");
237     assertEquals(rc.getResiduesForCount(0), "");
238     assertEquals(rc.getResiduesForCount(-1), "");
239
240     // modal count is in the 'short overflow' counts
241     rc = new ResidueCount(true);
242     rc.add('c');
243     rc.put('g', Short.MAX_VALUE);
244     rc.add('G');
245     assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "G");
246     assertEquals(rc.getResiduesForCount(1), "C");
247
248     // peptide modal count is in the 'short overflow' counts
249     rc = new ResidueCount(false);
250     rc.add('c');
251     rc.put('p', Short.MAX_VALUE);
252     rc.add('P');
253     assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "P");
254     assertEquals(rc.getResiduesForCount(1), "C");
255   
256     // modal count is in the 'other data' counts
257     rc = new ResidueCount();
258     rc.add('Q');
259     rc.add('{');
260     rc.add('{');
261     assertEquals(rc.getResiduesForCount(1), "Q");
262     assertEquals(rc.getResiduesForCount(2), "{");
263
264     // residues share modal count
265     rc = new ResidueCount();
266     rc.add('G');
267     rc.add('G');
268     rc.add('c');
269     rc.add('C');
270     rc.add('U');
271     assertEquals(rc.getResiduesForCount(1), "U");
272     assertEquals(rc.getResiduesForCount(2), "CG");
273
274     // expected and unexpected symbols share modal count
275     rc = new ResidueCount();
276     rc.add('G');
277     rc.add('t');
278     rc.add('[');
279     rc.add('[');
280     rc.add('t');
281     rc.add('G');
282     rc.add('c');
283     rc.add('C');
284     rc.add('U');
285     assertEquals(rc.getResiduesForCount(1), "U");
286     assertEquals(rc.getResiduesForCount(2), "CGT[");
287   }
288
289   @Test(groups = "Functional")
290   public void testGetSymbolCounts_nucleotide()
291   {
292     ResidueCount rc = new ResidueCount(true);
293     rc.add('g');
294     rc.add('c');
295     rc.add('G');
296     rc.add('J'); // 'otherData'
297     rc.add('g');
298     rc.add('N');
299     rc.put('[', 0); // 'otherdata'
300
301     SymbolCounts sc = rc.getSymbolCounts();
302     Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'J', '[' },
303             sc.symbols);
304     Assert.assertArrayEquals(new int[] { 1, 3, 1, 1, 0 }, sc.values);
305
306     // now with overflow to int counts
307     rc.put('U', Short.MAX_VALUE);
308     rc.add('u');
309     sc = rc.getSymbolCounts();
310     Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'U', 'J', '[' },
311             sc.symbols);
312     Assert.assertArrayEquals(new int[] { 1, 3, 1, 32768, 1, 0 }, sc.values);
313   }
314
315   @Test(groups = "Functional")
316   public void testGetSymbolCounts_peptide()
317   {
318     ResidueCount rc = new ResidueCount(false);
319     rc.add('W');
320     rc.add('q');
321     rc.add('W');
322     rc.add('Z'); // 'otherData'
323     rc.add('w');
324     rc.add('L');
325
326     SymbolCounts sc = rc.getSymbolCounts();
327     Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
328     Assert.assertArrayEquals(new int[] { 1, 1, 3, 1 }, sc.values);
329
330     // now with overflow to int counts
331     rc.put('W', Short.MAX_VALUE);
332     rc.add('W');
333     sc = rc.getSymbolCounts();
334     Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
335     Assert.assertArrayEquals(new int[] { 1, 1, 32768, 1 }, sc.values);
336   }
337
338   @Test(groups = "Functional")
339   public void testToString()
340   {
341     ResidueCount rc = new ResidueCount();
342     rc.add('q');
343     rc.add('c');
344     rc.add('Q');
345     assertEquals(rc.toString(), "[ C:1 Q:2 ]");
346
347     // add 'other data'
348     rc.add('{');
349     assertEquals(rc.toString(), "[ C:1 Q:2 {:1 ]");
350
351     // switch from short to int counting:
352     rc.put('G', Short.MAX_VALUE);
353     rc.add('g');
354     assertEquals(rc.toString(), "[ C:1 G:32768 Q:2 {:1 ]");
355   }
356
357   @Test(groups = "Functional")
358   public void testGetTooltip()
359   {
360     ResidueCount rc = new ResidueCount();
361
362     // no counts!
363     assertEquals(rc.getTooltip(20, 1), "");
364
365     /*
366      * count 7 C, 6 K, 7 Q, 10 P, 9 W, 1 F (total 40)
367      */
368     for (int i = 0; i < 7; i++)
369     {
370       rc.add('c');
371       rc.add('q');
372     }
373     for (int i = 0; i < 10; i++)
374     {
375       rc.add('p');
376     }
377     for (int i = 0; i < 9; i++)
378     {
379       rc.add('W');
380     }
381     for (int i = 0; i < 6; i++)
382     {
383       rc.add('K');
384     }
385     rc.add('F');
386     
387     /*
388      * percentages are rounded (0.5 rounded up)
389      * 10/40 9/40 7/40 6/40 1/40
390      */
391     assertEquals(rc.getTooltip(40, 0),
392             "P 25%; W 23%; C 18%; Q 18%; K 15%; F 3%");
393
394     rc.add('Q');
395     /*
396      * 10/30 9/30 8/30 7/30 6/30 1/30
397      */
398     assertEquals(rc.getTooltip(30, 1),
399             "P 33.3%; W 30.0%; Q 26.7%; C 23.3%; K 20.0%; F 3.3%");
400   }
401
402   @Test(groups = "Functional")
403   public void testPut()
404   {
405     ResidueCount rc = new ResidueCount();
406     rc.put('q', 3);
407     assertEquals(rc.getCount('Q'), 3);
408     rc.put(' ', 4);
409     assertEquals(rc.getGapCount(), 4);
410     rc.put('.', 5);
411     assertEquals(rc.getGapCount(), 5);
412     rc.put('-', 6);
413     assertEquals(rc.getGapCount(), 6);
414
415     rc.put('?', 5);
416     assertEquals(rc.getCount('?'), 5);
417     rc.put('?', 6);
418     rc.put('!', 7);
419     assertEquals(rc.getCount('?'), 6);
420     assertEquals(rc.getCount('!'), 7);
421   }
422 }