JAL-1705 further unit tests
[jalview.git] / test / jalview / ext / ensembl / EnsemblCdnaTest.java
1 package jalview.ext.ensembl;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertFalse;
5 import static org.testng.AssertJUnit.assertNull;
6 import static org.testng.AssertJUnit.assertTrue;
7
8 import jalview.datamodel.SequenceDummy;
9 import jalview.datamodel.SequenceFeature;
10 import jalview.datamodel.SequenceI;
11 import jalview.io.gff.SequenceOntologyFactory;
12 import jalview.io.gff.SequenceOntologyLite;
13 import jalview.util.MapList;
14
15 import java.util.List;
16
17 import org.testng.annotations.AfterClass;
18 import org.testng.annotations.BeforeClass;
19 import org.testng.annotations.Test;
20
21 public class EnsemblCdnaTest
22 {
23   @BeforeClass
24   public void setUp()
25   {
26     SequenceOntologyFactory.setInstance(new SequenceOntologyLite());
27   }
28
29   @AfterClass
30   public void tearDown()
31   {
32     SequenceOntologyFactory.setInstance(null);
33   }
34   /**
35    * Test that the cdna part of genomic sequence is correctly identified by
36    * 'exon' features (or subtypes) - reverse strand case.
37    */
38   @Test(groups = "Functional")
39   public void testGetGenomicRangesFromFeatures_reverseStrand()
40   {
41     EnsemblCdna testee = new EnsemblCdna();
42     SequenceI genomic = new SequenceDummy("chr7");
43     genomic.setStart(10000);
44     genomic.setEnd(50000);
45     String transcriptId = "ABC123";
46
47     // exon at (start+10000) length 501
48     SequenceFeature sf = new SequenceFeature("exon", "", 20000, 20500, 0f,
49             null);
50     sf.setValue("Parent", "transcript:" + transcriptId);
51     sf.setStrand("-");
52     genomic.addSequenceFeature(sf);
53
54     // exon (sub-type) at (start + exon_variant) length 101
55     sf = new SequenceFeature("coding_exon", "", 10500, 10600, 0f, null);
56     sf.setValue("Parent", "transcript:" + transcriptId);
57     sf.setStrand("-");
58     genomic.addSequenceFeature(sf);
59
60     // exon belonging to a different transcript doesn't count
61     sf = new SequenceFeature("exon", "", 11500, 12600, 0f, null);
62     sf.setValue("Parent", "transcript:anotherOne");
63     genomic.addSequenceFeature(sf);
64
65     // transcript feature doesn't count
66     sf = new SequenceFeature("transcript", "", 10000, 50000, 0f, null);
67     genomic.addSequenceFeature(sf);
68
69     MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
70             transcriptId, 23);
71     List<int[]> fromRanges = ranges.getFromRanges();
72     assertEquals(2, fromRanges.size());
73
74     /*
75      * from ranges should be sorted by start order descending
76      * and hold mappings from reverse strand sense
77      */
78     assertEquals(20500, fromRanges.get(0)[0]);
79     assertEquals(20000, fromRanges.get(0)[1]);
80     assertEquals(10600, fromRanges.get(1)[0]);
81     assertEquals(10500, fromRanges.get(1)[1]);
82     // to range should start from given start numbering
83     List<int[]> toRanges = ranges.getToRanges();
84     assertEquals(1, toRanges.size());
85     assertEquals(23, toRanges.get(0)[0]);
86     assertEquals(624, toRanges.get(0)[1]);
87   }
88
89   /**
90    * Test that the cdna part of genomic sequence is correctly identified by
91    * 'exon' features (or subtypes) with the desired transcript as parent
92    */
93   @Test(groups = "Functional")
94   public void testGetGenomicRangesFromFeatures()
95   {
96     EnsemblCdna testee = new EnsemblCdna();
97     SequenceI genomic = new SequenceDummy("chr7");
98     genomic.setStart(10000);
99     genomic.setEnd(50000);
100     String transcriptId = "ABC123";
101   
102     // exon at (start+10000) length 501
103     SequenceFeature sf = new SequenceFeature("exon", "", 20000, 20500, 0f,
104             null);
105     sf.setValue("Parent", "transcript:" + transcriptId);
106     sf.setStrand("+");
107     genomic.addSequenceFeature(sf);
108   
109     // exon (sub-type) at (start + exon_variant) length 101
110     sf = new SequenceFeature("coding_exon", "", 10500, 10600, 0f, null);
111     sf.setValue("Parent", "transcript:" + transcriptId);
112     sf.setStrand("+");
113     genomic.addSequenceFeature(sf);
114   
115     // exon belonging to a different transcript doesn't count
116     sf = new SequenceFeature("exon", "", 11500, 12600, 0f, null);
117     sf.setValue("Parent", "transcript:anotherOne");
118     genomic.addSequenceFeature(sf);
119   
120     // transcript feature doesn't count
121     sf = new SequenceFeature("transcript", "", 10000, 50000, 0f, null);
122     sf.setStrand("-"); // weird but ignored
123     genomic.addSequenceFeature(sf);
124   
125     MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
126             transcriptId, 23);
127     List<int[]> fromRanges = ranges.getFromRanges();
128     assertEquals(2, fromRanges.size());
129     // from ranges should be sorted by start order
130     assertEquals(10500, fromRanges.get(0)[0]);
131     assertEquals(10600, fromRanges.get(0)[1]);
132     assertEquals(20000, fromRanges.get(1)[0]);
133     assertEquals(20500, fromRanges.get(1)[1]);
134     // to range should start from given start numbering
135     List<int[]> toRanges = ranges.getToRanges();
136     assertEquals(1, toRanges.size());
137     assertEquals(23, toRanges.get(0)[0]);
138     assertEquals(624, toRanges.get(0)[1]);
139   }
140
141   /**
142    * The method under test should give up and return null if both forward and
143    * reverse strands are present in the features of interest
144    */
145   @Test(groups = "Functional")
146   public void testGetGenomicRangesFromFeatures_mixedStrand()
147   {
148     EnsemblCdna testee = new EnsemblCdna();
149     SequenceI genomic = new SequenceDummy("chr7");
150     genomic.setStart(10000);
151     genomic.setEnd(50000);
152     String transcriptId = "ABC123";
153   
154     SequenceFeature sf = new SequenceFeature("exon", "", 20000, 20500, 0f,
155             null);
156     sf.setValue("Parent", "transcript:" + transcriptId);
157     sf.setStrand("-");
158     genomic.addSequenceFeature(sf);
159   
160     sf = new SequenceFeature("coding_exon", "", 10500, 10600, 0f, null);
161     sf.setValue("Parent", "transcript:" + transcriptId);
162     sf.setStrand("+");
163     genomic.addSequenceFeature(sf);
164   
165     MapList ranges = testee.getGenomicRangesFromFeatures(genomic,
166             transcriptId, 23);
167     assertNull(ranges);
168   }
169
170   /**
171    * Test the method that retains features except for 'transcript' (or
172    * subtypes), or features with parent other than the given id
173    */
174   @Test(groups = "Functional")
175   public void testRetainFeature()
176   {
177     String accId = "ABC123";
178     EnsemblCdna testee = new EnsemblCdna();
179
180     SequenceFeature sf = new SequenceFeature("transcript", "", 20000,
181             20500, 0f, null);
182     assertFalse(testee.retainFeature(sf, accId));
183
184     sf.setType("aberrant_processed_transcript");
185     assertFalse(testee.retainFeature(sf, accId));
186
187     sf.setType("NMD_transcript_variant");
188     assertFalse(testee.retainFeature(sf, accId));
189
190     // other feature with no parent is retained
191     sf.setType("sequence_variant");
192     assertTrue(testee.retainFeature(sf, accId));
193
194     // other feature with desired parent is retained
195     sf.setValue("Parent", "transcript:" + accId);
196     assertTrue(testee.retainFeature(sf, accId));
197
198     // feature with wrong parent is not retained
199     sf.setValue("Parent", "transcript:XYZ");
200     assertFalse(testee.retainFeature(sf, accId));
201   }
202
203   /**
204    * Test the method that picks out 'exon' (or subtype) features with the
205    * accession id as parent
206    */
207   @Test(groups = "Functional")
208   public void testIdentifiesSequence()
209   {
210     String accId = "ABC123";
211     EnsemblCdna testee = new EnsemblCdna();
212
213     // exon with no parent not valid
214     SequenceFeature sf = new SequenceFeature("exon", "", 1, 2, 0f, null);
215     assertFalse(testee.identifiesSequence(sf, accId));
216
217     // exon with wrong parent not valid
218     sf.setValue("Parent", "transcript:XYZ");
219     assertFalse(testee.identifiesSequence(sf, accId));
220
221     // exon with right parent is valid
222     sf.setValue("Parent", "transcript:" + accId);
223     assertTrue(testee.identifiesSequence(sf, accId));
224
225     // exon sub-type with right parent is valid
226     sf.setType("coding_exon");
227     assertTrue(testee.identifiesSequence(sf, accId));
228
229     // transcript not valid:
230     sf.setType("transcript");
231     assertFalse(testee.identifiesSequence(sf, accId));
232
233     // CDS not valid:
234     sf.setType("CDS");
235     assertFalse(testee.identifiesSequence(sf, accId));
236   }
237 }