Merge branch 'develop' into trialMerge
[jalview.git] / test / jalview / io / FormatAdapterTest.java
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;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertNotNull;
25 import static org.testng.AssertJUnit.fail;
26
27 import jalview.datamodel.AlignmentI;
28 import jalview.datamodel.SequenceI;
29
30 import java.io.IOException;
31 import java.util.ArrayList;
32 import java.util.List;
33
34 import org.testng.annotations.DataProvider;
35 import org.testng.annotations.Test;
36
37 public class FormatAdapterTest
38 {
39
40   /**
41    * Test saving and re-reading in a specified format
42    * 
43    * @throws IOException
44    */
45   @Test(groups = { "Functional" }, dataProvider = "formats")
46   public void testRoundTrip(FileFormatI format) throws IOException
47   {
48     try
49     {
50       AlignmentI al = new FormatAdapter().readFile("examples/uniref50.fa",
51               DataSourceType.FILE, FileFormat.Fasta);
52
53       /*
54        * 'gap' is the gap character used in the alignment data file here,
55        * not the user preferred gap character
56        */
57       char gap = al.getGapCharacter();
58       assertNotNull(al);
59
60       SequenceI[] seqs = al.getSequencesArray();
61       String formatted = new FormatAdapter().formatSequences(format, al,
62               false);
63
64       AlignmentI reloaded = new FormatAdapter().readFile(formatted,
65               DataSourceType.PASTE, format);
66       List<SequenceI> reread = reloaded.getSequences();
67       assertEquals("Wrong number of reloaded sequences", seqs.length,
68               reread.size());
69
70       int i = 0;
71       for (SequenceI seq : reread)
72       {
73         String sequenceString = seq.getSequenceAsString();
74
75         /*
76          * special case: MSF always uses '.' as gap character
77          */
78         sequenceString = adjustForGapTreatment(sequenceString, gap, format);
79         assertEquals(
80                 String.format("Sequence %d: %s", i, seqs[i].getName()),
81                 seqs[i].getSequenceAsString(), sequenceString);
82         i++;
83       }
84     } catch (IOException e)
85     {
86       fail(String
87               .format("Format %s failed with %s", format, e.getMessage()));
88     }
89   }
90
91   /**
92    * Optionally change the gap character in the string to the given character,
93    * depending on the sequence file format
94    * 
95    * @param sequenceString
96    *          a sequence (as written in 'format' format)
97    * @param gap
98    *          the sequence's original gap character
99    * @param format
100    * @return
101    */
102   String adjustForGapTreatment(String sequenceString, char gap,
103           FileFormatI format)
104   {
105     if (FileFormat.MSF.equals(format))
106     {
107       /*
108        * MSF forces gap character to '.', so change it back
109        * for comparison purposes
110        */
111       sequenceString = sequenceString.replace('.', gap);
112     }
113     return sequenceString;
114   }
115
116   /**
117    * Data provider that serves alignment formats that are both readable and
118    * (text) writable
119    * 
120    * @return
121    */
122   @DataProvider(name = "formats")
123   static Object[][] getFormats()
124   {
125     List<FileFormatI> both = new ArrayList<FileFormatI>();
126     for (FileFormat format : FileFormat.values())
127     {
128       if (format.isReadable() && format.isWritable()
129               && format.isTextFormat())
130       {
131         both.add(format);
132       }
133     }
134
135     Object[][] formats = new Object[both.size()][];
136     int i = 0;
137     for (FileFormatI format : both)
138     {
139       formats[i] = new Object[] { format };
140       i++;
141     }
142     return formats;
143   }
144
145   /**
146    * Enable this to isolate testing to a single file format
147    * 
148    * @throws IOException
149    */
150   @Test(groups = { "Functional" }, enabled = false)
151   public void testOneFormatRoundTrip() throws IOException
152   {
153     testRoundTrip(FileFormat.Json);
154   }
155 }