JAL - 3690 AlignCalc rebuilt - FutureTask-based manager
[jalview.git] / test / jalview / workers / AlignCalcManagerTest.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.workers;
22
23 import static org.testng.AssertJUnit.assertEquals;
24 import static org.testng.AssertJUnit.assertFalse;
25 import static org.testng.AssertJUnit.assertTrue;
26
27 import jalview.api.AlignCalcManagerI;
28 import jalview.api.AlignCalcManagerI2;
29 import jalview.api.AlignCalcWorkerI;
30 import jalview.api.FeatureRenderer;
31 import jalview.datamodel.Alignment;
32 import jalview.datamodel.AlignmentAnnotation;
33 import jalview.datamodel.AlignmentI;
34 import jalview.datamodel.Annotation;
35 import jalview.datamodel.Sequence;
36 import jalview.datamodel.SequenceI;
37 import jalview.gui.AlignFrame;
38 import jalview.gui.JvOptionPane;
39
40 import java.util.Collections;
41 import java.util.List;
42
43 import org.testng.annotations.BeforeClass;
44 import org.testng.annotations.BeforeMethod;
45 import org.testng.annotations.Test;
46
47 public class AlignCalcManagerTest
48 {
49
50   @BeforeClass(alwaysRun = true)
51   public void setUpJvOptionPane()
52   {
53     JvOptionPane.setInteractiveMode(false);
54     JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION);
55   }
56
57   private AlignFrame alignFrame;
58
59   /**
60    * Test the method that removes a worker associated with an annotation,
61    * provided the worker is marked as 'deletable' (some workers should continue
62    * to run even when their results are no longer displayed)
63    */
64   @Test(groups = "Functional")
65   public void testRemoveWorkerForAnnotation()
66   {
67     AlignCalcManagerI2 acm = alignFrame.getViewport().getCalcManager();
68     final AlignmentAnnotation ann1 = new AlignmentAnnotation("Ann1",
69             "desc", new Annotation[] {});
70     final AlignmentAnnotation ann2 = new AlignmentAnnotation("Ann2",
71             "desc", new Annotation[] {});
72
73     /*
74      * make two workers for ann1, one deletable, one not
75      * and no worker for ann2
76      */
77     AlignCalcWorkerI worker1 = makeWorker(ann1, true);
78     AlignCalcWorkerI worker2 = makeWorker(ann1, false);
79
80     /*
81      * The new workers will get run each in their own thread.
82      * We can't tell here whether they have finished, or not yet started.
83      * They have to finish to be 'seen' by getRegisteredWorkersOfClass()
84      *   registerWorker adds to the 'restartable' list but
85      *   getRegisteredWorkers reads from the 'canUpdate' list
86      *   (which is only updated after a worker has run) - why?
87      * So just give workers time to start and finish
88      */
89     synchronized (this)
90     {
91       try
92       {
93         wait(100);
94       } catch (InterruptedException e)
95       {
96         //
97       }
98     }
99
100     List<AlignCalcWorkerI> workers = acm.getWorkersOfClass(worker1.getClass());
101     assertEquals(2, workers.size());
102     assertTrue(workers.contains(worker1));
103     assertTrue(workers.contains(worker2));
104     assertFalse(acm.isDisabled(worker1));
105     assertFalse(acm.isDisabled(worker2));
106
107     /*
108      * remove workers for ann2 (there aren't any)
109      */
110     acm.removeWorkerForAnnotation(ann2);
111     assertTrue(acm.getWorkersOfClass(worker1.getClass()).contains(worker1));
112     assertTrue(acm.getWorkersOfClass(worker1.getClass()).contains(worker2));
113     assertFalse(acm.isDisabled(worker1));
114     assertFalse(acm.isDisabled(worker2));
115
116     /*
117      * remove worker2 for ann1
118      * - should delete worker1 but not worker2
119      */
120     acm.removeWorkerForAnnotation(ann1);
121     assertEquals(1, acm.getWorkersOfClass(worker1.getClass()).size());
122     assertTrue(acm.getWorkersOfClass(worker1.getClass()).contains(worker2));
123     assertFalse(acm.isDisabled(worker1));
124     assertFalse(acm.isDisabled(worker2));
125   }
126
127   /**
128    * Make a worker linked to the given annotation
129    * 
130    * @param ann
131    * @param deletable
132    * @return
133    */
134   AnnotationWorker makeWorker(final AlignmentAnnotation ann,
135           final boolean deletable)
136   {
137     AnnotationProviderI annotationProvider = new AnnotationProviderI()
138     {
139       @Override
140       public List<AlignmentAnnotation> calculateAnnotation(AlignmentI al,
141               FeatureRenderer fr)
142       {
143         return Collections.singletonList(ann);
144       }
145     };
146     return new AnnotationWorker(alignFrame.getViewport(),
147             alignFrame.alignPanel, annotationProvider)
148     {
149       @Override
150       public boolean isDeletable()
151       {
152         return deletable;
153       }
154
155       @Override
156       public boolean involves(AlignmentAnnotation ann1)
157       {
158         return ann == ann1;
159       }
160     };
161   }
162
163   @BeforeMethod(alwaysRun = true)
164   public void setUp()
165   {
166     AlignmentI al = new Alignment(new SequenceI[] { new Sequence("Seq1",
167             "ABC") });
168     al.setDataset(null);
169     alignFrame = new AlignFrame(al, 3, 1);
170   }
171 }