View Javadoc
1   package org.djutils.cli;
2   
3   import static org.junit.Assert.assertEquals;
4   
5   import org.djunits.Throw;
6   import org.djunits.value.vdouble.scalar.Duration;
7   import org.junit.Test;
8   
9   import picocli.CommandLine.Command;
10  import picocli.CommandLine.Option;
11  
12  /**
13   * Program to test the CLI. <br>
14   * <br>
15   * Copyright (c) 2003-2018 Delft University of Technology, Jaffalaan 5, 2628 BX Delft, the Netherlands. All rights reserved. See
16   * for project information <a href="https://www.simulation.tudelft.nl/" target="_blank">www.simulation.tudelft.nl</a>. The
17   * source code and binary code of this software is proprietary information of Delft University of Technology.
18   * @author <a href="https://www.tudelft.nl/averbraeck" target="_blank">Alexander Verbraeck</a>
19   */
20  public class TestCLI
21  {
22      /** */
23      @Command(description = "Test program for CLI", name = "Program", mixinStandardHelpOptions = true, version = "1.0")
24      public static class Options implements Checkable
25      {
26          /** */
27          @Option(names = {"-p", "--port"}, description = "Internet port to use", defaultValue = "80")
28          private int port;
29  
30          /** */
31          private double noOption = 1.0;
32  
33          /** @return the port number */
34          public int getPort()
35          {
36              return this.port;
37          }
38  
39          /** @return noOption field. */
40          public double getNoOption()
41          {
42              return this.noOption;
43          }
44  
45          /** {@inheritDoc} */
46          @Override
47          public void check() throws Exception
48          {
49              if (this.port <= 0 || this.port > 65535)
50              {
51                  throw new Exception("Port should be between 1 and 65535");
52              }
53          }
54      }
55  
56      /** */
57      public static class NoCommandOptions implements Checkable
58      {
59          /** */
60          @Option(names = {"-t", "--timeout"}, description = "Timeout for network", defaultValue = "1min")
61          private Duration timeout;
62  
63  
64          /** @return timeout for network. */
65          public Duration getTimeout()
66          {
67              return this.timeout;
68          }
69  
70          /** {@inheritDoc} */
71          @Override
72          public void check() throws Exception
73          {
74              Throw.when(this.timeout.si <= 0.0, IllegalArgumentException.class, "timeout should be positive");
75          }
76      }
77  
78      /**
79       * Test the CliUtil methods.
80       * @throws CliException on error
81       * @throws IllegalAccessException on error
82       * @throws IllegalArgumentException on error
83       * @throws NoSuchFieldException on error
84       */
85      @Test
86      public void testCli() throws NoSuchFieldException, IllegalArgumentException, IllegalAccessException, CliException
87      {
88          String[] args = new String[] {"-p", "1200"};
89          Options options = new Options();
90          assertEquals("1.0", CliUtil.getCommandVersion(options)[0]);
91          assertEquals("Program", CliUtil.getCommandName(options));
92          assertEquals("Test program for CLI", CliUtil.getCommandDescription(options)[0]);
93          CliUtil.execute(options, args);
94          assertEquals(1200, options.getPort());
95          assertEquals("1.0", options.getClass().getAnnotation(Command.class).version()[0]);
96          assertEquals("Program", options.getClass().getAnnotation(Command.class).name());
97          assertEquals("Test program for CLI", options.getClass().getAnnotation(Command.class).description()[0]);
98  
99          args = new String[] {};
100         options = new Options();
101         CliUtil.execute(options, args);
102         assertEquals(80, options.getPort());
103 
104         args = new String[] {};
105         options = new Options();
106         CliUtil.changeOptionDefault(options, "port", "8080");
107         CliUtil.execute(options, args);
108         assertEquals(8080, options.getPort());
109 
110         // change the @Command annotation
111         args = new String[] {};
112         options = new Options();
113         CliUtil.changeCommandVersion(options, "2.0");
114         CliUtil.changeCommandName(options, "Program2");
115         CliUtil.changeCommandDescription(options, "2nd version of program");
116         CliUtil.execute(options, args);
117         assertEquals("2.0", CliUtil.getCommandVersion(options)[0]);
118         assertEquals("Program2", CliUtil.getCommandName(options));
119         assertEquals("2nd version of program", CliUtil.getCommandDescription(options)[0]);
120         
121         // The annotation itself should NOT have changed
122         Command command = CliUtil.getCommandAnnotation(Options.class);
123         assertEquals("1.0", command.version()[0]);
124         assertEquals("Program", command.name());
125         assertEquals("Test program for CLI", command.description()[0]);
126 
127         // clean the override map
128         CliUtil.overrideMap.clear();
129 
130         // test field without @Option
131         try
132         {
133             CliUtil.changeOptionDefault(Options.class, "noOption", "3.0");
134         }
135         catch (CliException e)
136         {
137             // ok
138         }
139 
140         // test class without @Command
141         try
142         {
143             NoCommandOptions nco = new NoCommandOptions();
144             CliUtil.changeCommandName(nco, "NoCommand");
145         }
146         catch (CliException e)
147         {
148             // ok
149         }
150         
151         // change the @Command annotations to other object types
152         args = new String[] {};
153         options = new Options();
154         Class<?> declaringClass = CliUtil.getCommandAnnotationClass(Options.class);
155         String key = CliUtil.makeOverrideKeyCommand(declaringClass, "version");
156         CliUtil.overrideMap.put(key, "6.0");
157         key = CliUtil.makeOverrideKeyCommand(declaringClass, "name");
158         CliUtil.overrideMap.put(key, "Prog60");
159         key = CliUtil.makeOverrideKeyCommand(declaringClass, "description");
160         CliUtil.overrideMap.put(key, "Program v60");
161         CliUtil.execute(options, args);
162         assertEquals("6.0", CliUtil.getCommandVersion(options)[0]);
163         assertEquals("Prog60", CliUtil.getCommandName(options));
164         assertEquals("Program v60", CliUtil.getCommandDescription(options)[0]);
165 
166         // clean the override map
167         CliUtil.overrideMap.clear();        
168     }
169 }