JAL-4090 JAL-1551 source license
[jalview.git] / test / jalview / bin / argparser / ArgParserTest.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.bin.argparser;
22
23 import java.io.File;
24 import java.io.IOException;
25 import java.util.List;
26 import java.util.Properties;
27
28 import org.testng.Assert;
29 import org.testng.annotations.AfterClass;
30 import org.testng.annotations.AfterMethod;
31 import org.testng.annotations.DataProvider;
32 import org.testng.annotations.Test;
33
34 import jalview.bin.Cache;
35 import jalview.gui.Desktop;
36
37 @Test(singleThreaded = true)
38 public class ArgParserTest
39 {
40   @AfterClass(alwaysRun = true)
41   public static void resetProps()
42   {
43     Cache.loadProperties("test/jalview/testProps.jvprops");
44   }
45
46   @AfterMethod(alwaysRun = true)
47   public void tearDown()
48   {
49     if (Desktop.instance != null)
50       Desktop.instance.closeAll_actionPerformed(null);
51   }
52
53   @Test(groups = "Functional", dataProvider = "argLines")
54   public void parseArgsTest(String commandLineArgs, Arg a, String other)
55   {
56     String[] args = commandLineArgs.split("\\s+");
57     ArgParser argparser = new ArgParser(args);
58   }
59
60   @Test(groups = "Functional", dataProvider = "argSubValsAndLinkedIds")
61   public void parseSubValsAndLinkedIdsTest(String commandLineArgs,
62           String linkedId, Arg a, String subvalKey, String value,
63           boolean trueOrFalse)
64   {
65     String[] args = commandLineArgs.split("\\s+");
66     ArgParser argparser = new ArgParser(args);
67     ArgValuesMap avm = argparser.getLinkedArgs(linkedId);
68     ArgValue av = avm.getArgValue(a);
69     SubVals sv = av.getSubVals();
70     String testString = null;
71     if (subvalKey.equals("GETINDEX"))
72     {
73       testString = String.valueOf(sv.getIndex());
74     }
75     else
76     {
77       testString = sv.get(subvalKey);
78     }
79     if (trueOrFalse)
80     {
81       Assert.assertEquals(testString, value);
82     }
83     else
84     {
85       Assert.assertNotEquals(testString, value);
86     }
87   }
88
89   @Test(
90     groups = "Functional",
91     dataProvider = "argAutoIndexAndSubstitutions")
92   public void parseAutoIndexAndSubstitutionsTest(String commandLineArgs,
93           String linkedId, Arg a, String filename)
94   {
95     // { "--append=filename0 --new --append=filename1", "JALVIEW:1",
96     // Arg.OPEN, "filename1" },
97     String[] args = commandLineArgs.split("\\s+");
98     ArgParser argparser = new ArgParser(args);
99     ArgValuesMap avm = argparser.getLinkedArgs(linkedId);
100     ArgValue av = avm.getArgValue(a);
101     Assert.assertEquals(av.getValue(), filename);
102   }
103
104   @Test(groups = "Functional", dataProvider = "argLines")
105   public void bootstrapArgsTest(String commandLineArgs, Arg a, String other)
106   {
107     String[] args = commandLineArgs.split("\\s+");
108     BootstrapArgs b = BootstrapArgs.getBootstrapArgs(args);
109
110     Assert.assertTrue(b.contains(a));
111     if (a == Arg.PROPS)
112     {
113       Properties bP = Cache.bootstrapProperties(b.getValue(Arg.PROPS));
114       Assert.assertNotNull(bP);
115       Assert.assertTrue(other.equals(bP.get(Cache.BOOTSTRAP_TEST)));
116       Assert.assertFalse(bP.contains("NOT" + Cache.BOOTSTRAP_TEST));
117     }
118     else if (a == Arg.ARGFILE)
119     {
120       List<String> filenames = b.getValueList(a);
121       boolean found = false;
122       for (String s : filenames)
123       {
124         File f = new File(s);
125         File fo = new File(other);
126         try
127         {
128           if (fo.getCanonicalPath().equals(f.getCanonicalPath()))
129           {
130             found = true;
131             break;
132           }
133         } catch (IOException e)
134         {
135         }
136       }
137       Assert.assertTrue(found,
138               "File '" + other + "' not found in shell expanded glob '"
139                       + commandLineArgs + "'");
140     }
141   }
142
143   @Test(groups = "Functional", dataProvider = "argFiles")
144   public void argFilesTest(String commandLineArgs, Arg a, String other)
145   {
146     String[] args = commandLineArgs.split("\\s+");
147     BootstrapArgs b = BootstrapArgs.getBootstrapArgs(args);
148
149     Assert.assertTrue(b.contains(a));
150     Assert.assertFalse(b.contains(Arg.APPEND));
151     if (a == Arg.PROPS)
152     {
153       Properties bP = Cache.bootstrapProperties(b.getValue(Arg.PROPS));
154       Assert.assertTrue("true".equals(bP.get(Cache.BOOTSTRAP_TEST)));
155     }
156   }
157
158   @DataProvider(name = "argLinesNotworking")
159   public Object[][] argLinesTest()
160   {
161     return new Object[][] {
162         // can't use this one yet as it doesn't get shell glob expanded by the
163         // test
164         { "--argfile test/jalview/bin/argparser/testfiles/argfile*.txt",
165             Arg.ARGFILE,
166             "test/jalview/bin/argparser/testfiles/argfile0.txt" }, };
167   }
168
169   @DataProvider(name = "argLines")
170   public Object[][] argLines()
171   {
172     return new Object[][] { {
173         "--append=test/jalview/bin/argparser/testfiles/test1.fa --props=test/jalview/bin/argparser/testfiles/testProps.jvprops",
174         Arg.PROPS, "true" },
175         { "--debug --append=test/jalview/bin/argparser/testfiles/test1.fa",
176             Arg.DEBUG, null },
177         { "--append=test/jalview/bin/argparser/testfiles/test1.fa --headless",
178             Arg.HEADLESS, null },
179
180         { "--argfile test/jalview/bin/argparser/testfiles/argfile0.txt",
181             Arg.ARGFILE,
182             "test/jalview/bin/argparser/testfiles/argfile0.txt" },
183         // these next three are what a shell glob expansion would look like
184         { "--argfile test/jalview/bin/argparser/testfiles/argfile0.txt test/jalview/bin/argparser/testfiles/argfile1.txt test/jalview/bin/argparser/testfiles/argfile2.txt",
185             Arg.ARGFILE,
186             "test/jalview/bin/argparser/testfiles/argfile0.txt" },
187         { "--argfile test/jalview/bin/argparser/testfiles/argfile0.txt test/jalview/bin/argparser/testfiles/argfile1.txt test/jalview/bin/argparser/testfiles/argfile2.txt",
188             Arg.ARGFILE,
189             "test/jalview/bin/argparser/testfiles/argfile1.txt" },
190         { "--argfile test/jalview/bin/argparser/testfiles/argfile0.txt test/jalview/bin/argparser/testfiles/argfile1.txt test/jalview/bin/argparser/testfiles/argfile2.txt",
191             Arg.ARGFILE,
192             "test/jalview/bin/argparser/testfiles/argfile2.txt" },
193         { "--argfile=test/jalview/bin/argparser/testfiles/argfile*.txt",
194             Arg.ARGFILE,
195             "test/jalview/bin/argparser/testfiles/argfile0.txt" },
196         { "--argfile=test/jalview/bin/argparser/testfiles/argfile*.txt",
197             Arg.ARGFILE,
198             "test/jalview/bin/argparser/testfiles/argfile1.txt" },
199         { "--argfile=test/jalview/bin/argparser/testfiles/argfile*.txt",
200             Arg.ARGFILE,
201             "test/jalview/bin/argparser/testfiles/argfile2.txt" } };
202   }
203
204   @DataProvider(name = "argSubValsAndLinkedIds")
205   public Object[][] argSubValsAndLinkedIds()
206   {
207     return new Object[][] {
208         //
209         /*
210          */
211         { "--debug --append=[hi]test/jalview/bin/argparser/testfiles/test1.fa",
212             "JALVIEW:0", Arg.APPEND, "hi", "true", true },
213         { "--append[linkedId1]=[new,hello=world,1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
214             "linkedId1", Arg.APPEND, "new", "true", true },
215         { "--append[linkedId2]=[new,hello=world,1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
216             "linkedId2", Arg.APPEND, "hello", "world", true },
217         { "--append[linkedId3]=[new,hello=world,1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
218             "linkedId3", Arg.APPEND, "GETINDEX", "1", true },
219         { "--append[linkedId4]=[new,hello=world,1]test/jalview/bin/argparser/testfiles/test1.fa --append[linkedId5]=[notnew;hello=world;1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
220             "linkedId5", Arg.APPEND, "new", "true", false },
221         { "--append[linkedId5]=[new,hello=worlddomination,1]test/jalview/bin/argparser/testfiles/test1.fa --append[linkedId2]=[new;hello=world;1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
222             "linkedId5", Arg.APPEND, "hello", "world", false },
223         { "--append[linkedId6]=[new,hello=world,0]test/jalview/bin/argparser/testfiles/test1.fa --append[linkedId7]=[new;hello=world;1]test/jalview/bin/argparser/testfiles/test1.fa --headless",
224             "linkedId7", Arg.APPEND, "GETINDEX", "0", false },
225         /*
226          */
227         //
228     };
229   }
230
231   @DataProvider(name = "argAutoIndexAndSubstitutions")
232   public Object[][] argAutoIndexAndSubstitutions()
233   {
234     return new Object[][] {
235         //
236         /*
237          */
238         { "--append=filename0 --append=filename1", "JALVIEW:0", Arg.APPEND,
239             "filename0" },
240         { "--append=filename0 --new --append=filename1", "JALVIEW:1",
241             Arg.APPEND, "filename1" },
242         { "--append=filename0 --new --new --append=filename2", "JALVIEW:0",
243             Arg.APPEND, "filename0" },
244         { "--append=filename0 --new --new --append=filename2", "JALVIEW:2",
245             Arg.APPEND, "filename2" },
246         { "--append[linkA-{n}]=filenameA0 --append[linkA-{++n}]=filenameA1",
247             "linkA-0", Arg.APPEND, "filenameA0" },
248         { "--append[linkB-{n}]=filenameB0 --append[linkB-{++n}]=filenameB1",
249             "linkB-1", Arg.APPEND, "filenameB1" },
250         { "--append[linkC-{n}]=filenameC0 --image[linkC-{n}]=outputC{n}.txt",
251             "linkC-0", Arg.IMAGE, "outputC{n}.txt" },
252         { "--append[linkD-{n}]=filenameD0 --substitutions --image[linkD-{n}]=outputD{n}.txt",
253             "linkD-0", Arg.IMAGE, "outputD0.txt" },
254         { "--append[linkE-{n}]=filenameE0 --substitutions --image[linkE-{n}]=output-E{n}.txt --nil[{++n}] --image[linkE-{n}]=outputE{n}.txt",
255             "linkE-0", Arg.IMAGE, "output-E0.txt" },
256         { "--append[linkF-{n}]=filenameF0 --substitutions --image[linkF-{n}]=output-F{n}.txt --nil[{++n}] --image[linkF-{n}]=outputF{n}.txt",
257             "linkF-1", Arg.IMAGE, "outputF1.txt" },
258         { "--append[linkG-{n}]=filenameG0 --substitutions --image[linkG-{n}]=output-G{n}.txt --nil[{++n}] --nosubstitutions --image[linkG-{n}]=outputG{n}.txt",
259             "linkG-1", Arg.IMAGE, "outputG{n}.txt" },
260         { "--append[linkH-{n}]=filenameH0 --substitutions --image[linkH-{n}]=output-H{n}.txt --nil[{++n}] --nosubstitutions --image[linkH-{n}]=outputH{n}.txt",
261             "linkH-0", Arg.IMAGE, "output-H0.txt" },
262         { "--open=filename0 --append=filename1", "JALVIEW:0", Arg.OPEN,
263             "filename0" },
264         { "--open=filename0 --new --append=filename1", "JALVIEW:1",
265             Arg.APPEND, "filename1" },
266         { "--open=filename0 --new --new --append=filename2", "JALVIEW:0",
267             Arg.OPEN, "filename0" },
268         { "--open=filename0 --new --new --append=filename2", "JALVIEW:2",
269             Arg.APPEND, "filename2" },
270         { "--open[linkA-{n}]=filenameA0 --append[linkA-{++n}]=filenameA1",
271             "linkA-0", Arg.OPEN, "filenameA0" },
272         { "--open[linkB-{n}]=filenameB0 --append[linkB-{++n}]=filenameB1",
273             "linkB-1", Arg.APPEND, "filenameB1" },
274         { "--open[linkC-{n}]=filenameC0 --image[linkC-{n}]=outputC{n}.txt",
275             "linkC-0", Arg.IMAGE, "outputC{n}.txt" },
276         { "--open[linkD-{n}]=filenameD0 --substitutions --image[linkD-{n}]=outputD{n}.txt",
277             "linkD-0", Arg.IMAGE, "outputD0.txt" },
278         { "--open[linkE-{n}]=filenameE0 --substitutions --image[linkE-{n}]=output-E{n}.txt --nil[{++n}] --image[linkE-{n}]=outputE{n}.txt",
279             "linkE-0", Arg.IMAGE, "output-E0.txt" },
280         { "--open[linkF-{n}]=filenameF0 --substitutions --image[linkF-{n}]=output-F{n}.txt --nil[{++n}] --image[linkF-{n}]=outputF{n}.txt",
281             "linkF-1", Arg.IMAGE, "outputF1.txt" },
282         { "--open[linkG-{n}]=filenameG0 --substitutions --image[linkG-{n}]=output-G{n}.txt --nil[{++n}] --nosubstitutions --image[linkG-{n}]=outputG{n}.txt",
283             "linkG-1", Arg.IMAGE, "outputG{n}.txt" },
284         { "--open[linkH-{n}]=filenameH0 --substitutions --image[linkH-{n}]=output-H{n}.txt --nil[{++n}] --nosubstitutions --image[linkH-{n}]=outputH{n}.txt",
285             "linkH-0", Arg.IMAGE, "output-H0.txt" },
286         /*
287          */
288
289         //
290     };
291   }
292
293   @DataProvider(name = "argFiles")
294   public Object[][] argFiles()
295   {
296     return new Object[][] { {
297         "--argfile=test/jalview/bin/argparser/testfiles/argfile0.txt --open=shouldntbeabootstrap",
298         Arg.ARGFILE, "test/jalview/bin/argfiles/testfiles/test1.fa" } };
299   }
300
301   @Test(groups = "Functional", dataProvider = "allLinkedIdsData")
302   public void allLinkedIdsTest(String pwd, String commandLineArgs, Arg a,
303           String[] values, String[] nonvalues)
304   {
305     String userDir = System.getProperty("user.dir");
306     if (pwd != null)
307     {
308       File pwdFile = new File(pwd);
309       System.setProperty("user.dir", pwdFile.getAbsolutePath());
310     }
311     String[] args = commandLineArgs.split("\\s+");
312     ArgParser argparser = new ArgParser(args);
313
314     int num = values.length;
315     List<String> linkedIds = argparser.getLinkedIds();
316     Assert.assertEquals(linkedIds.size(), num,
317             "Wrong number of linkedIds: " + linkedIds.toString());
318     for (int i = 0; i < num; i++)
319     {
320       String value = values[i];
321       String linkedId = linkedIds.get(i);
322       ArgValuesMap avm = argparser.getLinkedArgs(linkedId);
323       if (value == null)
324       {
325         Assert.assertTrue(avm.containsArg(a),
326                 "Arg value for " + a.argString()
327                         + " not applied correctly to linkedId '" + linkedId
328                         + "'");
329       }
330       else
331       {
332         ArgValues avs = avm.getArgValues(a);
333         ArgValue av = avs.getArgValue();
334         String v = av.getValue();
335         value = new File(value).getPath();
336         Assert.assertEquals(v, value, "Arg value for " + a.argString()
337                 + " not applied correctly to linkedId '" + linkedId + "'");
338       }
339     }
340
341     System.setProperty("user.dir", userDir);
342   }
343
344   @DataProvider(name = "allLinkedIdsData")
345   public Object[][] allLinkedIdsData()
346   {
347     return new Object[][] {
348         //
349         /*
350         */
351         { null,
352             "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
353             Arg.CLOSE, new String[]
354             { null, null, null },
355             null },
356         { null,
357             "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --output={dirname}/{basename}.stk --close",
358             Arg.OUTPUT, new String[]
359             { "test/jalview/bin/argparser/testfiles/test1.stk",
360                 "test/jalview/bin/argparser/testfiles/test2.stk",
361                 "test/jalview/bin/argparser/testfiles/test3.stk", },
362             null },
363         { null,
364             "--open=test/jalview/bin/argparser/testfiles/*.fa --substitutions --all --image={dirname}/{basename}.png --close",
365             Arg.IMAGE, new String[]
366             { "test/jalview/bin/argparser/testfiles/test1.png",
367                 "test/jalview/bin/argparser/testfiles/test2.png",
368                 "test/jalview/bin/argparser/testfiles/test3.png", },
369             null },
370         /*
371          * Find a way to change pwd reliably -- need to match "*.fa" against some files!
372          { "test/jalview/bin/argparser/testfiles",
373          
374             "--open=*.fa --image={dirname}/{basename}.png --close",
375             Arg.IMAGE, new String[]
376             { "./test1.png", "./test2.png", "./test3.png", }, null },
377             */
378         //
379     };
380   }
381
382   @Test(groups = "Functional", dataProvider = "bootstrapArgsData")
383   public void bootstrapArgsValuesAndHeadlessModeTest(String commandLineArgs,
384           Arg a, String valS, boolean valB, boolean headlessValue)
385   {
386     String[] args = commandLineArgs.split("\\s+");
387     BootstrapArgs bsa = BootstrapArgs.getBootstrapArgs(args);
388     if (a != null)
389     {
390       if (valS != null)
391       {
392         Assert.assertEquals(bsa.getValue(a), valS,
393                 "BootstrapArg " + a.argString()
394                         + " value does not match expected '" + valS + "'");
395       }
396       else
397       {
398         Assert.assertEquals(bsa.getBoolean(a), valB,
399                 "Boolean/Unary value of BootstrapArg " + a.argString()
400                         + "' is not the expected '" + valB + "'");
401       }
402     }
403
404     boolean isHeadless = bsa.isHeadless();
405     Assert.assertEquals(isHeadless, headlessValue,
406             "Assumed headless setting '" + isHeadless + "' is wrong.");
407   }
408
409   @DataProvider(name = "bootstrapArgsData")
410   public Object[][] bootstrapArgsData()
411   {
412     return new Object[][] {
413         /*
414          * cmdline args
415          * Arg (null if only testing headless)
416          * String value if there is one (null otherwise)
417          * boolean value if String value is null
418          * expected value of isHeadless()
419          */
420         /*
421         */
422         { "--open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
423             Arg.JABAWS, "https://forwardsandbackwards.com/", false, true },
424         { "--help-all --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
425             Arg.HELP, null, true, true },
426         { "--help-all --nonews --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
427             Arg.NEWS, null, false, true },
428         { "--help --nonews --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
429             Arg.NEWS, null, false, true },
430         { "--help-opening --nonews --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
431             Arg.NEWS, null, false, true },
432         { "--nonews --open thisway.fa --output thatway.fa --jabaws https://forwardsandbackwards.com/",
433             Arg.NEWS, null, false, true },
434         { "--open thisway.fa --image thatway.png", null, null, false,
435             true },
436         { "--open thisway.fa --output thatway.png", null, null, false,
437             true },
438         { "--open thisway.fa --image thatway.png --noheadless", null, null,
439             false, false },
440         { "--open thisway.fa --output thatway.png --noheadless", null, null,
441             false, false },
442         { "--open thisway.fa --image thatway.png --gui", null, null, false,
443             false },
444         { "--open thisway.fa --output thatway.png --gui", null, null, false,
445             false },
446         // --gui takes precedence
447         { "--open thisway.fa --image thatway.png --gui --headless", null,
448             null, false, false },
449         { "--open thisway.fa --output thatway.png --gui --headless", null,
450             null, false, false },
451         //
452     };
453   }
454
455 }