+package jalview.io;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import jalview.analysis.scoremodels.ScoreMatrix;
+
+import java.io.IOException;
+import java.net.MalformedURLException;
+
+import org.testng.annotations.Test;
+
+public class ScoreMatrixFileTest
+{
+
+ /**
+ * Test a successful parse of a (small) score matrix file
+ *
+ * @throws IOException
+ * @throws MalformedURLException
+ */
+ @Test(groups = "Functional")
+ public void testParse() throws MalformedURLException, IOException
+ {
+ /*
+ * some messy but valid input data, with comma, space
+ * or tab (or combinations) as score value delimiters
+ * this example includes 'guide' symbols on score rows
+ */
+ String data = "ScoreMatrix MyTest\n" + "ATU tx-\n"
+ + "A,1.1,1.2,1.3,1.4, 1.5, 1.6, 1.7\n"
+ + "T,2.1 2.2 2.3 2.4 2.5 2.6 2.7\n"
+ + "U\t3.1\t3.2\t3.3\t3.4\t3.5\t3.6\t3.7\n"
+ + " 4.1 ,4.2,\t,4.3 ,\t4.4\t, \4.5,4.6 4.7\n"
+ + "t, 5.1,5.3,5.3,5.4,5.5, 5.6, 5.7\n"
+ + "x\t6.1, 6.2 6.3 6.4 6.5 6.6 6.7\n"
+ + "-, \t7.1\t7.2 7.3, 7.4, 7.5\t,7.6,7.7\n";
+ FileParse fp = new FileParse(data, DataSourceType.PASTE);
+ ScoreMatrixFile parser = new ScoreMatrixFile(fp);
+ ScoreMatrix sm = parser.parseMatrix();
+
+ assertNotNull(sm);
+ assertEquals(sm.getName(), "MyTest");
+ assertTrue(sm.isDNA());
+ assertFalse(sm.isProtein());
+ assertEquals(sm.getPairwiseScore('A', 'A'), 1.1f);
+ assertEquals(sm.getPairwiseScore('A', 'T'), 1.2f);
+ assertEquals(sm.getPairwiseScore('a', 'T'), 1.2f); // A/a equivalent
+ assertEquals(sm.getPairwiseScore('A', 't'), 1.5f); // T/t not equivalent
+ assertEquals(sm.getPairwiseScore('a', 't'), 1.5f);
+ assertEquals(sm.getPairwiseScore('T', ' '), 2.4f);
+ assertEquals(sm.getPairwiseScore('U', 'x'), 3.6f);
+ assertEquals(sm.getPairwiseScore('u', 'x'), 3.6f);
+ assertEquals(sm.getPairwiseScore('U', 'X'), 0f); // X (upper) unmapped
+ assertEquals(sm.getPairwiseScore('A', '.'), 0f); // . unmapped
+ assertEquals(sm.getPairwiseScore('-', '-'), 7.7f);
+ assertEquals(sm.getPairwiseScore('A', (char) 128), 0f); // out of range
+
+ /*
+ * without guide symbols on score rows
+ */
+ data = "ScoreMatrix MyTest\nXY\n1 2\n3 4\n";
+ fp = new FileParse(data, DataSourceType.PASTE);
+ parser = new ScoreMatrixFile(fp);
+ sm = parser.parseMatrix();
+ assertNotNull(sm);
+ assertEquals(sm.getPairwiseScore('X', 'X'), 1f);
+ assertEquals(sm.getPairwiseScore('X', 'y'), 2f);
+ assertEquals(sm.getPairwiseScore('y', 'x'), 3f);
+ assertEquals(sm.getPairwiseScore('y', 'Y'), 4f);
+ assertEquals(sm.getPairwiseScore('D', 'R'), 0f);
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_headerMissing()
+ {
+ String data;
+
+ data = "XY\n1 2\n3 4\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Format error: 'ScoreMatrix <name>' should be the first non-comment line");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_notEnoughRows()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 rows of score data in score matrix but only found 1");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_notEnoughColumns()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n3\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 scores at line 4 but found 1");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_tooManyColumns()
+ {
+ /*
+ * with two too many columns:
+ */
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n3 4 5 6\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 scores at line 4 but found 4");
+ }
+
+ /*
+ * with guide character and one too many columns:
+ */
+ data = "ScoreMatrix MyTest\nXY\nX 1 2\nY 3 4 5\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 scores at line 4 but found 4");
+ }
+
+ /*
+ * with no guide character and one too many columns:
+ * parser guesses the first column is the guide character
+ */
+ data = "ScoreMatrix MyTest\nXY\n1 2\n3 4 5\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Error parsing score matrix at line 4, expected 'Y' but found '3'");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_tooManyRows()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n3 4\n6 7";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Unexpected extra input line in score model file: '6 7'");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_badDelimiter()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1|2\n3|4\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Expected 2 scores at line 3 but found 1");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_badFloat()
+ {
+ String data = "ScoreMatrix MyTest\nXY\n1 2\n3 four\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Invalid score value 'four' at line 4 column 1");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_badGuideCharacter()
+ {
+ String data = "ScoreMatrix MyTest\nXY\nX 1 2\ny 3 4\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(e.getMessage(),
+ "Error parsing score matrix at line 4, expected 'Y' but found 'y'");
+ }
+ }
+
+ @Test(groups = "Functional")
+ public void testParse_nameMissing()
+ {
+ /*
+ * Name missing
+ */
+ String data = "ScoreMatrix\nXY\n1 2\n3 4\n";
+ try
+ {
+ new ScoreMatrixFile(new FileParse(data, DataSourceType.PASTE))
+ .parseMatrix();
+ fail("expected exception");
+ } catch (IOException e)
+ {
+ assertEquals(
+ e.getMessage(),
+ "Format error: expected 'ScoreMatrix <name>', found 'ScoreMatrix' at line 1");
+ }
+ }
+}