JAL-2191 comments re chimera view code redundancy and JAL-1803
[jalview.git] / test / jalview / gui / AlignViewportTest.java
1 /*
2  * Jalview - A Sequence Alignment Editor and Viewer ($$Version-Rel$$)
3  * Copyright (C) $$Year-Rel$$ The Jalview Authors
4  * 
5  * This file is part of Jalview.
6  * 
7  * Jalview is free software: you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License 
9  * as published by the Free Software Foundation, either version 3
10  * of the License, or (at your option) any later version.
11  *  
12  * Jalview is distributed in the hope that it will be useful, but 
13  * WITHOUT ANY WARRANTY; without even the implied warranty 
14  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
15  * PURPOSE.  See the GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with Jalview.  If not, see <http://www.gnu.org/licenses/>.
19  * The Jalview Authors are detailed in the 'AUTHORS' file.
20  */
21 package jalview.gui;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertNotNull;
26 import static org.testng.AssertJUnit.assertSame;
27 import static org.testng.AssertJUnit.assertTrue;
28
29 import jalview.datamodel.AlignedCodonFrame;
30 import jalview.datamodel.Alignment;
31 import jalview.datamodel.AlignmentI;
32 import jalview.datamodel.PDBEntry;
33 import jalview.datamodel.PDBEntry.Type;
34 import jalview.datamodel.Sequence;
35 import jalview.datamodel.SequenceI;
36 import jalview.io.FileLoader;
37 import jalview.io.FormatAdapter;
38 import jalview.structure.StructureSelectionManager;
39 import jalview.util.MapList;
40
41 import java.util.ArrayList;
42 import java.util.List;
43
44 import org.testng.annotations.BeforeClass;
45 import org.testng.annotations.BeforeMethod;
46 import org.testng.annotations.Test;
47
48 public class AlignViewportTest
49 {
50
51   AlignmentI al;
52
53   AlignViewport testee;
54
55   @BeforeClass(alwaysRun = true)
56   public static void setUpBeforeClass() throws Exception
57   {
58     jalview.bin.Jalview.main(new String[] { "-props",
59         "test/jalview/testProps.jvprops" });
60   }
61
62   @BeforeMethod(alwaysRun = true)
63   public void setUp()
64   {
65     SequenceI seq1 = new Sequence("Seq1", "ABC");
66     SequenceI seq2 = new Sequence("Seq2", "ABC");
67     SequenceI seq3 = new Sequence("Seq3", "ABC");
68     SequenceI[] seqs = new SequenceI[] { seq1, seq2, seq3 };
69     al = new Alignment(seqs);
70     al.setDataset(null);
71     testee = new AlignViewport(al);
72   }
73
74   @Test(groups = { "Functional" })
75   public void testCollateForPdb()
76   {
77     // JBP: What behaviour is this supposed to test ?
78     /*
79      * Set up sequence pdb ids
80      */
81     PDBEntry pdb1 = new PDBEntry("1ABC", "B", Type.PDB, "1ABC.pdb");
82     PDBEntry pdb2 = new PDBEntry("2ABC", "C", Type.PDB, "2ABC.pdb");
83     PDBEntry pdb3 = new PDBEntry("3ABC", "D", Type.PDB, "3ABC.pdb");
84
85     /*
86      * seq1 and seq3 refer to 1abcB, seq2 to 2abcC, none to 3abcD
87      */
88     al.getSequenceAt(0).getDatasetSequence()
89             .addPDBId(new PDBEntry("1ABC", "B", Type.PDB, "1ABC.pdb"));
90     al.getSequenceAt(2).getDatasetSequence()
91             .addPDBId(new PDBEntry("1ABC", "B", Type.PDB, "1ABC.pdb"));
92     al.getSequenceAt(1).getDatasetSequence()
93             .addPDBId(new PDBEntry("2ABC", "C", Type.PDB, "2ABC.pdb"));
94     /*
95      * Add a second chain PDB xref to Seq2 - should not result in a duplicate in
96      * the results
97      */
98     al.getSequenceAt(1).getDatasetSequence()
99             .addPDBId(new PDBEntry("2ABC", "D", Type.PDB, "2ABC.pdb"));
100     /*
101      * Seq3 refers to 3abc - this does not match 3ABC (as the code stands)
102      */
103     al.getSequenceAt(2).getDatasetSequence()
104             .addPDBId(new PDBEntry("3abc", "D", Type.PDB, "3ABC.pdb"));
105
106     /*
107      * run method under test
108      */
109     SequenceI[][] seqs = testee.collateForPDB(new PDBEntry[] { pdb1, pdb2,
110         pdb3 });
111
112     // seq1 and seq3 refer to PDBEntry[0]
113     assertEquals(2, seqs[0].length);
114     assertSame(al.getSequenceAt(0), seqs[0][0]);
115     assertSame(al.getSequenceAt(2), seqs[0][1]);
116
117     // seq2 refers to PDBEntry[1]
118     assertEquals(1, seqs[1].length);
119     assertSame(al.getSequenceAt(1), seqs[1][0]);
120
121     // no sequence refers to PDBEntry[2]
122     assertEquals(0, seqs[2].length);
123   }
124
125   /**
126    * Test that a mapping is not deregistered when a second view is closed but
127    * the first still holds a reference to the mapping
128    */
129   @Test(groups = { "Functional" })
130   public void testDeregisterMapping_onCloseView()
131   {
132     /*
133      * alignment with reference to mappings
134      */
135     AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
136             ">Seq1\nCAGT\n", FormatAdapter.PASTE);
137
138     SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
139     AlignedCodonFrame acf1 = new AlignedCodonFrame();
140     acf1.addMap(s1, s1, new MapList(new int[] { 1, 4 }, new int[] { 1, 4 },
141             1, 1));
142     AlignedCodonFrame acf2 = new AlignedCodonFrame();
143     acf2.addMap(s1, s1, new MapList(new int[] { 1, 4 }, new int[] { 4, 1 },
144             1, 1));
145
146     List<AlignedCodonFrame> mappings = new ArrayList<AlignedCodonFrame>();
147     mappings.add(acf1);
148     mappings.add(acf2);
149     af1.getViewport().getAlignment().setCodonFrames(mappings);
150     af1.newView_actionPerformed(null);
151
152     /*
153      * Verify that creating the alignment for the new View has registered the
154      * mappings
155      */
156     StructureSelectionManager ssm = StructureSelectionManager
157             .getStructureSelectionManager(Desktop.instance);
158     assertEquals(2, ssm.getSequenceMappings().size());
159     assertTrue(ssm.getSequenceMappings().contains(acf1));
160     assertTrue(ssm.getSequenceMappings().contains(acf2));
161
162     /*
163      * Close the second view. Verify that mappings are not removed as the first
164      * view still holds a reference to them.
165      */
166     af1.closeMenuItem_actionPerformed(false);
167     assertEquals(2, ssm.getSequenceMappings().size());
168     assertTrue(ssm.getSequenceMappings().contains(acf1));
169     assertTrue(ssm.getSequenceMappings().contains(acf2));
170   }
171
172   /**
173    * Test that a mapping is deregistered if no alignment holds a reference to it
174    */
175   @Test(groups = { "Functional" })
176   public void testDeregisterMapping_withNoReference()
177   {
178     Desktop d = Desktop.instance;
179     assertNotNull(d);
180     StructureSelectionManager ssm = StructureSelectionManager
181             .getStructureSelectionManager(Desktop.instance);
182     ssm.resetAll();
183
184     AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
185             ">Seq1\nRSVQ\n", FormatAdapter.PASTE);
186     AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
187             ">Seq2\nDGEL\n", FormatAdapter.PASTE);
188     SequenceI cs1 = new Sequence("cseq1", "CCCGGGTTTAAA");
189     SequenceI cs2 = new Sequence("cseq2", "CTTGAGTCTAGA");
190     SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
191     SequenceI s2 = af2.getViewport().getAlignment().getSequenceAt(0);
192     // need to be distinct
193     AlignedCodonFrame acf1 = new AlignedCodonFrame();
194     acf1.addMap(cs1, s1, new MapList(new int[] { 1, 4 },
195             new int[] { 1, 12 }, 1, 3));
196     AlignedCodonFrame acf2 = new AlignedCodonFrame();
197     acf2.addMap(cs2, s2, new MapList(new int[] { 1, 4 },
198             new int[] { 1, 12 }, 1, 3));
199     AlignedCodonFrame acf3 = new AlignedCodonFrame();
200     acf3.addMap(cs2, cs2, new MapList(new int[] { 1, 12 }, new int[] { 1,
201         12 }, 1, 1));
202
203     List<AlignedCodonFrame> mappings1 = new ArrayList<AlignedCodonFrame>();
204     mappings1.add(acf1);
205     af1.getViewport().getAlignment().setCodonFrames(mappings1);
206
207     List<AlignedCodonFrame> mappings2 = new ArrayList<AlignedCodonFrame>();
208     mappings2.add(acf2);
209     mappings2.add(acf3);
210     af2.getViewport().getAlignment().setCodonFrames(mappings2);
211
212     /*
213      * AlignFrame1 has mapping acf1, AlignFrame2 has acf2 and acf3
214      */
215
216     List<AlignedCodonFrame> ssmMappings = ssm.getSequenceMappings();
217     assertEquals(0, ssmMappings.size());
218     ssm.registerMapping(acf1);
219     assertEquals(1, ssmMappings.size());
220     ssm.registerMapping(acf2);
221     assertEquals(2, ssmMappings.size());
222     ssm.registerMapping(acf3);
223     assertEquals(3, ssmMappings.size());
224
225     /*
226      * Closing AlignFrame2 should remove its mappings from
227      * StructureSelectionManager, since AlignFrame1 has no reference to them
228      */
229     af2.closeMenuItem_actionPerformed(true);
230     assertEquals(1, ssmMappings.size());
231     assertTrue(ssmMappings.contains(acf1));
232   }
233
234   /**
235    * Test that a mapping is not deregistered if another alignment holds a
236    * reference to it
237    */
238   @Test(groups = { "Functional" })
239   public void testDeregisterMapping_withReference()
240   {
241     Desktop d = Desktop.instance;
242     assertNotNull(d);
243     StructureSelectionManager ssm = StructureSelectionManager
244             .getStructureSelectionManager(Desktop.instance);
245     ssm.resetAll();
246
247     AlignFrame af1 = new FileLoader().LoadFileWaitTillLoaded(
248             ">Seq1\nRSVQ\n", FormatAdapter.PASTE);
249     AlignFrame af2 = new FileLoader().LoadFileWaitTillLoaded(
250             ">Seq2\nDGEL\n", FormatAdapter.PASTE);
251     SequenceI cs1 = new Sequence("cseq1", "CCCGGGTTTAAA");
252     SequenceI cs2 = new Sequence("cseq2", "CTTGAGTCTAGA");
253     SequenceI s1 = af1.getViewport().getAlignment().getSequenceAt(0);
254     SequenceI s2 = af2.getViewport().getAlignment().getSequenceAt(0);
255     // need to be distinct
256     AlignedCodonFrame acf1 = new AlignedCodonFrame();
257     acf1.addMap(cs1, s1, new MapList(new int[] { 1, 4 },
258             new int[] { 1, 12 }, 1, 3));
259     AlignedCodonFrame acf2 = new AlignedCodonFrame();
260     acf2.addMap(cs2, s2, new MapList(new int[] { 1, 4 },
261             new int[] { 1, 12 }, 1, 3));
262     AlignedCodonFrame acf3 = new AlignedCodonFrame();
263     acf3.addMap(cs2, cs2, new MapList(new int[] { 1, 12 }, new int[] { 1,
264         12 }, 1, 1));
265
266     List<AlignedCodonFrame> mappings1 = new ArrayList<AlignedCodonFrame>();
267     mappings1.add(acf1);
268     mappings1.add(acf2);
269     af1.getViewport().getAlignment().setCodonFrames(mappings1);
270
271     List<AlignedCodonFrame> mappings2 = new ArrayList<AlignedCodonFrame>();
272     mappings2.add(acf2);
273     mappings2.add(acf3);
274     af2.getViewport().getAlignment().setCodonFrames(mappings2);
275
276     /*
277      * AlignFrame1 has mappings acf1 and acf2, AlignFrame2 has acf2 and acf3
278      */
279
280     List<AlignedCodonFrame> ssmMappings = ssm.getSequenceMappings();
281     assertEquals(0, ssmMappings.size());
282     ssm.registerMapping(acf1);
283     assertEquals(1, ssmMappings.size());
284     ssm.registerMapping(acf2);
285     assertEquals(2, ssmMappings.size());
286     ssm.registerMapping(acf3);
287     assertEquals(3, ssmMappings.size());
288
289     /*
290      * Closing AlignFrame2 should remove mapping acf3 from
291      * StructureSelectionManager, but not acf2, since AlignFrame1 still has a
292      * reference to it
293      */
294     af2.closeMenuItem_actionPerformed(true);
295     assertEquals(2, ssmMappings.size());
296     assertTrue(ssmMappings.contains(acf1));
297     assertTrue(ssmMappings.contains(acf2));
298     assertFalse(ssmMappings.contains(acf3));
299   }
300 }