2 * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3 * Copyright (C) $$Year-Rel$$ The Jalview Authors
5 * This file is part of Jalview.
7 * Jalview is free software: you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation, either version 3
10 * of the License, or (at your option) any later version.
12 * Jalview is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty
14 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15 * PURPOSE. See the GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public License
18 * along with Jalview. If not, see <http://www.gnu.org/licenses/>.
19 * The Jalview Authors are detailed in the 'AUTHORS' file.
21 package jalview.datamodel;
23 import java.util.Locale;
25 import static org.testng.Assert.assertEquals;
26 import static org.testng.Assert.assertFalse;
27 import static org.testng.Assert.assertTrue;
29 import jalview.datamodel.ResidueCount.SymbolCounts;
30 import jalview.gui.JvOptionPane;
32 import org.junit.Assert;
33 import org.testng.annotations.BeforeClass;
34 import org.testng.annotations.Test;
36 public class ResidueCountTest
39 @BeforeClass(alwaysRun = true)
40 public void setUpJvOptionPane()
42 JvOptionPane.setInteractiveMode(false);
43 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
47 * Test a mix of add and put for nucleotide counting
49 @Test(groups = "Functional")
50 public void test_countNucleotide()
52 ResidueCount rc = new ResidueCount(true);
53 assertEquals(rc.getCount('A'), 0);
54 assertEquals(rc.getGapCount(), 0);
56 assertEquals(rc.add('A'), 1);
57 assertEquals(rc.add('a'), 2);
60 assertEquals(rc.add('G'), 4);
62 assertEquals(rc.add('c'), 1);
64 assertEquals(rc.add('N'), 1);
66 assertEquals(rc.getCount('a'), 2);
67 assertEquals(rc.getCount('A'), 2);
68 assertEquals(rc.getCount('G'), 4);
69 assertEquals(rc.getCount('c'), 4);
70 assertEquals(rc.getCount('T'), 0); // never seen
71 assertEquals(rc.getCount('N'), 1);
72 assertEquals(rc.getCount('?'), 0);
73 assertEquals(rc.getCount('-'), 0);
75 assertFalse(rc.isCountingInts());
76 assertFalse(rc.isUsingOtherData());
80 * Test adding to gap count (either using addGap or add)
82 @Test(groups = "Functional")
83 public void testAddGap()
85 ResidueCount rc = new ResidueCount(true);
91 assertEquals(rc.getGapCount(), 4);
92 assertEquals(rc.getCount(' '), 4);
93 assertEquals(rc.getCount('-'), 4);
94 assertEquals(rc.getCount('.'), 4);
95 assertFalse(rc.isUsingOtherData());
96 assertFalse(rc.isCountingInts());
98 rc.set(ResidueCount.GAP_COUNT, Short.MAX_VALUE - 2);
99 assertEquals(rc.getGapCount(), Short.MAX_VALUE - 2);
100 assertFalse(rc.isCountingInts());
102 assertEquals(rc.getGapCount(), Short.MAX_VALUE - 1);
103 assertFalse(rc.isCountingInts());
105 assertEquals(rc.getGapCount(), Short.MAX_VALUE);
107 assertTrue(rc.isCountingInts());
108 assertEquals(rc.getGapCount(), Short.MAX_VALUE + 1);
111 @Test(groups = "Functional")
112 public void testOverflow()
117 ResidueCount rc = new ResidueCount(true);
119 rc.put('A', Short.MAX_VALUE - 1);
120 assertFalse(rc.isCountingInts());
122 assertFalse(rc.isCountingInts());
124 assertTrue(rc.isCountingInts());
125 assertEquals(rc.getCount('a'), Short.MAX_VALUE + 1);
127 assertTrue(rc.isCountingInts());
128 assertEquals(rc.getCount('a'), Short.MAX_VALUE + 2);
129 assertEquals(rc.getGapCount(), 1);
131 assertEquals(rc.getGapCount(), 2);
136 rc = new ResidueCount(true);
137 rc.put('G', Short.MAX_VALUE + 1);
138 assertTrue(rc.isCountingInts());
139 assertEquals(rc.getCount('g'), Short.MAX_VALUE + 1);
141 assertTrue(rc.isCountingInts());
142 assertEquals(rc.getCount('g'), 1);
147 rc = new ResidueCount(true);
148 rc.put('G', Short.MIN_VALUE - 1);
149 assertTrue(rc.isCountingInts());
150 assertEquals(rc.getCount('g'), Short.MIN_VALUE - 1);
154 * Test a mix of add and put for peptide counting
156 @Test(groups = "Functional")
157 public void test_countPeptide()
159 ResidueCount rc = new ResidueCount(false);
169 assertEquals(rc.getCount('q'), 5);
170 assertEquals(rc.getCount('X'), 2);
171 assertEquals(rc.getCount('W'), 7);
172 assertEquals(rc.getCount('m'), 13);
173 assertEquals(rc.getCount('G'), 0);
174 assertEquals(rc.getCount('-'), 0);
176 assertFalse(rc.isCountingInts());
177 assertFalse(rc.isUsingOtherData());
180 @Test(groups = "Functional")
181 public void test_unexpectedPeptide()
183 ResidueCount rc = new ResidueCount(false);
184 // expected characters (upper or lower case):
185 String aas = "ACDEFGHIKLMNPQRSTVWXY";
186 String lower = aas.toLowerCase(Locale.ROOT);
187 for (int i = 0; i < aas.length(); i++)
189 rc.put(aas.charAt(i), i);
190 rc.add(lower.charAt(i));
192 for (int i = 0; i < aas.length(); i++)
194 assertEquals(rc.getCount(aas.charAt(i)), i + 1);
196 assertFalse(rc.isUsingOtherData());
199 assertTrue(rc.isUsingOtherData());
200 assertEquals(rc.getCount('J'), 4);
202 assertEquals(rc.getCount('J'), 5);
205 @Test(groups = "Functional")
206 public void test_unexpectedNucleotide()
208 ResidueCount rc = new ResidueCount(true);
209 // expected characters (upper or lower case):
210 String nucs = "ACGTUN";
211 String lower = nucs.toLowerCase(Locale.ROOT);
212 for (int i = 0; i < nucs.length(); i++)
214 rc.put(nucs.charAt(i), i);
215 rc.add(lower.charAt(i));
217 for (int i = 0; i < nucs.length(); i++)
219 assertEquals(rc.getCount(nucs.charAt(i)), i + 1);
221 assertFalse(rc.isUsingOtherData());
224 assertTrue(rc.isUsingOtherData());
227 @Test(groups = "Functional")
228 public void testGetModalCount()
230 ResidueCount rc = new ResidueCount(true);
234 assertEquals(rc.getModalCount(), 2);
236 // modal count is in the 'short overflow' counts
237 rc = new ResidueCount();
239 rc.put('g', Short.MAX_VALUE);
241 assertEquals(rc.getModalCount(), Short.MAX_VALUE + 1);
243 // modal count is in the 'other data' counts
244 rc = new ResidueCount(false);
248 assertEquals(rc.getModalCount(), 2);
250 // verify modal count excludes gap
251 rc = new ResidueCount();
258 assertEquals(rc.getModalCount(), 2);
261 @Test(groups = "Functional")
262 public void testGetResiduesForCount()
264 ResidueCount rc = new ResidueCount(true);
268 assertEquals(rc.getResiduesForCount(2), "C");
269 assertEquals(rc.getResiduesForCount(1), "G");
270 assertEquals(rc.getResiduesForCount(3), "");
271 assertEquals(rc.getResiduesForCount(0), "");
272 assertEquals(rc.getResiduesForCount(-1), "");
274 // modal count is in the 'short overflow' counts
275 rc = new ResidueCount(true);
277 rc.put('g', Short.MAX_VALUE);
279 assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "G");
280 assertEquals(rc.getResiduesForCount(1), "C");
282 // peptide modal count is in the 'short overflow' counts
283 rc = new ResidueCount(false);
285 rc.put('p', Short.MAX_VALUE);
287 assertEquals(rc.getResiduesForCount(Short.MAX_VALUE + 1), "P");
288 assertEquals(rc.getResiduesForCount(1), "C");
290 // modal count is in the 'other data' counts
291 rc = new ResidueCount();
295 assertEquals(rc.getResiduesForCount(1), "Q");
296 assertEquals(rc.getResiduesForCount(2), "{");
298 // residues share modal count
299 rc = new ResidueCount();
305 assertEquals(rc.getResiduesForCount(1), "U");
306 assertEquals(rc.getResiduesForCount(2), "CG");
308 // expected and unexpected symbols share modal count
309 rc = new ResidueCount();
319 assertEquals(rc.getResiduesForCount(1), "U");
320 assertEquals(rc.getResiduesForCount(2), "CGT[");
323 @Test(groups = "Functional")
324 public void testGetSymbolCounts_nucleotide()
326 ResidueCount rc = new ResidueCount(true);
330 rc.add('J'); // 'otherData'
333 rc.put('[', 0); // 'otherdata'
335 SymbolCounts sc = rc.getSymbolCounts();
336 Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'J', '[' },
338 Assert.assertArrayEquals(new int[] { 1, 3, 1, 1, 0 }, sc.values);
340 // now with overflow to int counts
341 rc.put('U', Short.MAX_VALUE);
343 sc = rc.getSymbolCounts();
344 Assert.assertArrayEquals(new char[] { 'C', 'G', 'N', 'U', 'J', '[' },
346 Assert.assertArrayEquals(new int[] { 1, 3, 1, 32768, 1, 0 }, sc.values);
349 @Test(groups = "Functional")
350 public void testGetSymbolCounts_peptide()
352 ResidueCount rc = new ResidueCount(false);
356 rc.add('Z'); // 'otherData'
360 SymbolCounts sc = rc.getSymbolCounts();
361 Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
362 Assert.assertArrayEquals(new int[] { 1, 1, 3, 1 }, sc.values);
364 // now with overflow to int counts
365 rc.put('W', Short.MAX_VALUE);
367 sc = rc.getSymbolCounts();
368 Assert.assertArrayEquals(new char[] { 'L', 'Q', 'W', 'Z' }, sc.symbols);
369 Assert.assertArrayEquals(new int[] { 1, 1, 32768, 1 }, sc.values);
372 @Test(groups = "Functional")
373 public void testToString()
375 ResidueCount rc = new ResidueCount();
379 assertEquals(rc.toString(), "[ C:1 Q:2 ]");
383 assertEquals(rc.toString(), "[ C:1 Q:2 {:1 ]");
385 // switch from short to int counting:
386 rc.put('G', Short.MAX_VALUE);
388 assertEquals(rc.toString(), "[ C:1 G:32768 Q:2 {:1 ]");
391 @Test(groups = "Functional")
392 public void testGetTooltip()
394 ResidueCount rc = new ResidueCount();
397 assertEquals(rc.getTooltip(20, 1), "");
400 * count 7 C, 6 K, 7 Q, 10 P, 9 W, 1 F (total 40)
402 for (int i = 0; i < 7; i++)
407 for (int i = 0; i < 10; i++)
411 for (int i = 0; i < 9; i++)
415 for (int i = 0; i < 6; i++)
422 * percentages are rounded (0.5 rounded up)
423 * 10/40 9/40 7/40 6/40 1/40
425 assertEquals(rc.getTooltip(40, 0),
426 "P 25%; W 23%; C 18%; Q 18%; K 15%; F 3%");
430 * 10/30 9/30 8/30 7/30 6/30 1/30
432 assertEquals(rc.getTooltip(30, 1),
433 "P 33.3%; W 30.0%; Q 26.7%; C 23.3%; K 20.0%; F 3.3%");
436 @Test(groups = "Functional")
437 public void testPut()
439 ResidueCount rc = new ResidueCount();
441 assertEquals(rc.getCount('Q'), 3);
443 assertEquals(rc.getGapCount(), 4);
445 assertEquals(rc.getGapCount(), 5);
447 assertEquals(rc.getGapCount(), 6);
450 assertEquals(rc.getCount('?'), 5);
453 assertEquals(rc.getCount('?'), 6);
454 assertEquals(rc.getCount('!'), 7);