/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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 org.apache.commons.cli.bug;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.ParameterMetaData;
import java.sql.Types;
import junit.framework.TestCase;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.Option;
import org.apache.commons.cli.OptionGroup;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
public class BugCLI162Test extends TestCase {
/** Constant for the line separator.*/
private static final String CR = System.getProperty("line.separator");
public void testInfiniteLoop() {
Options options = new Options();
options.addOption("h", "help", false, "This is a looooong description");
HelpFormatter formatter = new HelpFormatter();
formatter.setWidth(20);
formatter.printHelp("app", options); // used to hang & crash
}
public void testPrintHelpLongLines() throws ParseException, IOException {
// Constants used for options
final String OPT = "-";
final String OPT_COLUMN_NAMES = "l";
final String OPT_CONNECTION = "c";
final String OPT_DESCRIPTION = "e";
final String OPT_DRIVER = "d";
final String OPT_DRIVER_INFO = "n";
final String OPT_FILE_BINDING = "b";
final String OPT_FILE_JDBC = "j";
final String OPT_FILE_SFMD = "f";
final String OPT_HELP = "h";
final String OPT_HELP_ = "help";
final String OPT_INTERACTIVE = "i";
final String OPT_JDBC_TO_SFMD = "2";
final String OPT_JDBC_TO_SFMD_L = "jdbc2sfmd";
final String OPT_METADATA = "m";
final String OPT_PARAM_MODES_INT = "o";
final String OPT_PARAM_MODES_NAME = "O";
final String OPT_PARAM_NAMES = "a";
final String OPT_PARAM_TYPES_INT = "y";
final String OPT_PARAM_TYPES_NAME = "Y";
final String OPT_PASSWORD = "p";
final String OPT_PASSWORD_L = "password";
final String OPT_SQL = "s";
final String OPT_SQL_L = "sql";
final String OPT_SQL_SPLIT_DEFAULT = "###";
final String OPT_SQL_SPLIT_L = "splitSql";
final String OPT_STACK_TRACE = "t";
final String OPT_TIMING = "g";
final String OPT_TRIM_L = "trim";
final String OPT_USER = "u";
final String OPT_WRITE_TO_FILE = "w";
final String _PMODE_IN = "IN";
final String _PMODE_INOUT = "INOUT";
final String _PMODE_OUT = "OUT";
final String _PMODE_UNK = "Unknown";
final String PMODES = _PMODE_IN + ", " + _PMODE_INOUT + ", " + _PMODE_OUT + ", " + _PMODE_UNK;
// Options build
Options commandLineOptions;
commandLineOptions = new Options();
commandLineOptions.addOption(OPT_HELP, OPT_HELP_, false, "Prints help and quits");
commandLineOptions.addOption(OPT_DRIVER, "driver", true, "JDBC driver class name");
commandLineOptions.addOption(OPT_DRIVER_INFO, "info", false, "Prints driver information and properties. If "
+ OPT
+ OPT_CONNECTION
+ " is not specified, all drivers on the classpath are displayed.");
commandLineOptions.addOption(OPT_CONNECTION, "url", true, "Connection URL");
commandLineOptions.addOption(OPT_USER, "user", true, "A database user name");
commandLineOptions
.addOption(
OPT_PASSWORD,
OPT_PASSWORD_L,
true,
"The database password for the user specified with the "
+ OPT
+ OPT_USER
+ " option. You can obfuscate the password with org.mortbay.jetty.security.Password, see http://docs.codehaus.org/display/JETTY/Securing+Passwords");
commandLineOptions.addOption(OPT_SQL, OPT_SQL_L, true, "Runs SQL or {call stored_procedure(?, ?)} or {?=call function(?, ?)}");
commandLineOptions.addOption(OPT_FILE_SFMD, "sfmd", true, "Writes a SFMD file for the given SQL");
commandLineOptions.addOption(OPT_FILE_BINDING, "jdbc", true, "Writes a JDBC binding node file for the given SQL");
commandLineOptions.addOption(OPT_FILE_JDBC, "node", true, "Writes a JDBC node file for the given SQL (internal debugging)");
commandLineOptions.addOption(OPT_WRITE_TO_FILE, "outfile", true, "Writes the SQL output to the given file");
commandLineOptions.addOption(OPT_DESCRIPTION, "description", true,
"SFMD description. A default description is used if omited. Example: " + OPT + OPT_DESCRIPTION + " \"Runs such and such\"");
commandLineOptions.addOption(OPT_INTERACTIVE, "interactive", false,
"Runs in interactive mode, reading and writing from the console, 'go' or '/' sends a statement");
commandLineOptions.addOption(OPT_TIMING, "printTiming", false, "Prints timing information");
commandLineOptions.addOption(OPT_METADATA, "printMetaData", false, "Prints metadata information");
commandLineOptions.addOption(OPT_STACK_TRACE, "printStack", false, "Prints stack traces on errors");
Option option = new Option(OPT_COLUMN_NAMES, "columnNames", true, "Column XML names; default names column labels. Example: "
+ OPT
+ OPT_COLUMN_NAMES
+ " \"cname1 cname2\"");
commandLineOptions.addOption(option);
option = new Option(OPT_PARAM_NAMES, "paramNames", true, "Parameter XML names; default names are param1, param2, etc. Example: "
+ OPT
+ OPT_PARAM_NAMES
+ " \"pname1 pname2\"");
commandLineOptions.addOption(option);
//
OptionGroup pOutTypesOptionGroup = new OptionGroup();
String pOutTypesOptionGroupDoc = OPT + OPT_PARAM_TYPES_INT + " and " + OPT + OPT_PARAM_TYPES_NAME + " are mutually exclusive.";
final String typesClassName = Types.class.getName();
option = new Option(OPT_PARAM_TYPES_INT, "paramTypes", true, "Parameter types from "
+ typesClassName
+ ". "
+ pOutTypesOptionGroupDoc
+ " Example: "
+ OPT
+ OPT_PARAM_TYPES_INT
+ " \"-10 12\"");
commandLineOptions.addOption(option);
option = new Option(OPT_PARAM_TYPES_NAME, "paramTypeNames", true, "Parameter "
+ typesClassName
+ " names. "
+ pOutTypesOptionGroupDoc
+ " Example: "
+ OPT
+ OPT_PARAM_TYPES_NAME
+ " \"CURSOR VARCHAR\"");
commandLineOptions.addOption(option);
commandLineOptions.addOptionGroup(pOutTypesOptionGroup);
//
OptionGroup modesOptionGroup = new OptionGroup();
String modesOptionGroupDoc = OPT + OPT_PARAM_MODES_INT + " and " + OPT + OPT_PARAM_MODES_NAME + " are mutually exclusive.";
option = new Option(OPT_PARAM_MODES_INT, "paramModes", true, "Parameters modes ("
+ ParameterMetaData.parameterModeIn
+ "=IN, "
+ ParameterMetaData.parameterModeInOut
+ "=INOUT, "
+ ParameterMetaData.parameterModeOut
+ "=OUT, "
+ ParameterMetaData.parameterModeUnknown
+ "=Unknown"
+ "). "
+ modesOptionGroupDoc
+ " Example for 2 parameters, OUT and IN: "
+ OPT
+ OPT_PARAM_MODES_INT
+ " \""
+ ParameterMetaData.parameterModeOut
+ " "
+ ParameterMetaData.parameterModeIn
+ "\"");
modesOptionGroup.addOption(option);
option = new Option(OPT_PARAM_MODES_NAME, "paramModeNames", true, "Parameters mode names ("
+ PMODES
+ "). "
+ modesOptionGroupDoc
+ " Example for 2 parameters, OUT and IN: "
+ OPT
+ OPT_PARAM_MODES_NAME
+ " \""
+ _PMODE_OUT
+ " "
+ _PMODE_IN
+ "\"");
modesOptionGroup.addOption(option);
commandLineOptions.addOptionGroup(modesOptionGroup);
option = new Option(null, OPT_TRIM_L, true,
"Trims leading and trailing spaces from all column values. Column XML names can be optionally specified to set which columns to trim.");
option.setOptionalArg(true);
commandLineOptions.addOption(option);
option = new Option(OPT_JDBC_TO_SFMD, OPT_JDBC_TO_SFMD_L, true,
"Converts the JDBC file in the first argument to an SMFD file specified in the second argument.");
option.setArgs(2);
commandLineOptions.addOption(option);
new HelpFormatter().printHelp(this.getClass().getName(), commandLineOptions);
}
public void testLongLineChunking() throws ParseException, IOException {
Options options = new Options();
options.addOption("x", "extralongarg", false,
"This description has ReallyLongValuesThatAreLongerThanTheWidthOfTheColumns " +
"and also other ReallyLongValuesThatAreHugerAndBiggerThanTheWidthOfTheColumnsBob, " +
"yes. ");
HelpFormatter formatter = new HelpFormatter();
StringWriter sw = new StringWriter();
formatter.printHelp(new PrintWriter(sw), 35, this.getClass().getName(), "Header", options, 0, 5, "Footer");
String expected = "usage:" + CR +
" org.apache.commons.cli.bug.B" + CR +
" ugCLI162Test" + CR +
"Header" + CR +
"-x,--extralongarg This" + CR +
" description" + CR +
" has" + CR +
" ReallyLongVal" + CR +
" uesThatAreLon" + CR +
" gerThanTheWid" + CR +
" thOfTheColumn" + CR +
" s and also" + CR +
" other" + CR +
" ReallyLongVal" + CR +
" uesThatAreHug" + CR +
" erAndBiggerTh" + CR +
" anTheWidthOfT" + CR +
" heColumnsBob," + CR +
" yes." + CR +
"Footer" + CR;
assertEquals( "Long arguments did not split as expected", expected, sw.toString() );
}
public void testLongLineChunkingIndentIgnored() throws ParseException, IOException {
Options options = new Options();
options.addOption("x", "extralongarg", false, "This description is Long." );
HelpFormatter formatter = new HelpFormatter();
StringWriter sw = new StringWriter();
formatter.printHelp(new PrintWriter(sw), 22, this.getClass().getName(), "Header", options, 0, 5, "Footer");
System.err.println(sw.toString());
String expected = "usage:" + CR +
" org.apache.comm" + CR +
" ons.cli.bug.Bug" + CR +
" CLI162Test" + CR +
"Header" + CR +
"-x,--extralongarg" + CR +
" This description is" + CR +
" Long." + CR +
"Footer" + CR;
assertEquals( "Long arguments did not split as expected", expected, sw.toString() );
}
}