View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.cli2.option;
18  
19  import java.io.BufferedReader;
20  import java.io.IOException;
21  import java.io.PrintWriter;
22  import java.io.StringReader;
23  import java.io.StringWriter;
24  import java.util.ArrayList;
25  import java.util.Arrays;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Set;
29  
30  import org.apache.commons.cli2.CLITestCase;
31  import org.apache.commons.cli2.CommandLine;
32  import org.apache.commons.cli2.DisplaySetting;
33  import org.apache.commons.cli2.Group;
34  import org.apache.commons.cli2.OptionException;
35  import org.apache.commons.cli2.builder.ArgumentBuilder;
36  import org.apache.commons.cli2.builder.DefaultOptionBuilder;
37  import org.apache.commons.cli2.builder.GroupBuilder;
38  import org.apache.commons.cli2.commandline.Parser;
39  import org.apache.commons.cli2.util.HelpFormatter;
40  
41  
42  /**
43   * Test to exercise nested groups developed to demonstrate bug 32533
44   */
45  public class NestedGroupTest extends CLITestCase {
46      private static final String[] EXPECTED_USAGE = new String[] {
47              "Usage:                                                                          ",
48              " [-h -k -e|-d -b|-3 -f <file>|-s <string>]                                      ",
49              "encryptionService                                                               ",
50              "  -h (--help)               Print this message                                  ",
51              "  -k (--key)                Encryption key                                      ",
52              "  Action                    Action                                              ",
53              "    -e (--encrypt)          Encrypt input                                       ",
54              "    -d (--decrypt)          Decrypt input                                       ",
55              "  Algorithm                 Encryption Algorithm                                ",
56              "    -b (--blowfish)         Blowfish                                            ",
57              "    -3 (--3DES)             Triple DES                                          ",
58              "  Input                     Input                                               ",
59              "    -f (--file) file        Input file                                          ",
60              "    -s (--string) string    Input string                                        "
61      };
62  
63      final static DefaultOptionBuilder obuilder = new DefaultOptionBuilder();
64      final static ArgumentBuilder abuilder = new ArgumentBuilder();
65      final static GroupBuilder gbuilder = new GroupBuilder();
66  
67      static Group buildActionGroup() {
68          return gbuilder.withName("Action").withDescription("Action")
69                         .withMinimum(1).withMaximum(1)
70                         .withOption(obuilder.withId(5).withShortName("e")
71                                             .withLongName("encrypt")
72                                             .withDescription("Encrypt input")
73                                             .create())
74                         .withOption(obuilder.withId(6).withShortName("d")
75                                             .withLongName("decrypt")
76                                             .withDescription("Decrypt input")
77                                             .create()).create();
78      }
79  
80      static Group buildAlgorithmGroup() {
81          return gbuilder.withName("Algorithm")
82                         .withDescription("Encryption Algorithm").withMaximum(1)
83                         .withOption(obuilder.withId(0).withShortName("b")
84                                             .withLongName("blowfish")
85                                             .withDescription("Blowfish").create())
86                         .withOption(obuilder.withId(1).withShortName("3")
87                                             .withLongName("3DES")
88                                             .withDescription("Triple DES")
89                                             .create()).create();
90      }
91  
92      static Group buildInputGroup() {
93          return gbuilder.withName("Input").withDescription("Input").withMinimum(1)
94                         .withMaximum(1)
95                         .withOption(obuilder.withId(2).withShortName("f")
96                                             .withLongName("file")
97                                             .withDescription("Input file")
98                                             .withArgument(abuilder.withName(
99                      "file").withMinimum(1).withMaximum(1).create()).create())
100                        .withOption(obuilder.withId(3).withShortName("s")
101                                            .withLongName("string")
102                                            .withDescription("Input string")
103                                            .withArgument(abuilder.withName(
104                     "string").withMinimum(1).withMaximum(1).create()).create())
105                        .create();
106     }
107 
108     static Group buildEncryptionServiceGroup(Group[] nestedGroups) {
109         gbuilder.withName("encryptionService")
110                 .withOption(obuilder.withId(4).withShortName("h")
111                                     .withLongName("help")
112                                     .withDescription("Print this message")
113                                     .create()).withOption(obuilder.withShortName(
114                 "k").withLongName("key").withDescription("Encryption key")
115                                                                   .create());
116 
117         for (int i = 0; i < nestedGroups.length; i++) {
118             gbuilder.withOption(nestedGroups[i]);
119         }
120 
121         return gbuilder.create();
122     }
123 
124     public void testNestedGroup()
125         throws OptionException {
126         final String[] args = {
127                 "-eb",
128                 "--file",
129                 "/tmp/filename.txt"
130             };
131 
132         Group[] nestedGroups = {
133                 buildActionGroup(),
134                 buildAlgorithmGroup(),
135                 buildInputGroup()
136             };
137 
138         Parser parser = new Parser();
139         parser.setGroup(buildEncryptionServiceGroup(nestedGroups));
140 
141         CommandLine commandLine = parser.parse(args);
142 
143         assertTrue("/tmp/filename.txt".equals(commandLine.getValue("-f")));
144         assertTrue(commandLine.hasOption("-e"));
145         assertTrue(commandLine.hasOption("-b"));
146         assertFalse(commandLine.hasOption("-d"));
147     }
148 
149     public void testNestedGroupHelp() {
150         checkNestedGroupHelp(new HelpFormatter(), EXPECTED_USAGE);
151     }
152 
153     public void testNestedGroupHelpOptional()
154     {
155         HelpFormatter helpFormatter = new HelpFormatter();
156         Set dispOptions = new HashSet(helpFormatter.getFullUsageSettings());
157         dispOptions.add(DisplaySetting.DISPLAY_OPTIONAL_CHILD_GROUP);
158         List expLines = new ArrayList(Arrays.asList(EXPECTED_USAGE));
159         expLines.set(1," [-h -k -e|-d [-b|-3] -f <file>|-s <string>]                                    ");
160         helpFormatter.setFullUsageSettings(dispOptions);
161         checkNestedGroupHelp(helpFormatter, (String[]) expLines
162                 .toArray(new String[expLines.size()]));
163     }
164 
165     private void checkNestedGroupHelp(HelpFormatter helpFormatter, String[] expected) {
166         Group[] nestedGroups = {
167                 buildActionGroup(),
168                 buildAlgorithmGroup(),
169                 buildInputGroup()
170             };
171         helpFormatter.setGroup(buildEncryptionServiceGroup(nestedGroups));
172 
173         final StringWriter out = new StringWriter();
174         helpFormatter.setPrintWriter(new PrintWriter(out));
175 
176         try {
177             helpFormatter.print();
178 
179             final BufferedReader bufferedReader = new BufferedReader(new StringReader(
180                         out.toString()));
181 
182             List actual = new ArrayList(expected.length);
183             String input;
184 
185             while ((input = bufferedReader.readLine()) != null) {
186                 actual.add(input);
187             }
188 
189             // Show they are the same number of lines
190             assertEquals("Help text lines should be " + expected.length,
191                 actual.size(), expected.length);
192 
193             for (int i = 0; i < expected.length; i++) {
194                 if (!expected[i].equals(actual.get(i))) {
195                     for (int x = 0; x < expected.length; i++) {
196                         System.out.println("   " + expected[i]);
197                         System.out.println((expected[i].equals(actual.get(i))
198                             ? "== "
199                             : "!= ") + actual.get(i));
200                     }
201                 }
202 
203                 assertEquals(expected[i], actual.get(i));
204             }
205         }
206         catch (IOException e) {
207             fail(e.getLocalizedMessage());
208         }
209     }
210 }