| /* |
| * 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() ); |
| } |
| |
| } |