diff options
author | Cedric Beust <cedric@beust.com> | 2014-10-06 08:59:54 -0700 |
---|---|---|
committer | Cedric Beust <cedric@beust.com> | 2014-10-06 08:59:54 -0700 |
commit | c5f63328c0668f074d96f76666e2ff84da853329 (patch) | |
tree | e61e35cabd73ba5da766200513c389a8c0b74c42 | |
parent | 89820cc701ca41c85e3b000939f649df0636e35b (diff) | |
parent | 9d95b9d5cc6cf6eaa33b4170779e2191f2baefd9 (diff) | |
download | platform_external_jcommander-c5f63328c0668f074d96f76666e2ff84da853329.tar.gz platform_external_jcommander-c5f63328c0668f074d96f76666e2ff84da853329.tar.bz2 platform_external_jcommander-c5f63328c0668f074d96f76666e2ff84da853329.zip |
Merge branch 'master' of github.com:cbeust/jcommander
Conflicts:
doc/index.html
-rwxr-xr-x | build-with-maven | 7 | ||||
-rw-r--r-- | doc/index.html | 18 | ||||
-rw-r--r-- | pom.xml | 43 | ||||
-rw-r--r-- | src/main/java/com/beust/jcommander/JCommander.java | 55 | ||||
-rw-r--r-- | src/main/java/com/beust/jcommander/Parameter.java | 8 | ||||
-rw-r--r-- | src/main/java/com/beust/jcommander/ParameterDescription.java | 6 | ||||
-rw-r--r-- | src/main/java/com/beust/jcommander/Parameters.java | 5 | ||||
-rw-r--r-- | src/main/java/com/beust/jcommander/WrappedParameter.java | 3 | ||||
-rw-r--r-- | src/main/java/com/beust/jcommander/internal/DefaultConsole.java | 3 | ||||
-rw-r--r-- | src/test/java/com/beust/jcommander/JCommanderTest.java | 91 | ||||
-rw-r--r-- | src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java | 32 | ||||
-rw-r--r-- | src/test/java/com/beust/jcommander/command/CommandHidden.java | 17 | ||||
-rw-r--r-- | src/test/java/com/beust/jcommander/command/CommandTest.java | 22 | ||||
-rw-r--r-- | src/test/java/com/beust/jcommander/internal/DefaultConsoleTest.java | 64 |
14 files changed, 330 insertions, 44 deletions
diff --git a/build-with-maven b/build-with-maven index 41aef5a..8323640 100755 --- a/build-with-maven +++ b/build-with-maven @@ -2,11 +2,12 @@ mvn -B clean source:jar javadoc:jar repository:bundle-create -P sign #v=6.5.2beta -export TESTNG=`echo ../testng/target/testng-6.8.7.jar` +export TESTNG=`echo ../testng/target/testng-6.8.8.jar` -run="java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml" +run="java -classpath \"target/classes;target/test-classes;${TESTNG};$CLASSPATH\" org.testng.TestNG src/test/resources/testng.xml" echo "Launching tests: ${run}" -java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml +$run +#java -classpath target/classes:target/test-classes:${TESTNG}:$CLASSPATH org.testng.TestNG src/test/resources/testng.xml echo "To deploy to the snapshot repository: mvn deploy" echo "To deploy to the release directory: mvn -DskipTests=true release:clean release:prepare release:perform" diff --git a/doc/index.html b/doc/index.html index 6ed16c4..8ee8880 100644 --- a/doc/index.html +++ b/doc/index.html @@ -30,7 +30,19 @@ <td align="center"> <h1>JCommander</h1> <h2>Because life is too short to parse command line parameters</h2> -<h3>Donations welcome at <a href="bitcoin:1BhLmUZnDtjtqNetjqjHW1onqdykJW7Bd2">1BhLmUZnDtjtqNetjqjHW1onqdykJW7Bd2</a> +<h3> + <form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top"> + <input type="hidden" name="cmd" value="_donations"> + <input type="hidden" name="business" value="cedric@beust.com"> + <input type="hidden" name="lc" value="US"> + <input type="hidden" name="item_name" value="Cedric Beust"> + <input type="hidden" name="no_note" value="0"> + <input type="hidden" name="currency_code" value="USD"> + <input type="hidden" name="bn" value="PP-DonationsBF:btn_donate_LG.gif:NonHostedGuest"> + <input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donate_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!"> + <img alt="" border="0" src="https://www.paypalobjects.com/en_US/i/scr/pixel.gif" width="1" height="1"> + </form> +</h3> </td> </tr> <tr> @@ -40,7 +52,7 @@ </tr> <tr> <td align="right"> - Last updated: October 25th, 2012 + Last updated: August 2nd, 2014 </td> </tr> <tr><td align="right"><a href="mailto:cedric@beust.com">Cédric Beust</a></td></tr> @@ -201,7 +213,7 @@ For example, here is a converter that turns a string into a <tt>File</tt>: <pre class="brush: java"> public class FileConverter implements IStringConverter<File> { @Override - private File convert(String value) { + public File convert(String value) { return new File(value); } } @@ -24,7 +24,7 @@ <artifactId>jcommander</artifactId> <packaging>jar</packaging> <name>JCommander</name> - <version>1.33-SNAPSHOT</version> + <version>1.45-SNAPSHOT</version> <description>A Java framework to parse command line options with annotations.</description> <url>http://beust.com/jcommander</url> <licenses> @@ -40,6 +40,14 @@ <url>git@github.com:cbeust/jcommander.git</url> </scm> + <distributionManagement> + <repository> + <id>nexus-site</id> + <name>Nexus Staging Repository</name> + <url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url> + </repository> + </distributionManagement> + <developers> <developer> <name>Cedric Beust</name> @@ -155,6 +163,39 @@ </configuration> </plugin> </plugins> + <pluginManagement> + <plugins> + <!--This plugin's configuration is used to store Eclipse m2e settings only. It has no influence on the Maven build itself.--> + <plugin> + <groupId>org.eclipse.m2e</groupId> + <artifactId>lifecycle-mapping</artifactId> + <version>1.0.0</version> + <configuration> + <lifecycleMappingMetadata> + <pluginExecutions> + <pluginExecution> + <pluginExecutionFilter> + <groupId>org.apache.felix</groupId> + <artifactId> + maven-bundle-plugin + </artifactId> + <versionRange> + [2.1.0,) + </versionRange> + <goals> + <goal>manifest</goal> + </goals> + </pluginExecutionFilter> + <action> + <ignore /> + </action> + </pluginExecution> + </pluginExecutions> + </lifecycleMappingMetadata> + </configuration> + </plugin> + </plugins> + </pluginManagement> </build> <dependencies> diff --git a/src/main/java/com/beust/jcommander/JCommander.java b/src/main/java/com/beust/jcommander/JCommander.java index b78d890..98f112e 100644 --- a/src/main/java/com/beust/jcommander/JCommander.java +++ b/src/main/java/com/beust/jcommander/JCommander.java @@ -154,6 +154,7 @@ public class JCommander { private List<String> m_unknownArgs = Lists.newArrayList(); private boolean m_acceptUnknownOptions = false; + private boolean m_allowParameterOverwriting = false; private static Console m_console; @@ -485,8 +486,10 @@ public class JCommander { // Read through file one line at time. Print line # and line while ((line = bufRead.readLine()) != null) { - // Allow empty lines in these at files - if (line.length() > 0) result.add(line); + // Allow empty lines and # comments in these at files + if (line.length() > 0 && ! line.trim().startsWith("#")) { + result.add(line); + } } bufRead.close(); @@ -544,13 +547,13 @@ public class JCommander { m_mainParameterDescription = new ParameterDescription(object, p, parameterized, m_bundle, this); } else { + ParameterDescription pd = + new ParameterDescription(object, p, parameterized, m_bundle, this); for (String name : p.names()) { if (m_descriptions.containsKey(new StringKey(name))) { throw new ParameterException("Found the option " + name + " multiple times"); } p("Adding description for " + name); - ParameterDescription pd = - new ParameterDescription(object, p, parameterized, m_bundle, this); m_fields.put(parameterized, pd); m_descriptions.put(new StringKey(name), pd); @@ -677,6 +680,7 @@ public class JCommander { // object) boolean commandParsed = false; int i = 0; + boolean isDashDash = false; // once we encounter --, everything goes into the main parameter while (i < args.length && ! commandParsed) { String arg = args[i]; String a = trim(arg); @@ -685,7 +689,7 @@ public class JCommander { JCommander jc = findCommandByAlias(arg); int increment = 1; - if (isOption(args, a) && jc == null) { + if (! isDashDash && ! "--".equals(a) && isOption(args, a) && jc == null) { // // Option // @@ -744,6 +748,10 @@ public class JCommander { // Main parameter // if (! Strings.isStringEmpty(arg)) { + if ("--".equals(arg)) { + isDashDash = true; + a = trim(args[++i]); + } if (m_commands.isEmpty()) { // // Regular (non-command) parsing @@ -1116,13 +1124,17 @@ public class JCommander { // The magic value 3 is the number of spaces between the name of the option // and its description for (Map.Entry<ProgramName, JCommander> commands : m_commands.entrySet()) { - ProgramName progName = commands.getKey(); - String dispName = progName.getDisplayName(); - out.append(indent).append(" " + dispName); // + s(spaceCount) + getCommandDescription(progName.name) + "\n"); - - // Options for this command - usage(progName.getName(), out, " "); - out.append("\n"); + Object arg = commands.getValue().getObjects().get(0); + Parameters p = arg.getClass().getAnnotation(Parameters.class); + if (!p.hidden()) { + ProgramName progName = commands.getKey(); + String dispName = progName.getDisplayName(); + out.append(indent).append(" " + dispName); // + s(spaceCount) + getCommandDescription(progName.name) + "\n"); + + // Options for this command + usage(progName.getName(), out, " "); + out.append("\n"); + } } } } @@ -1256,12 +1268,16 @@ public class JCommander { if (converterClass != null && converterClass.isEnum()) { try { result = Enum.valueOf((Class<? extends Enum>) converterClass, value); - if (result == null) { - result = Enum.valueOf((Class<? extends Enum>) converterClass, value.toUpperCase()); - } + } catch (IllegalArgumentException e) { + try { + result = Enum.valueOf((Class<? extends Enum>) converterClass, value.toUpperCase()); + } catch (IllegalArgumentException ex) { + throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" + + EnumSet.allOf((Class<? extends Enum>) converterClass)); + } } catch (Exception e) { throw new ParameterException("Invalid value for " + optionName + " parameter. Allowed values:" + - EnumSet.allOf((Class<? extends Enum>) converterClass)); + EnumSet.allOf((Class<? extends Enum>) converterClass)); } } else { converter = instantiateConverter(optionName, converterClass); @@ -1362,6 +1378,7 @@ public class JCommander { JCommander jc = new JCommander(object); jc.setProgramName(name, aliases); jc.setDefaultProvider(m_defaultProvider); + jc.setAcceptUnknownOptions(m_acceptUnknownOptions); ProgramName progName = jc.m_programName; m_commands.put(progName, jc); @@ -1563,7 +1580,13 @@ public class JCommander { public List<String> getUnknownOptions() { return m_unknownArgs; } + public void setAllowParameterOverwriting(boolean b) { + m_allowParameterOverwriting = b; + } + public boolean isParameterOverwritingAllowed() { + return m_allowParameterOverwriting; + } // public void setCaseSensitiveCommands(boolean b) { // m_caseSensitiveCommands = b; // } diff --git a/src/main/java/com/beust/jcommander/Parameter.java b/src/main/java/com/beust/jcommander/Parameter.java index 974eeaa..d8cf87d 100644 --- a/src/main/java/com/beust/jcommander/Parameter.java +++ b/src/main/java/com/beust/jcommander/Parameter.java @@ -119,4 +119,12 @@ public @interface Parameter { * required parameters are no longer checked for their presence. */ boolean help() default false; + + /** + * If true, this parameter can be overwritten through a file or another appearance of the parameter + * @return + */ + boolean forceNonOverwritable() default false; + + } diff --git a/src/main/java/com/beust/jcommander/ParameterDescription.java b/src/main/java/com/beust/jcommander/ParameterDescription.java index 33574a9..e41c782 100644 --- a/src/main/java/com/beust/jcommander/ParameterDescription.java +++ b/src/main/java/com/beust/jcommander/ParameterDescription.java @@ -231,7 +231,7 @@ public class ParameterDescription { p("Adding " + (isDefault ? "default " : "") + "value:" + value + " to parameter:" + m_parameterized.getName()); String name = m_wrappedParameter.names()[0]; - if (m_assigned && ! isMultiOption()) { + if (m_assigned && ! isMultiOption() && !m_jCommander.isParameterOverwritingAllowed() || isNonOverwritableForced()) { throw new ParameterException("Can only specify option " + name + " once."); } @@ -358,4 +358,8 @@ public class ParameterDescription { public boolean isHelp() { return m_wrappedParameter.isHelp(); } + + public boolean isNonOverwritableForced() { + return m_wrappedParameter.isNonOverwritableForced(); + } } diff --git a/src/main/java/com/beust/jcommander/Parameters.java b/src/main/java/com/beust/jcommander/Parameters.java index 9834ea0..f2e8c76 100644 --- a/src/main/java/com/beust/jcommander/Parameters.java +++ b/src/main/java/com/beust/jcommander/Parameters.java @@ -67,4 +67,9 @@ public @interface Parameters { * An array of allowed command names. */ String[] commandNames() default {}; + + /** + * If true, this command won't appear in the usage(). + */ + boolean hidden() default false; } diff --git a/src/main/java/com/beust/jcommander/WrappedParameter.java b/src/main/java/com/beust/jcommander/WrappedParameter.java index 52cafc4..f4e7d56 100644 --- a/src/main/java/com/beust/jcommander/WrappedParameter.java +++ b/src/main/java/com/beust/jcommander/WrappedParameter.java @@ -109,4 +109,7 @@ public class WrappedParameter { return m_parameter != null && m_parameter.help(); } + public boolean isNonOverwritableForced() { + return m_parameter != null && m_parameter.forceNonOverwritable(); + } } diff --git a/src/main/java/com/beust/jcommander/internal/DefaultConsole.java b/src/main/java/com/beust/jcommander/internal/DefaultConsole.java index 65e87ba..8fd7d6d 100644 --- a/src/main/java/com/beust/jcommander/internal/DefaultConsole.java +++ b/src/main/java/com/beust/jcommander/internal/DefaultConsole.java @@ -18,11 +18,10 @@ public class DefaultConsole implements Console { public char[] readPassword(boolean echoInput) { try { + // Do not close the readers since System.in should not be closed InputStreamReader isr = new InputStreamReader(System.in); BufferedReader in = new BufferedReader(isr); String result = in.readLine(); - in.close(); - isr.close(); return result.toCharArray(); } catch (IOException e) { diff --git a/src/test/java/com/beust/jcommander/JCommanderTest.java b/src/test/java/com/beust/jcommander/JCommanderTest.java index 356d442..ad2c5e8 100644 --- a/src/test/java/com/beust/jcommander/JCommanderTest.java +++ b/src/test/java/com/beust/jcommander/JCommanderTest.java @@ -40,6 +40,7 @@ import org.testng.Assert; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; +import com.beust.jcommander.args.AlternateNamesForListArgs; import com.beust.jcommander.args.Args1; import com.beust.jcommander.args.Args1Setter; import com.beust.jcommander.args.Args2; @@ -96,6 +97,35 @@ public class JCommanderTest { Assert.assertEquals(args.date, new SimpleDateFormat("yyyy-MM-dd").parse("2011-10-26")); } + @DataProvider + public Object[][] alternateNamesListArgs() { + return new Object[][] { + new String[][] {new String[] {"--servers", "1", "-s", "2", "--servers", "3"}}, + new String[][] {new String[] {"-s", "1", "-s", "2", "--servers", "3"}}, + new String[][] {new String[] {"--servers", "1", "--servers", "2", "-s", "3"}}, + new String[][] {new String[] {"-s", "1", "--servers", "2", "-s", "3"}}, + new String[][] {new String[] {"-s", "1", "-s", "2", "--servers", "3"}}, + }; + } + + /** + * Confirm that List<?> parameters with alternate names return the correct + * List regardless of how the arguments are specified + */ + + @Test(dataProvider = "alternateNamesListArgs") + public void testAlternateNamesForListArguments(String[] argv) { + AlternateNamesForListArgs args = new AlternateNamesForListArgs(); + + new JCommander(args, argv); + + Assert.assertEquals(args.serverNames.size(), 3); + Assert.assertEquals(args.serverNames.get(0), argv[1]); + Assert.assertEquals(args.serverNames.get(1), argv[3]); + Assert.assertEquals(args.serverNames.get(2), argv[5]); + } + + /** * Make sure that if there are args with multiple names (e.g. "-log" and "-verbose"), * the usage will only display it once. @@ -566,12 +596,20 @@ public class JCommanderTest { JCommander jc = new JCommander(args, argv); Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE); - + List<ChoiceType> expected = Arrays.asList(ChoiceType.ONE, ChoiceType.Two); Assert.assertEquals(expected, args.choices); Assert.assertEquals(jc.getParameters().get(0).getDescription(), "Options: " + EnumSet.allOf((Class<? extends Enum>) ArgsEnum.ChoiceType.class)); - + + } + + public void enumArgsCaseInsensitive() { + ArgsEnum args = new ArgsEnum(); + String[] argv = { "-choice", "one"}; + JCommander jc = new JCommander(args, argv); + + Assert.assertEquals(args.choice, ArgsEnum.ChoiceType.ONE); } @Test(expectedExceptions = ParameterException.class) @@ -977,31 +1015,48 @@ public class JCommanderTest { Assert.assertEquals(a.endpoint, Lists.newArrayList("dev")); } - public void a() { + public void dashDashParameter() { class Arguments { - @Parameter(names = { "-help", "-h" }, arity = 0, description = "Show this help message") - public Boolean help = false; - - @Parameter(names = { "-verbose", "-v" }, arity = 0, description = "Verbose output mode") - public Boolean verbose = false; - - @Parameter(names = { "-target" }, arity = 1, description = "Target directory", required = true) - public File target; - - @Parameter(names = { "-input" }, variableArity = true, description = "Input paths", required = true) - public List<String> paths; + @Parameter(names = { "-name" }) + public String name; + @Parameter + public List<String> mainParameters; } + + Arguments a = new Arguments(); + new JCommander(a, new String[] { + "-name", "theName", "--", "param1", "param2"} + ); + Assert.assertEquals(a.name, "theName"); + Assert.assertEquals(a.mainParameters.size(), 2); + Assert.assertEquals(a.mainParameters.get(0), "param1"); + Assert.assertEquals(a.mainParameters.get(1), "param2"); + } + + public void dashDashParameter2() { + class Arguments { + @Parameter(names = { "-name" }) + public String name; + @Parameter + public List<String> mainParameters; + } + Arguments a = new Arguments(); new JCommander(a, new String[] { - "-input", "example_in1", "example_in2", "-target", "example_out" } + "param1", "param2", "--", "param3", "-name", "theName"} ); - Assert.assertEquals(a.paths, Lists.newArrayList("example_in1", "example_in2")); - Assert.assertEquals(a.target, new File("example_out")); + Assert.assertNull(a.name); + Assert.assertEquals(a.mainParameters.size(), 5); + Assert.assertEquals(a.mainParameters.get(0), "param1"); + Assert.assertEquals(a.mainParameters.get(1), "param2"); + Assert.assertEquals(a.mainParameters.get(2), "param3"); + Assert.assertEquals(a.mainParameters.get(3), "-name"); + Assert.assertEquals(a.mainParameters.get(4), "theName"); } @Test(enabled = false) public static void main(String[] args) throws Exception { - new JCommanderTest().a(); + new JCommanderTest().enumArgsFail(); // class A { // @Parameter(names = "-short", required = true) // List<String> parameters; diff --git a/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java b/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java new file mode 100644 index 0000000..18a1655 --- /dev/null +++ b/src/test/java/com/beust/jcommander/args/AlternateNamesForListArgs.java @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2014 the original author or authors. + * See the notice.md file distributed with this work for additional + * information regarding copyright ownership. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.beust.jcommander.args; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.internal.Lists; +import java.util.List; + +/** + * + * @author Andy Law <andy.law@roslin.ed.ac.uk> + */ +public class AlternateNamesForListArgs { + + @Parameter(names = {"-s", "--servers"}, description = "blah") + public List<String> serverNames = Lists.newLinkedList(); +} diff --git a/src/test/java/com/beust/jcommander/command/CommandHidden.java b/src/test/java/com/beust/jcommander/command/CommandHidden.java new file mode 100644 index 0000000..a3fc4fa --- /dev/null +++ b/src/test/java/com/beust/jcommander/command/CommandHidden.java @@ -0,0 +1,17 @@ +package com.beust.jcommander.command; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.Parameters; + +import java.util.List; + +@Parameters(commandNames = "add", commandDescription = "Hidden command to add file contents to the index", hidden = true) +public class CommandHidden { + + @Parameter(description = "Patterns of files to be added") + public List<String> patterns; + + @Parameter(names = "-i") + public Boolean interactive = false; + +} diff --git a/src/test/java/com/beust/jcommander/command/CommandTest.java b/src/test/java/com/beust/jcommander/command/CommandTest.java index 97e0007..cf921bd 100644 --- a/src/test/java/com/beust/jcommander/command/CommandTest.java +++ b/src/test/java/com/beust/jcommander/command/CommandTest.java @@ -87,6 +87,28 @@ public class CommandTest { Assert.assertEquals(commit.files, Arrays.asList("A.java", "B.java")); } + @Test + public void hiddenCommandTest() { + CommandMain cm = new CommandMain(); + JCommander jc = new JCommander(cm); + CommandAdd add = new CommandAdd(); + jc.addCommand("add", add); + CommandHidden hidden = new CommandHidden(); + jc.addCommand("hidden", hidden); + jc.parse("hidden", "-i", "A.java"); + + Assert.assertEquals(jc.getParsedCommand(), "hidden"); + Assert.assertEquals(hidden.interactive.booleanValue(), true); + Assert.assertEquals(hidden.patterns, Arrays.asList("A.java")); + + jc.setProgramName("TestCommander"); + StringBuilder out = new StringBuilder(); + jc.usage(out); + + Assert.assertTrue(out.toString().contains("add Add file contents to the index")); + Assert.assertFalse(out.toString().contains("hidden Hidden command to add file contents to the index")); + } + public static void main(String[] args) { new CommandTest().shouldComplainIfNoAnnotations(); } diff --git a/src/test/java/com/beust/jcommander/internal/DefaultConsoleTest.java b/src/test/java/com/beust/jcommander/internal/DefaultConsoleTest.java new file mode 100644 index 0000000..e101439 --- /dev/null +++ b/src/test/java/com/beust/jcommander/internal/DefaultConsoleTest.java @@ -0,0 +1,64 @@ +package com.beust.jcommander.internal; + +import java.io.IOException; +import java.io.InputStream; + +import org.testng.Assert; +import org.testng.annotations.Test; + +@Test +public class DefaultConsoleTest { + public void readPasswordCanBeCalledMultipleTimes() { + final InputStream inBackup = System.in; + try { + final StringInputStream in = new StringInputStream(); + System.setIn(in); + final Console console = new DefaultConsole(); + + in.setData("password1\n"); + char[] password = console.readPassword(false); + Assert.assertEquals(password, "password1".toCharArray()); + Assert.assertFalse(in.isClosedCalled(), "System.in stream shouldn't be closed"); + + in.setData("password2\n"); + password = console.readPassword(false); + Assert.assertEquals(password, "password2".toCharArray()); + Assert.assertFalse(in.isClosedCalled(), "System.in stream shouldn't be closed"); + } finally { + System.setIn(inBackup); + } + } + + private static class StringInputStream extends InputStream { + private byte[] data = new byte[0]; + private int offset = 0; + private boolean closedCalled; + + StringInputStream() { + super(); + } + + void setData(final String strData) { + data = strData.getBytes(); + offset = 0; + } + + boolean isClosedCalled() { + return closedCalled; + } + + @Override + public int read() throws IOException { + if (offset >= data.length) { + return -1; + } + return 0xFFFF & data[offset++]; + } + + @Override + public void close() throws IOException { + closedCalled = true; + super.close(); + } + } +} |