--- /dev/null
+package jalview.io;
+
+import static org.testng.AssertJUnit.assertEquals;
+import static org.testng.AssertJUnit.assertNotNull;
+import static org.testng.AssertJUnit.fail;
+
+import jalview.datamodel.AlignmentI;
+import jalview.datamodel.SequenceI;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.testng.annotations.DataProvider;
+import org.testng.annotations.Test;
+
+public class FormatAdapterTest
+{
+
+ /**
+ * Test saving and re-reading in a specified format
+ *
+ * @throws IOException
+ */
+ @Test(groups = { "Functional" }, dataProvider = "formats")
+ public void testRoundTrip(String format) throws IOException
+ {
+ try
+ {
+ AlignmentI al = new FormatAdapter().readFile("examples/uniref50.fa",
+ FormatAdapter.FILE, "FASTA");
+
+ /*
+ * 'gap' is the gap character used in the alignment data file here,
+ * not the user preferred gap character
+ */
+ char gap = al.getGapCharacter();
+ assertNotNull(al);
+
+ SequenceI[] seqs = al.getSequencesArray();
+ String formatted = new FormatAdapter().formatSequences(format, al,
+ false);
+
+ AlignmentI reloaded = new FormatAdapter().readFile(formatted,
+ FormatAdapter.PASTE, format);
+ List<SequenceI> reread = reloaded.getSequences();
+ assertEquals("Wrong number of reloaded sequences", seqs.length,
+ reread.size());
+
+ int i = 0;
+ for (SequenceI seq : reread)
+ {
+ String sequenceString = seq.getSequenceAsString();
+
+ /*
+ * special case: MSF always uses '.' as gap character
+ */
+ sequenceString = adjustForGapTreatment(sequenceString, gap, format);
+ assertEquals(
+ String.format("Sequence %d: %s", i,
+ seqs[i].getName()), seqs[i].getSequenceAsString(),
+ sequenceString);
+ i++;
+ }
+ } catch (IOException e)
+ {
+ fail(String
+ .format("Format %s failed with %s", format, e.getMessage()));
+ }
+ }
+
+ /**
+ * Optionally change the gap character in the string to the given character,
+ * depending on the sequence file format
+ *
+ * @param sequenceString
+ * a sequence (as written in 'format' format)
+ * @param gap
+ * the sequence's original gap character
+ * @param format
+ * @return
+ */
+ String adjustForGapTreatment(String sequenceString, char gap,
+ String format)
+ {
+ if ("MSF".equals(format))
+ {
+ /*
+ * MSF forces gap character to '.', so change it back
+ * for comparison purposes
+ */
+ sequenceString = sequenceString.replace('.', gap);
+ }
+ return sequenceString;
+ }
+
+ /**
+ * Data provider that serves alignment formats that are both readable and
+ * writable
+ *
+ * @return
+ */
+ @DataProvider(name = "formats")
+ static Object[][] getFormats()
+ {
+ List<String> both = new ArrayList<String>();
+ String[] readable = FormatAdapter.READABLE_FORMATS;
+ List<String> writeable = Arrays.asList(FormatAdapter.WRITEABLE_FORMATS);
+ for (String r : readable)
+ {
+ if (writeable.contains(r))
+ {
+ both.add(r);
+ }
+ }
+
+ Object[][] formats = new Object[both.size()][];
+ int i = 0;
+ for (String format : both)
+ {
+ formats[i] = new Object[] { format };
+ i++;
+ }
+ return formats;
+ }
+
+ /**
+ * Enable this to isolate testing to a single file format
+ *
+ * @throws IOException
+ */
+ @Test(groups = { "Functional" }, enabled = false)
+ public void testOneFormatRoundTrip() throws IOException
+ {
+ testRoundTrip("JSON");
+ }
+}