Class |
Line # |
Actions |
|||
---|---|---|---|---|---|
ChimeraXCommandsTest | 40 | 142 | 23 |
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.ext.rbvi.chimera; | |
22 | ||
23 | import static org.testng.Assert.assertEquals; | |
24 | import static org.testng.Assert.assertTrue; | |
25 | ||
26 | import java.awt.Color; | |
27 | import java.util.HashMap; | |
28 | import java.util.LinkedHashMap; | |
29 | import java.util.List; | |
30 | import java.util.Map; | |
31 | ||
32 | import org.testng.annotations.BeforeClass; | |
33 | import org.testng.annotations.Test; | |
34 | ||
35 | import jalview.structure.AtomSpecModel; | |
36 | import jalview.structure.StructureCommand; | |
37 | import jalview.structure.StructureCommandI; | |
38 | import jalview.structure.StructureCommandsI.AtomSpecType; | |
39 | ||
40 | public class ChimeraXCommandsTest | |
41 | { | |
42 | private ChimeraXCommands testee; | |
43 | ||
44 | 1 | @BeforeClass(alwaysRun = true) |
45 | public void setUp() | |
46 | { | |
47 | 1 | testee = new ChimeraXCommands(); |
48 | } | |
49 | ||
50 | 1 | @Test(groups = { "Functional" }) |
51 | public void testColourByCharge() | |
52 | { | |
53 | 1 | List<StructureCommandI> cmd = testee.colourByCharge(); |
54 | 1 | assertEquals(cmd.size(), 1); |
55 | 1 | assertEquals(cmd.get(0).getCommand(), |
56 | "color white;color :ASP,GLU red;color :LYS,ARG blue;color :CYS yellow"); | |
57 | } | |
58 | ||
59 | 1 | @Test(groups = { "Functional" }) |
60 | public void testColourByChain() | |
61 | { | |
62 | 1 | StructureCommandI cmd = testee.colourByChain(); |
63 | 1 | assertEquals(cmd.getCommand(), "rainbow chain"); |
64 | } | |
65 | ||
66 | 1 | @Test(groups = { "Functional" }) |
67 | public void testFocusView() | |
68 | { | |
69 | 1 | StructureCommandI cmd = testee.focusView(); |
70 | 1 | assertEquals(cmd.getCommand(), "view"); |
71 | } | |
72 | ||
73 | 1 | @Test(groups = { "Functional" }) |
74 | public void testSetBackgroundColour() | |
75 | { | |
76 | 1 | StructureCommandI cmd = testee.setBackgroundColour(Color.PINK); |
77 | 1 | assertEquals(cmd.getCommand(), "set bgColor #ffafaf"); |
78 | } | |
79 | ||
80 | 1 | @Test(groups = { "Functional" }) |
81 | public void testOpenSession() | |
82 | { | |
83 | 1 | StructureCommandI cmd = testee.openSession("/some/filepath"); |
84 | 1 | assertEquals(cmd.getCommand(), "open /some/filepath format session"); |
85 | } | |
86 | ||
87 | 1 | @Test(groups = { "Functional" }) |
88 | public void testColourBySequence() | |
89 | { | |
90 | 1 | Map<Object, AtomSpecModel> map = new LinkedHashMap<>(); |
91 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.blue, "1", 2, 5, "A"); |
92 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.blue, "1", 7, 7, "B"); |
93 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.blue, "1", 9, 23, "A"); |
94 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.blue, "2", 1, 1, "A"); |
95 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.blue, "2", 4, 7, "B"); |
96 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.yellow, "2", 8, 8, "A"); |
97 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.yellow, "2", 3, 5, "A"); |
98 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.red, "1", 3, 5, "A"); |
99 | 1 | ChimeraCommands.addAtomSpecRange(map, Color.red, "1", 6, 9, "A"); |
100 | ||
101 | /* | |
102 | * Colours should appear in the Chimera command in the order in which | |
103 | * they were added; within colour, by model, by chain, ranges in start order | |
104 | */ | |
105 | 1 | List<StructureCommandI> commands = testee.colourBySequence(map); |
106 | 1 | assertEquals(commands.size(), 1); |
107 | 1 | assertEquals(commands.get(0).getCommand(), |
108 | "color #1/A:2-5,9-23/B:7|#2/A:1/B:4-7 #0000ff;color #2/A:3-5,8 #ffff00;color #1/A:3-9 #ff0000"); | |
109 | } | |
110 | ||
111 | 1 | @Test(groups = { "Functional" }) |
112 | public void testSetAttributes() | |
113 | { | |
114 | /* | |
115 | * make a map of { featureType, {featureValue, {residue range specification } } } | |
116 | */ | |
117 | 1 | Map<String, Map<Object, AtomSpecModel>> featuresMap = new LinkedHashMap<>(); |
118 | 1 | Map<Object, AtomSpecModel> featureValues = new HashMap<>(); |
119 | ||
120 | /* | |
121 | * start with just one feature/value... | |
122 | */ | |
123 | 1 | featuresMap.put("chain", featureValues); |
124 | 1 | ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 8, 20, "A"); |
125 | ||
126 | 1 | List<StructureCommandI> commands = testee.setAttributes(featuresMap); |
127 | 1 | assertEquals(commands.size(), 1); |
128 | ||
129 | /* | |
130 | * feature name gets a jv_ namespace prefix | |
131 | * feature value is quoted in case it contains spaces | |
132 | */ | |
133 | 1 | assertEquals(commands.get(0).getCommand(), |
134 | "setattr #0/A:8-20 res jv_chain 'X' create true"); | |
135 | ||
136 | // add same feature value, overlapping range | |
137 | 1 | ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 3, 9, "A"); |
138 | // same feature value, contiguous range | |
139 | 1 | ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 21, 25, "A"); |
140 | 1 | commands = testee.setAttributes(featuresMap); |
141 | 1 | assertEquals(commands.size(), 1); |
142 | 1 | assertEquals(commands.get(0).getCommand(), |
143 | "setattr #0/A:3-25 res jv_chain 'X' create true"); | |
144 | ||
145 | // same feature value and model, different chain | |
146 | 1 | ChimeraCommands.addAtomSpecRange(featureValues, "X", "0", 21, 25, "B"); |
147 | // same feature value and chain, different model | |
148 | 1 | ChimeraCommands.addAtomSpecRange(featureValues, "X", "1", 26, 30, "A"); |
149 | 1 | commands = testee.setAttributes(featuresMap); |
150 | 1 | assertEquals(commands.size(), 1); |
151 | 1 | String expected1 = "setattr #0/A:3-25/B:21-25|#1/A:26-30 res jv_chain 'X' create true"; |
152 | 1 | assertEquals(commands.get(0).getCommand(), expected1); |
153 | ||
154 | // same feature, different value | |
155 | 1 | ChimeraCommands.addAtomSpecRange(featureValues, "Y", "0", 40, 50, "A"); |
156 | 1 | commands = testee.setAttributes(featuresMap); |
157 | 1 | assertEquals(2, commands.size()); |
158 | // commands are ordered by feature type but not by value | |
159 | // so test for the expected command in either order | |
160 | 1 | String cmd1 = commands.get(0).getCommand(); |
161 | 1 | String cmd2 = commands.get(1).getCommand(); |
162 | 1 | assertTrue(cmd1.equals(expected1) || cmd2.equals(expected1)); |
163 | 1 | String expected2 = "setattr #0/A:40-50 res jv_chain 'Y' create true"; |
164 | 1 | assertTrue(cmd1.equals(expected2) || cmd2.equals(expected2)); |
165 | ||
166 | 1 | featuresMap.clear(); |
167 | 1 | featureValues.clear(); |
168 | 1 | featuresMap.put("side-chain binding!", featureValues); |
169 | 1 | ChimeraCommands.addAtomSpecRange(featureValues, |
170 | "<html>metal <a href=\"http:a.b.c/x\"> 'ion!", "0", 7, 15, "A"); | |
171 | // feature names are sanitised to change non-alphanumeric to underscore | |
172 | // feature values are sanitised to encode single quote characters | |
173 | 1 | commands = testee.setAttributes(featuresMap); |
174 | 1 | assertEquals(commands.size(), 1); |
175 | 1 | String expected3 = "setattr #0/A:7-15 res jv_side_chain_binding_ '<html>metal <a href=\"http:a.b.c/x\"> 'ion!' create true"; |
176 | 1 | assertTrue(commands.get(0).getCommand().equals(expected3)); |
177 | } | |
178 | ||
179 | 1 | @Test(groups = { "Functional" }) |
180 | public void testSuperposeStructures() | |
181 | { | |
182 | 1 | AtomSpecModel ref = new AtomSpecModel(); |
183 | 1 | ref.addRange("1", 12, 14, "A"); |
184 | 1 | ref.addRange("1", 18, 18, "B"); |
185 | 1 | ref.addRange("1", 22, 23, "B"); |
186 | 1 | AtomSpecModel toAlign = new AtomSpecModel(); |
187 | 1 | toAlign.addRange("2", 15, 17, "B"); |
188 | 1 | toAlign.addRange("2", 20, 21, "B"); |
189 | 1 | toAlign.addRange("2", 22, 22, "C"); |
190 | 1 | List<StructureCommandI> command = testee.superposeStructures(ref, |
191 | toAlign, AtomSpecType.ALPHA); | |
192 | 1 | assertEquals(command.size(), 1); |
193 | 1 | String cmd = command.get(0).getCommand(); |
194 | 1 | String refSpec = "#1/A:12-14/B:18,22-23"; |
195 | 1 | String toAlignSpec = "#2/B:15-17,20-21/C:22"; |
196 | ||
197 | /* | |
198 | * superposition arguments include AlphaCarbon restriction, | |
199 | * ribbon command does not | |
200 | */ | |
201 | 1 | String expected = String.format( |
202 | "align %s@CA toAtoms %s@CA; ribbon %s|%s; view", toAlignSpec, | |
203 | refSpec, toAlignSpec, refSpec); | |
204 | 1 | assertEquals(cmd, expected); |
205 | } | |
206 | ||
207 | 1 | @Test(groups = "Functional") |
208 | public void testGetAtomSpec() | |
209 | { | |
210 | 1 | AtomSpecModel model = new AtomSpecModel(); |
211 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), ""); |
212 | 1 | model.addRange("1", 2, 4, "A"); |
213 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
214 | "#1/A:2-4"); | |
215 | 1 | model.addRange("1", 8, 8, "A"); |
216 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
217 | "#1/A:2-4,8"); | |
218 | 1 | model.addRange("1", 5, 7, "B"); |
219 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
220 | "#1/A:2-4,8/B:5-7"); | |
221 | 1 | model.addRange("1", 3, 5, "A"); |
222 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
223 | "#1/A:2-5,8/B:5-7"); | |
224 | 1 | model.addRange("0", 1, 4, "B"); |
225 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
226 | "#0/B:1-4|#1/A:2-5,8/B:5-7"); | |
227 | 1 | model.addRange("0", 5, 9, "C"); |
228 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
229 | "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-7"); | |
230 | 1 | model.addRange("1", 8, 10, "B"); |
231 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
232 | "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-10"); | |
233 | 1 | model.addRange("1", 8, 9, "B"); |
234 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
235 | "#0/B:1-4/C:5-9|#1/A:2-5,8/B:5-10"); | |
236 | 1 | model.addRange("0", 3, 10, "C"); // subsumes 5-9 |
237 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
238 | "#0/B:1-4/C:3-10|#1/A:2-5,8/B:5-10"); | |
239 | 1 | model.addRange("5", 25, 35, " "); |
240 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.RESIDUE_ONLY), |
241 | "#0/B:1-4/C:3-10|#1/A:2-5,8/B:5-10|#5/:25-35"); | |
242 | } | |
243 | ||
244 | 1 | @Test(groups = "Functional") |
245 | public void testGetAtomSpec_alphaOnly() | |
246 | { | |
247 | 1 | AtomSpecModel model = new AtomSpecModel(); |
248 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), ""); |
249 | 1 | model.addRange("1", 2, 4, "A"); |
250 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
251 | "#1/A:2-4@CA"); | |
252 | 1 | model.addRange("1", 8, 8, "A"); |
253 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
254 | "#1/A:2-4,8@CA"); | |
255 | 1 | model.addRange("1", 5, 7, "B"); |
256 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
257 | "#1/A:2-4,8/B:5-7@CA"); | |
258 | 1 | model.addRange("1", 3, 5, "A"); |
259 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
260 | "#1/A:2-5,8/B:5-7@CA"); | |
261 | 1 | model.addRange("0", 1, 4, "B"); |
262 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
263 | "#0/B:1-4@CA|#1/A:2-5,8/B:5-7@CA"); | |
264 | 1 | model.addRange("0", 5, 9, "C"); |
265 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
266 | "#0/B:1-4/C:5-9@CA|#1/A:2-5,8/B:5-7@CA"); | |
267 | 1 | model.addRange("1", 8, 10, "B"); |
268 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
269 | "#0/B:1-4/C:5-9@CA|#1/A:2-5,8/B:5-10@CA"); | |
270 | 1 | model.addRange("1", 8, 9, "B"); |
271 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
272 | "#0/B:1-4/C:5-9@CA|#1/A:2-5,8/B:5-10@CA"); | |
273 | 1 | model.addRange("0", 3, 10, "C"); // subsumes 5-9 |
274 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
275 | "#0/B:1-4/C:3-10@CA|#1/A:2-5,8/B:5-10@CA"); | |
276 | 1 | model.addRange("5", 25, 35, " "); // empty chain code |
277 | 1 | assertEquals(testee.getAtomSpec(model, AtomSpecType.ALPHA), |
278 | "#0/B:1-4/C:3-10@CA|#1/A:2-5,8/B:5-10@CA|#5/:25-35@CA"); | |
279 | } | |
280 | ||
281 | 1 | @Test(groups = "Functional") |
282 | public void testGetModelStartNo() | |
283 | { | |
284 | 1 | assertEquals(testee.getModelStartNo(), 1); |
285 | } | |
286 | ||
287 | 1 | @Test(groups = "Functional") |
288 | public void testGetResidueSpec() | |
289 | { | |
290 | 1 | assertEquals(testee.getResidueSpec("ALA"), ":ALA"); |
291 | } | |
292 | ||
293 | 1 | @Test(groups = "Functional") |
294 | public void testShowBackbone() | |
295 | { | |
296 | 1 | List<StructureCommandI> showBackbone = testee.showBackbone(); |
297 | 1 | assertEquals(showBackbone.size(), 1); |
298 | 1 | assertEquals(showBackbone.get(0).getCommand(), |
299 | "~display all;~ribbon;show @CA|P atoms"); | |
300 | } | |
301 | ||
302 | 1 | @Test(groups = "Functional") |
303 | public void testOpenCommandFile() | |
304 | { | |
305 | 1 | assertEquals(testee.openCommandFile("nowhere").getCommand(), |
306 | "open nowhere"); | |
307 | } | |
308 | ||
309 | 1 | @Test(groups = "Functional") |
310 | public void testSaveSession() | |
311 | { | |
312 | 1 | assertEquals(testee.saveSession("somewhere").getCommand(), |
313 | "save somewhere format session"); | |
314 | } | |
315 | ||
316 | 1 | @Test(groups = "Functional") |
317 | public void testGetColourCommand() | |
318 | { | |
319 | 1 | assertEquals( |
320 | testee.colourResidues("something", Color.MAGENTA).getCommand(), | |
321 | "color something #ff00ff"); | |
322 | } | |
323 | ||
324 | 1 | @Test(groups = "Functional") |
325 | public void testSetAttribute() | |
326 | { | |
327 | 1 | AtomSpecModel model = new AtomSpecModel(); |
328 | 1 | model.addRange("1", 89, 92, "A"); |
329 | 1 | model.addRange("2", 12, 20, "B"); |
330 | 1 | model.addRange("2", 8, 9, "B"); |
331 | 1 | assertEquals(testee.setAttribute("jv_kd", "27.3", model).getCommand(), |
332 | "setattr #1/A:89-92|#2/B:8-9,12-20 res jv_kd '27.3' create true"); | |
333 | } | |
334 | ||
335 | 1 | @Test(groups = "Functional") |
336 | public void testCloseViewer() | |
337 | { | |
338 | 1 | assertEquals(testee.closeViewer(), new StructureCommand("exit")); |
339 | } | |
340 | ||
341 | 1 | @Test(groups = "Functional") |
342 | public void testGetSelectedResidues() | |
343 | { | |
344 | 1 | assertEquals(testee.getSelectedResidues(), |
345 | new StructureCommand("info selection level residue")); | |
346 | } | |
347 | ||
348 | 1 | @Test(groups = "Functional") |
349 | public void testStartNotifications() | |
350 | { | |
351 | 1 | List<StructureCommandI> cmds = testee.startNotifications("to here"); |
352 | 1 | assertEquals(cmds.size(), 2); |
353 | 1 | assertEquals(cmds.get(0), new StructureCommand( |
354 | "info notify start models jalview prefix ModelChanged url to here")); | |
355 | 1 | assertEquals(cmds.get(1), new StructureCommand( |
356 | "info notify start selection jalview prefix SelectionChanged url to here")); | |
357 | } | |
358 | ||
359 | 1 | @Test(groups = "Functional") |
360 | public void testStopNotifications() | |
361 | { | |
362 | 1 | List<StructureCommandI> cmds = testee.stopNotifications(); |
363 | 1 | assertEquals(cmds.size(), 2); |
364 | 1 | assertEquals(cmds.get(0), |
365 | new StructureCommand("info notify stop models jalview")); | |
366 | 1 | assertEquals(cmds.get(1), |
367 | new StructureCommand("info notify stop selection jalview")); | |
368 | } | |
369 | ||
370 | 1 | @Test(groups = "Functional") |
371 | public void testListResidueAttributes() | |
372 | { | |
373 | 1 | assertEquals(testee.listResidueAttributes(), |
374 | new StructureCommand("info resattr")); | |
375 | } | |
376 | } |