Clover icon

Coverage Report

  1. Project Clover database Wed Nov 13 2024 16:21:17 GMT
  2. Package jalview.io.gff

File Gff3HelperTest.java

 

Code metrics

0
103
6
1
281
170
6
0.06
17.17
6
1

Classes

Class Line # Actions
Gff3HelperTest 47 103 6
1.0100%
 

Contributing tests

This file is covered by 5 tests. .

Source view

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.io.gff;
22   
23    import static org.testng.AssertJUnit.assertEquals;
24    import static org.testng.AssertJUnit.assertNull;
25    import static org.testng.AssertJUnit.assertSame;
26    import static org.testng.AssertJUnit.assertTrue;
27    import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals;
28   
29    import jalview.datamodel.AlignedCodonFrame;
30    import jalview.datamodel.Alignment;
31    import jalview.datamodel.AlignmentI;
32    import jalview.datamodel.Sequence;
33    import jalview.datamodel.SequenceDummy;
34    import jalview.datamodel.SequenceFeature;
35    import jalview.datamodel.SequenceI;
36    import jalview.gui.JvOptionPane;
37   
38    import java.io.IOException;
39    import java.util.ArrayList;
40    import java.util.HashMap;
41    import java.util.List;
42    import java.util.Map;
43   
44    import org.testng.annotations.BeforeClass;
45    import org.testng.annotations.Test;
46   
 
47    public class Gff3HelperTest
48    {
49   
 
50  1 toggle @BeforeClass(alwaysRun = true)
51    public void setUpJvOptionPane()
52    {
53  1 JvOptionPane.setInteractiveMode(false);
54  1 JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
55    }
56   
57    /**
58    * Test processing one PASA GFF line giving a match from forward strand to
59    * forward strand
60    *
61    * @throws IOException
62    */
 
63  1 toggle @Test(groups = "Functional")
64    public void testProcessCdnaMatch_forwardToForward() throws IOException
65    {
66  1 GffHelperBase testee = new Gff3Helper();
67  1 List<SequenceI> newseqs = new ArrayList<SequenceI>();
68  1 String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 +"
69    .split("\\t");
70  1 SequenceI seq = new Sequence("gi|68711",
71    "GAATTCGTTCATGTAGGTTGATTTTTATT");
72  1 seq.createDatasetSequence();
73  1 AlignmentI align = new Alignment(new SequenceI[] {});
74   
75    /*
76    * this should create a mapping from gi|68711/12923-13060
77    * to virtual sequence gi|N37351 (added to newseqs) positions 1-138
78    */
79  1 testee.processGff(seq, gff, align, newseqs, false);
80  1 assertEquals(1, newseqs.size());
81  1 assertTrue(newseqs.get(0) instanceof SequenceDummy);
82  1 assertEquals("gi|N37351", newseqs.get(0).getName());
83  1 assertEquals(1, align.getCodonFrames().size());
84  1 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
85   
86    /*
87    * 'dnaseqs' (map from) is here [gi|68711]
88    * 'aaseqs' (map to) is here [gi|N37351]
89    */
90    // TODO use more suitable naming in AlignedCodonFrame
91  1 assertEquals(1, mapping.getAaSeqs().length);
92  1 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
93  1 assertEquals(1, mapping.getdnaSeqs().length);
94  1 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
95  1 assertEquals(1, mapping.getdnaToProt().length);
96  1 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
97  1 assertArrayEquals(new int[] { 12923, 13060 },
98    mapping.getdnaToProt()[0].getFromRanges().get(0));
99  1 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
100  1 assertArrayEquals(new int[] { 1, 138 },
101    mapping.getdnaToProt()[0].getToRanges().get(0));
102    }
103   
104    /**
105    * Test processing one PASA GFF line giving a match from forward strand to
106    * reverse strand
107    *
108    * @throws IOException
109    */
 
110  1 toggle @Test(groups = "Functional")
111    public void testProcessCdnaMatch_forwardToReverse() throws IOException
112    {
113  1 GffHelperBase testee = new Gff3Helper();
114  1 List<SequenceI> newseqs = new ArrayList<SequenceI>();
115  1 String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 -"
116    .split("\\t");
117  1 SequenceI seq = new Sequence("gi|68711",
118    "GAATTCGTTCATGTAGGTTGATTTTTATT");
119  1 seq.createDatasetSequence();
120  1 AlignmentI align = new Alignment(new SequenceI[] {});
121   
122    /*
123    * this should create a mapping from gi|68711/12923-13060
124    * to virtual sequence gi|N37351 (added to newseqs) positions 138-1
125    */
126  1 testee.processGff(seq, gff, align, newseqs, false);
127  1 assertEquals(1, newseqs.size());
128  1 assertTrue(newseqs.get(0) instanceof SequenceDummy);
129  1 assertEquals("gi|N37351", newseqs.get(0).getName());
130  1 assertEquals(1, align.getCodonFrames().size());
131  1 AlignedCodonFrame mapping = align.getCodonFrames().iterator().next();
132   
133    /*
134    * 'dnaseqs' (map from) is here [gi|68711]
135    * 'aaseqs' (map to) is here [gi|N37351]
136    */
137    // TODO use more suitable naming in AlignedCodonFrame
138  1 assertEquals(1, mapping.getAaSeqs().length);
139  1 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
140  1 assertEquals(1, mapping.getdnaSeqs().length);
141  1 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
142  1 assertEquals(1, mapping.getdnaToProt().length);
143  1 assertEquals(1, mapping.getdnaToProt()[0].getFromRanges().size());
144  1 assertArrayEquals(new int[] { 12923, 13060 },
145    mapping.getdnaToProt()[0].getFromRanges().get(0));
146  1 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
147  1 assertArrayEquals(new int[] { 138, 1 },
148    mapping.getdnaToProt()[0].getToRanges().get(0));
149    }
150   
151    /**
152    * Test processing one PASA GFF line giving a match from reverse complement
153    * strand to forward strand
154    *
155    * @throws IOException
156    */
 
157  1 toggle @Test(groups = "Functional")
158    public void testProcessCdnaMatch_reverseToForward() throws IOException
159    {
160  1 GffHelperBase testee = new Gff3Helper();
161  1 List<SequenceI> newseqs = new ArrayList<SequenceI>();
162  1 String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t-\t.\tID=align_68;Target=gi|N37351 1 138 +"
163    .split("\\t");
164  1 SequenceI seq = new Sequence("gi|68711",
165    "GAATTCGTTCATGTAGGTTGATTTTTATT");
166  1 seq.createDatasetSequence();
167  1 AlignmentI align = new Alignment(new SequenceI[] {});
168   
169    /*
170    * (For now) we don't process reverse complement mappings; to do this
171    * would require (a) creating a virtual sequence placeholder for the
172    * reverse complement (b) resolving the sequence by its id from some
173    * source (GFF ##FASTA or other) (c) creating the reverse complement
174    * sequence (d) updating the mapping to be to the reverse complement
175    */
176  1 SequenceFeature sf = testee.processGff(seq, gff, align, newseqs, false);
177  1 assertNull(sf);
178  1 assertTrue(newseqs.isEmpty());
179    }
180   
181    /**
182    * Test processing two PASA GFF lines representing a spliced mapping
183    *
184    * @throws IOException
185    */
 
186  1 toggle @Test(groups = "Functional")
187    public void testProcessCdnaMatch_spliced() throws IOException
188    {
189  1 GffHelperBase testee = new Gff3Helper();
190  1 List<SequenceI> newseqs = new ArrayList<SequenceI>();
191  1 SequenceI seq = new Sequence("gi|68711",
192    "GAATTCGTTCATGTAGGTTGATTTTTATT");
193  1 seq.createDatasetSequence();
194  1 AlignmentI align = new Alignment(new SequenceI[] {});
195   
196    // mapping from gi|68711 12923-13060 to gi|N37351 1-138
197  1 String[] gff = "gi|68711\tblat-pasa\tcDNA_match\t12923\t13060\t98.55\t+\t.\tID=align_68;Target=gi|N37351 1 138 +"
198    .split("\\t");
199  1 testee.processGff(seq, gff, align, newseqs, false);
200    // mapping from gi|68711 13411-13550 to gi|N37351 139-278
201  1 gff = "gi|68711\tblat-pasa\tcDNA_match\t13411\t13550\t98.55\t+\t.\tID=align_68;Target=gi|N37351 139 278 +"
202    .split("\\t");
203  1 testee.processGff(seq, gff, align, newseqs, false);
204   
205  1 assertEquals(1, newseqs.size());
206  1 assertTrue(newseqs.get(0) instanceof SequenceDummy);
207  1 assertEquals("gi|N37351", newseqs.get(0).getName());
208   
209    // only 1 AlignedCodonFrame added to the alignment with both mappings!
210    // (this is important for 'align cdna to genome' to work correctly)
211  1 assertEquals(1, align.getCodonFrames().size());
212  1 AlignedCodonFrame mapping = align.getCodonFrames().get(0);
213   
214    /*
215    * 'dnaseqs' (map from) is here [gi|68711]
216    * 'aaseqs' (map to) is here [gi|N37351]
217    */
218    // TODO use more suitable naming in AlignedCodonFrame
219  1 assertEquals(1, mapping.getAaSeqs().length);
220  1 assertSame(seq.getDatasetSequence(), mapping.getdnaSeqs()[0]);
221  1 assertEquals(1, mapping.getdnaSeqs().length);
222  1 assertSame(newseqs.get(0), mapping.getAaSeqs()[0]);
223  1 assertEquals(1, mapping.getdnaToProt().length);
224  1 assertEquals(2, mapping.getdnaToProt()[0].getFromRanges().size());
225    // the two spliced dna ranges are combined in one MapList
226  1 assertArrayEquals(new int[] { 12923, 13060 },
227    mapping.getdnaToProt()[0].getFromRanges().get(0));
228  1 assertArrayEquals(new int[] { 13411, 13550 },
229    mapping.getdnaToProt()[0].getFromRanges().get(1));
230  1 assertEquals(1, mapping.getdnaToProt()[0].getToRanges().size());
231    // the two cdna ranges are merged into one contiguous region
232  1 assertArrayEquals(new int[] { 1, 278 },
233    mapping.getdnaToProt()[0].getToRanges().get(0));
234    }
235   
 
236  1 toggle @Test(groups = "Functional")
237    public void testGetDescription()
238    {
239  1 Gff3Helper testee = new Gff3Helper();
240  1 SequenceFeature sf = new SequenceFeature("type", "desc", 10, 20, 3f,
241    "group");
242  1 Map<String, List<String>> attributes = new HashMap<String, List<String>>();
243  1 assertNull(testee.getDescription(sf, attributes));
244   
245    // ID if any is a fall-back for description
246  1 sf.setValue("ID", "Patrick");
247  1 assertEquals("Patrick", testee.getDescription(sf, attributes));
248   
249    // Target is set by Exonerate
250  1 sf.setValue("Target", "Destination Moon");
251  1 assertEquals("Destination", testee.getDescription(sf, attributes));
252   
253    // Ensembl variant feature - extract "alleles" value
254    // may be sequence_variant or a sub-type in the sequence ontology
255  1 sf = new SequenceFeature("feature_variant", "desc", 10, 20, 3f,
256    "group");
257  1 List<String> atts = new ArrayList<String>();
258  1 atts.add("A");
259  1 atts.add("C");
260  1 atts.add("T");
261  1 attributes.put("alleles", atts);
262  1 assertEquals("A,C,T", testee.getDescription(sf, attributes));
263   
264    // Ensembl transcript or exon feature - extract Name
265  1 List<String> atts2 = new ArrayList<String>();
266  1 atts2.add("ENSE00001871077");
267  1 attributes.put("Name", atts2);
268  1 sf = new SequenceFeature("transcript", "desc", 10, 20, 3f, "group");
269  1 assertEquals("ENSE00001871077", testee.getDescription(sf, attributes));
270    // transcript sub-type in SO
271  1 sf = new SequenceFeature("mRNA", "desc", 10, 20, 3f, "group");
272  1 assertEquals("ENSE00001871077", testee.getDescription(sf, attributes));
273    // special usage of feature by Ensembl
274  1 sf = new SequenceFeature("NMD_transcript_variant", "desc", 10, 20, 3f,
275    "group");
276  1 assertEquals("ENSE00001871077", testee.getDescription(sf, attributes));
277    // exon feature
278  1 sf = new SequenceFeature("exon", "desc", 10, 20, 3f, "group");
279  1 assertEquals("ENSE00001871077", testee.getDescription(sf, attributes));
280    }
281    }