JAL-2189 format tests
[jalview.git] / test / jalview / io / FormatAdapterTest.java
1 package jalview.io;
2
3 import static org.testng.AssertJUnit.assertEquals;
4 import static org.testng.AssertJUnit.assertNotNull;
5 import static org.testng.AssertJUnit.fail;
6
7 import jalview.datamodel.AlignmentI;
8 import jalview.datamodel.SequenceI;
9
10 import java.io.IOException;
11 import java.util.ArrayList;
12 import java.util.Arrays;
13 import java.util.List;
14
15 import org.testng.annotations.DataProvider;
16 import org.testng.annotations.Test;
17
18 public class FormatAdapterTest
19 {
20
21   /**
22    * Test saving and re-reading in a specified format
23    * 
24    * @throws IOException
25    */
26   @Test(groups = { "Functional" }, dataProvider = "formats")
27   public void testRoundTrip(String format) throws IOException
28   {
29     try
30     {
31       AlignmentI al = new FormatAdapter().readFile("examples/uniref50.fa",
32               FormatAdapter.FILE, "FASTA");
33
34       /*
35        * 'gap' is the gap character used in the alignment data file here,
36        * not the user preferred gap character
37        */
38       char gap = al.getGapCharacter();
39       assertNotNull(al);
40
41       SequenceI[] seqs = al.getSequencesArray();
42       String formatted = new FormatAdapter().formatSequences(format, al,
43               false);
44
45       AlignmentI reloaded = new FormatAdapter().readFile(formatted,
46               FormatAdapter.PASTE, format);
47       List<SequenceI> reread = reloaded.getSequences();
48       assertEquals("Wrong number of reloaded sequences", seqs.length,
49               reread.size());
50
51       int i = 0;
52       for (SequenceI seq : reread)
53       {
54         String sequenceString = seq.getSequenceAsString();
55
56         /*
57          * special case: MSF always uses '.' as gap character
58          */
59         sequenceString = adjustForGapTreatment(sequenceString, gap, format);
60         assertEquals(
61                 String.format("Sequence %d: %s", i, seqs[i].getName()),
62                 seqs[i].getSequenceAsString(), sequenceString);
63         i++;
64       }
65     } catch (IOException e)
66     {
67       fail(String
68               .format("Format %s failed with %s", format, e.getMessage()));
69     }
70   }
71
72   /**
73    * Optionally change the gap character in the string to the given character,
74    * depending on the sequence file format
75    * 
76    * @param sequenceString
77    *          a sequence (as written in 'format' format)
78    * @param gap
79    *          the sequence's original gap character
80    * @param format
81    * @return
82    */
83   String adjustForGapTreatment(String sequenceString, char gap,
84           String format)
85   {
86     if ("MSF".equals(format))
87     {
88       /*
89        * MSF forces gap character to '.', so change it back
90        * for comparison purposes
91        */
92       sequenceString = sequenceString.replace('.', gap);
93     }
94     return sequenceString;
95   }
96
97   /**
98    * Data provider that serves alignment formats that are both readable and
99    * writable
100    * 
101    * @return
102    */
103   @DataProvider(name = "formats")
104   static Object[][] getFormats()
105   {
106     List<String> both = new ArrayList<String>();
107     String[] readable = FormatAdapter.READABLE_FORMATS;
108     List<String> writeable = Arrays.asList(FormatAdapter.WRITEABLE_FORMATS);
109     for (String r : readable)
110     {
111       if (writeable.contains(r))
112       {
113         both.add(r);
114       }
115     }
116
117     Object[][] formats = new Object[both.size()][];
118     int i = 0;
119     for (String format : both)
120     {
121       formats[i] = new Object[] { format };
122       i++;
123     }
124     return formats;
125   }
126
127   /**
128    * Enable this to isolate testing to a single file format
129    * 
130    * @throws IOException
131    */
132   @Test(groups = { "Functional" }, enabled = false)
133   public void testOneFormatRoundTrip() throws IOException
134   {
135     testRoundTrip("JSON");
136   }
137 }