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