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