X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fdatamodel%2FAlignmentTest.java;h=915d860017f613bee10c3af5119bc58e365dbf87;hb=dedd44136e37982fc2c713ae229b5a97a9b0b639;hp=07b8abf0e6595a13a4a26cb2bc96da7b3accabe5;hpb=2b237dfb6fc6d232af79673700b2f57ae8d5a10f;p=jalview.git diff --git a/test/jalview/datamodel/AlignmentTest.java b/test/jalview/datamodel/AlignmentTest.java index 07b8abf..915d860 100644 --- a/test/jalview/datamodel/AlignmentTest.java +++ b/test/jalview/datamodel/AlignmentTest.java @@ -27,6 +27,7 @@ import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertSame; import static org.testng.AssertJUnit.assertTrue; +import jalview.datamodel.AlignedCodonFrame.SequenceToSequenceMapping; import jalview.io.AppletFormatAdapter; import jalview.io.FormatAdapter; import jalview.util.MapList; @@ -37,6 +38,7 @@ import java.util.Arrays; import java.util.Iterator; import java.util.List; +import org.testng.Assert; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; @@ -101,6 +103,305 @@ public class AlignmentTest return a; } + /** + * assert wrapper: tests all references in the given alignment are consistent + * + * @param alignment + */ + public static void assertAlignmentDatasetRefs(AlignmentI alignment) + { + verifyAlignmentDatasetRefs(alignment, true, null); + } + + /** + * assert wrapper: tests all references in the given alignment are consistent + * + * @param alignment + * @param message + * - prefixed to any assert failed messages + */ + public static void assertAlignmentDatasetRefs(AlignmentI alignment, + String message) + { + verifyAlignmentDatasetRefs(alignment, true, message); + } + + /** + * verify sequence and dataset references are properly contained within + * dataset + * + * @param alignment + * - the alignmentI object to verify (either alignment or dataset) + * @param raiseAssert + * - when set, testng assertions are raised. + * @param message + * - null or a string message to prepend to the assert failed messages. + * @return true if alignment references were in order, otherwise false. + */ + public static boolean verifyAlignmentDatasetRefs(AlignmentI alignment, + boolean raiseAssert, String message) + { + if (message==null) { message = ""; } + if (alignment == null) + { + if (raiseAssert) + { + Assert.fail(message+"Alignment for verification was null."); + } + return false; + } + if (alignment.getDataset() != null) + { + AlignmentI dataset = alignment.getDataset(); + // check all alignment sequences have their dataset within the dataset + for (SequenceI seq : alignment.getSequences()) + { + SequenceI seqds = seq.getDatasetSequence(); + if (seqds.getDatasetSequence() != null) + { + if (raiseAssert) + { + Assert.fail(message+" Alignment contained a sequence who's dataset sequence has a second dataset reference."); + } + return false; + } + if (dataset.findIndex(seqds) == -1) + { + if (raiseAssert) + { + Assert.fail(message+" Alignment contained a sequence who's dataset sequence was not in the dataset."); + } + return false; + } + } + return verifyAlignmentDatasetRefs(alignment.getDataset(), raiseAssert, message); + } + else + { + // verify all dataset sequences + for (SequenceI seqds : alignment.getSequences()) + { + if (seqds.getDatasetSequence() != null) + { + if (raiseAssert) + { + Assert.fail(message+" Dataset contained a sequence with non-null dataset reference (ie not a dataset sequence!)"); + } + return false; + } + if (seqds.getDBRefs() != null) + { + for (DBRefEntry dbr : seqds.getDBRefs()) + { + if (dbr.getMap() != null) + { + SequenceI seqdbrmapto = dbr.getMap().getTo(); + if (seqdbrmapto != null) + { + if (seqdbrmapto.getDatasetSequence() != null) + { + if (raiseAssert) + { + Assert.fail(message+" DBRefEntry for sequence in alignment had map to sequence which was not a dataset sequence"); + } + return false; + + } + if (alignment.findIndex(dbr.getMap().getTo()) == -1) + { + if (raiseAssert) + { + Assert.fail(message+" DBRefEntry for sequence in alignment had map to sequence not in dataset"); + } + return false; + } + } + } + } + } + } + // finally, verify codonmappings involve only dataset sequences. + if (alignment.getCodonFrames() != null) + { + for (AlignedCodonFrame alc : alignment.getCodonFrames()) + { + for (SequenceToSequenceMapping ssm : alc.getMappings()) + { + if (ssm.getFromSeq().getDatasetSequence() != null) + { + if (raiseAssert) + { + Assert.fail(message+" CodonFrame-SSM-FromSeq is not a dataset sequence"); + } + return false; + } + if (alignment.findIndex(ssm.getFromSeq()) == -1) + { + + if (raiseAssert) + { + Assert.fail(message+" CodonFrame-SSM-FromSeq is not contained in dataset"); + } + return false; + } + if (ssm.getMapping().getTo().getDatasetSequence() != null) + { + if (raiseAssert) + { + Assert.fail(message+" CodonFrame-SSM-Mapping-ToSeq is not a dataset sequence"); + } + return false; + } + if (alignment.findIndex(ssm.getMapping().getTo()) == -1) + { + + if (raiseAssert) + { + Assert.fail(message+" CodonFrame-SSM-Mapping-ToSeq is not contained in dataset"); + } + return false; + } + } + } + } + } + return true; // all relationships verified! + } + + /** + * call verifyAlignmentDatasetRefs with and without assertion raising enabled, + * to check expected pass/fail actually occurs in both conditions + * + * @param al + * @param expected + * @param msg + */ + private void assertVerifyAlignment(AlignmentI al, boolean expected, + String msg) + { + if (expected) + { + try + { + + Assert.assertTrue(verifyAlignmentDatasetRefs(al, true, null), + "Valid test alignment failed when raiseAsserts enabled:" + + msg); + } catch (AssertionError ae) + { + ae.printStackTrace(); + Assert.fail( + "Valid test alignment raised assertion errors when raiseAsserts enabled: " + + msg, ae); + } + // also check validation passes with asserts disabled + Assert.assertTrue(verifyAlignmentDatasetRefs(al, false, null), + "Valid test alignment failed when raiseAsserts disabled:" + + msg); + } + else + { + try + { + Assert.assertFalse(verifyAlignmentDatasetRefs(al, true, null)); + Assert.fail("Invalid test alignment passed but no assertion raised when raiseAsserts enabled:" + + msg); + } catch (AssertionError ae) + { + // expected behaviour + } + // also check validation passes with asserts disabled + Assert.assertFalse(verifyAlignmentDatasetRefs(al, false, null), + "Invalid test alignment passed when raiseAsserts disabled:" + + msg); + } + } + @Test(groups = { "Functional" }) + public void testVerifyAlignmentDatasetRefs() + { + SequenceI sq1 = new Sequence("sq1", "ASFDD"), sq2 = new Sequence("sq2", + "TTTTTT"); + + // construct simple valid alignment dataset + Alignment al = new Alignment(new SequenceI[] { + sq1, sq2 }); + // expect this to pass + assertVerifyAlignment(al, true, "Simple valid alignment didn't verify"); + + // check test for sequence->datasetSequence validity + sq1.setDatasetSequence(sq2); + assertVerifyAlignment( + al, + false, + "didn't detect dataset sequence with a dataset sequence reference."); + + sq1.setDatasetSequence(null); + assertVerifyAlignment( + al, + true, + "didn't reinstate validity after nulling dataset sequence dataset reference"); + + // now create dataset and check again + al.createDatasetAlignment(); + assertNotNull(al.getDataset()); + + assertVerifyAlignment(al, true, + "verify failed after createDatasetAlignment"); + + // create a dbref on sq1 with a sequence ref to sq2 + DBRefEntry dbrs1tos2 = new DBRefEntry("UNIPROT", "1", "Q111111"); + dbrs1tos2.setMap(new Mapping(sq2.getDatasetSequence(), + new int[] { 1, 5 }, new int[] { 2, 6 }, 1, 1)); + sq1.getDatasetSequence().addDBRef(dbrs1tos2); + assertVerifyAlignment(al, true, + "verify failed after addition of valid DBRefEntry/map"); + // now create a dbref on a new sequence which maps to another sequence + // outside of the dataset + SequenceI sqout = new Sequence("sqout", "ututututucagcagcag"), sqnew = new Sequence( + "sqnew", "EEERRR"); + DBRefEntry sqnewsqout = new DBRefEntry("ENAFOO", "1", "R000001"); + sqnewsqout.setMap(new Mapping(sqout, new int[] { 1, 6 }, new int[] { 1, + 18 }, 1, 3)); + al.getDataset().addSequence(sqnew); + + assertVerifyAlignment(al, true, + "verify failed after addition of new sequence to dataset"); + // now start checking exception conditions + sqnew.addDBRef(sqnewsqout); + assertVerifyAlignment( + al, + false, + "verify passed when a dbref with map to sequence outside of dataset was added"); + // make the verify pass by adding the outsider back in + al.getDataset().addSequence(sqout); + assertVerifyAlignment(al, true, + "verify should have passed after adding dbref->to sequence in to dataset"); + // and now the same for a codon mapping... + SequenceI sqanotherout = new Sequence("sqanotherout", + "aggtutaggcagcagcag"); + + AlignedCodonFrame alc = new AlignedCodonFrame(); + alc.addMap(sqanotherout, sqnew, new MapList(new int[] { 1, 6 }, + new int[] { 1, 18 }, 3, 1)); + + al.addCodonFrame(alc); + Assert.assertEquals(al.getDataset().getCodonFrames().size(), 1); + + assertVerifyAlignment( + al, + false, + "verify passed when alCodonFrame mapping to sequence outside of dataset was added"); + // make the verify pass by adding the outsider back in + al.getDataset().addSequence(sqanotherout); + assertVerifyAlignment( + al, + true, + "verify should have passed once all sequences involved in alCodonFrame were added to dataset"); + al.getDataset().addSequence(sqanotherout); + assertVerifyAlignment(al, false, + "verify should have failed when a sequence was added twice to the dataset"); + + } /* * Read in Stockholm format test data including secondary structure * annotations. @@ -232,7 +533,7 @@ public class AlignmentTest * Realign DNA; currently keeping existing gaps in introns only */ ((Alignment) al1).alignAs(al2, false, true); - assertEquals("ACG---GCUCCA------ACT", al1.getSequenceAt(0) + assertEquals("ACG---GCUCCA------ACT---", al1.getSequenceAt(0) .getSequenceAsString()); assertEquals("---CGT---TAACGA---AGT---", al1.getSequenceAt(1) .getSequenceAsString()); @@ -460,6 +761,60 @@ public class AlignmentTest assertTrue(ds.getCodonFrames().contains(acf)); } + /** + * tests the addition of *all* sequences referred to by a sequence being added + * to the dataset + */ + @Test(groups = "Functional") + public void testCreateDatasetAlignmentWithMappedToSeqs() + { + // Alignment with two sequences, gapped. + SequenceI sq1 = new Sequence("sq1", "A--SDF"); + SequenceI sq2 = new Sequence("sq2", "G--TRQ"); + + // cross-references to two more sequences. + DBRefEntry dbr = new DBRefEntry("SQ1", "", "sq3"); + SequenceI sq3 = new Sequence("sq3", "VWANG"); + dbr.setMap(new Mapping(sq3, new MapList(new int[] { 1, 4 }, new int[] { + 2, 5 }, 1, 1))); + sq1.addDBRef(dbr); + + SequenceI sq4 = new Sequence("sq4", "ERKWI"); + DBRefEntry dbr2 = new DBRefEntry("SQ2", "", "sq4"); + dbr2.setMap(new Mapping(sq4, new MapList(new int[] { 1, 4 }, new int[] { + 2, 5 }, 1, 1))); + sq2.addDBRef(dbr2); + // and a 1:1 codonframe mapping between them. + AlignedCodonFrame alc = new AlignedCodonFrame(); + alc.addMap(sq1, sq2, new MapList(new int[] { 1, 4 }, + new int[] { 1, 4 }, 1, 1)); + + AlignmentI protein = new Alignment(new SequenceI[] { sq1, sq2 }); + + /* + * create the alignment dataset + * note this creates sequence datasets where missing + * as a side-effect (in this case, on seq2 + */ + + // TODO promote this method to AlignmentI + ((Alignment) protein).createDatasetAlignment(); + + AlignmentI ds = protein.getDataset(); + + // should be 4 sequences in dataset - two materialised, and two propagated + // from dbref + assertEquals(4, ds.getHeight()); + assertTrue(ds.getSequences().contains(sq1.getDatasetSequence())); + assertTrue(ds.getSequences().contains(sq2.getDatasetSequence())); + assertTrue(ds.getSequences().contains(sq3)); + assertTrue(ds.getSequences().contains(sq4)); + // Should have one codon frame mapping between sq1 and sq2 via dataset + // sequences + assertEquals(ds.getCodonFrame(sq1.getDatasetSequence()), + ds.getCodonFrame(sq2.getDatasetSequence())); + } + @Test(groups = "Functional") public void testAddCodonFrame() {