Package home | Report new bug | New search | Development Roadmap Status: Open | Feedback | All | Closed Since Version 1.2.0

Request #15324 Add ability to set custom error messages
Submitted: 2008-12-16 16:55 UTC Modified: 2009-06-19 11:39 UTC
From: gauthierm Assigned: izi
Status: Closed Package: Console_CommandLine (version CVS)
PHP Version: Irrelevant OS: Irrelevant
Roadmaps: (Not assigned)    
Subscription  



Patch custom-messages-2009-06-19.diff Revisions
Revision 2009-06-19 05:53 UTC
Developer gauthierm
 
Download patch

? Console_CommandLine-1.0.6.tgz
? Console_CommandLine-1.0.7.tgz
? build.sh
? custom-messages-2009-06-19.diff
? invalid-subcommand-detection-2009-06-17.diff
? package-party.diff
? xml-optional-arguments-2009-06-15.diff
? Console/exception-classes.diff
Index: package.xml
===================================================================
RCS file: /repository/pear/Console_CommandLine/package.xml,v
retrieving revision 1.27
diff -u -r1.27 package.xml
--- package.xml	27 Dec 2008 10:52:27 -0000	1.27
+++ package.xml	19 Jun 2009 04:54:13 -0000
@@ -50,6 +50,9 @@
    <file baseinstalldir="Console" name="Console/CommandLine/Command.php" role="php">
     <tasks:replace from="@package_version@" to="version" type="package-info" />
    </file>
+   <file baseinstalldir="Console" name="Console/CommandLine/CustomMessageProvider.php" role="php">
+    <tasks:replace from="@package_version@" to="version" type="package-info" />
+   </file>
    <file baseinstalldir="Console" name="Console/CommandLine/Element.php" role="php">
     <tasks:replace from="@package_version@" to="version" type="package-info" />
    </file>
Index: Console/CommandLine.php
===================================================================
RCS file: /repository/pear/Console_CommandLine/Console/CommandLine.php,v
retrieving revision 1.4
diff -u -r1.4 CommandLine.php
--- Console/CommandLine.php	17 Jun 2009 07:41:20 -0000	1.4
+++ Console/CommandLine.php	19 Jun 2009 04:54:13 -0000
@@ -227,6 +227,38 @@
     );
 
     /**
+     * Custom errors messages for this command
+     *
+     * This array is of the form:
+     * <code>
+     * <?php
+     * array(
+     *     $messageName => $messageText,
+     *     $messageName => $messageText,
+     *     ...
+     * );
+     * ?>
+     * </code>
+     *
+     * If specified, these messages override the messages provided by the
+     * default message provider. For example:
+     * <code>
+     * <?php
+     * $messages = array(
+     *     'ARGUMENT_REQUIRED' => 'The argument foo is required.',
+     * );
+     * ?>
+     * </code>
+     *
+     * @var array
+     * @see Console_CommandLine_MessageProvider_Default
+     */
+    public $messages = array();
+
+    // }}}
+    // {{{ Private properties
+
+    /**
      * Array of options that must be dispatched at the end.
      *
      * @var array $_dispatchLater Options to be dispatched
@@ -283,6 +315,9 @@
         } else if (getenv('POSIXLY_CORRECT')) {
             $this->force_posix = true;
         }
+        if (isset($params['messages']) && is_array($params['messages'])) {
+            $this->messages = $params['messages'];
+        }
         // set default instances
         $this->renderer         = new Console_CommandLine_Renderer_Default($this);
         $this->outputter        = new Console_CommandLine_Outputter_Default();
@@ -317,7 +352,9 @@
         } else {
             throw Console_CommandLine_Exception::factory(
                 'INVALID_CUSTOM_INSTANCE',
-                array(), $this
+                array(),
+                $this,
+                $this->messages
             );
         }
     }
@@ -667,7 +704,8 @@
                 throw Console_CommandLine_Exception::factory(
                     'OPTION_AMBIGUOUS',
                     array('name' => $str, 'matches' => $matches_str),
-                    $this
+                    $this,
+                    $this->messages
                 );
             }
             return $matches[0];
@@ -820,7 +858,8 @@
             throw Console_CommandLine_Exception::factory(
                 'INVALID_SUBCOMMAND',
                 array('command' => $args[0]),
-                $this
+                $this,
+                $this->messages
             );
         }
         // minimum argument number check
@@ -834,7 +873,8 @@
             throw Console_CommandLine_Exception::factory(
                 'ARGUMENT_REQUIRED',
                 array('argnum' => $argnum, 'plural' => $argnum>1 ? 's': ''),
-                $this
+                $this,
+                $this->messages
             );
         }
         // handle arguments
@@ -890,7 +930,8 @@
                     throw Console_CommandLine_Exception::factory(
                         'OPTION_VALUE_REQUIRED',
                         array('name' => $lastopt->name),
-                        $this
+                        $this,
+                        $this->messages
                     );
                 }
             } else {
@@ -925,7 +966,8 @@
                 throw Console_CommandLine_Exception::factory(
                     'OPTION_UNKNOWN',
                     array('name' => $optkv[0]),
-                    $this
+                    $this,
+                    $this->messages
                 );
             }
             $value = isset($optkv[1]) ? $optkv[1] : false;
@@ -933,7 +975,8 @@
                 throw Console_CommandLine_Exception::factory(
                     'OPTION_VALUE_UNEXPECTED',
                     array('name' => $opt->name, 'value' => $value),
-                    $this
+                    $this,
+                    $this->messages
                 );
             }
             if ($opt->expectsArgument() && $value === false) {
@@ -943,7 +986,8 @@
                     throw Console_CommandLine_Exception::factory(
                         'OPTION_VALUE_REQUIRED',
                         array('name' => $opt->name),
-                        $this
+                        $this,
+                        $this->messages
                     );
                 }
                 // we will have a value next time
@@ -967,7 +1011,8 @@
                 throw Console_CommandLine_Exception::factory(
                     'OPTION_UNKNOWN',
                     array('name' => $optname),
-                    $this
+                    $this,
+                    $this->messages
                 );
             }
             // parse other options or set the value
@@ -980,7 +1025,8 @@
                         throw Console_CommandLine_Exception::factory(
                             'OPTION_VALUE_REQUIRED',
                             array('name' => $opt->name),
-                            $this
+                            $this,
+                            $this->messages
                         );
                     }
                     // we will have a value next time
@@ -999,7 +1045,8 @@
                         throw Console_CommandLine_Exception::factory(
                             'OPTION_UNKNOWN',
                             array('name' => $next),
-                            $this
+                            $this,
+                            $this->messages
                         );
                     }
                 }
Index: Console/CommandLine/CustomMessageProvider.php
===================================================================
RCS file: Console/CommandLine/CustomMessageProvider.php
diff -N Console/CommandLine/CustomMessageProvider.php
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ Console/CommandLine/CustomMessageProvider.php	19 Jun 2009 04:54:13 -0000
@@ -0,0 +1,66 @@
+<?php
+
+/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
+
+/**
+ * This file is part of the PEAR Console_CommandLine package.
+ *
+ * PHP version 5
+ *
+ * LICENSE: This source file is subject to the MIT license that is available
+ * through the world-wide-web at the following URI:
+ * http://opensource.org/licenses/mit-license.php
+ *
+ * @category  Console
+ * @package   Console_CommandLine
+ * @author    David JEAN LOUIS <izimobil@gmail.com>
+ * @author    Michael Gauthier <mike@silverorange.com>
+ * @copyright 2007 David JEAN LOUIS, 2009 silverorange
+ * @license   http://opensource.org/licenses/mit-license.php MIT License
+ * @version   CVS: $Id:$
+ * @link      http://pear.php.net/package/Console_CommandLine
+ * @since     File available since release 1.1.0
+ * @filesource
+ */
+
+/**
+ * Common interfacefor message providers that allow overriding with custom
+ * messages
+ *
+ * Message providers may optionally implement this interface.
+ *
+ * @category  Console
+ * @package   Console_CommandLine
+ * @author    David JEAN LOUIS <izimobil@gmail.com>
+ * @author    Michael Gauthier <mike@silverorange.com>
+ * @copyright 2007 David JEAN LOUIS, 2009 silverorange
+ * @license   http://opensource.org/licenses/mit-license.php MIT License
+ * @version   Release: @package_version@
+ * @link      http://pear.php.net/package/Console_CommandLine
+ * @since     Interface available since release 1.1.0
+ */
+interface Console_CommandLine_CustomMessageProvider
+{
+    // getWithCustomMesssages() {{{
+
+    /**
+     * Retrieves the given string identifier corresponding message.
+     *
+     * For a list of identifiers please see the provided default message
+     * provider.
+     *
+     * @param string $code     The string identifier of the message
+     * @param array  $vars     An array of template variables
+     * @param array  $messages An optional array of messages to use. Array
+     *                         indexes are message codes.
+     *
+     * @return string
+     * @see Console_CommandLine_MessageProvider
+     * @see Console_CommandLine_MessageProvider_Default
+     */
+    public function getWithCustomMessages(
+        $code, $vars = array(), $messages = array()
+    );
+
+    // }}}
+}
Index: Console/CommandLine/Element.php
===================================================================
RCS file: /repository/pear/Console_CommandLine/Console/CommandLine/Element.php,v
retrieving revision 1.1
diff -u -r1.1 Element.php
--- Console/CommandLine/Element.php	27 Dec 2008 10:52:27 -0000	1.1
+++ Console/CommandLine/Element.php	19 Jun 2009 04:54:13 -0000
@@ -60,6 +60,35 @@
      */
     public $description;
 
+    /**
+     * Custom errors messages for this element
+     *
+     * This array is of the form:
+     * <code>
+     * <?php
+     * array(
+     *     $messageName => $messageText,
+     *     $messageName => $messageText,
+     *     ...
+     * );
+     * ?>
+     * </code>
+     *
+     * If specified, these messages override the messages provided by the
+     * default message provider. For example:
+     * <code>
+     * <?php
+     * $messages = array(
+     *     'ARGUMENT_REQUIRED' => 'The argument foo is required.',
+     * );
+     * ?>
+     * </code>
+     *
+     * @var array
+     * @see Console_CommandLine_MessageProvider_Default
+     */
+    public $messages = array();
+
     // }}}
     // __construct() {{{
 
Index: Console/CommandLine/Exception.php
===================================================================
RCS file: /repository/pear/Console_CommandLine/Console/CommandLine/Exception.php,v
retrieving revision 1.2
diff -u -r1.2 Exception.php
--- Console/CommandLine/Exception.php	17 Jun 2009 07:41:20 -0000	1.2
+++ Console/CommandLine/Exception.php	19 Jun 2009 04:54:13 -0000
@@ -28,6 +28,11 @@
 require_once 'PEAR/Exception.php';
 
 /**
+ * Interface for custom message provider.
+ */
+require_once 'Console/CommandLine/CustomMessageProvider.php';
+
+/**
  * Class for exceptions raised by the Console_CommandLine package.
  *
  * @category  Console
@@ -58,18 +63,31 @@
     // factory() {{{
 
     /**
-     * Convenience method that builds the exception with the array of params by 
+     * Convenience method that builds the exception with the array of params by
      * calling the message provider class.
      *
-     * @param string              $code   The string identifier of the exception
-     * @param array               $params Array of template vars/values
-     * @param Console_CommandLine $parser An instance of the parser
+     * @param string              $code     The string identifier of the
+     *                                      exception.
+     * @param array               $params   Array of template vars/values
+     * @param Console_CommandLine $parser   An instance of the parser
+     * @param array               $messages An optional array of messages
+     *                                      passed to the message provider.
      *
      * @return object an instance of Console_CommandLine_Exception
      */
-    public static function factory($code, $params, $parser)
-    {
-        $msg   = $parser->message_provider->get($code, $params);
+    public static function factory(
+        $code, $params, $parser, array $messages = array()
+    ) {
+        $provider = $parser->message_provider;
+        if ($provider instanceof Console_CommandLine_CustomMessageProvider) {
+            $msg = $provider->getWithCustomMessages(
+                $code,
+                $params,
+                $messages
+            );
+        } else {
+            $msg = $provider->get($code, $params);
+        }
         $const = 'Console_CommandLine_Exception::' . $code;
         $code  = defined($const) ? constant($const) : 0;
         return new Console_CommandLine_Exception($msg, $code);
Index: Console/CommandLine/Option.php
===================================================================
RCS file: /repository/pear/Console_CommandLine/Console/CommandLine/Option.php,v
retrieving revision 1.3
diff -u -r1.3 Option.php
--- Console/CommandLine/Option.php	12 Jun 2009 16:34:29 -0000	1.3
+++ Console/CommandLine/Option.php	19 Jun 2009 04:54:13 -0000
@@ -248,7 +248,9 @@
                     'name'    => $this->name,
                     'choices' => implode('", "', $this->choices),
                     'value'   => $value,
-                ), $parser
+                ),
+                $parser,
+                $this->messages
             );
         }
         $actionInfo = Console_CommandLine::$actions[$this->action];
Index: Console/CommandLine/XmlParser.php
===================================================================
RCS file: /repository/pear/Console_CommandLine/Console/CommandLine/XmlParser.php,v
retrieving revision 1.3
diff -u -r1.3 XmlParser.php
--- Console/CommandLine/XmlParser.php	16 Jun 2009 07:07:43 -0000	1.3
+++ Console/CommandLine/XmlParser.php	19 Jun 2009 04:54:13 -0000
@@ -167,6 +167,9 @@
                     }
                 }
                 break;
+            case 'messages':
+                $obj->messages = self::_messages($cNode);
+                break;
             default:
                 break;
             }
@@ -191,14 +194,22 @@
         $obj = new Console_CommandLine_Option($node->getAttribute('name'));
         foreach ($node->childNodes as $cNode) {
             $cNodeName = $cNode->nodeName;
-            if ($cNodeName == 'choices') {
+            switch ($cNodeName) {
+            case 'choices':
                 foreach ($cNode->childNodes as $subChildNode) {
                     if ($subChildNode->nodeName == 'choice') {
                         $obj->choices[] = trim($subChildNode->nodeValue);
                     }
                 }
-            } elseif (property_exists($obj, $cNodeName)) {
-                $obj->$cNodeName = trim($cNode->nodeValue);
+                break;
+            case 'messages':
+                $obj->messages = self::_messages($cNode);
+                break;
+            default:
+                if (property_exists($obj, $cNodeName)) {
+                    $obj->$cNodeName = trim($cNode->nodeValue);
+                }
+                break;
             }
         }
         if ($obj->action == 'Password') {
@@ -236,6 +247,9 @@
             case 'optional':
                 $obj->optional = self::_bool(trim($cNode->nodeValue));
                 break;
+            case 'messages':
+                $obj->messages = self::_messages($cNode);
+                break;
             default:
                 break;
             }
@@ -259,4 +273,33 @@
     }
 
     // }}}
+    // _messages() {{{
+
+    /**
+     * Returns an array of custom messages for the element
+     *
+     * @param DOMNode $node The messages node to process
+     *
+     * @return array an array of messages
+     *
+     * @see Console_CommandLine::$messages
+     * @see Console_CommandLine_Element::$messages
+     */
+    private static function _messages(DOMNode $node)
+    {
+        $messages = array();
+
+        foreach ($node->childNodes as $cNode) {
+            if ($cNode->nodeType == XML_ELEMENT_NODE) {
+                $name  = $cNode->getAttribute('name');
+                $value = trim($cNode->nodeValue);
+
+                $messages[$name] = $value;
+            }
+        }
+
+        return $messages;
+    }
+
+    // }}}
 }
Index: Console/CommandLine/MessageProvider/Default.php
===================================================================
RCS file: /repository/pear/Console_CommandLine/Console/CommandLine/MessageProvider/Default.php,v
retrieving revision 1.2
diff -u -r1.2 Default.php
--- Console/CommandLine/MessageProvider/Default.php	17 Jun 2009 07:41:20 -0000	1.2
+++ Console/CommandLine/MessageProvider/Default.php	19 Jun 2009 04:54:13 -0000
@@ -28,6 +28,11 @@
 require_once 'Console/CommandLine/MessageProvider.php';
 
 /**
+ * The custom message provider interface.
+ */
+require_once 'Console/CommandLine/CustomMessageProvider.php';
+
+/**
  * Lightweight class that manages messages used by Console_CommandLine package, 
  * allowing the developper to customize these messages, for example to 
  * internationalize a command line frontend.
@@ -41,7 +46,9 @@
  * @link      http://pear.php.net/package/Console_CommandLine
  * @since     Class available since release 0.1.0
  */
-class Console_CommandLine_MessageProvider_Default implements Console_CommandLine_MessageProvider
+class Console_CommandLine_MessageProvider_Default
+    implements Console_CommandLine_MessageProvider,
+    Console_CommandLine_CustomMessageProvider
 {
     // Properties {{{
 
@@ -89,12 +96,55 @@
         if (!isset($this->messages[$code])) {
             return 'UNKNOWN';
         }
+        return $this->replaceTemplateVars($this->messages[$code], $vars);
+    }
+
+    // }}}
+    // getWithCustomMessages() {{{
+
+    /**
+     * Retrieve the given string identifier corresponding message.
+     *
+     * @param string $code     The string identifier of the message
+     * @param array  $vars     An array of template variables
+     * @param array  $messages An optional array of messages to use. Array
+     *                         indexes are message codes.
+     *
+     * @return string
+     */
+    public function getWithCustomMessages(
+        $code, $vars = array(), $messages = array()
+    ) {
+        // get message
+        if (isset($messages[$code])) {
+            $message = $messages[$code];
+        } elseif (isset($this->messages[$code])) {
+            $message = $this->messages[$code];
+        } else {
+            $message = 'UNKNOWN';
+        }
+        return $this->replaceTemplateVars($message, $vars);
+    }
+
+    // }}}
+    // replaceTemplateVars() {{{
+
+    /**
+     * Replaces template vars in a message
+     *
+     * @param string $message The message
+     * @param array  $vars    An array of template variables
+     *
+     * @return string
+     */
+    protected function replaceTemplateVars($message, $vars = array())
+    {
         $tmpkeys = array_keys($vars);
         $keys    = array();
         foreach ($tmpkeys as $key) {
             $keys[] = '{$' . $key . '}';
         }
-        return str_replace($keys, array_values($vars), $this->messages[$code]);
+        return str_replace($keys, array_values($vars), $message);
     }
 
     // }}}
Index: data/xmlschema.rng
===================================================================
RCS file: /repository/pear/Console_CommandLine/data/xmlschema.rng,v
retrieving revision 1.6
diff -u -r1.6 xmlschema.rng
--- data/xmlschema.rng	16 Jun 2009 07:07:43 -0000	1.6
+++ data/xmlschema.rng	19 Jun 2009 04:54:13 -0000
@@ -49,6 +49,9 @@
           <ref name="ref_bool_choices"/>
         </element>
       </optional>
+      <optional>
+        <ref name="ref_messages_common"/>
+      </optional>
       <zeroOrMore>
         <ref name="ref_option"/>
       </zeroOrMore>
@@ -90,6 +93,21 @@
     </element>
   </define>
 
+  <!-- custom messages common element -->
+
+  <define name="ref_messages_common">
+    <element name="messages">
+      <oneOrMore>
+        <element name="message">
+          <attribute name="name">
+            <data type="string"/>
+          </attribute>
+          <text/>
+        </element>
+      </oneOrMore>
+    </element>
+  </define>
+
   <!-- options and arguments common elements -->
 
   <define name="ref_option_argument_common">
@@ -109,6 +127,9 @@
           <text/>
         </element>
       </optional>
+      <optional>
+        <ref name="ref_messages_common"/>
+      </optional>
     </interleave>
   </define>
 
Index: tests/console_commandline_addargument.phpt
===================================================================
RCS file: /repository/pear/Console_CommandLine/tests/console_commandline_addargument.phpt,v
retrieving revision 1.4
diff -u -r1.4 console_commandline_addargument.phpt
--- tests/console_commandline_addargument.phpt	6 Dec 2008 11:45:14 -0000	1.4
+++ tests/console_commandline_addargument.phpt	19 Jun 2009 04:54:13 -0000
@@ -27,7 +27,7 @@
 --EXPECTF--
 array(4) {
   ["arg1"]=>
-  object(Console_CommandLine_Argument)#5 (5) {
+  object(Console_CommandLine_Argument)#5 (6) {
     ["multiple"]=>
     bool(false)
     ["optional"]=>
@@ -38,9 +38,12 @@
     string(4) "arg1"
     ["description"]=>
     NULL
+    ["messages"]=>
+    array(0) {
+    }
   }
   ["arg2"]=>
-  object(Console_CommandLine_Argument)#6 (5) {
+  object(Console_CommandLine_Argument)#6 (6) {
     ["multiple"]=>
     bool(true)
     ["optional"]=>
@@ -51,9 +54,12 @@
     string(4) "arg2"
     ["description"]=>
     string(19) "description of arg2"
+    ["messages"]=>
+    array(0) {
+    }
   }
   ["arg3"]=>
-  object(Console_CommandLine_Argument)#7 (5) {
+  object(Console_CommandLine_Argument)#7 (6) {
     ["multiple"]=>
     bool(true)
     ["optional"]=>
@@ -64,9 +70,12 @@
     string(4) "arg3"
     ["description"]=>
     string(19) "description of arg3"
+    ["messages"]=>
+    array(0) {
+    }
   }
   ["arg4"]=>
-  object(Console_CommandLine_Argument)#8 (5) {
+  object(Console_CommandLine_Argument)#8 (6) {
     ["multiple"]=>
     bool(false)
     ["optional"]=>
@@ -77,6 +86,9 @@
     string(4) "arg4"
     ["description"]=>
     NULL
+    ["messages"]=>
+    array(0) {
+    }
   }
 }
 
Index: tests/console_commandline_addoption.phpt
===================================================================
RCS file: /repository/pear/Console_CommandLine/tests/console_commandline_addoption.phpt,v
retrieving revision 1.7
diff -u -r1.7 console_commandline_addoption.phpt
--- tests/console_commandline_addoption.phpt	12 Jun 2009 16:34:30 -0000	1.7
+++ tests/console_commandline_addoption.phpt	19 Jun 2009 04:54:13 -0000
@@ -31,7 +31,7 @@
 --EXPECT--
 array(4) {
   ["opt1"]=>
-  object(Console_CommandLine_Option)#5 (13) {
+  object(Console_CommandLine_Option)#5 (14) {
     ["short_name"]=>
     string(2) "-a"
     ["long_name"]=>
@@ -60,9 +60,12 @@
     string(4) "opt1"
     ["description"]=>
     NULL
+    ["messages"]=>
+    array(0) {
+    }
   }
   ["opt2"]=>
-  object(Console_CommandLine_Option)#6 (13) {
+  object(Console_CommandLine_Option)#6 (14) {
     ["short_name"]=>
     string(2) "-b"
     ["long_name"]=>
@@ -97,9 +100,12 @@
     string(3) "bar"
     ["description"]=>
     string(19) "description of opt2"
+    ["messages"]=>
+    array(0) {
+    }
   }
   ["list_opt2"]=>
-  object(Console_CommandLine_Option)#7 (13) {
+  object(Console_CommandLine_Option)#7 (14) {
     ["short_name"]=>
     NULL
     ["long_name"]=>
@@ -137,9 +143,12 @@
     string(9) "list_opt2"
     ["description"]=>
     string(35) "lists valid choices for option opt2"
+    ["messages"]=>
+    array(0) {
+    }
   }
   ["opt3"]=>
-  object(Console_CommandLine_Option)#8 (13) {
+  object(Console_CommandLine_Option)#8 (14) {
     ["short_name"]=>
     NULL
     ["long_name"]=>
@@ -168,5 +177,8 @@
     string(4) "opt3"
     ["description"]=>
     string(19) "description of opt3"
+    ["messages"]=>
+    array(0) {
+    }
   }
 }
Index: tests/console_commandline_parse_24.phpt
===================================================================
RCS file: tests/console_commandline_parse_24.phpt
diff -N tests/console_commandline_parse_24.phpt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/console_commandline_parse_24.phpt	19 Jun 2009 04:54:13 -0000
@@ -0,0 +1,21 @@
+--TEST--
+Test for Console_CommandLine::parse() method (invalid subcommand detection).
+--SKIPIF--
+<?php if(php_sapi_name()!='cli') echo 'skip'; ?>
+--ARGS--
+upgrade
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tests.inc.php';
+
+$parser = buildParser4();
+try {
+    $result = $parser->parse();
+} catch (Exception $exc) {
+    echo $exc->getMessage();
+}
+
+?>
+--EXPECT--
+Package name is required.
Index: tests/console_commandline_parse_25.phpt
===================================================================
RCS file: tests/console_commandline_parse_25.phpt
diff -N tests/console_commandline_parse_25.phpt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/console_commandline_parse_25.phpt	19 Jun 2009 04:54:13 -0000
@@ -0,0 +1,21 @@
+--TEST--
+Test for Console_CommandLine::parse() method (invalid subcommand detection).
+--SKIPIF--
+<?php if(php_sapi_name()!='cli') echo 'skip'; ?>
+--ARGS--
+upgrade -s foo
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tests.inc.php';
+
+$parser = buildParser4();
+try {
+    $result = $parser->parse();
+} catch (Exception $exc) {
+    echo $exc->getMessage();
+}
+
+?>
+--EXPECT--
+Valid states are "stable" and "beta".
Index: tests/console_commandline_parse_26.phpt
===================================================================
RCS file: tests/console_commandline_parse_26.phpt
diff -N tests/console_commandline_parse_26.phpt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/console_commandline_parse_26.phpt	19 Jun 2009 04:54:13 -0000
@@ -0,0 +1,21 @@
+--TEST--
+Test for Console_CommandLine::parse() method (invalid subcommand detection).
+--SKIPIF--
+<?php if(php_sapi_name()!='cli') echo 'skip'; ?>
+--ARGS--
+upgrade -s
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tests.inc.php';
+
+$parser = buildParser4();
+try {
+    $result = $parser->parse();
+} catch (Exception $exc) {
+    echo $exc->getMessage();
+}
+
+?>
+--EXPECT--
+Option requires value.
Index: tests/console_commandline_parse_27.phpt
===================================================================
RCS file: tests/console_commandline_parse_27.phpt
diff -N tests/console_commandline_parse_27.phpt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/console_commandline_parse_27.phpt	19 Jun 2009 04:54:13 -0000
@@ -0,0 +1,21 @@
+--TEST--
+Test for Console_CommandLine::parse() method (invalid subcommand detection).
+--SKIPIF--
+<?php if(php_sapi_name()!='cli') echo 'skip'; ?>
+--ARGS--
+upgrade -t
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tests.inc.php';
+
+$parser = buildParser4();
+try {
+    $result = $parser->parse();
+} catch (Exception $exc) {
+    echo $exc->getMessage();
+}
+
+?>
+--EXPECT--
+Mysterious option encountered.
Index: tests/console_commandline_parse_28.phpt
===================================================================
RCS file: tests/console_commandline_parse_28.phpt
diff -N tests/console_commandline_parse_28.phpt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/console_commandline_parse_28.phpt	19 Jun 2009 04:54:13 -0000
@@ -0,0 +1,21 @@
+--TEST--
+Test for Console_CommandLine::parse() method (invalid subcommand detection).
+--SKIPIF--
+<?php if(php_sapi_name()!='cli') echo 'skip'; ?>
+--ARGS--
+upgrade --dry-run=foo
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tests.inc.php';
+
+$parser = buildParser4();
+try {
+    $result = $parser->parse();
+} catch (Exception $exc) {
+    echo $exc->getMessage();
+}
+
+?>
+--EXPECT--
+Option should not have a value.
Index: tests/console_commandline_parse_29.phpt
===================================================================
RCS file: tests/console_commandline_parse_29.phpt
diff -N tests/console_commandline_parse_29.phpt
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/console_commandline_parse_29.phpt	19 Jun 2009 04:54:13 -0000
@@ -0,0 +1,21 @@
+--TEST--
+Test for Console_CommandLine::parse() method (invalid subcommand detection).
+--SKIPIF--
+<?php if(php_sapi_name()!='cli') echo 'skip'; ?>
+--ARGS--
+foo
+--FILE--
+<?php
+
+require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . 'tests.inc.php';
+
+$parser = buildParser4();
+try {
+    $result = $parser->parse();
+} catch (Exception $exc) {
+    echo $exc->getMessage();
+}
+
+?>
+--EXPECT--
+Only "upgrade" is supported.
Index: tests/tests.inc.php
===================================================================
RCS file: /repository/pear/Console_CommandLine/tests/tests.inc.php,v
retrieving revision 1.13
diff -u -r1.13 tests.inc.php
--- tests/tests.inc.php	12 Jun 2009 15:06:21 -0000	1.13
+++ tests/tests.inc.php	19 Jun 2009 04:54:13 -0000
@@ -285,6 +285,64 @@
 }
 
 // }}}
+// {{{ buildParser4()
+
+/**
+ * Build a parser instance and return it.
+ *
+ * For testing custom messages.
+ *
+ * @return object Console_CommandLine instance
+ */
+function buildParser4()
+{
+    $parser = new Console_CommandLine(array(
+        'messages' => array(
+            'INVALID_SUBCOMMAND' => 'Only "upgrade" is supported.',
+        ),
+    ));
+    $parser->name        = 'some_program';
+    $parser->version     = '0.1.0';
+    $parser->description = 'Description of our parser goes here...';
+
+    // some subcommand
+    $cmd1 = $parser->addCommand('upgrade', array(
+        'description' => 'upgrade given package',
+        'aliases'     => array('up'),
+        'messages'    => array(
+            'ARGUMENT_REQUIRED'       => 'Package name is required.',
+            'OPTION_VALUE_REQUIRED'   => 'Option requires value.',
+            'OPTION_VALUE_UNEXPECTED' => 'Option should not have a value.',
+            'OPTION_UNKNOWN'          => 'Mysterious option encountered.',
+        ),
+    ));
+    // add option
+    $cmd1->addOption('state', array(
+        'short_name'  => '-s',
+        'long_name'   => '--state',
+        'action'      => 'StoreString',
+        'choices'     => array('stable', 'beta'),
+        'description' => 'accepted package states',
+        'messages'    => array(
+            'OPTION_VALUE_NOT_VALID' => 'Valid states are "stable" and "beta".',
+        ),
+    ));
+    // add another option
+    $cmd1->addOption('dry_run', array(
+        'short_name'  => '-d',
+        'long_name'   => '--dry-run',
+        'action'      => 'StoreTrue',
+        'description' => 'dry run',
+    ));
+    // add argument
+    $cmd1->addArgument('package', array(
+        'description' => 'package to upgrade'
+    ));
+
+    return $parser;
+}
+
+// }}}
 // CustomRenderer() {{{
 
 /**