Clover icon

Coverage Report

  1. Project Clover database Thu Aug 13 2020 12:04:21 BST
  2. Package jalview.datamodel.features

File FeatureStoreTest.java

 

Code metrics

0
498
20
1
884
637
20
0.04
24.9
20
1

Classes

Class Line # Actions
FeatureStoreTest 16 498 20
1.0100%
 

Contributing tests

This file is covered by 19 tests. .

Source view

1    package jalview.datamodel.features;
2   
3    import static org.testng.Assert.assertEquals;
4    import static org.testng.Assert.assertFalse;
5    import static org.testng.Assert.assertSame;
6    import static org.testng.Assert.assertTrue;
7   
8    import jalview.datamodel.SequenceFeature;
9   
10    import java.util.ArrayList;
11    import java.util.List;
12    import java.util.Set;
13   
14    import org.testng.annotations.Test;
15   
 
16    public class FeatureStoreTest
17    {
18   
 
19  1 toggle @Test(groups = "Functional")
20    public void testFindFeatures_nonNested()
21    {
22  1 FeatureStore fs = new FeatureStore();
23  1 fs.addFeature(new SequenceFeature("", "", 10, 20, Float.NaN,
24    null));
25    // same range different description
26  1 fs.addFeature(new SequenceFeature("", "desc", 10, 20, Float.NaN, null));
27  1 fs.addFeature(new SequenceFeature("", "", 15, 25, Float.NaN, null));
28  1 fs.addFeature(new SequenceFeature("", "", 20, 35, Float.NaN, null));
29   
30  1 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
31  1 assertTrue(overlaps.isEmpty());
32   
33  1 overlaps = fs.findOverlappingFeatures(8, 10);
34  1 assertEquals(overlaps.size(), 2);
35  1 assertEquals(overlaps.get(0).getEnd(), 20);
36  1 assertEquals(overlaps.get(1).getEnd(), 20);
37   
38  1 overlaps = fs.findOverlappingFeatures(12, 16);
39  1 assertEquals(overlaps.size(), 3);
40  1 assertEquals(overlaps.get(0).getEnd(), 20);
41  1 assertEquals(overlaps.get(1).getEnd(), 20);
42  1 assertEquals(overlaps.get(2).getEnd(), 25);
43   
44  1 overlaps = fs.findOverlappingFeatures(33, 33);
45  1 assertEquals(overlaps.size(), 1);
46  1 assertEquals(overlaps.get(0).getEnd(), 35);
47    }
48   
 
49  1 toggle @Test(groups = "Functional")
50    public void testFindFeatures_nested()
51    {
52  1 FeatureStore fs = new FeatureStore();
53  1 SequenceFeature sf1 = addFeature(fs, 10, 50);
54  1 SequenceFeature sf2 = addFeature(fs, 10, 40);
55  1 SequenceFeature sf3 = addFeature(fs, 20, 30);
56    // fudge feature at same location but different group (so is added)
57  1 SequenceFeature sf4 = new SequenceFeature("", "", 20, 30, Float.NaN,
58    "different group");
59  1 fs.addFeature(sf4);
60  1 SequenceFeature sf5 = addFeature(fs, 35, 36);
61   
62  1 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
63  1 assertTrue(overlaps.isEmpty());
64   
65  1 overlaps = fs.findOverlappingFeatures(10, 15);
66  1 assertEquals(overlaps.size(), 2);
67  1 assertTrue(overlaps.contains(sf1));
68  1 assertTrue(overlaps.contains(sf2));
69   
70  1 overlaps = fs.findOverlappingFeatures(45, 60);
71  1 assertEquals(overlaps.size(), 1);
72  1 assertTrue(overlaps.contains(sf1));
73   
74  1 overlaps = fs.findOverlappingFeatures(32, 38);
75  1 assertEquals(overlaps.size(), 3);
76  1 assertTrue(overlaps.contains(sf1));
77  1 assertTrue(overlaps.contains(sf2));
78  1 assertTrue(overlaps.contains(sf5));
79   
80  1 overlaps = fs.findOverlappingFeatures(15, 25);
81  1 assertEquals(overlaps.size(), 4);
82  1 assertTrue(overlaps.contains(sf1));
83  1 assertTrue(overlaps.contains(sf2));
84  1 assertTrue(overlaps.contains(sf3));
85  1 assertTrue(overlaps.contains(sf4));
86    }
87   
 
88  1 toggle @Test(groups = "Functional")
89    public void testFindFeatures_mixed()
90    {
91  1 FeatureStore fs = new FeatureStore();
92  1 SequenceFeature sf1 = addFeature(fs, 10, 50);
93  1 SequenceFeature sf2 = addFeature(fs, 1, 15);
94  1 SequenceFeature sf3 = addFeature(fs, 20, 30);
95  1 SequenceFeature sf4 = addFeature(fs, 40, 100);
96  1 SequenceFeature sf5 = addFeature(fs, 60, 100);
97  1 SequenceFeature sf6 = addFeature(fs, 70, 70);
98   
99  1 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(200, 200);
100  1 assertTrue(overlaps.isEmpty());
101   
102  1 overlaps = fs.findOverlappingFeatures(1, 9);
103  1 assertEquals(overlaps.size(), 1);
104  1 assertTrue(overlaps.contains(sf2));
105   
106  1 overlaps = fs.findOverlappingFeatures(5, 18);
107  1 assertEquals(overlaps.size(), 2);
108  1 assertTrue(overlaps.contains(sf1));
109  1 assertTrue(overlaps.contains(sf2));
110   
111  1 overlaps = fs.findOverlappingFeatures(30, 40);
112  1 assertEquals(overlaps.size(), 3);
113  1 assertTrue(overlaps.contains(sf1));
114  1 assertTrue(overlaps.contains(sf3));
115  1 assertTrue(overlaps.contains(sf4));
116   
117  1 overlaps = fs.findOverlappingFeatures(80, 90);
118  1 assertEquals(overlaps.size(), 2);
119  1 assertTrue(overlaps.contains(sf4));
120  1 assertTrue(overlaps.contains(sf5));
121   
122  1 overlaps = fs.findOverlappingFeatures(68, 70);
123  1 assertEquals(overlaps.size(), 3);
124  1 assertTrue(overlaps.contains(sf4));
125  1 assertTrue(overlaps.contains(sf5));
126  1 assertTrue(overlaps.contains(sf6));
127    }
128   
129    /**
130    * Helper method to add a feature of no particular type
131    *
132    * @param fs
133    * @param from
134    * @param to
135    * @return
136    */
 
137  23 toggle SequenceFeature addFeature(FeatureStore fs, int from, int to)
138    {
139  23 SequenceFeature sf1 = new SequenceFeature("", "", from, to, Float.NaN,
140    null);
141  23 fs.addFeature(sf1);
142  23 return sf1;
143    }
144   
 
145  1 toggle @Test(groups = "Functional")
146    public void testFindFeatures_contactFeatures()
147    {
148  1 FeatureStore fs = new FeatureStore();
149   
150  1 SequenceFeature sf = new SequenceFeature("disulphide bond", "bond", 10,
151    20, Float.NaN, null);
152  1 fs.addFeature(sf);
153   
154    /*
155    * neither contact point in range
156    */
157  1 List<SequenceFeature> overlaps = fs.findOverlappingFeatures(1, 9);
158  1 assertTrue(overlaps.isEmpty());
159   
160    /*
161    * neither contact point in range
162    */
163  1 overlaps = fs.findOverlappingFeatures(11, 19);
164  1 assertTrue(overlaps.isEmpty());
165   
166    /*
167    * first contact point in range
168    */
169  1 overlaps = fs.findOverlappingFeatures(5, 15);
170  1 assertEquals(overlaps.size(), 1);
171  1 assertTrue(overlaps.contains(sf));
172   
173    /*
174    * second contact point in range
175    */
176  1 overlaps = fs.findOverlappingFeatures(15, 25);
177  1 assertEquals(overlaps.size(), 1);
178  1 assertTrue(overlaps.contains(sf));
179   
180    /*
181    * both contact points in range
182    */
183  1 overlaps = fs.findOverlappingFeatures(5, 25);
184  1 assertEquals(overlaps.size(), 1);
185  1 assertTrue(overlaps.contains(sf));
186    }
187   
 
188  1 toggle @Test(groups = "Functional")
189    public void testGetPositionalFeatures()
190    {
191  1 FeatureStore store = new FeatureStore();
192  1 SequenceFeature sf1 = new SequenceFeature("Metal", "desc", 10, 20,
193    Float.NaN, null);
194  1 store.addFeature(sf1);
195    // same range, different description
196  1 SequenceFeature sf2 = new SequenceFeature("Metal", "desc2", 10, 20,
197    Float.NaN, null);
198  1 store.addFeature(sf2);
199    // discontiguous range
200  1 SequenceFeature sf3 = new SequenceFeature("Metal", "desc", 30, 40,
201    Float.NaN, null);
202  1 store.addFeature(sf3);
203    // overlapping range
204  1 SequenceFeature sf4 = new SequenceFeature("Metal", "desc", 15, 35,
205    Float.NaN, null);
206  1 store.addFeature(sf4);
207    // enclosing range
208  1 SequenceFeature sf5 = new SequenceFeature("Metal", "desc", 5, 50,
209    Float.NaN, null);
210  1 store.addFeature(sf5);
211    // non-positional feature
212  1 SequenceFeature sf6 = new SequenceFeature("Metal", "desc", 0, 0,
213    Float.NaN, null);
214  1 store.addFeature(sf6);
215    // contact feature
216  1 SequenceFeature sf7 = new SequenceFeature("Disulphide bond", "desc",
217    18, 45, Float.NaN, null);
218  1 store.addFeature(sf7);
219   
220  1 List<SequenceFeature> features = store.getPositionalFeatures();
221  1 assertEquals(features.size(), 6);
222  1 assertTrue(features.contains(sf1));
223  1 assertTrue(features.contains(sf2));
224  1 assertTrue(features.contains(sf3));
225  1 assertTrue(features.contains(sf4));
226  1 assertTrue(features.contains(sf5));
227  1 assertFalse(features.contains(sf6));
228  1 assertTrue(features.contains(sf7));
229   
230  1 features = store.getNonPositionalFeatures();
231  1 assertEquals(features.size(), 1);
232  1 assertTrue(features.contains(sf6));
233    }
234   
 
235  1 toggle @Test(groups = "Functional")
236    public void testDelete()
237    {
238  1 FeatureStore store = new FeatureStore();
239  1 SequenceFeature sf1 = addFeature(store, 10, 20);
240  1 assertTrue(store.getPositionalFeatures().contains(sf1));
241   
242    /*
243    * simple deletion
244    */
245  1 assertTrue(store.delete(sf1));
246  1 assertTrue(store.getPositionalFeatures().isEmpty());
247   
248    /*
249    * non-positional feature deletion
250    */
251  1 SequenceFeature sf2 = addFeature(store, 0, 0);
252  1 assertFalse(store.getPositionalFeatures().contains(sf2));
253  1 assertTrue(store.getNonPositionalFeatures().contains(sf2));
254  1 assertTrue(store.delete(sf2));
255  1 assertTrue(store.getNonPositionalFeatures().isEmpty());
256   
257    /*
258    * contact feature deletion
259    */
260  1 SequenceFeature sf3 = new SequenceFeature("", "Disulphide Bond", 11,
261    23, Float.NaN, null);
262  1 store.addFeature(sf3);
263  1 assertEquals(store.getPositionalFeatures().size(), 1);
264  1 assertTrue(store.getPositionalFeatures().contains(sf3));
265  1 assertTrue(store.delete(sf3));
266  1 assertTrue(store.getPositionalFeatures().isEmpty());
267   
268    /*
269    * nested feature deletion
270    */
271  1 SequenceFeature sf4 = addFeature(store, 20, 30);
272  1 SequenceFeature sf5 = addFeature(store, 22, 26); // to NCList
273  1 SequenceFeature sf6 = addFeature(store, 23, 24); // child of sf5
274  1 SequenceFeature sf7 = addFeature(store, 25, 25); // sibling of sf6
275  1 SequenceFeature sf8 = addFeature(store, 24, 24); // child of sf6
276  1 SequenceFeature sf9 = addFeature(store, 23, 23); // child of sf6
277  1 assertEquals(store.getPositionalFeatures().size(), 6);
278   
279    // delete a node with children - they take its place
280  1 assertTrue(store.delete(sf6)); // sf8, sf9 should become children of sf5
281  1 assertEquals(store.getPositionalFeatures().size(), 5);
282  1 assertFalse(store.getPositionalFeatures().contains(sf6));
283   
284    // delete a node with no children
285  1 assertTrue(store.delete(sf7));
286  1 assertEquals(store.getPositionalFeatures().size(), 4);
287  1 assertFalse(store.getPositionalFeatures().contains(sf7));
288   
289    // delete root of NCList
290  1 assertTrue(store.delete(sf5));
291  1 assertEquals(store.getPositionalFeatures().size(), 3);
292  1 assertFalse(store.getPositionalFeatures().contains(sf5));
293   
294    // continue the killing fields
295  1 assertTrue(store.delete(sf4));
296  1 assertEquals(store.getPositionalFeatures().size(), 2);
297  1 assertFalse(store.getPositionalFeatures().contains(sf4));
298   
299  1 assertTrue(store.delete(sf9));
300  1 assertEquals(store.getPositionalFeatures().size(), 1);
301  1 assertFalse(store.getPositionalFeatures().contains(sf9));
302   
303  1 assertTrue(store.delete(sf8));
304  1 assertTrue(store.getPositionalFeatures().isEmpty());
305    }
306   
 
307  1 toggle @Test(groups = "Functional")
308    public void testAddFeature()
309    {
310  1 FeatureStore fs = new FeatureStore();
311   
312  1 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
313    Float.NaN, null);
314  1 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
315    Float.NaN, null);
316   
317  1 assertTrue(fs.addFeature(sf1));
318  1 assertEquals(fs.getFeatureCount(true), 1); // positional
319  1 assertEquals(fs.getFeatureCount(false), 0); // non-positional
320   
321    /*
322    * re-adding the same or an identical feature should fail
323    */
324  1 assertFalse(fs.addFeature(sf1));
325  1 assertEquals(fs.getFeatureCount(true), 1);
326  1 assertFalse(fs.addFeature(sf2));
327  1 assertEquals(fs.getFeatureCount(true), 1);
328   
329    /*
330    * add non-positional
331    */
332  1 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
333    null);
334  1 assertTrue(fs.addFeature(sf3));
335  1 assertEquals(fs.getFeatureCount(true), 1); // positional
336  1 assertEquals(fs.getFeatureCount(false), 1); // non-positional
337  1 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
338    null);
339  1 assertFalse(fs.addFeature(sf4)); // already stored
340  1 assertEquals(fs.getFeatureCount(true), 1); // positional
341  1 assertEquals(fs.getFeatureCount(false), 1); // non-positional
342   
343    /*
344    * add contact
345    */
346  1 SequenceFeature sf5 = new SequenceFeature("Disulfide bond", "", 10, 20,
347    Float.NaN, null);
348  1 assertTrue(fs.addFeature(sf5));
349  1 assertEquals(fs.getFeatureCount(true), 2); // positional - add 1 for contact
350  1 assertEquals(fs.getFeatureCount(false), 1); // non-positional
351  1 SequenceFeature sf6 = new SequenceFeature("Disulfide bond", "", 10, 20,
352    Float.NaN, null);
353  1 assertFalse(fs.addFeature(sf6)); // already stored
354  1 assertEquals(fs.getFeatureCount(true), 2); // no change
355  1 assertEquals(fs.getFeatureCount(false), 1); // no change
356    }
357   
 
358  1 toggle @Test(groups = "Functional")
359    public void testIsEmpty()
360    {
361  1 FeatureStore fs = new FeatureStore();
362  1 assertTrue(fs.isEmpty());
363  1 assertEquals(fs.getFeatureCount(true), 0);
364   
365    /*
366    * non-nested feature
367    */
368  1 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
369    Float.NaN, null);
370  1 fs.addFeature(sf1);
371  1 assertFalse(fs.isEmpty());
372  1 assertEquals(fs.getFeatureCount(true), 1);
373  1 fs.delete(sf1);
374  1 assertTrue(fs.isEmpty());
375  1 assertEquals(fs.getFeatureCount(true), 0);
376   
377    /*
378    * non-positional feature
379    */
380  1 sf1 = new SequenceFeature("Cath", "", 0, 0, Float.NaN, null);
381  1 fs.addFeature(sf1);
382  1 assertFalse(fs.isEmpty());
383  1 assertEquals(fs.getFeatureCount(false), 1); // non-positional
384  1 assertEquals(fs.getFeatureCount(true), 0); // positional
385  1 fs.delete(sf1);
386  1 assertTrue(fs.isEmpty());
387  1 assertEquals(fs.getFeatureCount(false), 0);
388   
389    /*
390    * contact feature
391    */
392  1 sf1 = new SequenceFeature("Disulfide bond", "", 19, 49, Float.NaN, null);
393  1 fs.addFeature(sf1);
394  1 assertFalse(fs.isEmpty());
395  1 assertEquals(fs.getFeatureCount(true), 1);
396  1 fs.delete(sf1);
397  1 assertTrue(fs.isEmpty());
398  1 assertEquals(fs.getFeatureCount(true), 0);
399   
400    /*
401    * sf2, sf3 added as nested features
402    */
403  1 sf1 = new SequenceFeature("Cath", "", 19, 49, Float.NaN, null);
404  1 SequenceFeature sf2 = new SequenceFeature("Cath", "", 20, 40,
405    Float.NaN, null);
406  1 SequenceFeature sf3 = new SequenceFeature("Cath", "", 25, 35,
407    Float.NaN, null);
408  1 fs.addFeature(sf1);
409  1 fs.addFeature(sf2);
410  1 fs.addFeature(sf3);
411  1 assertEquals(fs.getFeatureCount(true), 3);
412  1 assertTrue(fs.delete(sf1));
413  1 assertEquals(fs.getFeatureCount(true), 2);
414  1 assertEquals(fs.features.size(), 2);
415  1 assertFalse(fs.isEmpty());
416  1 assertTrue(fs.delete(sf2));
417  1 assertEquals(fs.getFeatureCount(true), 1);
418  1 assertFalse(fs.isEmpty());
419  1 assertTrue(fs.delete(sf3));
420  1 assertEquals(fs.getFeatureCount(true), 0);
421  1 assertTrue(fs.isEmpty()); // all gone
422    }
423   
 
424  1 toggle @Test(groups = "Functional")
425    public void testGetFeatureGroups()
426    {
427  1 FeatureStore fs = new FeatureStore();
428  1 assertTrue(fs.getFeatureGroups(true).isEmpty());
429  1 assertTrue(fs.getFeatureGroups(false).isEmpty());
430   
431  1 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
432  1 fs.addFeature(sf1);
433  1 Set<String> groups = fs.getFeatureGroups(true);
434  1 assertEquals(groups.size(), 1);
435  1 assertTrue(groups.contains("group1"));
436   
437    /*
438    * add another feature of the same group, delete one, delete both
439    */
440  1 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group1");
441  1 fs.addFeature(sf2);
442  1 groups = fs.getFeatureGroups(true);
443  1 assertEquals(groups.size(), 1);
444  1 assertTrue(groups.contains("group1"));
445  1 fs.delete(sf2);
446  1 groups = fs.getFeatureGroups(true);
447  1 assertEquals(groups.size(), 1);
448  1 assertTrue(groups.contains("group1"));
449  1 fs.delete(sf1);
450  1 groups = fs.getFeatureGroups(true);
451  1 assertTrue(fs.getFeatureGroups(true).isEmpty());
452   
453  1 SequenceFeature sf3 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "group2");
454  1 fs.addFeature(sf3);
455  1 SequenceFeature sf4 = new SequenceFeature("Cath", "desc", 20, 30, 1f, "Group2");
456  1 fs.addFeature(sf4);
457  1 SequenceFeature sf5 = new SequenceFeature("Cath", "desc", 20, 30, 1f, null);
458  1 fs.addFeature(sf5);
459  1 groups = fs.getFeatureGroups(true);
460  1 assertEquals(groups.size(), 3);
461  1 assertTrue(groups.contains("group2"));
462  1 assertTrue(groups.contains("Group2")); // case sensitive
463  1 assertTrue(groups.contains(null)); // null allowed
464  1 assertTrue(fs.getFeatureGroups(false).isEmpty()); // non-positional
465   
466  1 fs.delete(sf3);
467  1 groups = fs.getFeatureGroups(true);
468  1 assertEquals(groups.size(), 2);
469  1 assertFalse(groups.contains("group2"));
470  1 fs.delete(sf4);
471  1 groups = fs.getFeatureGroups(true);
472  1 assertEquals(groups.size(), 1);
473  1 assertFalse(groups.contains("Group2"));
474  1 fs.delete(sf5);
475  1 groups = fs.getFeatureGroups(true);
476  1 assertTrue(groups.isEmpty());
477   
478    /*
479    * add non-positional feature
480    */
481  1 SequenceFeature sf6 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
482    "CathGroup");
483  1 fs.addFeature(sf6);
484  1 groups = fs.getFeatureGroups(false);
485  1 assertEquals(groups.size(), 1);
486  1 assertTrue(groups.contains("CathGroup"));
487  1 assertTrue(fs.delete(sf6));
488  1 assertTrue(fs.getFeatureGroups(false).isEmpty());
489    }
490   
 
491  1 toggle @Test(groups = "Functional")
492    public void testGetTotalFeatureLength()
493    {
494  1 FeatureStore fs = new FeatureStore();
495  1 assertEquals(fs.getTotalFeatureLength(), 0);
496   
497  1 addFeature(fs, 10, 20); // 11
498  1 assertEquals(fs.getTotalFeatureLength(), 11);
499  1 addFeature(fs, 17, 37); // 21
500  1 SequenceFeature sf1 = addFeature(fs, 14, 74); // 61
501  1 assertEquals(fs.getTotalFeatureLength(), 93);
502   
503    // non-positional features don't count
504  1 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
505    "group1");
506  1 fs.addFeature(sf2);
507  1 assertEquals(fs.getTotalFeatureLength(), 93);
508   
509    // contact features count 1
510  1 SequenceFeature sf3 = new SequenceFeature("disulphide bond", "desc",
511    15, 35, 1f, "group1");
512  1 fs.addFeature(sf3);
513  1 assertEquals(fs.getTotalFeatureLength(), 94);
514   
515  1 assertTrue(fs.delete(sf1));
516  1 assertEquals(fs.getTotalFeatureLength(), 33);
517  1 assertFalse(fs.delete(sf1));
518  1 assertEquals(fs.getTotalFeatureLength(), 33);
519  1 assertTrue(fs.delete(sf2));
520  1 assertEquals(fs.getTotalFeatureLength(), 33);
521  1 assertTrue(fs.delete(sf3));
522  1 assertEquals(fs.getTotalFeatureLength(), 32);
523    }
524   
 
525  1 toggle @Test(groups = "Functional")
526    public void testGetFeatureLength()
527    {
528    /*
529    * positional feature
530    */
531  1 SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 10, 20, 1f, "group1");
532  1 assertEquals(FeatureStore.getFeatureLength(sf1), 11);
533   
534    /*
535    * non-positional feature
536    */
537  1 SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 0, 0, 1f,
538    "CathGroup");
539  1 assertEquals(FeatureStore.getFeatureLength(sf2), 0);
540   
541    /*
542    * contact feature counts 1
543    */
544  1 SequenceFeature sf3 = new SequenceFeature("Disulphide Bond", "desc",
545    14, 28, 1f, "AGroup");
546  1 assertEquals(FeatureStore.getFeatureLength(sf3), 1);
547    }
548   
 
549  1 toggle @Test(groups = "Functional")
550    public void testMin()
551    {
552  1 assertEquals(FeatureStore.min(Float.NaN, Float.NaN), Float.NaN);
553  1 assertEquals(FeatureStore.min(Float.NaN, 2f), 2f);
554  1 assertEquals(FeatureStore.min(-2f, Float.NaN), -2f);
555  1 assertEquals(FeatureStore.min(2f, -3f), -3f);
556    }
557   
 
558  1 toggle @Test(groups = "Functional")
559    public void testMax()
560    {
561  1 assertEquals(FeatureStore.max(Float.NaN, Float.NaN), Float.NaN);
562  1 assertEquals(FeatureStore.max(Float.NaN, 2f), 2f);
563  1 assertEquals(FeatureStore.max(-2f, Float.NaN), -2f);
564  1 assertEquals(FeatureStore.max(2f, -3f), 2f);
565    }
566   
 
567  1 toggle @Test(groups = "Functional")
568    public void testGetMinimumScore_getMaximumScore()
569    {
570  1 FeatureStore fs = new FeatureStore();
571  1 assertEquals(fs.getMinimumScore(true), Float.NaN); // positional
572  1 assertEquals(fs.getMaximumScore(true), Float.NaN);
573  1 assertEquals(fs.getMinimumScore(false), Float.NaN); // non-positional
574  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
575   
576    // add features with no score
577  1 SequenceFeature sf1 = new SequenceFeature("type", "desc", 0, 0,
578    Float.NaN, "group");
579  1 fs.addFeature(sf1);
580  1 SequenceFeature sf2 = new SequenceFeature("type", "desc", 10, 20,
581    Float.NaN, "group");
582  1 fs.addFeature(sf2);
583  1 assertEquals(fs.getMinimumScore(true), Float.NaN);
584  1 assertEquals(fs.getMaximumScore(true), Float.NaN);
585  1 assertEquals(fs.getMinimumScore(false), Float.NaN);
586  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
587   
588    // add positional features with score
589  1 SequenceFeature sf3 = new SequenceFeature("type", "desc", 10, 20, 1f,
590    "group");
591  1 fs.addFeature(sf3);
592  1 SequenceFeature sf4 = new SequenceFeature("type", "desc", 12, 16, 4f,
593    "group");
594  1 fs.addFeature(sf4);
595  1 assertEquals(fs.getMinimumScore(true), 1f);
596  1 assertEquals(fs.getMaximumScore(true), 4f);
597  1 assertEquals(fs.getMinimumScore(false), Float.NaN);
598  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
599   
600    // add non-positional features with score
601  1 SequenceFeature sf5 = new SequenceFeature("type", "desc", 0, 0, 11f,
602    "group");
603  1 fs.addFeature(sf5);
604  1 SequenceFeature sf6 = new SequenceFeature("type", "desc", 0, 0, -7f,
605    "group");
606  1 fs.addFeature(sf6);
607  1 assertEquals(fs.getMinimumScore(true), 1f);
608  1 assertEquals(fs.getMaximumScore(true), 4f);
609  1 assertEquals(fs.getMinimumScore(false), -7f);
610  1 assertEquals(fs.getMaximumScore(false), 11f);
611   
612    // delete one positional and one non-positional
613    // min-max should be recomputed
614  1 assertTrue(fs.delete(sf6));
615  1 assertTrue(fs.delete(sf3));
616  1 assertEquals(fs.getMinimumScore(true), 4f);
617  1 assertEquals(fs.getMaximumScore(true), 4f);
618  1 assertEquals(fs.getMinimumScore(false), 11f);
619  1 assertEquals(fs.getMaximumScore(false), 11f);
620   
621    // delete remaining features with score
622  1 assertTrue(fs.delete(sf4));
623  1 assertTrue(fs.delete(sf5));
624  1 assertEquals(fs.getMinimumScore(true), Float.NaN);
625  1 assertEquals(fs.getMaximumScore(true), Float.NaN);
626  1 assertEquals(fs.getMinimumScore(false), Float.NaN);
627  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
628   
629    // delete all features
630  1 assertTrue(fs.delete(sf1));
631  1 assertTrue(fs.delete(sf2));
632  1 assertTrue(fs.isEmpty());
633  1 assertEquals(fs.getMinimumScore(true), Float.NaN);
634  1 assertEquals(fs.getMaximumScore(true), Float.NaN);
635  1 assertEquals(fs.getMinimumScore(false), Float.NaN);
636  1 assertEquals(fs.getMaximumScore(false), Float.NaN);
637    }
638   
 
639  1 toggle @Test(groups = "Functional")
640    public void testListContains()
641    {
642  1 assertFalse(FeatureStore.listContains(null, null));
643  1 List<SequenceFeature> features = new ArrayList<>();
644  1 assertFalse(FeatureStore.listContains(features, null));
645   
646  1 SequenceFeature sf1 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
647    "group1");
648  1 assertFalse(FeatureStore.listContains(null, sf1));
649  1 assertFalse(FeatureStore.listContains(features, sf1));
650   
651  1 features.add(sf1);
652  1 SequenceFeature sf2 = new SequenceFeature("type1", "desc1", 20, 30, 3f,
653    "group1");
654  1 SequenceFeature sf3 = new SequenceFeature("type1", "desc1", 20, 40, 3f,
655    "group1");
656   
657    // sf2.equals(sf1) so contains should return true
658  1 assertTrue(FeatureStore.listContains(features, sf2));
659  1 assertFalse(FeatureStore.listContains(features, sf3));
660    }
661   
 
662  1 toggle @Test(groups = "Functional")
663    public void testGetFeaturesForGroup()
664    {
665  1 FeatureStore fs = new FeatureStore();
666   
667    /*
668    * with no features
669    */
670  1 assertTrue(fs.getFeaturesForGroup(true, null).isEmpty());
671  1 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
672  1 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
673  1 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
674   
675    /*
676    * sf1: positional feature in the null group
677    */
678  1 SequenceFeature sf1 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
679    null);
680  1 fs.addFeature(sf1);
681  1 assertTrue(fs.getFeaturesForGroup(true, "uniprot").isEmpty());
682  1 assertTrue(fs.getFeaturesForGroup(false, "uniprot").isEmpty());
683  1 assertTrue(fs.getFeaturesForGroup(false, null).isEmpty());
684  1 List<SequenceFeature> features = fs.getFeaturesForGroup(true, null);
685  1 assertEquals(features.size(), 1);
686  1 assertTrue(features.contains(sf1));
687   
688    /*
689    * sf2: non-positional feature in the null group
690    * sf3: positional feature in a non-null group
691    * sf4: non-positional feature in a non-null group
692    */
693  1 SequenceFeature sf2 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
694    null);
695  1 SequenceFeature sf3 = new SequenceFeature("Pfam", "desc", 4, 10, 0f,
696    "Uniprot");
697  1 SequenceFeature sf4 = new SequenceFeature("Pfam", "desc", 0, 0, 0f,
698    "Rfam");
699  1 fs.addFeature(sf2);
700  1 fs.addFeature(sf3);
701  1 fs.addFeature(sf4);
702   
703  1 features = fs.getFeaturesForGroup(true, null);
704  1 assertEquals(features.size(), 1);
705  1 assertTrue(features.contains(sf1));
706   
707  1 features = fs.getFeaturesForGroup(false, null);
708  1 assertEquals(features.size(), 1);
709  1 assertTrue(features.contains(sf2));
710   
711  1 features = fs.getFeaturesForGroup(true, "Uniprot");
712  1 assertEquals(features.size(), 1);
713  1 assertTrue(features.contains(sf3));
714   
715  1 features = fs.getFeaturesForGroup(false, "Rfam");
716  1 assertEquals(features.size(), 1);
717  1 assertTrue(features.contains(sf4));
718    }
719   
 
720  1 toggle @Test(groups = "Functional")
721    public void testShiftFeatures()
722    {
723  1 FeatureStore fs = new FeatureStore();
724  1 assertFalse(fs.shiftFeatures(0, 1)); // nothing to do
725   
726  1 SequenceFeature sf1 = new SequenceFeature("Cath", "", 2, 5, 0f, null);
727  1 fs.addFeature(sf1);
728    // nested feature:
729  1 SequenceFeature sf2 = new SequenceFeature("Cath", "", 8, 14, 0f, null);
730  1 fs.addFeature(sf2);
731    // contact feature:
732  1 SequenceFeature sf3 = new SequenceFeature("Disulfide bond", "", 23, 32,
733    0f, null);
734  1 fs.addFeature(sf3);
735    // non-positional feature:
736  1 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f, null);
737  1 fs.addFeature(sf4);
738   
739    /*
740    * shift all features right by 5
741    */
742  1 assertTrue(fs.shiftFeatures(0, 5));
743   
744    // non-positional features untouched:
745  1 List<SequenceFeature> nonPos = fs.getNonPositionalFeatures();
746  1 assertEquals(nonPos.size(), 1);
747  1 assertTrue(nonPos.contains(sf4));
748   
749    // positional features are replaced
750  1 List<SequenceFeature> pos = fs.getPositionalFeatures();
751  1 assertEquals(pos.size(), 3);
752  1 assertFalse(pos.contains(sf1));
753  1 assertFalse(pos.contains(sf2));
754  1 assertFalse(pos.contains(sf3));
755  1 SequenceFeatures.sortFeatures(pos, true); // ascending start pos
756  1 assertEquals(pos.get(0).getBegin(), 7);
757  1 assertEquals(pos.get(0).getEnd(), 10);
758  1 assertEquals(pos.get(1).getBegin(), 13);
759  1 assertEquals(pos.get(1).getEnd(), 19);
760  1 assertEquals(pos.get(2).getBegin(), 28);
761  1 assertEquals(pos.get(2).getEnd(), 37);
762   
763    /*
764    * now shift left by 15
765    * feature at [7-10] should be removed
766    * feature at [13-19] should become [1-4]
767    */
768  1 assertTrue(fs.shiftFeatures(0, -15));
769  1 pos = fs.getPositionalFeatures();
770  1 assertEquals(pos.size(), 2);
771  1 SequenceFeatures.sortFeatures(pos, true);
772  1 assertEquals(pos.get(0).getBegin(), 1);
773  1 assertEquals(pos.get(0).getEnd(), 4);
774  1 assertEquals(pos.get(1).getBegin(), 13);
775  1 assertEquals(pos.get(1).getEnd(), 22);
776   
777    /*
778    * shift right by 4 from position 2 onwards
779    * feature at [1-4] unchanged, feature at [13-22] shifts
780    */
781  1 assertTrue(fs.shiftFeatures(2, 4));
782  1 pos = fs.getPositionalFeatures();
783  1 assertEquals(pos.size(), 2);
784  1 SequenceFeatures.sortFeatures(pos, true);
785  1 assertEquals(pos.get(0).getBegin(), 1);
786  1 assertEquals(pos.get(0).getEnd(), 4);
787  1 assertEquals(pos.get(1).getBegin(), 17);
788  1 assertEquals(pos.get(1).getEnd(), 26);
789   
790    /*
791    * shift right by 4 from position 18 onwards
792    * should be no change
793    */
794  1 SequenceFeature f1 = pos.get(0);
795  1 SequenceFeature f2 = pos.get(1);
796  1 assertFalse(fs.shiftFeatures(18, 4)); // no update
797  1 pos = fs.getPositionalFeatures();
798  1 assertEquals(pos.size(), 2);
799  1 SequenceFeatures.sortFeatures(pos, true);
800  1 assertSame(pos.get(0), f1);
801  1 assertSame(pos.get(1), f2);
802    }
803   
 
804  1 toggle @Test(groups = "Functional")
805    public void testDelete_readd()
806    {
807    /*
808    * add a feature and a nested feature
809    */
810  1 FeatureStore store = new FeatureStore();
811  1 SequenceFeature sf1 = addFeature(store, 10, 20);
812    // sf2 is nested in sf1 so will be stored in nestedFeatures
813  1 SequenceFeature sf2 = addFeature(store, 12, 14);
814  1 List<SequenceFeature> features = store.getPositionalFeatures();
815  1 assertEquals(features.size(), 2);
816  1 assertTrue(features.contains(sf1));
817  1 assertTrue(features.contains(sf2));
818  1 assertTrue(store.features.contains(sf1));
819  1 assertTrue(store.features.contains(sf2));
820   
821    /*
822    * delete the first feature
823    */
824  1 assertTrue(store.delete(sf1));
825  1 features = store.getPositionalFeatures();
826  1 assertFalse(features.contains(sf1));
827  1 assertTrue(features.contains(sf2));
828   
829    /*
830    * re-add the 'nested' feature; is it now duplicated?
831    */
832  1 store.addFeature(sf2);
833  1 features = store.getPositionalFeatures();
834  1 assertEquals(features.size(), 1);
835  1 assertTrue(features.contains(sf2));
836    }
837   
 
838  1 toggle @Test(groups = "Functional")
839    public void testContains()
840    {
841  1 FeatureStore fs = new FeatureStore();
842  1 SequenceFeature sf1 = new SequenceFeature("Cath", "", 10, 20,
843    Float.NaN, "group1");
844  1 SequenceFeature sf2 = new SequenceFeature("Cath", "", 10, 20,
845    Float.NaN, "group2");
846  1 SequenceFeature sf3 = new SequenceFeature("Cath", "", 0, 0, Float.NaN,
847    "group1");
848  1 SequenceFeature sf4 = new SequenceFeature("Cath", "", 0, 0, 0f,
849    "group1");
850  1 SequenceFeature sf5 = new SequenceFeature("Disulphide Bond", "", 5, 15,
851    Float.NaN, "group1");
852  1 SequenceFeature sf6 = new SequenceFeature("Disulphide Bond", "", 5, 15,
853    Float.NaN, "group2");
854   
855  1 fs.addFeature(sf1);
856  1 fs.addFeature(sf3);
857  1 fs.addFeature(sf5);
858  1 assertTrue(fs.contains(sf1)); // positional feature
859  1 assertTrue(fs.contains(new SequenceFeature(sf1))); // identical feature
860  1 assertFalse(fs.contains(sf2)); // different group
861  1 assertTrue(fs.contains(sf3)); // non-positional
862  1 assertTrue(fs.contains(new SequenceFeature(sf3)));
863  1 assertFalse(fs.contains(sf4)); // different score
864  1 assertTrue(fs.contains(sf5)); // contact feature
865  1 assertTrue(fs.contains(new SequenceFeature(sf5)));
866  1 assertFalse(fs.contains(sf6)); // different group
867   
868    /*
869    * add a nested feature
870    */
871  1 SequenceFeature sf7 = new SequenceFeature("Cath", "", 12, 16,
872    Float.NaN, "group1");
873  1 fs.addFeature(sf7);
874  1 assertTrue(fs.contains(sf7));
875  1 assertTrue(fs.contains(new SequenceFeature(sf7)));
876   
877    /*
878    * delete the outer (enclosing, non-nested) feature
879    */
880  1 fs.delete(sf1);
881  1 assertFalse(fs.contains(sf1));
882  1 assertTrue(fs.contains(sf7));
883    }
884    }