X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fdatamodel%2FSequenceTest.java;h=d7e720e8887eefde157e763eadf65cb78a958650;hb=b9d3d1f71c6a8aee09cd23e1303b062cbe43a239;hp=24a63dc4b7e65d01b1b84163c1bd286faafc9235;hpb=a64dc4fefdcb2447a3f0b09ddfdcb64392731c6e;p=jalview.git diff --git a/test/jalview/datamodel/SequenceTest.java b/test/jalview/datamodel/SequenceTest.java index 24a63dc..d7e720e 100644 --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@ -23,22 +23,39 @@ package jalview.datamodel; import static org.testng.AssertJUnit.assertEquals; import static org.testng.AssertJUnit.assertFalse; import static org.testng.AssertJUnit.assertNotNull; +import static org.testng.AssertJUnit.assertNotSame; import static org.testng.AssertJUnit.assertNull; import static org.testng.AssertJUnit.assertSame; import static org.testng.AssertJUnit.assertTrue; import static org.testng.internal.junit.ArrayAsserts.assertArrayEquals; import jalview.datamodel.PDBEntry.Type; +import jalview.gui.JvOptionPane; +import jalview.util.MapList; +import java.io.File; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Vector; +import junit.extensions.PA; + +import org.testng.Assert; +import org.testng.annotations.BeforeClass; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; public class SequenceTest { + + @BeforeClass(alwaysRun = true) + public void setUpJvOptionPane() + { + JvOptionPane.setInteractiveMode(false); + JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); + } + Sequence seq; @BeforeMethod(alwaysRun = true) @@ -62,6 +79,30 @@ public class SequenceTest assertEquals("Gap interval 2 end wrong", 8, gapInt.get(1)[1]); } + @Test(groups = ("Functional")) + public void testIsProtein() + { + // test Protein + assertTrue(new Sequence("prot", "ASDFASDFASDF").isProtein()); + // test DNA + assertFalse(new Sequence("prot", "ACGTACGTACGT").isProtein()); + // test RNA + SequenceI sq = new Sequence("prot", "ACGUACGUACGU"); + assertFalse(sq.isProtein()); + // change sequence, should trigger an update of cached result + sq.setSequence("ASDFASDFADSF"); + assertTrue(sq.isProtein()); + /* + * in situ change of sequence doesn't change hashcode :-O + * (sequence should not expose internal implementation) + */ + for (int i = 0; i < sq.getSequence().length; i++) + { + sq.getSequence()[i] = "acgtu".charAt(i % 5); + } + assertTrue(sq.isProtein()); // but it isn't + } + @Test(groups = { "Functional" }) public void testGetAnnotation() { @@ -83,8 +124,7 @@ public class SequenceTest { AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1", 1f); - AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2", - 1f); + addAnnotation("label2", "desc2", "calcId2", 1f); AlignmentAnnotation ann3 = addAnnotation("label1", "desc3", "calcId3", 1f); AlignmentAnnotation[] anns = seq.getAnnotation("label1"); @@ -106,16 +146,15 @@ public class SequenceTest @Test(groups = { "Functional" }) public void testGetAlignmentAnnotations_forCalcIdAndLabel() { - AlignmentAnnotation ann1 = addAnnotation("label1", "desc1", "calcId1", - 1f); + addAnnotation("label1", "desc1", "calcId1", 1f); AlignmentAnnotation ann2 = addAnnotation("label2", "desc2", "calcId2", 1f); - AlignmentAnnotation ann3 = addAnnotation("label2", "desc3", "calcId3", - 1f); + addAnnotation("label2", "desc3", "calcId3", 1f); AlignmentAnnotation ann4 = addAnnotation("label2", "desc3", "calcId2", 1f); - AlignmentAnnotation ann5 = addAnnotation("label5", "desc3", null, 1f); - AlignmentAnnotation ann6 = addAnnotation(null, "desc3", "calcId3", 1f); + addAnnotation("label5", "desc3", null, 1f); + addAnnotation(null, "desc3", "calcId3", 1f); + List anns = seq.getAlignmentAnnotations("calcId2", "label2"); assertEquals(2, anns.size()); @@ -249,19 +288,129 @@ public class SequenceTest @Test(groups = { "Functional" }) public void testDeleteChars() { + /* + * internal delete + */ + SequenceI sq = new Sequence("test", "ABCDEF"); + assertNull(PA.getValue(sq, "datasetSequence")); + assertEquals(1, sq.getStart()); + assertEquals(6, sq.getEnd()); + sq.deleteChars(2, 3); + assertEquals("ABDEF", sq.getSequenceAsString()); + assertEquals(1, sq.getStart()); + assertEquals(5, sq.getEnd()); + assertNull(PA.getValue(sq, "datasetSequence")); + + /* + * delete at start + */ + sq = new Sequence("test", "ABCDEF"); + sq.deleteChars(0, 2); + assertEquals("CDEF", sq.getSequenceAsString()); + assertEquals(3, sq.getStart()); + assertEquals(6, sq.getEnd()); + assertNull(PA.getValue(sq, "datasetSequence")); + + /* + * delete at end + */ + sq = new Sequence("test", "ABCDEF"); + sq.deleteChars(4, 6); + assertEquals("ABCD", sq.getSequenceAsString()); + assertEquals(1, sq.getStart()); + assertEquals(4, sq.getEnd()); + assertNull(PA.getValue(sq, "datasetSequence")); + } + + @Test(groups = { "Functional" }) + public void testDeleteChars_withDbRefsAndFeatures() + { + /* + * internal delete - new dataset sequence created + * gets a copy of any dbrefs + */ SequenceI sq = new Sequence("test", "ABCDEF"); + sq.createDatasetSequence(); + DBRefEntry dbr1 = new DBRefEntry("Uniprot", "0", "a123"); + sq.addDBRef(dbr1); + Object ds = PA.getValue(sq, "datasetSequence"); + assertNotNull(ds); assertEquals(1, sq.getStart()); assertEquals(6, sq.getEnd()); sq.deleteChars(2, 3); assertEquals("ABDEF", sq.getSequenceAsString()); assertEquals(1, sq.getStart()); assertEquals(5, sq.getEnd()); + Object newDs = PA.getValue(sq, "datasetSequence"); + assertNotNull(newDs); + assertNotSame(ds, newDs); + assertNotNull(sq.getDBRefs()); + assertEquals(1, sq.getDBRefs().length); + assertNotSame(dbr1, sq.getDBRefs()[0]); + assertEquals(dbr1, sq.getDBRefs()[0]); + + /* + * internal delete with sequence features + * (failure case for JAL-2541) + */ + sq = new Sequence("test", "ABCDEF"); + sq.createDatasetSequence(); + SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 2, 4, 2f, + "CathGroup"); + sq.addSequenceFeature(sf1); + ds = PA.getValue(sq, "datasetSequence"); + assertNotNull(ds); + assertEquals(1, sq.getStart()); + assertEquals(6, sq.getEnd()); + sq.deleteChars(2, 4); + assertEquals("ABEF", sq.getSequenceAsString()); + assertEquals(1, sq.getStart()); + assertEquals(4, sq.getEnd()); + newDs = PA.getValue(sq, "datasetSequence"); + assertNotNull(newDs); + assertNotSame(ds, newDs); + SequenceFeature[] sfs = sq.getSequenceFeatures(); + assertNotNull(sfs); + assertEquals(1, sfs.length); + assertNotSame(sf1, sfs[0]); + assertEquals(sf1, sfs[0]); + /* + * delete at start - no new dataset sequence created + * any sequence features remain as before + */ sq = new Sequence("test", "ABCDEF"); + sq.createDatasetSequence(); + ds = PA.getValue(sq, "datasetSequence"); + sf1 = new SequenceFeature("Cath", "desc", 2, 4, 2f, "CathGroup"); + sq.addSequenceFeature(sf1); sq.deleteChars(0, 2); assertEquals("CDEF", sq.getSequenceAsString()); assertEquals(3, sq.getStart()); assertEquals(6, sq.getEnd()); + assertSame(ds, PA.getValue(sq, "datasetSequence")); + sfs = sq.getSequenceFeatures(); + assertNotNull(sfs); + assertEquals(1, sfs.length); + assertSame(sf1, sfs[0]); + + /* + * delete at end - no new dataset sequence created + * any dbrefs remain as before + */ + sq = new Sequence("test", "ABCDEF"); + sq.createDatasetSequence(); + ds = PA.getValue(sq, "datasetSequence"); + dbr1 = new DBRefEntry("Uniprot", "0", "a123"); + sq.addDBRef(dbr1); + sq.deleteChars(4, 6); + assertEquals("ABCD", sq.getSequenceAsString()); + assertEquals(1, sq.getStart()); + assertEquals(4, sq.getEnd()); + assertSame(ds, PA.getValue(sq, "datasetSequence")); + assertNotNull(sq.getDBRefs()); + assertEquals(1, sq.getDBRefs().length); + assertSame(dbr1, sq.getDBRefs()[0]); } @Test(groups = { "Functional" }) @@ -304,7 +453,7 @@ public class SequenceTest /* * SequenceFeature on sequence */ - SequenceFeature sf = new SequenceFeature(); + SequenceFeature sf = new SequenceFeature("Cath", "desc", 2, 4, 2f, null); sq.addSequenceFeature(sf); SequenceFeature[] sfs = sq.getSequenceFeatures(); assertEquals(1, sfs.length); @@ -313,8 +462,12 @@ public class SequenceTest /* * SequenceFeature on sequence and dataset sequence; returns that on * sequence + * + * Note JAL-2046: spurious: we have no use case for this at the moment. + * This test also buggy - as sf2.equals(sf), no new feature is added */ - SequenceFeature sf2 = new SequenceFeature(); + SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 2, 4, 2f, + null); sq.getDatasetSequence().addSequenceFeature(sf2); sfs = sq.getSequenceFeatures(); assertEquals(1, sfs.length); @@ -322,18 +475,30 @@ public class SequenceTest /* * SequenceFeature on dataset sequence only + * Note JAL-2046: spurious: we have no use case for setting a non-dataset sequence's feature array to null at the moment. */ sq.setSequenceFeatures(null); - sfs = sq.getSequenceFeatures(); - assertEquals(1, sfs.length); - assertSame(sf2, sfs[0]); + assertNull(sq.getDatasetSequence().getSequenceFeatures()); /* * Corrupt case - no SequenceFeature, dataset's dataset is the original * sequence. Test shows no infinite loop results. */ sq.getDatasetSequence().setSequenceFeatures(null); - sq.getDatasetSequence().setDatasetSequence(sq); // loop! + /** + * is there a usecase for this ? setDatasetSequence should throw an error if + * this actually occurs. + */ + try + { + sq.getDatasetSequence().setDatasetSequence(sq); // loop! + Assert.fail("Expected Error to be raised when calling setDatasetSequence with self reference"); + } catch (IllegalArgumentException e) + { + // TODO Jalview error/exception class for raising implementation errors + assertTrue(e.getMessage().toLowerCase() + .contains("implementation error")); + } assertNull(sq.getSequenceFeatures()); } @@ -378,6 +543,35 @@ public class SequenceTest } /** + * test createDatasetSequence behaves to doc + */ + @Test(groups = { "Functional" }) + public void testCreateDatasetSequence() + { + SequenceI sq = new Sequence("my", "ASDASD"); + sq.addSequenceFeature(new SequenceFeature("type", "desc", 1, 10, 1f, + "group")); + sq.addDBRef(new DBRefEntry("source", "version", "accession")); + assertNull(sq.getDatasetSequence()); + assertNotNull(PA.getValue(sq, "sequenceFeatures")); // to be removed! + assertNotNull(PA.getValue(sq, "sequenceFeatureStore")); + assertNotNull(PA.getValue(sq, "dbrefs")); + + SequenceI rds = sq.createDatasetSequence(); + assertNotNull(rds); + assertNull(rds.getDatasetSequence()); + assertSame(sq.getDatasetSequence(), rds); + + // sequence features and dbrefs transferred to dataset sequence + assertNull(PA.getValue(sq, "sequenceFeatures")); + assertNull(PA.getValue(sq, "sequenceFeatureStore")); + assertNull(PA.getValue(sq, "dbrefs")); + assertNotNull(PA.getValue(rds, "sequenceFeatures")); + assertNotNull(PA.getValue(rds, "sequenceFeatureStore")); + assertNotNull(PA.getValue(rds, "dbrefs")); + } + + /** * Test for deriveSequence applied to a sequence with a dataset */ @Test(groups = { "Functional" }) @@ -390,7 +584,94 @@ public class SequenceTest sq.setStart(3); sq.setEnd(4); + sq.setDescription("Test sequence description.."); + sq.setVamsasId("TestVamsasId"); + sq.addDBRef(new DBRefEntry("PDB", "version0", "1TST")); + + sq.addDBRef(new DBRefEntry("PDB", "version1", "1PDB")); + sq.addDBRef(new DBRefEntry("PDB", "version2", "2PDB")); + sq.addDBRef(new DBRefEntry("PDB", "version3", "3PDB")); + sq.addDBRef(new DBRefEntry("PDB", "version4", "4PDB")); + + sq.addPDBId(new PDBEntry("1PDB", "A", Type.PDB, "filePath/test1")); + sq.addPDBId(new PDBEntry("1PDB", "B", Type.PDB, "filePath/test1")); + sq.addPDBId(new PDBEntry("2PDB", "A", Type.MMCIF, "filePath/test2")); + sq.addPDBId(new PDBEntry("2PDB", "B", Type.MMCIF, "filePath/test2")); + + // these are the same as ones already added + DBRefEntry pdb1pdb = new DBRefEntry("PDB", "version1", "1PDB"); + DBRefEntry pdb2pdb = new DBRefEntry("PDB", "version2", "2PDB"); + + List primRefs = Arrays.asList(new DBRefEntry[] { pdb1pdb, + pdb2pdb }); + + sq.getDatasetSequence().addDBRef(pdb1pdb); // should do nothing + sq.getDatasetSequence().addDBRef(pdb2pdb); // should do nothing + sq.getDatasetSequence().addDBRef( + new DBRefEntry("PDB", "version3", "3PDB")); // should do nothing + sq.getDatasetSequence().addDBRef( + new DBRefEntry("PDB", "version4", "4PDB")); // should do nothing + + PDBEntry pdbe1a = new PDBEntry("1PDB", "A", Type.PDB, "filePath/test1"); + PDBEntry pdbe1b = new PDBEntry("1PDB", "B", Type.PDB, "filePath/test1"); + PDBEntry pdbe2a = new PDBEntry("2PDB", "A", Type.MMCIF, + "filePath/test2"); + PDBEntry pdbe2b = new PDBEntry("2PDB", "B", Type.MMCIF, + "filePath/test2"); + sq.getDatasetSequence().addPDBId(pdbe1a); + sq.getDatasetSequence().addPDBId(pdbe1b); + sq.getDatasetSequence().addPDBId(pdbe2a); + sq.getDatasetSequence().addPDBId(pdbe2b); + + /* + * test we added pdb entries to the dataset sequence + */ + Assert.assertEquals(sq.getDatasetSequence().getAllPDBEntries(), Arrays + .asList(new PDBEntry[] { pdbe1a, pdbe1b, pdbe2a, pdbe2b }), + "PDB Entries were not found on dataset sequence."); + + /* + * we should recover a pdb entry that is on the dataset sequence via PDBEntry + */ + Assert.assertEquals(pdbe1a, + sq.getDatasetSequence().getPDBEntry("1PDB"), + "PDB Entry '1PDB' not found on dataset sequence via getPDBEntry."); + ArrayList annotsList = new ArrayList(); + System.out.println(">>>>>> " + sq.getSequenceAsString().length()); + annotsList.add(new Annotation("A", "A", 'X', 0.1f)); + annotsList.add(new Annotation("A", "A", 'X', 0.1f)); + Annotation[] annots = annotsList.toArray(new Annotation[0]); + sq.addAlignmentAnnotation(new AlignmentAnnotation("Test annot", + "Test annot description", annots)); + sq.getDatasetSequence().addAlignmentAnnotation( + new AlignmentAnnotation("Test annot", "Test annot description", + annots)); + Assert.assertEquals(sq.getDescription(), "Test sequence description.."); + Assert.assertEquals(sq.getDBRefs().length, 5); // DBRefs are on dataset + // sequence + Assert.assertEquals(sq.getAllPDBEntries().size(), 4); + Assert.assertNotNull(sq.getAnnotation()); + Assert.assertEquals(sq.getAnnotation()[0].annotations.length, 2); + Assert.assertEquals(sq.getDatasetSequence().getDBRefs().length, 5); // same + // as + // sq.getDBRefs() + Assert.assertEquals(sq.getDatasetSequence().getAllPDBEntries().size(), + 4); + Assert.assertNotNull(sq.getDatasetSequence().getAnnotation()); + Sequence derived = (Sequence) sq.deriveSequence(); + + Assert.assertEquals(derived.getDescription(), + "Test sequence description.."); + Assert.assertEquals(derived.getDBRefs().length, 5); // come from dataset + Assert.assertEquals(derived.getAllPDBEntries().size(), 4); + Assert.assertNotNull(derived.getAnnotation()); + Assert.assertEquals(derived.getAnnotation()[0].annotations.length, 2); + Assert.assertEquals(derived.getDatasetSequence().getDBRefs().length, 5); + Assert.assertEquals(derived.getDatasetSequence().getAllPDBEntries() + .size(), 4); + Assert.assertNotNull(derived.getDatasetSequence().getAnnotation()); + assertEquals("CD", derived.getSequenceAsString()); assertSame(sq.getDatasetSequence(), derived.getDatasetSequence()); @@ -400,6 +681,17 @@ public class SequenceTest assertNotNull(sq.getSequenceFeatures()); assertArrayEquals(sq.getSequenceFeatures(), derived.getSequenceFeatures()); + + /* + * verify we have primary db refs *just* for PDB IDs with associated + * PDBEntry objects + */ + + assertEquals(primRefs, sq.getPrimaryDBRefs()); + assertEquals(primRefs, sq.getDatasetSequence().getPrimaryDBRefs()); + + assertEquals(sq.getPrimaryDBRefs(), derived.getPrimaryDBRefs()); + } /** @@ -444,7 +736,7 @@ public class SequenceTest 12.4f, "group")); seq1.addPDBId(new PDBEntry("1A70", "B", Type.PDB, "File")); seq1.addDBRef(new DBRefEntry("EMBL", "1.2", "AZ12345")); - + SequenceI copy = new Sequence(seq1); assertNull(copy.getDatasetSequence()); @@ -471,6 +763,8 @@ public class SequenceTest seq1.setDescription("description"); seq1.addAlignmentAnnotation(new AlignmentAnnotation("label", "desc", 1.3d)); + // JAL-2046 - what is the contract for using a derived sequence's + // addSequenceFeature ? seq1.addSequenceFeature(new SequenceFeature("type", "desc", 22, 33, 12.4f, "group")); seq1.addPDBId(new PDBEntry("1A70", "B", Type.PDB, "File")); @@ -518,9 +812,13 @@ public class SequenceTest // copy has a copy of the sequence feature: SequenceFeature[] sfs = copy.getSequenceFeatures(); assertEquals(1, sfs.length); - if (seq1.getDatasetSequence()!=null && copy.getDatasetSequence()==seq1.getDatasetSequence()) { + if (seq1.getDatasetSequence() != null + && copy.getDatasetSequence() == seq1.getDatasetSequence()) + { assertTrue(sfs[0] == seq1.getSequenceFeatures()[0]); - } else { + } + else + { assertFalse(sfs[0] == seq1.getSequenceFeatures()[0]); } assertTrue(sfs[0].equals(seq1.getSequenceFeatures()[0])); @@ -541,4 +839,334 @@ public class SequenceTest assertEquals(' ', sq.getCharAt(5)); assertEquals(' ', sq.getCharAt(-1)); } + + @Test(groups = { "Functional" }) + public void testAddSequenceFeatures() + { + SequenceI sq = new Sequence("", "abcde"); + // type may not be null + assertFalse(sq.addSequenceFeature(new SequenceFeature(null, "desc", 4, + 8, 0f, null))); + assertTrue(sq.addSequenceFeature(new SequenceFeature("Cath", "desc", 4, + 8, 0f, null))); + // can't add a duplicate feature + assertFalse(sq.addSequenceFeature(new SequenceFeature("Cath", "desc", + 4, 8, 0f, null))); + // can add a different feature + assertTrue(sq.addSequenceFeature(new SequenceFeature("Scop", "desc", 4, + 8, 0f, null))); // different type + assertTrue(sq.addSequenceFeature(new SequenceFeature("Cath", + "description", 4, 8, 0f, null)));// different description + assertTrue(sq.addSequenceFeature(new SequenceFeature("Cath", "desc", 3, + 8, 0f, null))); // different start position + assertTrue(sq.addSequenceFeature(new SequenceFeature("Cath", "desc", 4, + 9, 0f, null))); // different end position + assertTrue(sq.addSequenceFeature(new SequenceFeature("Cath", "desc", 4, + 8, 1f, null))); // different score + assertTrue(sq.addSequenceFeature(new SequenceFeature("Cath", "desc", 4, + 8, Float.NaN, null))); // score NaN + assertTrue(sq.addSequenceFeature(new SequenceFeature("Cath", "desc", 4, + 8, 0f, "Metal"))); // different group + assertEquals(8, sq.getFeatures().getAllFeatures().size()); + } + + /** + * Tests for adding (or updating) dbrefs + * + * @see DBRefEntry#updateFrom(DBRefEntry) + */ + @Test(groups = { "Functional" }) + public void testAddDBRef() + { + SequenceI sq = new Sequence("", "abcde"); + assertNull(sq.getDBRefs()); + DBRefEntry dbref = new DBRefEntry("Uniprot", "1", "P00340"); + sq.addDBRef(dbref); + assertEquals(1, sq.getDBRefs().length); + assertSame(dbref, sq.getDBRefs()[0]); + + /* + * change of version - new entry + */ + DBRefEntry dbref2 = new DBRefEntry("Uniprot", "2", "P00340"); + sq.addDBRef(dbref2); + assertEquals(2, sq.getDBRefs().length); + assertSame(dbref, sq.getDBRefs()[0]); + assertSame(dbref2, sq.getDBRefs()[1]); + + /* + * matches existing entry - not added + */ + sq.addDBRef(new DBRefEntry("UNIPROT", "1", "p00340")); + assertEquals(2, sq.getDBRefs().length); + + /* + * different source = new entry + */ + DBRefEntry dbref3 = new DBRefEntry("UniRef", "1", "p00340"); + sq.addDBRef(dbref3); + assertEquals(3, sq.getDBRefs().length); + assertSame(dbref3, sq.getDBRefs()[2]); + + /* + * different ref = new entry + */ + DBRefEntry dbref4 = new DBRefEntry("UniRef", "1", "p00341"); + sq.addDBRef(dbref4); + assertEquals(4, sq.getDBRefs().length); + assertSame(dbref4, sq.getDBRefs()[3]); + + /* + * matching ref with a mapping - map updated + */ + DBRefEntry dbref5 = new DBRefEntry("UniRef", "1", "p00341"); + Mapping map = new Mapping(new MapList(new int[] { 1, 3 }, new int[] { + 1, 1 }, 3, 1)); + dbref5.setMap(map); + sq.addDBRef(dbref5); + assertEquals(4, sq.getDBRefs().length); + assertSame(dbref4, sq.getDBRefs()[3]); + assertSame(map, dbref4.getMap()); + + /* + * 'real' version replaces "0" version + */ + dbref2.setVersion("0"); + DBRefEntry dbref6 = new DBRefEntry(dbref2.getSource(), "3", + dbref2.getAccessionId()); + sq.addDBRef(dbref6); + assertEquals(4, sq.getDBRefs().length); + assertSame(dbref2, sq.getDBRefs()[1]); + assertEquals("3", dbref2.getVersion()); + + /* + * 'real' version replaces "source:0" version + */ + dbref3.setVersion("Uniprot:0"); + DBRefEntry dbref7 = new DBRefEntry(dbref3.getSource(), "3", + dbref3.getAccessionId()); + sq.addDBRef(dbref7); + assertEquals(4, sq.getDBRefs().length); + assertSame(dbref3, sq.getDBRefs()[2]); + assertEquals("3", dbref2.getVersion()); + } + + @Test(groups = { "Functional" }) + public void testGetPrimaryDBRefs_peptide() + { + SequenceI sq = new Sequence("aseq", "ASDFKYLMQPRST", 10, 22); + + // no dbrefs + List primaryDBRefs = sq.getPrimaryDBRefs(); + assertTrue(primaryDBRefs.isEmpty()); + + // empty dbrefs + sq.setDBRefs(new DBRefEntry[] {}); + primaryDBRefs = sq.getPrimaryDBRefs(); + assertTrue(primaryDBRefs.isEmpty()); + + // primary - uniprot + DBRefEntry upentry1 = new DBRefEntry("UNIPROT", "0", "Q04760"); + sq.addDBRef(upentry1); + + // primary - uniprot with congruent map + DBRefEntry upentry2 = new DBRefEntry("UNIPROT", "0", "Q04762"); + upentry2.setMap(new Mapping(null, new MapList(new int[] { 10, 22 }, + new int[] { 10, 22 }, 1, 1))); + sq.addDBRef(upentry2); + + // primary - uniprot with map of enclosing sequence + DBRefEntry upentry3 = new DBRefEntry("UNIPROT", "0", "Q04763"); + upentry3.setMap(new Mapping(null, new MapList(new int[] { 8, 24 }, + new int[] { 8, 24 }, 1, 1))); + sq.addDBRef(upentry3); + + // not primary - uniprot with map of sub-sequence (5') + DBRefEntry upentry4 = new DBRefEntry("UNIPROT", "0", "Q04764"); + upentry4.setMap(new Mapping(null, new MapList(new int[] { 10, 18 }, + new int[] { 10, 18 }, 1, 1))); + sq.addDBRef(upentry4); + + // not primary - uniprot with map that overlaps 3' + DBRefEntry upentry5 = new DBRefEntry("UNIPROT", "0", "Q04765"); + upentry5.setMap(new Mapping(null, new MapList(new int[] { 12, 22 }, + new int[] { 12, 22 }, 1, 1))); + sq.addDBRef(upentry5); + + // not primary - uniprot with map to different coordinates frame + DBRefEntry upentry6 = new DBRefEntry("UNIPROT", "0", "Q04766"); + upentry6.setMap(new Mapping(null, new MapList(new int[] { 12, 18 }, + new int[] { 112, 118 }, 1, 1))); + sq.addDBRef(upentry6); + + // not primary - dbref to 'non-core' database + DBRefEntry upentry7 = new DBRefEntry("Pfam", "0", "PF00903"); + sq.addDBRef(upentry7); + + // primary - type is PDB + DBRefEntry pdbentry = new DBRefEntry("PDB", "0", "1qip"); + sq.addDBRef(pdbentry); + + // not primary - PDBEntry has no file + sq.addDBRef(new DBRefEntry("PDB", "0", "1AAA")); + + // not primary - no PDBEntry + sq.addDBRef(new DBRefEntry("PDB", "0", "1DDD")); + + // add corroborating PDB entry for primary DBref - + // needs to have a file as well as matching ID + // note PDB ID is not treated as case sensitive + sq.addPDBId(new PDBEntry("1QIP", null, Type.PDB, new File("/blah") + .toString())); + + // not valid DBRef - no file.. + sq.addPDBId(new PDBEntry("1AAA", null, null, null)); + + primaryDBRefs = sq.getPrimaryDBRefs(); + assertEquals(4, primaryDBRefs.size()); + assertTrue("Couldn't find simple primary reference (UNIPROT)", + primaryDBRefs.contains(upentry1)); + assertTrue("Couldn't find mapped primary reference (UNIPROT)", + primaryDBRefs.contains(upentry2)); + assertTrue("Couldn't find mapped context reference (UNIPROT)", + primaryDBRefs.contains(upentry3)); + assertTrue("Couldn't find expected PDB primary reference", + primaryDBRefs.contains(pdbentry)); + } + + @Test(groups = { "Functional" }) + public void testGetPrimaryDBRefs_nucleotide() + { + SequenceI sq = new Sequence("aseq", "TGATCACTCGACTAGCATCAGCATA", 10, 34); + + // primary - Ensembl + DBRefEntry dbr1 = new DBRefEntry("ENSEMBL", "0", "ENSG1234"); + sq.addDBRef(dbr1); + + // not primary - Ensembl 'transcript' mapping of sub-sequence + DBRefEntry dbr2 = new DBRefEntry("ENSEMBL", "0", "ENST1234"); + dbr2.setMap(new Mapping(null, new MapList(new int[] { 15, 25 }, + new int[] { 1, 11 }, 1, 1))); + sq.addDBRef(dbr2); + + // primary - EMBL with congruent map + DBRefEntry dbr3 = new DBRefEntry("EMBL", "0", "J1234"); + dbr3.setMap(new Mapping(null, new MapList(new int[] { 10, 34 }, + new int[] { 10, 34 }, 1, 1))); + sq.addDBRef(dbr3); + + // not primary - to non-core database + DBRefEntry dbr4 = new DBRefEntry("CCDS", "0", "J1234"); + sq.addDBRef(dbr4); + + // not primary - to protein + DBRefEntry dbr5 = new DBRefEntry("UNIPROT", "0", "Q87654"); + sq.addDBRef(dbr5); + + List primaryDBRefs = sq.getPrimaryDBRefs(); + assertEquals(2, primaryDBRefs.size()); + assertTrue(primaryDBRefs.contains(dbr1)); + assertTrue(primaryDBRefs.contains(dbr3)); + } + + /** + * Test the method that updates the list of PDBEntry from any new DBRefEntry + * for PDB + */ + @Test(groups = { "Functional" }) + public void testUpdatePDBIds() + { + PDBEntry pdbe1 = new PDBEntry("3A6S", null, null, null); + seq.addPDBId(pdbe1); + seq.addDBRef(new DBRefEntry("Ensembl", "8", "ENST1234")); + seq.addDBRef(new DBRefEntry("PDB", "0", "1A70")); + seq.addDBRef(new DBRefEntry("PDB", "0", "4BQGa")); + seq.addDBRef(new DBRefEntry("PDB", "0", "3a6sB")); + // 7 is not a valid chain code: + seq.addDBRef(new DBRefEntry("PDB", "0", "2GIS7")); + + seq.updatePDBIds(); + List pdbIds = seq.getAllPDBEntries(); + assertEquals(4, pdbIds.size()); + assertSame(pdbe1, pdbIds.get(0)); + // chain code got added to 3A6S: + assertEquals("B", pdbe1.getChainCode()); + assertEquals("1A70", pdbIds.get(1).getId()); + // 4BQGA is parsed into id + chain + assertEquals("4BQG", pdbIds.get(2).getId()); + assertEquals("a", pdbIds.get(2).getChainCode()); + assertEquals("2GIS7", pdbIds.get(3).getId()); + assertNull(pdbIds.get(3).getChainCode()); + } + + /** + * Test the method that either adds a pdbid or updates an existing one + */ + @Test(groups = { "Functional" }) + public void testAddPDBId() + { + PDBEntry pdbe = new PDBEntry("3A6S", null, null, null); + seq.addPDBId(pdbe); + assertEquals(1, seq.getAllPDBEntries().size()); + assertSame(pdbe, seq.getPDBEntry("3A6S")); + assertSame(pdbe, seq.getPDBEntry("3a6s")); // case-insensitive + + // add the same entry + seq.addPDBId(pdbe); + assertEquals(1, seq.getAllPDBEntries().size()); + assertSame(pdbe, seq.getPDBEntry("3A6S")); + + // add an identical entry + seq.addPDBId(new PDBEntry("3A6S", null, null, null)); + assertEquals(1, seq.getAllPDBEntries().size()); + assertSame(pdbe, seq.getPDBEntry("3A6S")); + + // add a different entry + PDBEntry pdbe2 = new PDBEntry("1A70", null, null, null); + seq.addPDBId(pdbe2); + assertEquals(2, seq.getAllPDBEntries().size()); + assertSame(pdbe, seq.getAllPDBEntries().get(0)); + assertSame(pdbe2, seq.getAllPDBEntries().get(1)); + + // update pdbe with chain code, file, type + PDBEntry pdbe3 = new PDBEntry("3a6s", "A", Type.PDB, "filepath"); + seq.addPDBId(pdbe3); + assertEquals(2, seq.getAllPDBEntries().size()); + assertSame(pdbe, seq.getAllPDBEntries().get(0)); // updated in situ + assertEquals("3A6S", pdbe.getId()); // unchanged + assertEquals("A", pdbe.getChainCode()); // updated + assertEquals(Type.PDB.toString(), pdbe.getType()); // updated + assertEquals("filepath", pdbe.getFile()); // updated + assertSame(pdbe2, seq.getAllPDBEntries().get(1)); + + // add with a different file path + PDBEntry pdbe4 = new PDBEntry("3a6s", "A", Type.PDB, "filepath2"); + seq.addPDBId(pdbe4); + assertEquals(3, seq.getAllPDBEntries().size()); + assertSame(pdbe4, seq.getAllPDBEntries().get(2)); + + // add with a different chain code + PDBEntry pdbe5 = new PDBEntry("3a6s", "B", Type.PDB, "filepath"); + seq.addPDBId(pdbe5); + assertEquals(4, seq.getAllPDBEntries().size()); + assertSame(pdbe5, seq.getAllPDBEntries().get(3)); + } + + @Test( + groups = { "Functional" }, + expectedExceptions = { IllegalArgumentException.class }) + public void testSetDatasetSequence_toSelf() + { + seq.setDatasetSequence(seq); + } + + @Test( + groups = { "Functional" }, + expectedExceptions = { IllegalArgumentException.class }) + public void testSetDatasetSequence_cascading() + { + SequenceI seq2 = new Sequence("Seq2", "xyz"); + seq2.createDatasetSequence(); + seq.setDatasetSequence(seq2); + } }