Merge branch 'develop' into update_212_Dec_merge_with_21125_chamges
[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;
60       if (format == FileFormat.HMMER3)
61       {
62         al = new FormatAdapter().readFile("examples/uniref50.hmm",
63                 DataSourceType.FILE, FileFormat.HMMER3);
64       }
65       else
66       {
67         al = new FormatAdapter().readFile("examples/uniref50.fa",
68               DataSourceType.FILE, FileFormat.Fasta);
69       }
70
71       /*
72        * 'gap' is the gap character used in the alignment data file here,
73        * not the user preferred gap character
74        */
75       char gap = al.getGapCharacter();
76       assertNotNull(al);
77
78       SequenceI[] seqs = al.getSequencesArray();
79       String formatted = new FormatAdapter().formatSequences(format, al,
80               false);
81
82       AlignmentI reloaded = new FormatAdapter().readFile(formatted,
83               DataSourceType.PASTE, format);
84       List<SequenceI> reread = reloaded.getSequences();
85         assertEquals("Wrong number of reloaded sequences", seqs.length,
86                 reread.size());
87
88
89       int i = 0;
90       for (SequenceI seq : reread)
91       {
92         String sequenceString = seq.getSequenceAsString();
93
94         /*
95          * special case: MSF always uses '.' as gap character
96          */
97         sequenceString = adjustForGapTreatment(sequenceString, gap, format);
98         assertEquals(String.format("Sequence %d: %s", i, seqs[i].getName()),
99                 seqs[i].getSequenceAsString(), sequenceString);
100         i++;
101       }
102     } catch (IOException e)
103     {
104       fail(String.format("Format %s failed with %s", format,
105               e.getMessage()));
106     }
107   }
108
109   /**
110    * Optionally change the gap character in the string to the given character,
111    * depending on the sequence file format
112    * 
113    * @param sequenceString
114    *          a sequence (as written in 'format' format)
115    * @param gap
116    *          the sequence's original gap character
117    * @param format
118    * @return
119    */
120   String adjustForGapTreatment(String sequenceString, char gap,
121           FileFormatI format)
122   {
123     if (FileFormat.MSF.equals(format))
124     {
125       /*
126        * MSF forces gap character to '.', so change it back
127        * for comparison purposes
128        */
129       sequenceString = sequenceString.replace('.', gap);
130     }
131     return sequenceString;
132   }
133
134   /**
135    * Data provider that serves alignment formats that are both readable and
136    * (text) writable
137    * 
138    * @return
139    */
140   @DataProvider(name = "formats")
141   static Object[][] getFormats()
142   {
143     List<FileFormatI> both = new ArrayList<>();
144     for (FileFormatI format : FileFormats.getInstance().getFormats())
145     {
146       if (format.isReadable() && format.isWritable()
147               && format.isTextFormat())
148       {
149         both.add(format);
150       }
151     }
152
153     Object[][] formats = new Object[both.size()][];
154     int i = 0;
155     for (FileFormatI format : both)
156     {
157       formats[i] = new Object[] { format };
158       i++;
159     }
160     return formats;
161   }
162
163   /**
164    * Enable this to isolate testing to a single file format
165    * 
166    * @throws IOException
167    */
168   @Test(groups = { "Functional" }, enabled = false)
169   public void testOneFormatRoundTrip() throws IOException
170   {
171     testRoundTrip(FileFormat.Json);
172   }
173 }