X-Git-Url: http://source.jalview.org/gitweb/?a=blobdiff_plain;f=test%2Fjalview%2Fdatamodel%2FSequenceTest.java;h=68440725fc6bee2235f7b226fbc83550d14166f4;hb=92389e0816624da2c0530b0a7477c70f8da6ec4d;hp=97a75f9ee33cddbcc3f65ca63c83b254a484f763;hpb=b5aea33b1a9dcb1831ef681342be55c8929cf080;p=jalview.git diff --git a/test/jalview/datamodel/SequenceTest.java b/test/jalview/datamodel/SequenceTest.java index 97a75f9..6844072 100644 --- a/test/jalview/datamodel/SequenceTest.java +++ b/test/jalview/datamodel/SequenceTest.java @@ -106,15 +106,6 @@ public class SequenceTest // 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" }) @@ -286,6 +277,8 @@ public class SequenceTest SequenceI sq = new Sequence("test/8-13", "ABCDEF"); assertEquals(8, sq.findPosition(0)); // Sequence should now hold a cursor at [8, 0] + assertEquals("test:Pos8:Col1:startCol1:endCol0:tok0", + PA.getValue(sq, "cursor").toString()); SequenceCursor cursor = (SequenceCursor) PA.getValue(sq, "cursor"); int token = (int) PA.getValue(sq, "changeCount"); assertEquals(new SequenceCursor(sq, 8, 1, token), cursor); @@ -294,11 +287,14 @@ public class SequenceTest /* * find F13 at column offset 5, cursor should update to [13, 6] + * endColumn is found and saved in cursor */ assertEquals(13, sq.findPosition(5)); cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(++token, (int) PA.getValue(sq, "changeCount")); assertEquals(new SequenceCursor(sq, 13, 6, token), cursor); + assertEquals("test:Pos13:Col6:startCol1:endCol6:tok1", + PA.getValue(sq, "cursor").toString()); // assertEquals(-1, seq.findPosition(6)); // fails @@ -307,11 +303,15 @@ public class SequenceTest assertEquals(8, sq.findPosition(0)); cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(new SequenceCursor(sq, 8, 1, token), cursor); + assertEquals("test:Pos8:Col1:startCol1:endCol0:tok0", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); assertEquals(9, sq.findPosition(1)); cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(new SequenceCursor(sq, 9, 2, ++token), cursor); + assertEquals("test:Pos9:Col2:startCol1:endCol0:tok1", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); // gap position 'finds' residue to the right (not the left as per javadoc) @@ -319,11 +319,15 @@ public class SequenceTest assertEquals(10, sq.findPosition(2)); cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(new SequenceCursor(sq, 9, 2, ++token), cursor); + assertEquals("test:Pos9:Col2:startCol1:endCol0:tok2", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); assertEquals(10, sq.findPosition(3)); cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(new SequenceCursor(sq, 10, 4, ++token), cursor); + assertEquals("test:Pos10:Col4:startCol1:endCol0:tok3", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); // column[4] is the gap after C - returns D11 @@ -331,11 +335,16 @@ public class SequenceTest assertEquals(11, sq.findPosition(4)); cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(new SequenceCursor(sq, 10, 4, ++token), cursor); + assertEquals("test:Pos10:Col4:startCol1:endCol0:tok4", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); assertEquals(11, sq.findPosition(5)); // D cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(new SequenceCursor(sq, 11, 6, ++token), cursor); + // lastCol has been found and saved in the cursor + assertEquals("test:Pos11:Col6:startCol1:endCol6:tok5", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); // returns 1 more than sequence length if off the end ?!? @@ -344,38 +353,68 @@ public class SequenceTest sq.sequenceChanged(); assertEquals(12, sq.findPosition(7)); + /* + * first findPosition should also set firstResCol in cursor + */ sq = new Sequence("test/8-13", "--AB-C-DEF--"); assertEquals(8, sq.findPosition(0)); + assertNull(PA.getValue(sq, "cursor")); sq.sequenceChanged(); assertEquals(8, sq.findPosition(1)); + assertNull(PA.getValue(sq, "cursor")); sq.sequenceChanged(); assertEquals(8, sq.findPosition(2)); + assertEquals("test:Pos8:Col3:startCol3:endCol0:tok2", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); assertEquals(9, sq.findPosition(3)); + assertEquals("test:Pos9:Col4:startCol3:endCol0:tok3", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); + // column[4] is a gap, returns next residue pos (C10) + // cursor is set to last residue found [B] assertEquals(10, sq.findPosition(4)); + assertEquals("test:Pos9:Col4:startCol3:endCol0:tok4", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); assertEquals(10, sq.findPosition(5)); + assertEquals("test:Pos10:Col6:startCol3:endCol0:tok5", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); + // column[6] is a gap, returns next residue pos (D11) + // cursor is set to last residue found [C] assertEquals(11, sq.findPosition(6)); + assertEquals("test:Pos10:Col6:startCol3:endCol0:tok6", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); assertEquals(11, sq.findPosition(7)); + assertEquals("test:Pos11:Col8:startCol3:endCol0:tok7", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); assertEquals(12, sq.findPosition(8)); + assertEquals("test:Pos12:Col9:startCol3:endCol0:tok8", + PA.getValue(sq, "cursor").toString()); + /* + * when the last residue column is found, it is set in the cursor + */ sq.sequenceChanged(); assertEquals(13, sq.findPosition(9)); + assertEquals("test:Pos13:Col10:startCol3:endCol10:tok9", + PA.getValue(sq, "cursor").toString()); sq.sequenceChanged(); assertEquals(14, sq.findPosition(10)); + assertEquals("test:Pos13:Col10:startCol3:endCol10:tok10", + PA.getValue(sq, "cursor").toString()); /* * findPosition for column beyond sequence length @@ -383,8 +422,34 @@ public class SequenceTest */ sq.sequenceChanged(); assertEquals(14, sq.findPosition(11)); + assertEquals("test:Pos13:Col10:startCol3:endCol10:tok11", + PA.getValue(sq, "cursor").toString()); + sq.sequenceChanged(); assertEquals(14, sq.findPosition(99)); + assertEquals("test:Pos13:Col10:startCol3:endCol10:tok12", + PA.getValue(sq, "cursor").toString()); + + /* + * gapped sequence ending in non-gap + */ + sq = new Sequence("test/8-13", "--AB-C-DEF"); + assertEquals(13, sq.findPosition(9)); + assertEquals("test:Pos13:Col10:startCol3:endCol10:tok0", + PA.getValue(sq, "cursor").toString()); + sq.sequenceChanged(); + assertEquals(12, sq.findPosition(8)); + cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + // sequenceChanged() invalidates cursor.lastResidueColumn + cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals("test:Pos12:Col9:startCol3:endCol0:tok1", + cursor.toString()); + // findPosition with cursor accepts base 1 column values + assertEquals(13, ((Sequence) sq).findPosition(10, cursor)); + assertEquals(13, sq.findPosition(9)); // F13 + // lastResidueColumn has now been found and saved in cursor + assertEquals("test:Pos13:Col10:startCol3:endCol10:tok1", + PA.getValue(sq, "cursor").toString()); } @Test(groups = { "Functional" }) @@ -1278,23 +1343,25 @@ public class SequenceTest null); sq.addSequenceFeature(sf0); // add feature on BCD - SequenceFeature sf1 = new SequenceFeature("Cath", "desc", 9, 11, 2f, + SequenceFeature sfBCD = new SequenceFeature("Cath", "desc", 9, 11, 2f, null); - sq.addSequenceFeature(sf1); + sq.addSequenceFeature(sfBCD); // add feature on DE - SequenceFeature sf2 = new SequenceFeature("Cath", "desc", 11, 12, 2f, + SequenceFeature sfDE = new SequenceFeature("Cath", "desc", 11, 12, 2f, null); - sq.addSequenceFeature(sf2); + sq.addSequenceFeature(sfDE); // add contact feature at [B, H] - SequenceFeature sf3 = new SequenceFeature("Disulphide bond", "desc", 9, - 15, 2f, - null); - sq.addSequenceFeature(sf3); + SequenceFeature sfContactBH = new SequenceFeature("Disulphide bond", + "desc", 9, 15, 2f, null); + sq.addSequenceFeature(sfContactBH); // add contact feature at [F, G] - SequenceFeature sf4 = new SequenceFeature("Disulfide Bond", "desc", 13, - 14, 2f, - null); - sq.addSequenceFeature(sf4); + SequenceFeature sfContactFG = new SequenceFeature("Disulfide Bond", + "desc", 13, 14, 2f, null); + sq.addSequenceFeature(sfContactFG); + // add single position feature at [I] + SequenceFeature sfI = new SequenceFeature("Disulfide Bond", + "desc", 16, 16, null); + sq.addSequenceFeature(sfI); // no features in columns 1-2 (-A) List found = sq.findFeatures(1, 2); @@ -1303,20 +1370,29 @@ public class SequenceTest // columns 1-6 (-ABC--) includes BCD and B/H feature but not DE found = sq.findFeatures(1, 6); assertEquals(2, found.size()); - assertTrue(found.contains(sf1)); - assertTrue(found.contains(sf3)); + assertTrue(found.contains(sfBCD)); + assertTrue(found.contains(sfContactBH)); // columns 5-6 (--) includes (enclosing) BCD but not (contact) B/H feature found = sq.findFeatures(5, 6); assertEquals(1, found.size()); - assertTrue(found.contains(sf1)); + assertTrue(found.contains(sfBCD)); // columns 7-10 (DEF-) includes BCD, DE, F/G but not B/H feature found = sq.findFeatures(7, 10); assertEquals(3, found.size()); - assertTrue(found.contains(sf1)); - assertTrue(found.contains(sf2)); - assertTrue(found.contains(sf4)); + assertTrue(found.contains(sfBCD)); + assertTrue(found.contains(sfDE)); + assertTrue(found.contains(sfContactFG)); + + // columns 10-11 (--) should find nothing + found = sq.findFeatures(10, 11); + assertEquals(0, found.size()); + + // columns 14-14 (I) should find variant feature + found = sq.findFeatures(14, 14); + assertEquals(1, found.size()); + assertTrue(found.contains(sfI)); } @Test(groups = { "Functional" }) @@ -1339,41 +1415,41 @@ public class SequenceTest { Sequence sq = new Sequence("test/8-13", "-A--BCD-EF--"); - // find F pos given A + // find F pos given A - lastCol gets set in cursor assertEquals(13, sq.findPosition(10, new SequenceCursor(sq, 8, 2, 0))); - int token = (int) PA.getValue(sq, "changeCount"); // 0 - SequenceCursor cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 13, 10, token), cursor); + assertEquals("test:Pos13:Col10:startCol0:endCol10:tok0", + PA.getValue(sq, "cursor").toString()); - // find A pos given F + // find A pos given F - first residue column is saved in cursor assertEquals(8, sq.findPosition(2, new SequenceCursor(sq, 13, 10, 0))); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 8, 2, token), cursor); + assertEquals("test:Pos8:Col2:startCol2:endCol10:tok0", + PA.getValue(sq, "cursor").toString()); - // find C pos given C + // find C pos given C (neither startCol nor endCol is set) assertEquals(10, sq.findPosition(6, new SequenceCursor(sq, 10, 6, 0))); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 10, 6, token), cursor); + assertEquals("test:Pos10:Col6:startCol0:endCol0:tok0", + PA.getValue(sq, "cursor").toString()); // now the grey area - what residue position for a gapped column? JAL-2562 // find 'residue' for column 3 given cursor for D (so working left) // returns B9; cursor is updated to [B 5] assertEquals(9, sq.findPosition(3, new SequenceCursor(sq, 11, 7, 0))); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 9, 5, token), cursor); + assertEquals("test:Pos9:Col5:startCol0:endCol0:tok0", + PA.getValue(sq, "cursor").toString()); // find 'residue' for column 8 given cursor for D (so working right) // returns E12; cursor is updated to [D 7] assertEquals(12, sq.findPosition(8, new SequenceCursor(sq, 11, 7, 0))); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 11, 7, token), cursor); + assertEquals("test:Pos11:Col7:startCol0:endCol0:tok0", + PA.getValue(sq, "cursor").toString()); // find 'residue' for column 12 given cursor for B // returns 1 more than last residue position; cursor is updated to [F 10] + // lastCol position is saved in cursor assertEquals(14, sq.findPosition(12, new SequenceCursor(sq, 9, 5, 0))); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 13, 10, token), cursor); + assertEquals("test:Pos13:Col10:startCol0:endCol10:tok0", + PA.getValue(sq, "cursor").toString()); /* * findPosition for column beyond length of sequence @@ -1381,8 +1457,8 @@ public class SequenceTest * cursor is set to last real residue position [F 10] */ assertEquals(14, sq.findPosition(99, new SequenceCursor(sq, 8, 2, 0))); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 13, 10, token), cursor); + assertEquals("test:Pos13:Col10:startCol0:endCol10:tok0", + PA.getValue(sq, "cursor").toString()); /* * and the case without a trailing gap @@ -1390,13 +1466,14 @@ public class SequenceTest sq = new Sequence("test/8-13", "-A--BCD-EF"); // first find C from A assertEquals(10, sq.findPosition(6, new SequenceCursor(sq, 8, 2, 0))); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 10, 6, token), cursor); + SequenceCursor cursor = (SequenceCursor) PA.getValue(sq, "cursor"); + assertEquals("test:Pos10:Col6:startCol0:endCol0:tok0", + cursor.toString()); // now 'find' 99 from C - // cursor is set to [F 10] + // cursor is set to [F 10] and saved lastCol assertEquals(14, sq.findPosition(99, cursor)); - cursor = (SequenceCursor) PA.getValue(sq, "cursor"); - assertEquals(new SequenceCursor(sq, 13, 10, token), cursor); + assertEquals("test:Pos13:Col10:startCol0:endCol10:tok0", + PA.getValue(sq, "cursor").toString()); } @Test @@ -1414,11 +1491,11 @@ public class SequenceTest assertTrue(sq.isValidCursor(cursor)); /* - * column position outside [0 - length-1] is rejected + * column position outside [0 - length] is rejected */ cursor = new SequenceCursor(sq, 13, -1, changeCount); assertFalse(sq.isValidCursor(cursor)); - cursor = new SequenceCursor(sq, 13, 9, changeCount); + cursor = new SequenceCursor(sq, 13, 10, changeCount); assertFalse(sq.isValidCursor(cursor)); cursor = new SequenceCursor(sq, 7, 8, changeCount); assertFalse(sq.isValidCursor(cursor)); @@ -1499,4 +1576,100 @@ public class SequenceTest cursor = (SequenceCursor) PA.getValue(sq, "cursor"); assertEquals(new SequenceCursor(sq, 13, 10, ++token), cursor); } + + @Test(groups = { "Functional" }) + public void testGetSequence() + { + String seqstring = "-A--BCD-EF--"; + Sequence sq = new Sequence("test/8-13", seqstring); + sq.createDatasetSequence(); + assertTrue(Arrays.equals(sq.getSequence(), seqstring.toCharArray())); + assertTrue(Arrays.equals(sq.getDatasetSequence().getSequence(), + "ABCDEF".toCharArray())); + + // verify a copy of the sequence array is returned + char[] theSeq = (char[]) PA.getValue(sq, "sequence"); + assertNotSame(theSeq, sq.getSequence()); + theSeq = (char[]) PA.getValue(sq.getDatasetSequence(), "sequence"); + assertNotSame(theSeq, sq.getDatasetSequence().getSequence()); + } + + @Test(groups = { "Functional" }) + public void testReplace() + { + String seqstring = "-A--BCD-EF--"; + SequenceI sq = new Sequence("test/8-13", seqstring); + assertEquals(0, PA.getValue(sq, "changeCount")); + + assertEquals(0, sq.replace('A', 'A')); // same char + assertEquals(seqstring, sq.getSequenceAsString()); + assertEquals(0, PA.getValue(sq, "changeCount")); + + assertEquals(0, sq.replace('X', 'Y')); // not there + assertEquals(seqstring, sq.getSequenceAsString()); + assertEquals(0, PA.getValue(sq, "changeCount")); + + assertEquals(1, sq.replace('A', 'K')); + assertEquals("-K--BCD-EF--", sq.getSequenceAsString()); + assertEquals(1, PA.getValue(sq, "changeCount")); + + assertEquals(6, sq.replace('-', '.')); + assertEquals(".K..BCD.EF..", sq.getSequenceAsString()); + assertEquals(2, PA.getValue(sq, "changeCount")); + } + + @Test(groups = { "Functional" }) + public void testFindPositions() + { + SequenceI sq = new Sequence("test/8-13", "-ABC---DE-F--"); + + /* + * invalid inputs + */ + assertNull(sq.findPositions(6, 5)); + assertNull(sq.findPositions(0, 5)); + assertNull(sq.findPositions(-1, 5)); + + /* + * all gapped ranges + */ + assertNull(sq.findPositions(1, 1)); // 1-based columns + assertNull(sq.findPositions(5, 5)); + assertNull(sq.findPositions(5, 6)); + assertNull(sq.findPositions(5, 7)); + + /* + * all ungapped ranges + */ + assertEquals(new Range(8, 8), sq.findPositions(2, 2)); // A + assertEquals(new Range(8, 9), sq.findPositions(2, 3)); // AB + assertEquals(new Range(8, 10), sq.findPositions(2, 4)); // ABC + assertEquals(new Range(9, 10), sq.findPositions(3, 4)); // BC + + /* + * gap to ungapped range + */ + assertEquals(new Range(8, 10), sq.findPositions(1, 4)); // ABC + assertEquals(new Range(11, 12), sq.findPositions(6, 9)); // DE + + /* + * ungapped to gapped range + */ + assertEquals(new Range(10, 10), sq.findPositions(4, 5)); // C + assertEquals(new Range(9, 13), sq.findPositions(3, 11)); // BCDEF + + /* + * ungapped to ungapped enclosing gaps + */ + assertEquals(new Range(10, 11), sq.findPositions(4, 8)); // CD + assertEquals(new Range(8, 13), sq.findPositions(2, 11)); // ABCDEF + + /* + * gapped to gapped enclosing ungapped + */ + assertEquals(new Range(8, 10), sq.findPositions(1, 5)); // ABC + assertEquals(new Range(11, 12), sq.findPositions(5, 10)); // DE + assertEquals(new Range(8, 13), sq.findPositions(1, 13)); // the lot + assertEquals(new Range(8, 13), sq.findPositions(1, 99)); + } }