Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
StructureChooserTest | 66 | 126 | 25 |
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.Assert.assertEquals; | |
24 | import static org.testng.AssertJUnit.assertNotNull; | |
25 | import static org.testng.AssertJUnit.assertTrue; | |
26 | ||
27 | import java.io.File; | |
28 | import java.util.Collection; | |
29 | import java.util.List; | |
30 | import java.util.Vector; | |
31 | ||
32 | import org.junit.Assert; | |
33 | import org.testng.annotations.AfterMethod; | |
34 | import org.testng.annotations.BeforeClass; | |
35 | import org.testng.annotations.BeforeMethod; | |
36 | import org.testng.annotations.DataProvider; | |
37 | import org.testng.annotations.Test; | |
38 | ||
39 | import jalview.api.AlignViewportI; | |
40 | import jalview.bin.Cache; | |
41 | import jalview.bin.Jalview; | |
42 | import jalview.datamodel.AlignmentAnnotation; | |
43 | import jalview.datamodel.AlignmentI; | |
44 | import jalview.datamodel.DBRefEntry; | |
45 | import jalview.datamodel.PDBEntry; | |
46 | import jalview.datamodel.Sequence; | |
47 | import jalview.datamodel.SequenceI; | |
48 | import jalview.fts.api.FTSData; | |
49 | import jalview.fts.core.FTSRestClient; | |
50 | import jalview.fts.service.pdb.PDBFTSRestClient; | |
51 | import jalview.fts.service.pdb.PDBFTSRestClientTest; | |
52 | import jalview.fts.service.threedbeacons.TDBeaconsFTSRestClient; | |
53 | import jalview.fts.threedbeacons.TDBeaconsFTSRestClientTest; | |
54 | import jalview.gui.StructureViewer.ViewerType; | |
55 | import jalview.gui.structurechooser.PDBStructureChooserQuerySource; | |
56 | import jalview.io.DataSourceType; | |
57 | import jalview.io.FileFormatException; | |
58 | import jalview.io.FileFormatI; | |
59 | import jalview.io.FileLoader; | |
60 | import jalview.io.IdentifyFile; | |
61 | import jalview.jbgui.FilterOption; | |
62 | import jalview.structure.StructureImportSettings.TFType; | |
63 | import junit.extensions.PA; | |
64 | ||
65 | @Test(singleThreaded = true) | |
66 | public class StructureChooserTest | |
67 | { | |
68 | ||
69 | 1 | @BeforeClass(alwaysRun = true) |
70 | public void setUpJvOptionPane() | |
71 | { | |
72 | 1 | JvOptionPane.setInteractiveMode(false); |
73 | 1 | JvOptionPane.setMockResponse(JvOptionPane.CANCEL_OPTION); |
74 | } | |
75 | ||
76 | Sequence seq, upSeq, upSeq_nocanonical; | |
77 | ||
78 | 10 | @BeforeMethod(alwaysRun = true) |
79 | public void setUp() throws Exception | |
80 | { | |
81 | 10 | seq = new Sequence("PDB|4kqy|4KQY|A", "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 1, |
82 | 26); | |
83 | 10 | seq.createDatasetSequence(); |
84 | 50 | for (int x = 1; x < 5; x++) |
85 | { | |
86 | 40 | DBRefEntry dbRef = new DBRefEntry(); |
87 | 40 | dbRef.setAccessionId("XYZ_" + x); |
88 | 40 | seq.addDBRef(dbRef); |
89 | } | |
90 | ||
91 | 10 | PDBEntry dbRef = new PDBEntry(); |
92 | 10 | dbRef.setId("1tim"); |
93 | ||
94 | 10 | Vector<PDBEntry> pdbIds = new Vector<>(); |
95 | 10 | pdbIds.add(dbRef); |
96 | ||
97 | 10 | seq.setPDBId(pdbIds); |
98 | ||
99 | // Uniprot sequence for 3D-Beacons mocks | |
100 | 10 | upSeq = new Sequence("P38398", |
101 | "MDLSALRVEEVQNVINAMQKILECPICLELIKEPVSTKCDHIFCKFCMLKLLNQKKGPSQCPLCKNDITKRS\n" | |
102 | + "LQESTRFSQLVEELLKIICAFQLDTGLEYANSYNFAKKENNSPEHLKDEVSIIQSMGYRNRAKRLLQSEPEN\n" | |
103 | + "PSLQETSLSVQLSNLGTVRTLRTKQRIQPQKTSVYIELGSDSSEDTVNKATYCSVGDQELLQITPQGTRDEI\n" | |
104 | + "SLDSAKKAACEFSETDVTNTEHHQPSNNDLNTTEKRAAERHPEKYQGSSVSNLHVEPCGTNTHASSLQHENS\n" | |
105 | + "SLLLTKDRMNVEKAEFCNKSKQPGLARSQHNRWAGSKETCNDRRTPSTEKKVDLNADPLCERKEWNKQKLPC\n" | |
106 | + "SENPRDTEDVPWITLNSSIQKVNEWFSRSDELLGSDDSHDGESESNAKVADVLDVLNEVDEYSGSSEKIDLL\n" | |
107 | + "ASDPHEALICKSERVHSKSVESNIEDKIFGKTYRKKASLPNLSHVTENLIIGAFVTEPQIIQERPLTNKLKR\n" | |
108 | + "KRRPTSGLHPEDFIKKADLAVQKTPEMINQGTNQTEQNGQVMNITNSGHENKTKGDSIQNEKNPNPIESLEK\n" | |
109 | + "ESAFKTKAEPISSSISNMELELNIHNSKAPKKNRLRRKSSTRHIHALELVVSRNLSPPNCTELQIDSCSSSE\n" | |
110 | + "EIKKKKYNQMPVRHSRNLQLMEGKEPATGAKKSNKPNEQTSKRHDSDTFPELKLTNAPGSFTKCSNTSELKE\n" | |
111 | + "FVNPSLPREEKEEKLETVKVSNNAEDPKDLMLSGERVLQTERSVESSSISLVPGTDYGTQESISLLEVSTLG\n" | |
112 | + "KAKTEPNKCVSQCAAFENPKGLIHGCSKDNRNDTEGFKYPLGHEVNHSRETSIEMEESELDAQYLQNTFKVS\n" | |
113 | + "KRQSFAPFSNPGNAEEECATFSAHSGSLKKQSPKVTFECEQKEENQGKNESNIKPVQTVNITAGFPVVGQKD\n" | |
114 | + "KPVDNAKCSIKGGSRFCLSSQFRGNETGLITPNKHGLLQNPYRIPPLFPIKSFVKTKCKKNLLEENFEEHSM\n" | |
115 | + "SPEREMGNENIPSTVSTISRNNIRENVFKEASSSNINEVGSSTNEVGSSINEIGSSDENIQAELGRNRGPKL\n" | |
116 | + "NAMLRLGVLQPEVYKQSLPGSNCKHPEIKKQEYEEVVQTVNTDFSPYLISDNLEQPMGSSHASQVCSETPDD\n" | |
117 | + "LLDDGEIKEDTSFAENDIKESSAVFSKSVQKGELSRSPSPFTHTHLAQGYRRGAKKLESSEENLSSEDEELP\n" | |
118 | + "CFQHLLFGKVNNIPSQSTRHSTVATECLSKNTEENLLSLKNSLNDCSNQVILAKASQEHHLSEETKCSASLF\n" | |
119 | + "SSQCSELEDLTANTNTQDPFLIGSSKQMRHQSESQGVGLSDKELVSDDEERGTGLEENNQEEQSMDSNLGEA\n" | |
120 | + "ASGCESETSVSEDCSGLSSQSDILTTQQRDTMQHNLIKLQQEMAELEAVLEQHGSQPSNSYPSIISDSSALE\n" | |
121 | + "DLRNPEQSTSEKAVLTSQKSSEYPISQNPEGLSADKFEVSADSSTSKNKEPGVERSSPSKCPSLDDRWYMHS\n" | |
122 | + "CSGSLQNRNYPSQEELIKVVDVEEQQLEESGPHDLTETSYLPRQDLEGTPYLESGISLFSDDPESDPSEDRA\n" | |
123 | + "PESARVGNIPSSTSALKVPQLKVAESAQSPAAAHTTDTAGYNAMEESVSREKPELTASTERVNKRMSMVVSG\n" | |
124 | + "LTPEEFMLVYKFARKHHITLTNLITEETTHVVMKTDAEFVCERTLKYFLGIAGGKWVVSYFWVTQSIKERKM\n" | |
125 | + "LNEHDFEVRGDVVNGRNHQGPKRARESQDRKIFRGLEICCYGPFTNMPTDQLEWMVQLCGASVVKELSSFTL\n" | |
126 | + "GTGVHPIVVVQPDAWTEDNGFHAIGQMCEAPVVTREWVLDSVALYQCQELDTYLIPQIPHSHY\n" | |
127 | + "", | |
128 | 1, 1863); | |
129 | 10 | upSeq.setDescription("Breast cancer type 1 susceptibility protein"); |
130 | 10 | upSeq_nocanonical = new Sequence(upSeq); |
131 | 10 | upSeq.createDatasetSequence(); |
132 | 10 | upSeq.addDBRef(new DBRefEntry("UNIPROT", "0", "P38398", null, true)); |
133 | ||
134 | 10 | upSeq_nocanonical.createDatasetSequence(); |
135 | // not a canonical reference | |
136 | 10 | upSeq_nocanonical.addDBRef( |
137 | new DBRefEntry("UNIPROT", "0", "P38398", null, false)); | |
138 | ||
139 | } | |
140 | ||
141 | 10 | @AfterMethod(alwaysRun = true) |
142 | public void tearDown() throws Exception | |
143 | { | |
144 | 10 | seq = null; |
145 | 10 | upSeq = null; |
146 | 10 | upSeq_nocanonical = null; |
147 | } | |
148 | ||
149 | 1 | @Test(groups = { "Functional" }) |
150 | public void populateFilterComboBoxTest() throws InterruptedException | |
151 | { | |
152 | 1 | TDBeaconsFTSRestClientTest.setMock(); |
153 | 1 | PDBFTSRestClientTest.setMock(); |
154 | ||
155 | 1 | SequenceI[] selectedSeqs = new SequenceI[] { seq }; |
156 | 1 | StructureChooser sc = new StructureChooser(selectedSeqs, seq, null); |
157 | 1 | ThreadwaitFor(200, sc); |
158 | ||
159 | // if structures are not discovered then don't | |
160 | // populate filter options | |
161 | 1 | sc.populateFilterComboBox(false, false); |
162 | 1 | int optionsSize = sc.getCmbFilterOption().getItemCount(); |
163 | 1 | System.out.println("Items (no data, no cache): "); |
164 | 1 | StringBuilder items = new StringBuilder(); |
165 | 3 | for (int p = 0; p < optionsSize; p++) |
166 | { | |
167 | 2 | items.append("- ") |
168 | .append(sc.getCmbFilterOption().getItemAt(p).getName()) | |
169 | .append("\n"); | |
170 | ||
171 | } | |
172 | // report items when this fails - seems to be a race condition | |
173 | 1 | Assert.assertEquals(items.toString(), optionsSize, 2); |
174 | ||
175 | 1 | sc.populateFilterComboBox(true, false); |
176 | 1 | optionsSize = sc.getCmbFilterOption().getItemCount(); |
177 | 1 | assertTrue(optionsSize > 3); // if structures are found, filter options |
178 | // should be populated | |
179 | ||
180 | 1 | sc.populateFilterComboBox(true, true); |
181 | 1 | assertTrue(sc.getCmbFilterOption().getSelectedItem() != null); |
182 | 1 | FilterOption filterOpt = (FilterOption) sc.getCmbFilterOption() |
183 | .getSelectedItem(); | |
184 | 1 | assertEquals("Cached Structures", filterOpt.getName()); |
185 | 1 | FTSRestClient |
186 | .unMock((FTSRestClient) TDBeaconsFTSRestClient.getInstance()); | |
187 | 1 | FTSRestClient.unMock((FTSRestClient) PDBFTSRestClient.getInstance()); |
188 | ||
189 | } | |
190 | ||
191 | 1 | @Test(groups = { "Functional" }) |
192 | public void displayTDBQueryTest() throws InterruptedException | |
193 | { | |
194 | 1 | TDBeaconsFTSRestClientTest.setMock(); |
195 | 1 | PDBFTSRestClientTest.setMock(); |
196 | ||
197 | 1 | SequenceI[] selectedSeqs = new SequenceI[] { upSeq_nocanonical }; |
198 | 1 | StructureChooser sc = new StructureChooser(selectedSeqs, |
199 | upSeq_nocanonical, null); | |
200 | // mock so should be quick. Exceptions from mocked PDBFTS are expected too | |
201 | 1 | ThreadwaitFor(500, sc); |
202 | ||
203 | 1 | assertTrue(sc.isCanQueryTDB() && sc.isNotQueriedTDBYet()); |
204 | } | |
205 | ||
206 | 0 | @Test(groups = { "Network" }) |
207 | public void fetchStructuresInfoTest() | |
208 | { | |
209 | 0 | FTSRestClient |
210 | .unMock((FTSRestClient) TDBeaconsFTSRestClient.getInstance()); | |
211 | 0 | PDBFTSRestClient.unMock((FTSRestClient) PDBFTSRestClient.getInstance()); |
212 | 0 | SequenceI[] selectedSeqs = new SequenceI[] { seq }; |
213 | 0 | StructureChooser sc = new StructureChooser(selectedSeqs, seq, null); |
214 | // not mocked, wait for 2s | |
215 | 0 | ThreadwaitFor(2000, sc); |
216 | ||
217 | 0 | sc.fetchStructuresMetaData(); |
218 | 0 | Collection<FTSData> ss = (Collection<FTSData>) PA.getValue(sc, |
219 | "discoveredStructuresSet"); | |
220 | 0 | assertNotNull(ss); |
221 | 0 | assertTrue(ss.size() > 0); |
222 | } | |
223 | ||
224 | 1 | @Test(groups = { "Functional" }) |
225 | public void fetchStructuresInfoMockedTest() | |
226 | { | |
227 | 1 | TDBeaconsFTSRestClientTest.setMock(); |
228 | 1 | PDBFTSRestClientTest.setMock(); |
229 | 1 | SequenceI[] selectedSeqs = new SequenceI[] { upSeq }; |
230 | 1 | StructureChooser sc = new StructureChooser(selectedSeqs, seq, null); |
231 | 1 | ThreadwaitFor(500, sc); |
232 | ||
233 | 1 | sc.fetchStructuresMetaData(); |
234 | 1 | Collection<FTSData> ss = (Collection<FTSData>) PA.getValue(sc, |
235 | "discoveredStructuresSet"); | |
236 | 1 | assertNotNull(ss); |
237 | 1 | assertTrue(ss.size() > 0); |
238 | } | |
239 | ||
240 | 3 | private void ThreadwaitFor(int i, StructureChooser sc) |
241 | { | |
242 | 3 | long timeout = i + System.currentTimeMillis(); |
243 | 12 | while (!sc.isDialogVisible() && timeout > System.currentTimeMillis()) |
244 | { | |
245 | 9 | try |
246 | { | |
247 | 9 | Thread.sleep(50); |
248 | } catch (InterruptedException x) | |
249 | { | |
250 | ||
251 | } | |
252 | } | |
253 | ||
254 | } | |
255 | ||
256 | 1 | @Test(groups = { "Functional" }) |
257 | public void sanitizeSeqNameTest() | |
258 | { | |
259 | 1 | String name = "ab_cdEF|fwxyz012349"; |
260 | 1 | assertEquals(name, |
261 | PDBStructureChooserQuerySource.sanitizeSeqName(name)); | |
262 | ||
263 | // remove a [nn] substring | |
264 | 1 | name = "abcde12[345]fg"; |
265 | 1 | assertEquals("abcde12fg", |
266 | PDBStructureChooserQuerySource.sanitizeSeqName(name)); | |
267 | ||
268 | // remove characters other than a-zA-Z0-9 | or _ | |
269 | 1 | name = "ab[cd],.\t£$*!- \\\"@:e"; |
270 | 1 | assertEquals("abcde", |
271 | PDBStructureChooserQuerySource.sanitizeSeqName(name)); | |
272 | ||
273 | 1 | name = "abcde12[345a]fg"; |
274 | 1 | assertEquals("abcde12345afg", |
275 | PDBStructureChooserQuerySource.sanitizeSeqName(name)); | |
276 | } | |
277 | ||
278 | 6 | @Test(groups = { "Functional" }, dataProvider = "openStructureFileParams") |
279 | public void openStructureFileForSequenceTest(String alfile, String seqid, | |
280 | String sFilename, TFType tft, String paeFilename, | |
281 | boolean showRefAnnotations, boolean doXferSettings, | |
282 | ViewerType viewerType, int seqNum, int annNum, int viewerNum, | |
283 | String propsFile) | |
284 | { | |
285 | 6 | Cache.loadProperties( |
286 | 6 | propsFile == null ? "test/jalview/io/testProps.jvprops" |
287 | : propsFile); | |
288 | ||
289 | 6 | Jalview.main( |
290 | 6 | propsFile == null ? null : new String[] |
291 | { "--props", propsFile }); | |
292 | 6 | if (Desktop.instance != null) |
293 | 6 | Desktop.instance.closeAll_actionPerformed(null); |
294 | 6 | JvOptionPane.setInteractiveMode(false); |
295 | 6 | JvOptionPane.setMockResponse(JvOptionPane.OK_OPTION); |
296 | ||
297 | 6 | FileLoader fileLoader = new FileLoader(true); |
298 | 6 | FileFormatI format = null; |
299 | 6 | File alFile = new File(alfile); |
300 | 6 | try |
301 | { | |
302 | 6 | format = new IdentifyFile().identify(alFile, DataSourceType.FILE); |
303 | } catch (FileFormatException e1) | |
304 | { | |
305 | 0 | Assert.fail( |
306 | "Unknown file format for '" + alFile.getAbsolutePath() + "'"); | |
307 | } | |
308 | ||
309 | 6 | AlignFrame af = fileLoader.LoadFileWaitTillLoaded(alFile, |
310 | DataSourceType.FILE, format); | |
311 | 6 | AlignmentPanel ap = af.alignPanel; |
312 | 6 | Assert.assertNotNull("No alignPanel", ap); |
313 | ||
314 | 6 | AlignmentI al = ap.getAlignment(); |
315 | 6 | Assert.assertNotNull(al); |
316 | ||
317 | 6 | SequenceI seq = al.findName(seqid); |
318 | 6 | Assert.assertNotNull("Sequence '" + seqid + "' not found in alignment", |
319 | seq); | |
320 | ||
321 | 6 | StructureChooser.openStructureFileForSequence(null, null, ap, seq, |
322 | false, sFilename, tft, paeFilename, false, showRefAnnotations, | |
323 | doXferSettings, viewerType); | |
324 | ||
325 | 6 | List<SequenceI> seqs = al.getSequences(); |
326 | 6 | Assert.assertNotNull(seqs); |
327 | ||
328 | 6 | Assert.assertEquals("Wrong number of sequences", seqNum, seqs.size()); |
329 | ||
330 | 6 | AlignViewportI av = ap.getAlignViewport(); |
331 | 6 | Assert.assertNotNull(av); |
332 | ||
333 | 6 | AlignmentAnnotation[] aas = al.getAlignmentAnnotation(); |
334 | 6 | int visibleAnn = 0; |
335 | 6 | for (AlignmentAnnotation aa : aas) |
336 | { | |
337 | 36 | if (aa.visible) |
338 | 36 | visibleAnn++; |
339 | } | |
340 | 6 | Assert.assertEquals("Wrong number of viewed annotations", annNum, |
341 | visibleAnn); | |
342 | ||
343 | 6 | if (viewerNum > -1) |
344 | { | |
345 | 6 | try |
346 | { | |
347 | 6 | Thread.sleep(100); |
348 | } catch (InterruptedException e) | |
349 | { | |
350 | // TODO Auto-generated catch block | |
351 | 0 | e.printStackTrace(); |
352 | } | |
353 | 6 | List<StructureViewerBase> openViewers = Desktop.instance |
354 | .getStructureViewers(ap, null); | |
355 | 6 | Assert.assertNotNull(openViewers); |
356 | 6 | int count = 0; |
357 | 6 | for (StructureViewerBase svb : openViewers) |
358 | { | |
359 | 3 | if (svb.isVisible()) |
360 | 3 | count++; |
361 | } | |
362 | 6 | Assert.assertEquals("Wrong number of structure viewers opened", |
363 | viewerNum, count); | |
364 | ||
365 | } | |
366 | ||
367 | 6 | if (af != null) |
368 | { | |
369 | 6 | af.setVisible(false); |
370 | 6 | af.dispose(); |
371 | } | |
372 | } | |
373 | ||
374 | 1 | @DataProvider(name = "openStructureFileParams") |
375 | public Object[][] openStructureFileParams() | |
376 | { | |
377 | /* | |
378 | String alFile, | |
379 | String seqid, | |
380 | String structureFilename, | |
381 | TFType tft, | |
382 | String paeFilename, | |
383 | boolean showRefAnnotations, | |
384 | boolean doXferSettings, // false for Commands | |
385 | ViewerType viewerType, | |
386 | int seqNum, | |
387 | int annNum, | |
388 | int viewerNum, | |
389 | String propsFile | |
390 | */ | |
391 | 1 | return new Object[][] { |
392 | /* | |
393 | */ | |
394 | { "examples/uniref50.fa", "FER1_SPIOL", | |
395 | "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT, | |
396 | "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", | |
397 | true, false, null, 15, 7, 0, null }, | |
398 | { "examples/uniref50.fa", "FER1_SPIOL", | |
399 | "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT, | |
400 | "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", | |
401 | true, false, null, 15, 7, 0, null }, | |
402 | { "examples/uniref50.fa", "FER1_SPIOL", | |
403 | "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT, | |
404 | "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", | |
405 | false, false, null, 15, 4, 0, null }, | |
406 | { "examples/uniref50.fa", "FER1_SPIOL", | |
407 | "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.DEFAULT, | |
408 | "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", | |
409 | true, false, ViewerType.JMOL, 15, 7, 1, null }, | |
410 | { "examples/uniref50.fa", "FER1_SPIOL", | |
411 | "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT, | |
412 | "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", | |
413 | true, false, ViewerType.JMOL, 15, 7, 1, null }, | |
414 | { "examples/uniref50.fa", "FER1_SPIOL", | |
415 | "examples/AlphaFold/AF-P00221-F1-model_v4.cif", TFType.PLDDT, | |
416 | "examples/AlphaFold/AF-P00221-F1-predicted_aligned_error_v4.json", | |
417 | false, false, ViewerType.JMOL, 15, 4, 1, null }, }; | |
418 | } | |
419 | ||
420 | } |