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