package jalview.gui; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; import jalview.datamodel.AlignmentAnnotation; import jalview.datamodel.AlignmentI; import jalview.datamodel.SequenceGroup; import jalview.datamodel.SequenceI; import jalview.io.AppletFormatAdapter; import java.io.IOException; import java.util.BitSet; import java.util.HashMap; import java.util.List; import java.util.Map; import org.junit.Before; import org.junit.Test; /** * Unit tests for PopupMenu * * @author gmcarstairs * */ public class PopupMenuTest { // 4 sequences x 13 positions final static String TEST_DATA = ">FER_CAPAA Ferredoxin\n" + "TIETHKEAELVG-\n" + ">FER_CAPAN Ferredoxin, chloroplast precursor\n" + "TIETHKEAELVG-\n" + ">FER1_SOLLC Ferredoxin-1, chloroplast precursor\n" + "TIETHKEEELTA-\n" + ">Q93XJ9_SOLTU Ferredoxin I precursor\n" + "TIETHKEEELTA-\n"; private static final int SEQ_ANN_COUNT = 10; private static final int AUTO_ANNS = 3; AlignmentI alignment; AlignmentPanel parentPanel; @Before public void setUp() throws IOException { AlignmentI al = new jalview.io.FormatAdapter().readFile(TEST_DATA, AppletFormatAdapter.PASTE, "FASTA"); AlignFrame af = new AlignFrame(al, 700, 500); parentPanel = new AlignmentPanel(af, af.getViewport()); alignment = parentPanel.getAlignment(); AlignmentAnnotation[] anns = new AlignmentAnnotation[SEQ_ANN_COUNT]; for (int i = 0; i < anns.length; i++) { anns[i] = new AlignmentAnnotation("Label" + i, null, 0d); anns[i].setCalcId("CalcId" + i); anns[i].visible = true; alignment.addAnnotation(anns[i]); } } /** * Test method that determines visible graph groups. */ @Test public void testGetVisibleGraphGroups() { AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation(); /* * a bar graph group is not included */ anns[0].graph = AlignmentAnnotation.BAR_GRAPH; anns[0].graphGroup = 1; anns[0].visible = true; /* * a line graph group is included as long as one of its members is visible */ anns[1].graph = AlignmentAnnotation.LINE_GRAPH; anns[1].graphGroup = 5; anns[1].visible = false; anns[2].graph = AlignmentAnnotation.LINE_GRAPH; anns[2].graphGroup = 5; anns[2].visible = true; /* * a line graph group with no visible rows is not included */ anns[3].graph = AlignmentAnnotation.LINE_GRAPH; anns[3].graphGroup = 3; anns[3].visible = false; // a visible line graph with no graph group is not included anns[4].graph = AlignmentAnnotation.LINE_GRAPH; anns[4].graphGroup = -1; anns[4].visible = true; BitSet result = PopupMenu.getVisibleLineGraphGroups(anns); assertTrue(result.get(5)); assertFalse(result.get(0)); assertFalse(result.get(1)); assertFalse(result.get(2)); assertFalse(result.get(3)); } /** * Test a mixture of show/hidden annotations in/outside selection group. */ @Test public void testGetAnnotationTypesForShowHide_forSelectionGroup() { Map>> shownTypes = new HashMap>>(); Map>> hiddenTypes = new HashMap>>(); AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation(); BitSet visibleGraphGroups = new BitSet(); selectSequences(0, 3); SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray(); /* * Configure annotation properties for test (offsetting for auto-calculated * rows). */ // not in selection group (should be ignored): // hidden annotation Label4 not in selection group anns[AUTO_ANNS + 4].sequenceRef = seqs[2]; anns[AUTO_ANNS + 4].visible = false; anns[AUTO_ANNS + 7].sequenceRef = seqs[1]; anns[AUTO_ANNS + 7].visible = true; /* * in selection group, hidden: */ anns[AUTO_ANNS + 2].sequenceRef = seqs[3]; // CalcId2/Label2 anns[AUTO_ANNS + 2].visible = false; anns[AUTO_ANNS + 3].sequenceRef = seqs[3]; // CalcId3/Label2 anns[AUTO_ANNS + 3].visible = false; anns[AUTO_ANNS + 3].label = "Label2"; anns[AUTO_ANNS + 4].sequenceRef = seqs[3]; // CalcId2/Label3 anns[AUTO_ANNS + 4].visible = false; anns[AUTO_ANNS + 4].label = "Label3"; anns[AUTO_ANNS + 4].setCalcId("CalcId2"); anns[AUTO_ANNS + 8].sequenceRef = seqs[0]; // CalcId9/Label9 anns[AUTO_ANNS + 8].visible = false; anns[AUTO_ANNS + 8].label = "Label9"; anns[AUTO_ANNS + 8].setCalcId("CalcId9"); /* * in selection group, visible */ anns[AUTO_ANNS + 6].sequenceRef = seqs[0]; // CalcId6/Label6 anns[AUTO_ANNS + 6].visible = true; anns[AUTO_ANNS + 9].sequenceRef = seqs[3]; // CalcId9/Label9 anns[AUTO_ANNS + 9].visible = true; PopupMenu.getAnnotationTypesForShowHide(shownTypes, hiddenTypes, visibleGraphGroups, anns, parentPanel.av.getSelectionGroup()); // check results; note CalcId9/Label9 is both hidden and shown (for // different sequences) so should be in both // shown: CalcId6/Label6 and CalcId9/Label9 assertEquals(2, shownTypes.size()); assertEquals(1, shownTypes.get("CalcId6").size()); assertEquals(1, shownTypes.get("CalcId6").get(0).size()); assertEquals("Label6", shownTypes.get("CalcId6").get(0).get(0)); assertEquals(1, shownTypes.get("CalcId9").size()); assertEquals(1, shownTypes.get("CalcId9").get(0).size()); assertEquals("Label9", shownTypes.get("CalcId9").get(0).get(0)); // hidden: CalcId2/Label2, CalcId2/Label3, CalcId3/Label2, CalcId9/Label9 assertEquals(3, hiddenTypes.size()); assertEquals(2, hiddenTypes.get("CalcId2").size()); assertEquals(1, hiddenTypes.get("CalcId2").get(0).size()); assertEquals("Label2", hiddenTypes.get("CalcId2").get(0).get(0)); assertEquals(1, hiddenTypes.get("CalcId2").get(1).size()); assertEquals("Label3", hiddenTypes.get("CalcId2").get(1).get(0)); assertEquals(1, hiddenTypes.get("CalcId3").size()); assertEquals(1, hiddenTypes.get("CalcId3").get(0).size()); assertEquals("Label2", hiddenTypes.get("CalcId3").get(0).get(0)); assertEquals(1, hiddenTypes.get("CalcId9").size()); assertEquals(1, hiddenTypes.get("CalcId9").get(0).size()); assertEquals("Label9", hiddenTypes.get("CalcId9").get(0).get(0)); consoleDebug(shownTypes, hiddenTypes); } /** * This output is not part of the test but may help make sense of it... * * @param shownTypes * @param hiddenTypes */ protected void consoleDebug(Map>> shownTypes, Map>> hiddenTypes) { for (String calcId : shownTypes.keySet()) { System.out.println("Visible annotation types for calcId=" + calcId); for (List type : shownTypes.get(calcId)) { System.out.println(" " + type); } } for (String calcId : hiddenTypes.keySet()) { System.out.println("Hidden annotation types for calcId=" + calcId); for (List type : hiddenTypes.get(calcId)) { System.out.println(" " + type); } } } /** * Test case where there are 'grouped' annotations, visible and hidden, within * and without the selection group. */ @Test public void testGetAnnotationTypesForShowHide_withGraphGroups() { final int GROUP_4 = 4; final int GROUP_5 = 5; final int GROUP_6 = 6; Map>> shownTypes = new HashMap>>(); Map>> hiddenTypes = new HashMap>>(); AlignmentAnnotation[] anns = alignment.getAlignmentAnnotation(); BitSet visibleGraphGroups = new BitSet(); visibleGraphGroups.set(GROUP_4); visibleGraphGroups.set(GROUP_6); selectSequences(0, 3); SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray(); /* * Configure annotation properties for test (offsetting for auto-calculated * rows). */ // annotations for selection group and graph group // hidden annotations Label2, Label3, in (hidden) group 5 anns[AUTO_ANNS + 2].sequenceRef = seqs[3]; anns[AUTO_ANNS + 2].visible = false; anns[AUTO_ANNS + 2].graph = AlignmentAnnotation.LINE_GRAPH; anns[AUTO_ANNS + 2].graphGroup = GROUP_5; // not a visible group anns[AUTO_ANNS + 3].sequenceRef = seqs[0]; anns[AUTO_ANNS + 3].visible = false; anns[AUTO_ANNS + 3].graph = AlignmentAnnotation.LINE_GRAPH; anns[AUTO_ANNS + 3].graphGroup = GROUP_5; // need to ensure annotations have the same calcId as well anns[AUTO_ANNS + 3].setCalcId("CalcId2"); // annotations Label1 (hidden), Label5 (visible) in group 6 (visible) anns[AUTO_ANNS + 1].sequenceRef = seqs[3]; // being in a visible group should take precedence over this visibility anns[AUTO_ANNS + 1].visible = false; anns[AUTO_ANNS + 1].graph = AlignmentAnnotation.LINE_GRAPH; anns[AUTO_ANNS + 1].graphGroup = GROUP_6; anns[AUTO_ANNS + 5].sequenceRef = seqs[0]; anns[AUTO_ANNS + 5].visible = true; // visibleGraphGroups overrides this anns[AUTO_ANNS + 5].graph = AlignmentAnnotation.LINE_GRAPH; anns[AUTO_ANNS + 5].graphGroup = GROUP_6; anns[AUTO_ANNS + 5].setCalcId("CalcId1"); // annotations outwith selection group - should be ignored // hidden grouped annotations anns[AUTO_ANNS + 6].sequenceRef = seqs[2]; anns[AUTO_ANNS + 6].visible = false; anns[AUTO_ANNS + 6].graph = AlignmentAnnotation.LINE_GRAPH; anns[AUTO_ANNS + 6].graphGroup = GROUP_4; anns[AUTO_ANNS + 8].sequenceRef = seqs[1]; anns[AUTO_ANNS + 8].visible = false; anns[AUTO_ANNS + 8].graph = AlignmentAnnotation.LINE_GRAPH; anns[AUTO_ANNS + 8].graphGroup = GROUP_4; // visible grouped annotations Label7, Label9 anns[AUTO_ANNS + 7].sequenceRef = seqs[2]; anns[AUTO_ANNS + 7].visible = true; anns[AUTO_ANNS + 7].graph = AlignmentAnnotation.LINE_GRAPH; anns[AUTO_ANNS + 7].graphGroup = GROUP_4; anns[AUTO_ANNS + 9].sequenceRef = seqs[1]; anns[AUTO_ANNS + 9].visible = true; anns[AUTO_ANNS + 9].graph = AlignmentAnnotation.LINE_GRAPH; anns[AUTO_ANNS + 9].graphGroup = GROUP_4; PopupMenu.getAnnotationTypesForShowHide(shownTypes, hiddenTypes, visibleGraphGroups, anns, parentPanel.av.getSelectionGroup()); consoleDebug(shownTypes, hiddenTypes); // CalcId1 / Label1, Label5 (only) should be 'shown', as a compound type assertEquals(1, shownTypes.get("CalcId1").size()); assertEquals(2, shownTypes.get("CalcId1").get(0).size()); assertEquals("Label1", shownTypes.get("CalcId1").get(0).get(0)); assertEquals("Label5", shownTypes.get("CalcId1").get(0).get(1)); // CalcId2 / Label2, Label3 (only) should be 'hidden' assertEquals(1, hiddenTypes.get("CalcId2").size()); assertEquals(2, hiddenTypes.get("CalcId2").get(0).size()); assertEquals("Label2", hiddenTypes.get("CalcId2").get(0).get(0)); assertEquals("Label3", hiddenTypes.get("CalcId2").get(0).get(1)); } /** * Add a sequence group to the alignment with the specified sequences (base 0) * in it * * @param i * @param more */ private void selectSequences(int... selected) { SequenceI[] seqs = parentPanel.getAlignment().getSequencesArray(); SequenceGroup sg = new SequenceGroup(); for (int i : selected) { sg.addSequence(seqs[i], false); } parentPanel.av.setSelectionGroup(sg); } }