Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
ColumnSelectionTest | 44 | 368 | 29 |
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 static org.testng.AssertJUnit.assertEquals; | |
24 | import static org.testng.AssertJUnit.assertFalse; | |
25 | import static org.testng.AssertJUnit.assertTrue; | |
26 | import static org.testng.AssertJUnit.fail; | |
27 | ||
28 | import java.util.Arrays; | |
29 | import java.util.BitSet; | |
30 | import java.util.Collections; | |
31 | import java.util.ConcurrentModificationException; | |
32 | import java.util.Iterator; | |
33 | import java.util.List; | |
34 | ||
35 | import org.testng.annotations.BeforeClass; | |
36 | import org.testng.annotations.Test; | |
37 | ||
38 | import jalview.analysis.AlignmentGenerator; | |
39 | import jalview.gui.JvOptionPane; | |
40 | import jalview.viewmodel.annotationfilter.AnnotationFilterParameter; | |
41 | import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.SearchableAnnotationField; | |
42 | import jalview.viewmodel.annotationfilter.AnnotationFilterParameter.ThresholdType; | |
43 | ||
44 | public class ColumnSelectionTest | |
45 | { | |
46 | ||
47 | 1 | @BeforeClass(alwaysRun = true) |
48 | public void setUpJvOptionPane() | |
49 | { | |
50 | 1 | JvOptionPane.setInteractiveMode(false); |
51 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
52 | } | |
53 | ||
54 | 1 | @Test(groups = { "Functional" }) |
55 | public void testAddElement() | |
56 | { | |
57 | 1 | ColumnSelection cs = new ColumnSelection(); |
58 | 1 | cs.addElement(2); |
59 | 1 | cs.addElement(5); |
60 | 1 | cs.addElement(3); |
61 | 1 | cs.addElement(5); // ignored |
62 | 1 | List<Integer> sel = cs.getSelected(); |
63 | 1 | assertEquals("[2, 5, 3]", sel.toString()); |
64 | } | |
65 | ||
66 | 1 | @Test(groups = { "Functional" }) |
67 | public void testSetElementsFrom() | |
68 | { | |
69 | 1 | ColumnSelection fromcs = new ColumnSelection(); |
70 | 1 | ColumnSelection tocs = new ColumnSelection(); |
71 | 1 | HiddenColumns hidden = new HiddenColumns(); |
72 | ||
73 | 1 | fromcs.addElement(2); |
74 | 1 | fromcs.addElement(3); |
75 | 1 | fromcs.addElement(5); |
76 | ||
77 | 1 | tocs.setElementsFrom(fromcs, hidden); |
78 | 1 | assertTrue(tocs.equals(fromcs)); |
79 | ||
80 | 1 | hidden.hideColumns(4, 6); |
81 | 1 | tocs.setElementsFrom(fromcs, hidden); |
82 | ||
83 | // expect cols 2 and 3 to be selected but not 5 | |
84 | 1 | ColumnSelection expectcs = new ColumnSelection(); |
85 | 1 | expectcs.addElement(2); |
86 | 1 | expectcs.addElement(3); |
87 | 1 | assertTrue(tocs.equals(expectcs)); |
88 | } | |
89 | ||
90 | /** | |
91 | * Test the remove method - in particular to verify that remove(int i) removes | |
92 | * the element whose value is i, _NOT_ the i'th element. | |
93 | */ | |
94 | 1 | @Test(groups = { "Functional" }) |
95 | public void testRemoveElement() | |
96 | { | |
97 | 1 | ColumnSelection cs = new ColumnSelection(); |
98 | 1 | cs.addElement(2); |
99 | 1 | cs.addElement(5); |
100 | ||
101 | // removing elements not in the list has no effect | |
102 | 1 | cs.removeElement(0); |
103 | 1 | cs.removeElement(1); |
104 | 1 | List<Integer> sel = cs.getSelected(); |
105 | 1 | assertEquals(2, sel.size()); |
106 | 1 | assertEquals(Integer.valueOf(2), sel.get(0)); |
107 | 1 | assertEquals(Integer.valueOf(5), sel.get(1)); |
108 | ||
109 | // removing an element in the list removes it | |
110 | 1 | cs.removeElement(2); |
111 | // ...and also from the read-only view | |
112 | 1 | assertEquals(1, sel.size()); |
113 | 1 | sel = cs.getSelected(); |
114 | 1 | assertEquals(1, sel.size()); |
115 | 1 | assertEquals(Integer.valueOf(5), sel.get(0)); |
116 | } | |
117 | ||
118 | /** | |
119 | * Test the method that hides a specified column including any adjacent | |
120 | * selected columns. This is a convenience method for the case where multiple | |
121 | * column regions are selected and then hidden using menu option View | Hide | | |
122 | * Selected Columns. | |
123 | */ | |
124 | 1 | @Test(groups = { "Functional" }) |
125 | public void testHideColumns_withSelection() | |
126 | { | |
127 | // create random alignment | |
128 | 1 | AlignmentGenerator gen = new AlignmentGenerator(false); |
129 | 1 | AlignmentI al = gen.generate(50, 20, 123, 5, 5); |
130 | ||
131 | 1 | ColumnSelection cs = new ColumnSelection(); |
132 | // select columns 4-6 | |
133 | 1 | cs.addElement(4); |
134 | 1 | cs.addElement(5); |
135 | 1 | cs.addElement(6); |
136 | // hide column 5 (and adjacent): | |
137 | 1 | cs.hideSelectedColumns(5, al.getHiddenColumns()); |
138 | // 4,5,6 now hidden: | |
139 | 1 | Iterator<int[]> regions = al.getHiddenColumns().iterator(); |
140 | 1 | assertEquals(1, al.getHiddenColumns().getNumberOfRegions()); |
141 | 1 | assertEquals("[4, 6]", Arrays.toString(regions.next())); |
142 | // none now selected: | |
143 | 1 | assertTrue(cs.getSelected().isEmpty()); |
144 | ||
145 | // repeat, hiding column 4 (5 and 6) | |
146 | 1 | al = gen.generate(50, 20, 123, 5, 5); |
147 | 1 | cs = new ColumnSelection(); |
148 | 1 | cs.addElement(4); |
149 | 1 | cs.addElement(5); |
150 | 1 | cs.addElement(6); |
151 | 1 | cs.hideSelectedColumns(4, al.getHiddenColumns()); |
152 | 1 | regions = al.getHiddenColumns().iterator(); |
153 | 1 | assertEquals(1, al.getHiddenColumns().getNumberOfRegions()); |
154 | 1 | assertEquals("[4, 6]", Arrays.toString(regions.next())); |
155 | 1 | assertTrue(cs.getSelected().isEmpty()); |
156 | ||
157 | // repeat, hiding column (4, 5 and) 6 | |
158 | 1 | al = gen.generate(50, 20, 123, 5, 5); |
159 | 1 | cs = new ColumnSelection(); |
160 | 1 | cs.addElement(4); |
161 | 1 | cs.addElement(5); |
162 | 1 | cs.addElement(6); |
163 | 1 | cs.hideSelectedColumns(6, al.getHiddenColumns()); |
164 | 1 | regions = al.getHiddenColumns().iterator(); |
165 | 1 | assertEquals(1, al.getHiddenColumns().getNumberOfRegions()); |
166 | 1 | assertEquals("[4, 6]", Arrays.toString(regions.next())); |
167 | 1 | assertTrue(cs.getSelected().isEmpty()); |
168 | ||
169 | // repeat, with _only_ adjacent columns selected | |
170 | 1 | al = gen.generate(50, 20, 123, 5, 5); |
171 | 1 | cs = new ColumnSelection(); |
172 | 1 | cs.addElement(4); |
173 | 1 | cs.addElement(6); |
174 | 1 | cs.hideSelectedColumns(5, al.getHiddenColumns()); |
175 | 1 | regions = al.getHiddenColumns().iterator(); |
176 | 1 | assertEquals(1, al.getHiddenColumns().getNumberOfRegions()); |
177 | 1 | assertEquals("[4, 6]", Arrays.toString(regions.next())); |
178 | 1 | assertTrue(cs.getSelected().isEmpty()); |
179 | } | |
180 | ||
181 | /** | |
182 | * Test the method that hides all (possibly disjoint) selected column ranges | |
183 | */ | |
184 | 1 | @Test(groups = { "Functional" }) |
185 | public void testHideSelectedColumns() | |
186 | { | |
187 | // create random alignment | |
188 | 1 | AlignmentGenerator gen = new AlignmentGenerator(false); |
189 | 1 | AlignmentI al = gen.generate(50, 20, 123, 5, 5); |
190 | ||
191 | 1 | ColumnSelection cs = new ColumnSelection(); |
192 | 1 | int[] sel = { 2, 3, 4, 7, 8, 9, 20, 21, 22 }; |
193 | 1 | for (int col : sel) |
194 | { | |
195 | 9 | cs.addElement(col); |
196 | } | |
197 | ||
198 | 1 | HiddenColumns cols = al.getHiddenColumns(); |
199 | 1 | cols.hideColumns(15, 18); |
200 | ||
201 | 1 | cs.hideSelectedColumns(al); |
202 | 1 | assertTrue(cs.getSelected().isEmpty()); |
203 | 1 | Iterator<int[]> regions = cols.iterator(); |
204 | 1 | assertEquals(4, cols.getNumberOfRegions()); |
205 | 1 | assertEquals("[2, 4]", Arrays.toString(regions.next())); |
206 | 1 | assertEquals("[7, 9]", Arrays.toString(regions.next())); |
207 | 1 | assertEquals("[15, 18]", Arrays.toString(regions.next())); |
208 | 1 | assertEquals("[20, 22]", Arrays.toString(regions.next())); |
209 | } | |
210 | ||
211 | /** | |
212 | * Test the method that gets runs of selected columns ordered by column. If | |
213 | * this fails, HideSelectedColumns may also fail | |
214 | */ | |
215 | 1 | @Test(groups = { "Functional" }) |
216 | public void testGetSelectedRanges() | |
217 | { | |
218 | /* | |
219 | * getSelectedRanges returns ordered columns regardless | |
220 | * of the order in which they are added | |
221 | */ | |
222 | 1 | ColumnSelection cs = new ColumnSelection(); |
223 | 1 | int[] sel = { 4, 3, 7, 21, 9, 20, 8, 22, 2 }; |
224 | 1 | for (int col : sel) |
225 | { | |
226 | 9 | cs.addElement(col); |
227 | } | |
228 | 1 | List<int[]> range; |
229 | 1 | range = cs.getSelectedRanges(); |
230 | 1 | assertEquals(3, range.size()); |
231 | 1 | assertEquals("[2, 4]", Arrays.toString(range.get(0))); |
232 | 1 | assertEquals("[7, 9]", Arrays.toString(range.get(1))); |
233 | 1 | assertEquals("[20, 22]", Arrays.toString(range.get(2))); |
234 | 1 | cs.addElement(0); |
235 | 1 | cs.addElement(1); |
236 | 1 | range = cs.getSelectedRanges(); |
237 | 1 | assertEquals(3, range.size()); |
238 | 1 | assertEquals("[0, 4]", Arrays.toString(range.get(0))); |
239 | } | |
240 | ||
241 | 1 | @Test(groups = { "Functional" }) |
242 | public void testInvertColumnSelection() | |
243 | { | |
244 | // create random alignment | |
245 | 1 | AlignmentGenerator gen = new AlignmentGenerator(false); |
246 | 1 | AlignmentI al = gen.generate(50, 20, 123, 5, 5); |
247 | ||
248 | 1 | ColumnSelection cs = new ColumnSelection(); |
249 | 1 | cs.addElement(4); |
250 | 1 | cs.addElement(6); |
251 | 1 | cs.addElement(8); |
252 | ||
253 | 1 | HiddenColumns cols = al.getHiddenColumns(); |
254 | 1 | cols.hideColumns(3, 3); |
255 | 1 | cols.hideColumns(6, 6); |
256 | ||
257 | // invert selection from start (inclusive) to end (exclusive) | |
258 | 1 | cs.invertColumnSelection(2, 9, al); |
259 | 1 | assertEquals("[2, 5, 7]", cs.getSelected().toString()); |
260 | ||
261 | 1 | cs.invertColumnSelection(1, 9, al); |
262 | 1 | assertEquals("[1, 4, 8]", cs.getSelected().toString()); |
263 | } | |
264 | ||
265 | 1 | @Test(groups = { "Functional" }) |
266 | public void testMaxColumnSelection() | |
267 | { | |
268 | 1 | ColumnSelection cs = new ColumnSelection(); |
269 | 1 | cs.addElement(0); |
270 | 1 | cs.addElement(513); |
271 | 1 | cs.addElement(1); |
272 | 1 | assertEquals(513, cs.getMax()); |
273 | 1 | cs.removeElement(513); |
274 | 1 | assertEquals(1, cs.getMax()); |
275 | 1 | cs.removeElement(1); |
276 | 1 | assertEquals(0, cs.getMax()); |
277 | 1 | cs.addElement(512); |
278 | 1 | cs.addElement(513); |
279 | 1 | assertEquals(513, cs.getMax()); |
280 | ||
281 | } | |
282 | ||
283 | 1 | @Test(groups = { "Functional" }) |
284 | public void testMinColumnSelection() | |
285 | { | |
286 | 1 | ColumnSelection cs = new ColumnSelection(); |
287 | 1 | cs.addElement(0); |
288 | 1 | cs.addElement(513); |
289 | 1 | cs.addElement(1); |
290 | 1 | assertEquals(0, cs.getMin()); |
291 | 1 | cs.removeElement(0); |
292 | 1 | assertEquals(1, cs.getMin()); |
293 | 1 | cs.addElement(0); |
294 | 1 | assertEquals(0, cs.getMin()); |
295 | } | |
296 | ||
297 | 1 | @Test(groups = { "Functional" }) |
298 | public void testEquals() | |
299 | { | |
300 | 1 | ColumnSelection cs = new ColumnSelection(); |
301 | 1 | cs.addElement(0); |
302 | 1 | cs.addElement(513); |
303 | 1 | cs.addElement(1); |
304 | ||
305 | // same selections added in a different order | |
306 | 1 | ColumnSelection cs2 = new ColumnSelection(); |
307 | 1 | cs2.addElement(1); |
308 | 1 | cs2.addElement(513); |
309 | 1 | cs2.addElement(0); |
310 | ||
311 | 1 | assertTrue(cs.equals(cs2)); |
312 | 1 | assertTrue(cs.equals(cs)); |
313 | 1 | assertTrue(cs2.equals(cs)); |
314 | 1 | assertTrue(cs2.equals(cs2)); |
315 | ||
316 | 1 | cs2.addElement(12); |
317 | 1 | assertFalse(cs.equals(cs2)); |
318 | 1 | assertFalse(cs2.equals(cs)); |
319 | ||
320 | 1 | cs2.removeElement(12); |
321 | 1 | assertTrue(cs.equals(cs2)); |
322 | } | |
323 | ||
324 | /* | |
325 | cs2.hideSelectedColumns(88); | |
326 | assertFalse(cs.equals(cs2)); | |
327 | /* | |
328 | * unhiding a column adds it to selection! | |
329 | */ | |
330 | /* cs2.revealHiddenColumns(88); | |
331 | assertFalse(cs.equals(cs2)); | |
332 | cs.addElement(88); | |
333 | assertTrue(cs.equals(cs2)); | |
334 | */ | |
335 | ||
336 | /** | |
337 | * Test the method that returns selected columns, in the order in which they | |
338 | * were added | |
339 | */ | |
340 | 1 | @Test(groups = { "Functional" }) |
341 | public void testGetSelected() | |
342 | { | |
343 | 1 | ColumnSelection cs = new ColumnSelection(); |
344 | 1 | int[] sel = { 4, 3, 7, 21 }; |
345 | 1 | for (int col : sel) |
346 | { | |
347 | 4 | cs.addElement(col); |
348 | } | |
349 | ||
350 | 1 | List<Integer> selected = cs.getSelected(); |
351 | 1 | assertEquals(4, selected.size()); |
352 | 1 | assertEquals("[4, 3, 7, 21]", selected.toString()); |
353 | ||
354 | /* | |
355 | * getSelected returns a read-only view of the list | |
356 | * verify the view follows any changes in it | |
357 | */ | |
358 | 1 | cs.removeElement(7); |
359 | 1 | cs.addElement(1); |
360 | 1 | cs.removeElement(4); |
361 | 1 | assertEquals("[3, 21, 1]", selected.toString()); |
362 | } | |
363 | ||
364 | /** | |
365 | * Test to verify that the list returned by getSelection cannot be modified | |
366 | */ | |
367 | 1 | @Test(groups = { "Functional" }) |
368 | public void testGetSelected_isReadOnly() | |
369 | { | |
370 | 1 | ColumnSelection cs = new ColumnSelection(); |
371 | 1 | cs.addElement(3); |
372 | ||
373 | 1 | List<Integer> selected = cs.getSelected(); |
374 | 1 | try |
375 | { | |
376 | 1 | selected.clear(); |
377 | 0 | fail("expected exception"); |
378 | } catch (UnsupportedOperationException e) | |
379 | { | |
380 | // expected | |
381 | } | |
382 | 1 | try |
383 | { | |
384 | 1 | selected.add(1); |
385 | 0 | fail("expected exception"); |
386 | } catch (UnsupportedOperationException e) | |
387 | { | |
388 | // expected | |
389 | } | |
390 | 1 | try |
391 | { | |
392 | 1 | selected.remove(3); |
393 | 0 | fail("expected exception"); |
394 | } catch (UnsupportedOperationException e) | |
395 | { | |
396 | // expected | |
397 | } | |
398 | 1 | try |
399 | { | |
400 | 1 | Collections.sort(selected); |
401 | 0 | fail("expected exception"); |
402 | } catch (UnsupportedOperationException e) | |
403 | { | |
404 | // expected | |
405 | } | |
406 | } | |
407 | ||
408 | /** | |
409 | * Test that demonstrates a ConcurrentModificationException is thrown if you | |
410 | * change the selection while iterating over it | |
411 | */ | |
412 | 1 | @Test( |
413 | groups = "Functional", | |
414 | expectedExceptions = | |
415 | { ConcurrentModificationException.class }) | |
416 | public void testGetSelected_concurrentModification() | |
417 | { | |
418 | 1 | ColumnSelection cs = new ColumnSelection(); |
419 | 1 | cs.addElement(0); |
420 | 1 | cs.addElement(1); |
421 | 1 | cs.addElement(2); |
422 | ||
423 | /* | |
424 | * simulate changing the list under us (e.g. in a separate | |
425 | * thread) while iterating over it -> ConcurrentModificationException | |
426 | */ | |
427 | 1 | List<Integer> selected = cs.getSelected(); |
428 | 1 | for (Integer col : selected) |
429 | { | |
430 | 1 | if (col.intValue() == 0) |
431 | { | |
432 | 1 | cs.removeElement(1); |
433 | } | |
434 | } | |
435 | } | |
436 | ||
437 | 1 | @Test(groups = "Functional") |
438 | public void testMarkColumns() | |
439 | { | |
440 | 1 | ColumnSelection cs = new ColumnSelection(); |
441 | 1 | cs.addElement(5); // this will be cleared |
442 | 1 | BitSet toMark = new BitSet(); |
443 | 1 | toMark.set(1); |
444 | 1 | toMark.set(3); |
445 | 1 | toMark.set(6); |
446 | 1 | toMark.set(9); |
447 | ||
448 | 1 | assertTrue(cs.markColumns(toMark, 3, 8, false, false, false)); |
449 | 1 | List<Integer> selected = cs.getSelected(); |
450 | 1 | assertEquals(2, selected.size()); |
451 | 1 | assertTrue(selected.contains(3)); |
452 | 1 | assertTrue(selected.contains(6)); |
453 | } | |
454 | ||
455 | 1 | @Test(groups = "Functional") |
456 | public void testMarkColumns_extend() | |
457 | { | |
458 | 1 | ColumnSelection cs = new ColumnSelection(); |
459 | 1 | cs.addElement(1); |
460 | 1 | cs.addElement(5); |
461 | 1 | BitSet toMark = new BitSet(); |
462 | 1 | toMark.set(1); |
463 | 1 | toMark.set(3); |
464 | 1 | toMark.set(6); |
465 | 1 | toMark.set(9); |
466 | ||
467 | /* | |
468 | * extending selection of {3, 6} should leave {1, 3, 5, 6} selected | |
469 | */ | |
470 | 1 | assertTrue(cs.markColumns(toMark, 3, 8, false, true, false)); |
471 | 1 | List<Integer> selected = cs.getSelected(); |
472 | 1 | assertEquals(4, selected.size()); |
473 | 1 | assertTrue(selected.contains(1)); |
474 | 1 | assertTrue(selected.contains(3)); |
475 | 1 | assertTrue(selected.contains(5)); |
476 | 1 | assertTrue(selected.contains(6)); |
477 | } | |
478 | ||
479 | 1 | @Test(groups = "Functional") |
480 | public void testMarkColumns_invert() | |
481 | { | |
482 | 1 | ColumnSelection cs = new ColumnSelection(); |
483 | 1 | cs.addElement(5); // this will be cleared |
484 | 1 | BitSet toMark = new BitSet(); |
485 | 1 | toMark.set(1); |
486 | 1 | toMark.set(3); |
487 | 1 | toMark.set(6); |
488 | 1 | toMark.set(9); |
489 | ||
490 | /* | |
491 | * inverted selection of {3, 6} should select {4, 5, 7, 8} | |
492 | */ | |
493 | 1 | assertTrue(cs.markColumns(toMark, 3, 8, true, false, false)); |
494 | 1 | List<Integer> selected = cs.getSelected(); |
495 | 1 | assertEquals(4, selected.size()); |
496 | 1 | assertTrue(selected.contains(4)); |
497 | 1 | assertTrue(selected.contains(5)); |
498 | 1 | assertTrue(selected.contains(7)); |
499 | 1 | assertTrue(selected.contains(8)); |
500 | } | |
501 | ||
502 | 1 | @Test(groups = "Functional") |
503 | public void testMarkColumns_toggle() | |
504 | { | |
505 | 1 | ColumnSelection cs = new ColumnSelection(); |
506 | 1 | cs.addElement(1); // outside change range |
507 | 1 | cs.addElement(3); |
508 | 1 | cs.addElement(4); |
509 | 1 | cs.addElement(10); // outside change range |
510 | 1 | BitSet toMark = new BitSet(); |
511 | 1 | toMark.set(1); |
512 | 1 | toMark.set(3); |
513 | 1 | toMark.set(6); |
514 | 1 | toMark.set(9); |
515 | ||
516 | /* | |
517 | * toggling state of {3, 6} should leave {1, 4, 6, 10} selected | |
518 | */ | |
519 | 1 | assertTrue(cs.markColumns(toMark, 3, 8, false, false, true)); |
520 | 1 | List<Integer> selected = cs.getSelected(); |
521 | 1 | assertEquals(4, selected.size()); |
522 | 1 | assertTrue(selected.contains(1)); |
523 | 1 | assertTrue(selected.contains(4)); |
524 | 1 | assertTrue(selected.contains(6)); |
525 | 1 | assertTrue(selected.contains(10)); |
526 | } | |
527 | ||
528 | 1 | @Test(groups = "Functional") |
529 | public void testCopyConstructor() | |
530 | { | |
531 | 1 | ColumnSelection cs = new ColumnSelection(); |
532 | 1 | cs.addElement(3); |
533 | 1 | cs.addElement(1); |
534 | ||
535 | 1 | ColumnSelection cs2 = new ColumnSelection(cs); |
536 | 1 | assertTrue(cs2.hasSelectedColumns()); |
537 | ||
538 | // order of column selection is preserved | |
539 | 1 | assertEquals("[3, 1]", cs2.getSelected().toString()); |
540 | } | |
541 | ||
542 | 1 | @Test(groups = { "Functional" }) |
543 | public void testStretchGroup_expand() | |
544 | { | |
545 | /* | |
546 | * test that emulates clicking column 4 (selected) | |
547 | * and dragging right to column 5 (all base 0) | |
548 | */ | |
549 | 1 | ColumnSelection cs = new ColumnSelection(); |
550 | 1 | cs.addElement(4); |
551 | 1 | SequenceGroup sg = new SequenceGroup(); |
552 | 1 | sg.setStartRes(4); |
553 | 1 | sg.setEndRes(4); |
554 | 1 | cs.stretchGroup(5, sg, 4, 4); |
555 | 1 | assertEquals(cs.getSelected().size(), 2); |
556 | 1 | assertTrue(cs.contains(4)); |
557 | 1 | assertTrue(cs.contains(5)); |
558 | 1 | assertEquals(sg.getStartRes(), 4); |
559 | 1 | assertEquals(sg.getEndRes(), 5); |
560 | ||
561 | /* | |
562 | * emulate drag right with columns 10-20 already selected | |
563 | */ | |
564 | 1 | cs.clear(); |
565 | 12 | for (int i = 10; i <= 20; i++) |
566 | { | |
567 | 11 | cs.addElement(i); |
568 | } | |
569 | 1 | assertEquals(cs.getSelected().size(), 11); |
570 | 1 | sg = new SequenceGroup(); |
571 | 1 | sg.setStartRes(10); |
572 | 1 | sg.setEndRes(20); |
573 | 1 | cs.stretchGroup(21, sg, 10, 20); |
574 | 1 | assertEquals(cs.getSelected().size(), 12); |
575 | 1 | assertTrue(cs.contains(10)); |
576 | 1 | assertTrue(cs.contains(21)); |
577 | 1 | assertEquals(sg.getStartRes(), 10); |
578 | 1 | assertEquals(sg.getEndRes(), 21); |
579 | } | |
580 | ||
581 | 1 | @Test(groups = { "Functional" }) |
582 | public void testStretchGroup_shrink() | |
583 | { | |
584 | /* | |
585 | * emulate drag left to 19 with columns 10-20 already selected | |
586 | */ | |
587 | 1 | ColumnSelection cs = new ColumnSelection(); |
588 | 12 | for (int i = 10; i <= 20; i++) |
589 | { | |
590 | 11 | cs.addElement(i); |
591 | } | |
592 | 1 | assertEquals(cs.getSelected().size(), 11); |
593 | 1 | SequenceGroup sg = new SequenceGroup(); |
594 | 1 | sg.setStartRes(10); |
595 | 1 | sg.setEndRes(20); |
596 | 1 | cs.stretchGroup(19, sg, 10, 20); |
597 | 1 | assertEquals(cs.getSelected().size(), 10); |
598 | 1 | assertTrue(cs.contains(10)); |
599 | 1 | assertTrue(cs.contains(19)); |
600 | 1 | assertFalse(cs.contains(20)); |
601 | 1 | assertEquals(sg.getStartRes(), 10); |
602 | 1 | assertEquals(sg.getEndRes(), 19); |
603 | } | |
604 | ||
605 | 1 | @Test(groups = { "Functional" }) |
606 | public void testFilterAnnotations() | |
607 | { | |
608 | 1 | ColumnSelection cs = new ColumnSelection(); |
609 | 1 | AlignmentAnnotation alann = new AlignmentAnnotation("dummy", |
610 | "dummyDesc", null); | |
611 | ||
612 | /* | |
613 | * filter with no conditions clears the selection | |
614 | */ | |
615 | 1 | Annotation[] anns = new Annotation[] { null }; |
616 | 1 | AnnotationFilterParameter filter = new AnnotationFilterParameter(); |
617 | 1 | cs.addElement(3); |
618 | 1 | alann.annotations = anns; |
619 | 1 | int added = cs.filterAnnotations(alann, filter); |
620 | 1 | assertEquals(0, added); |
621 | 1 | assertTrue(cs.isEmpty()); |
622 | ||
623 | /* | |
624 | * select on description (regex) | |
625 | */ | |
626 | 1 | filter.setRegexString("w.rld"); |
627 | 1 | filter.addRegexSearchField(SearchableAnnotationField.DESCRIPTION); |
628 | 1 | Annotation helix = new Annotation("(", "hello", '<', 2f); |
629 | 1 | Annotation sheet = new Annotation("(", "world", '<', 2f); |
630 | 1 | alann.annotations = new Annotation[] { null, helix, sheet }; |
631 | 1 | added = cs.filterAnnotations(alann, filter); |
632 | 1 | assertEquals(1, added); |
633 | 1 | assertTrue(cs.contains(2)); |
634 | ||
635 | /* | |
636 | * select on label (invalid regex, exact match) | |
637 | */ | |
638 | 1 | filter = new AnnotationFilterParameter(); |
639 | 1 | filter.setRegexString("("); |
640 | 1 | filter.addRegexSearchField(SearchableAnnotationField.DISPLAY_STRING); |
641 | 1 | alann.annotations = new Annotation[] { null, helix, sheet }; |
642 | 1 | added = cs.filterAnnotations(alann, filter); |
643 | 1 | assertEquals(2, added); |
644 | 1 | assertTrue(cs.contains(1)); |
645 | 1 | assertTrue(cs.contains(2)); |
646 | ||
647 | /* | |
648 | * select Helix (secondary structure symbol H) | |
649 | */ | |
650 | 1 | filter = new AnnotationFilterParameter(); |
651 | 1 | filter.setFilterAlphaHelix(true); |
652 | 1 | helix = new Annotation("x", "desc", 'H', 0f); |
653 | 1 | sheet = new Annotation("x", "desc", 'E', 1f); |
654 | 1 | Annotation turn = new Annotation("x", "desc", 'S', 2f); |
655 | 1 | Annotation ann4 = new Annotation("x", "desc", 'Y', 3f); |
656 | 1 | alann.annotations = new Annotation[] { null, helix, sheet, turn, ann4 }; |
657 | 1 | added = cs.filterAnnotations(alann, filter); |
658 | 1 | assertEquals(1, added); |
659 | 1 | assertTrue(cs.contains(1)); |
660 | ||
661 | /* | |
662 | * select Helix and Sheet (E) | |
663 | */ | |
664 | 1 | filter.setFilterBetaSheet(true); |
665 | 1 | alann.annotations = new Annotation[] { null, helix, sheet, turn, ann4 }; |
666 | 1 | added = cs.filterAnnotations(alann, filter); |
667 | 1 | assertEquals(2, added); |
668 | 1 | assertTrue(cs.contains(1)); |
669 | 1 | assertTrue(cs.contains(2)); |
670 | ||
671 | /* | |
672 | * select Sheet and Turn (S) | |
673 | */ | |
674 | 1 | filter.setFilterAlphaHelix(false); |
675 | 1 | filter.setFilterTurn(true); |
676 | 1 | alann.annotations = new Annotation[] { null, helix, sheet, turn, ann4 }; |
677 | 1 | added = cs.filterAnnotations(alann, filter); |
678 | 1 | assertEquals(2, added); |
679 | 1 | assertTrue(cs.contains(2)); |
680 | 1 | assertTrue(cs.contains(3)); |
681 | ||
682 | /* | |
683 | * select value < 2f (ann1, ann2) | |
684 | */ | |
685 | 1 | filter = new AnnotationFilterParameter(); |
686 | 1 | filter.setThresholdType(ThresholdType.BELOW_THRESHOLD); |
687 | 1 | filter.setThresholdValue(2f); |
688 | 1 | alann.annotations = new Annotation[] { null, helix, sheet, turn, ann4 }; |
689 | 1 | added = cs.filterAnnotations(alann, filter); |
690 | 1 | assertEquals(2, added); |
691 | 1 | assertTrue(cs.contains(1)); |
692 | 1 | assertTrue(cs.contains(2)); |
693 | ||
694 | /* | |
695 | * select value > 2f (ann4 only) | |
696 | */ | |
697 | 1 | filter.setThresholdType(ThresholdType.ABOVE_THRESHOLD); |
698 | 1 | alann.annotations = new Annotation[] { null, helix, sheet, turn, ann4 }; |
699 | 1 | added = cs.filterAnnotations(alann, filter); |
700 | 1 | assertEquals(1, added); |
701 | 1 | assertTrue(cs.contains(4)); |
702 | ||
703 | /* | |
704 | * select >2f or Helix | |
705 | */ | |
706 | 1 | filter.setFilterAlphaHelix(true); |
707 | 1 | alann.annotations = new Annotation[] { null, helix, sheet, turn, ann4 }; |
708 | 1 | added = cs.filterAnnotations(alann, filter); |
709 | 1 | assertEquals(2, added); |
710 | 1 | assertTrue(cs.contains(1)); |
711 | 1 | assertTrue(cs.contains(4)); |
712 | ||
713 | /* | |
714 | * select < 1f or Helix; one annotation matches both | |
715 | * return value should only count it once | |
716 | */ | |
717 | 1 | filter.setThresholdType(ThresholdType.BELOW_THRESHOLD); |
718 | 1 | filter.setThresholdValue(1f); |
719 | 1 | alann.annotations = new Annotation[] { null, helix, sheet, turn, ann4 }; |
720 | 1 | added = cs.filterAnnotations(alann, filter); |
721 | 1 | assertEquals(1, added); |
722 | 1 | assertTrue(cs.contains(1)); |
723 | } | |
724 | } |