Skip to content
Browse files

added more test coverage, bug fixes, examples and docs

  • Loading branch information...
1 parent ac0a374 commit aa4a3b7c950188599392291623a7df45e53d3cb6 @nategood committed Aug 19, 2012
Showing with 551 additions and 73 deletions.
  1. +7 −0 LICENSE.txt
  2. +161 −0 README.md
  3. +7 −2 composer.json
  4. +12 −0 examples/basic
  5. +9 −0 examples/basic.php
  6. +45 −0 examples/greet.php
  7. +193 −65 src/Commando/Commando.php
  8. +39 −1 src/Commando/Option.php
  9. +78 −3 tests/Commando/CommandoTest.php
  10. +0 −2 tests/Commando/OptionTest.php
View
7 LICENSE.txt
@@ -0,0 +1,7 @@
+Copyright (c) 2012 Nate Good <me@nategood.com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
View
161 README.md
@@ -0,0 +1,161 @@
+# Commando
+## An Elegant PHP CLI Library
+
+Commando is a PHP command line interface library that beautifies and simplifies writing PHP scripts intended for command line use.
+
+## Why?
+
+PHP's `$argv` magic variable and global `$_SERVER['argv']` make me cringe, (`getopt`)[http://php.net/manual/en/function.getopt.php] isn't there yet, and most other PHP CLI libraries are far too OOP bloated. Commando gets down to business without a ton of overhead, removes the common boilerplate stuff when it comes to handling cli input, all while providing a clean and readable interface.
+
+# Example
+
+Here is a trivial example of a PHP Commando script packed with some of the cool stuff Commando supports. Let's say it is in a file called `hello.php`.
+
+``` php
+<?php
+
+$salutations = array('Mister' => 'Mr', 'Misses' => 'Mrs', 'Miss' => 'Ms', 'Doctor' => 'Dr');
+
+$hello_cmd = new Commando\Commando();
+$hello_cmd
+ // Define first option
+ ->option()
+ ->required()
+ ->describedAs('A person\'s name')
+ // Define a flag "-s" a.k.a. "--salutation"
+ ->option('s')
+ ->alias('salutation')
+ ->describedAs('When set, use this salutation to address the person')
+ ->must(function($salutation) {
+ return array_key_exists($salutation, $salutations) || in_array($salutation, $salutations);
+ })
+ ->map(function($salutation) {
+ if (array_key_exists($salutation, $salutations))
+ $salutation = $salutations[$salutation];
+ return "$salutation. ";
+ })
+ // Define a boolean flag "-c" aka "--capitalize"
+ ->option('c')
+ ->alias('capitalize')
+ ->describedAs('Always capitalize the words in a name')
+ ->boolean();
+
+$name = $hello_cmd[0];
+
+if ($hello_cmd['capitlize'])
+ $name = ucwords($hello_cmd[0]);
+
+echo "Hello, {$hello_cmd['salutation']}{$name}!";
+```
+
+Running it:
+
+ > php hello.php Nate
+ Hello, Nate!
+
+ > php hello.php --capitalize nate
+ Hello, Nate!
+
+ > php hello.php -c -s Mr 'nate good'
+ Hello, Mr. Nate Good!
+
+Things to note:
+
+ - Commando implements ArrayAccess so it acts much like an array when you want to retrieve values for it
+ - For "annonymous" (i.e. not a named flag) arguments, we access them based on their numeric index
+ - We can access option values in an array via a flags name OR it's alias
+ - We can use closures to perform validation and map operations right as part of our option definition
+
+## Option Definition Options
+
+### `option` (mixed name = null)
+
+Aliases: o
+
+Define a new option. When `name` is set, the option will be a named "flag" option and must only be a single char (e.g. `f` for option `-f`). When no `name` is defined, the option is an annonymous argument and is referenced in the future by it's position.
+
+### `alias` (string alias)
+
+Aliases: a, aka
+
+Add a long form (e.g. --example) alias for a named option. This method can be called multiple times to add multiple aliases.
+
+### `description` (string description)
+
+Aliases: d, describe, describedAs, h, help
+
+Text to describe this option. This text will be used to build the "help" page and as such, it is end user facing.
+
+### `require`
+
+Aliases: r, required
+
+Require that this flag is specified
+
+### `must` (Closure rule)
+
+Aliases: _N/A_
+
+Define a rule to validate input against. Takes function that accepts a string $value and returns a boolean as to whether or not $value is valid.
+
+### `map` (Closure map)
+
+Aliases: cast, castTo
+
+Perform a map operation on the value for this option. Takes function that accepts a string $value and return mixed (you can map to whatever you wish).
+
+## Installation
+
+Httpful is [PSR-0](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md) compliant and can be installed using [Composer](http://getcomposer.org/). Add `nategood/commando` to your `composer.json`
+
+ "require": {
+ "nategood/commando": "*"
+ }
+
+If you're new to Composer...
+
+ - [Download and build Composer](http://getcomposer.org/download/)
+ - Make it [globally accessible](http://getcomposer.org/doc/00-intro.md#globally)
+ - `cd` to your the directory where you'll be writing your Commando script and run `composer install`
+
+*Currently installing via Composer is the only option (phar build coming soon).*
+
+Notice
+
+ - Commando implements ArrayAccess so it acts much like an array when you want to retrieve values for it
+ - For "annonymous" (i.e. not a named flag) arguments, we access them based on their numeric index
+ - We can access option values in an array via a flags name OR it's alias
+
+## Baked in Help
+
+Commando has automatic `--help` support built in. Calling your script with this flag will print out a pretty help page based on your option definitions and Commando settings. If you define an option with the alias of 'help', it will override this built in support.
+
+## Trainwreck
+
+If you, [like Martin](http://www.amazon.com/gp/product/0132350882), are of the _train_ of thought that the chaining pattern is a "trainwreck", Commando also works fine without chaining. Commando reads much nicer with the chaining, however, chaining may require a bit more work when debugging and additional indentation diligence.
+
+```
+<?php
+// Commando without using chaining
+$cmd = new Commando();
+$option = $cmd->option('f');
+$option->alias('foo');
+$option2 = $cmd->option('g');
+```
+
+# Contributing
+
+Commando highly encourages sending in pull requests. When submitting a pull request please:
+
+ - All pull requests should target the `dev` branch (not `master`)
+ - Make sure your code follows the coding standards laid out in [PSR-1](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-1-basic-coding-standard.md) and [PSR-2](https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-2-coding-style-guide.md)
+ - Make sure you add appropriate test coverage for your changes
+ - Run all unit tests in the test directory via `phpunit ./tests`
+ - Include commenting where appropriate and add a descriptive pull request message
+
+## Inspiration
+
+ - [Commander](https://github.com/visionmedia/commander/)
+ - [Optimist](https://github.com/substack/node-optimist)
+
+Released under MIT license.
View
9 composer.json
@@ -1,14 +1,19 @@
{
"name": "nategood/commando",
"description": "PHP CLI Commando Style",
+ "homepage": "http://github.com/nategood/commando",
+ "license": "MIT",
+ "keywords": ["cli", "command line", "command", "command line interface", "scripting", "automation"],
"authors": [
{
"name": "Nate Good",
"email": "me@nategood.com"
}
],
- "require": {},
- "version": "0.0.0",
+ "require": {
+ "php": ">=5.3"
+ },
+ "version": "0.0.1",
"autoload": {
"psr-0": {"Commando": "src/"}
}
View
12 examples/basic
@@ -0,0 +1,12 @@
+#! /usr/bin/env php
+<?php
+// Same as basic.php demoing that the library works fine as an executable as well
+// This example is Unix-ish specific
+// Usage
+// ./basic test
+
+require dirname(__DIR__) . '/vendor/autoload.php';
+
+$cmd = new Commando\Commando();
+
+echo "Argument #1: {$cmd[0]}";
View
9 examples/basic.php
@@ -0,0 +1,9 @@
+<?php
+// Usage
+// php basic.php test
+
+require dirname(__DIR__) . '/vendor/autoload.php';
+
+$cmd = new Commando\Commando();
+
+echo "Argument #1: {$cmd[0]}";
View
45 examples/greet.php
@@ -0,0 +1,45 @@
+<?php
+
+/**
+ * Example showing several of the option definition options in use, including
+ * map, must, required, alias (a.k.a. aka), desription (aka describedAs), and
+ * boolean.
+ */
+
+require dirname(__DIR__) . '/vendor/autoload.php';
+
+use Commando\Commando;
+
+$salutations = array('Mister' => 'Mr', 'Misses' => 'Mrs', 'Miss' => 'Ms', 'Doctor' => 'Dr');
+
+$hello_cmd = new Commando();
+$hello_cmd
+ // Define first option
+ ->option()
+ ->required()
+ ->describedAs('A person\'s name')
+ // Define a flag "-s" a.k.a. "--salutation"
+ ->option('s')
+ ->aka('salutation')
+ ->describedAs('When set, use this salutation to address the person')
+ ->must(function($salutation) {
+ return array_key_exists($salutation, $salutations) || in_array($salutation, $salutations);
+ })
+ ->map(function($salutation) {
+ if (array_key_exists($salutation, $salutations))
+ $salutation = $salutations[$salutation];
+ return "$salutation. ";
+ })
+ // Define a boolean flag "-c" aka "--capitalize"
+ ->option('c')
+ ->aka('capitalize')
+ ->aka('cap')
+ ->describedAs('Always capitalize the words in a name')
+ ->boolean();
+
+$name = $hello_cmd[0];
+
+if ($hello_cmd['capitlize'])
+ $name = ucwords($hello_cmd[0]);
+
+echo "Hello {$hello_cmd['salutation']}$name";
View
258 src/Commando/Commando.php
@@ -1,27 +1,41 @@
<?php
+/**
+ * @author Nate Good <me@nategood.com>
+ */
namespace Commando;
-class Commando
+class Commando implements \ArrayAccess
{
-
const OPTION_TYPE_ARGUMENT = 1; // e.g. foo
const OPTION_TYPE_SHORT = 2; // e.g. -u
const OPTION_TYPE_VERBOSE = 4; // e.g. --username
const OPTION_TYPE_MULTI = 8; // e.g. -fbg
- const OPTION_TYPE_OPTION = 2 | 4; // e.g. -u or --username
private
- $current_option = null,
- $options = array(),
- $nameless_option_counter = 0;
+ $current_option = null,
+ $options = array(),
+ $nameless_option_counter = 0,
+ $tokens = array(),
+ $parsed = false;
- public function __contstructor($tokens = null)
+ public function __construct($tokens = null)
{
if (empty($tokens)) {
- $tokens = $argv;
+ $tokens = $_SERVER['argv'];
}
- $this->_parse($tokens);
+
+ $this->setTokens($tokens);
+ }
+
+ /**
+ * Factory style reads a little nicer
+ * @param array $tokens defaults to $argv
+ * @return Commando
+ */
+ public static function define($tokens = null)
+ {
+ return new Commando($tokens);
}
/**
@@ -36,19 +50,24 @@ public function __contstructor($tokens = null)
'bool' => 'boolean',
'b' => 'boolean',
- 'required' => 'required',
- 'r' => 'required',
+ 'require' => 'require',
+ 'r' => 'require',
'alias' => 'alias',
+ 'aka' => 'alias',
'a' => 'alias',
'describe' => 'describe',
'd' => 'describe',
'help' => 'describe',
'h' => 'describe',
+ 'description' => 'describe',
+ 'describedAs' => 'describe',
'map' => 'map',
+ 'mapTo' => 'map',
'cast' => 'map',
+ 'castWith' => 'map',
'must' => 'must',
@@ -63,43 +82,31 @@ public function __contstructor($tokens = null)
/**
+ * This is the meat of Commando. Any time we are operating on
+ * an individual option for commando (e.g. $cmd->option()->require()...)
+ * it relies on this magic method. It allows us to handle some logic
+ * that is applicable across the board and also allows easy aliasing of
+ * methods (e.g. "o" for "option")... since it is a CLI library, such
+ * minified aliases would only be fitting :-).
+ *
* @param string $name
* @param array $arguments
* @return Commando
*/
public function __call($name, $arguments)
{
- if (empty($methods[$name])) {
- throw new \Exception('Unknown function called');
+ if (empty(self::$methods[$name])) {
+ throw new \Exception(sprintf('Unknown function, %s, called', $name));
}
- $name = $methods[$name]; // use the fully quantified name, e.g. "option" when "o"
-
- if ($name === 'option') {
- // We've reached a new "option", wrap up the previous
- // option in the chain
- if (!empty($this->current_option)) {
- // Add in alias references
- foreach ($option->getAliases() => $key) {
- $this->options[$key] = $option;
- }
- }
-
- // Is this a previously declared option?
- if (!empty($this->options[$arguments[0]])) {
- $this->current_option = $this->getOption($arguments[0]);
- } else {
- $this->current_option = new Option;
- }
- }
+ // use the fully quantified name, e.g. "option" when "o"
+ $name = self::$methods[$name];
// set the option we'll be acting on
- if (empty($this->current_option)) {
+ if (empty($this->current_option) && $name !== 'option') {
throw new \Exception(sprintf('Invalid Option Chain: Attempting to call %s before an "option" declaration', $name));
}
- // TODO SPECIAL CASE FOR "GLOBAL" methods (or maybe just define the global methods instead of using magic)???
-
// call method
array_unshift($arguments, $this->current_option);
$option = call_user_func_array(array($this, "_$name"), $arguments);
@@ -108,25 +115,42 @@ public function __call($name, $arguments)
}
/**
- * @param Option $option
- * @param string $name if null, it is presumed to be a nameless argument and is ID'd by an int
+ * @param Option|null $option
* @return Option
*/
- public function _option(Option $option, $name = null)
+ public function _option($option, $name = null)
{
- if (empty($name)) {
- $name = $this->nameless_option_counter++;
+ // Is this a previously declared option?
+ if (!empty($name) && !empty($this->options[$name])) {
+ $this->current_option = $this->getOption($name);
+ } else {
+ if (empty($name)) {
+ $name = $this->nameless_option_counter++;
+ }
+ $this->current_option = $this->options[$name] = new Option($name);
}
- return $option->setName($name);
+
+ return $this->current_option;
+ }
+
+ // OPTION OPERATIONS
+
+ /**
+ * @param Option $option
+ * @return Option
+ */
+ public function _boolean(Option $option, $boolean = true)
+ {
+ return $option->setBoolean($boolean);
}
/**
* @param Option $option
* @return Option
*/
- public function _boolean(Option $option)
+ public function _require(Option $option, $require = true)
{
- return $option->setBoolean();
+ return $option->setRequired($require);
}
/**
@@ -136,6 +160,7 @@ public function _boolean(Option $option)
*/
public function _alias(Option $option, $alias)
{
+ $this->options[$alias] = $this->current_option;
return $option->addAlias($alias);
}
@@ -150,12 +175,43 @@ public function _describe(Option $option, $description)
}
/**
- * @param array $tokens command line tokens
- * @throws \Exception
+ * @param Option $option
+ * @param \Closure $callback (string $value) -> boolean
+ * @return Option
+ */
+ public function _must(Option $option, \Closure $callback)
+ {
+ return $option->setRule($callback);
+ }
+
+ /**
+ * @param Option $option
+ * @param \Closure $callback
+ * @return Option
*/
- public function _parse($tokens)
+ public function _map(Option $option, \Closure $callback)
{
+ return $option->setMap($callback);
+ }
+
+ // END OPTION OPERATIONS
+
+ /**
+ * Rare that you would need to use this other than for testing,
+ * allows defining the cli tokens, instead of using $argv
+ * @param array $cli_tokens
+ */
+ public function setTokens(array $cli_tokens)
+ {
+ $this->tokens = $cli_tokens;
+ }
+ /**
+ * @throws \Exception
+ */
+ public function parse()
+ {
+ $tokens = $this->tokens;
$filename = array_shift($tokens);
$keyvals = array();
@@ -168,7 +224,16 @@ public function _parse($tokens)
if ($type === self::OPTION_TYPE_ARGUMENT) {
// its an argument, use an int as the index
- $keyvals[$count++] = $name;
+ $keyvals[$count] = $name;
+
+ // We allow for "dynamic" annonymous arguments, so we
+ // add an option for any annonymous arguments that
+ // weren't predefined
+ if (!$this->hasOption($count)) {
+ $this->options[$count] = new Option($count);
+ }
+
+ $count++;
} else {
// no combo support yet (e.g. -abc !== -a -b -c)
$option = $this->getOption($name);
@@ -185,23 +250,42 @@ public function _parse($tokens)
}
}
- // todo, have the Options do their thing (check constraints, perform mapping, perform casting, etc.)
+ // Set values (validates and performs map when applicable)
+ foreach ($keyvals as $key => $value) {
+ $this->getOption($key)->setValue($value);
+ }
+
+ // todo protect against duplicates caused by aliases
+ foreach ($this->options as $option) {
+ if (is_null($option->getValue()) && $option->isRequired()) {
+ throw new Exception(sprintf('Required option, %s, must be specified', $option->getName()));
+ }
+ }
+
+ $this->parsed = true;
+ }
- // todo implement required
- // foreach required option, make sure a value has been set
+ /**
+ * Has this Commando instance parsed its arguments?
+ * @return bool
+ */
+ public function isParsed()
+ {
+ return $this->parsed;
}
- private function _parseOption($token) {
+ private function _parseOption($token)
+ {
$matches = array();
- if (!preg_match('/(?P<hyphen>-{1,2})?(?P<name>[a-z][a-z0-9_]+)/', $token, $matches)) {
+ if (!preg_match('/(?P<hyphen>\-{1,2})?(?P<name>[a-z][a-z0-9_]*)/i', $token, $matches)) {
throw new \Exception(sprintf('Unable to parse option %s: Invalid syntax', $token));
}
$type = self::OPTION_TYPE_ARGUMENT;
if (!empty($matches['hyphen'])) {
$type = (strlen($matches['hyphen']) === 1) ?
- self::OPTION_TYPE_SINGLE:
+ self::OPTION_TYPE_SHORT:
self::OPTION_TYPE_VERBOSE;
}
@@ -216,6 +300,7 @@ private function _parseOption($token) {
*/
public function getOption($option)
{
+ // var_dump(array_keys($this->options));
if (!$this->hasOption($option)) {
throw new \Exception(sprintf('Unknown option, %s, specified', $option));
}
@@ -233,22 +318,65 @@ public function hasOption($option)
}
/**
- * @return string help page
+ * @return string dump values
*/
public function _toString()
{
- // todo pretty help doc
+ // todo return values of set options as map of option name => value
+ }
+
+ /**
+ * @return string help docs
+ */
+ public function helpText()
+ {
+ // todo
+ return '';
}
-}
+ // ARRAYACCESS METHODS
+
+ /**
+ * @param string $offset
+ */
+ public function offsetExists($offset)
+ {
+ return isset($this->options[$offset]);
+ }
+
+ /**
+ * @param string $offset
+ */
+ public function offsetGet($offset)
+ {
+ // Support implicit/lazy parsing
+ if (!$this->isParsed()) {
+ $this->parse();
+ }
+ if (!isset($this->options[$offset])) {
+ return null; // bc it is PHP like... might want to throw an Exception?
+ }
+ return $this->options[$offset]->getValue();
+ }
+
+ /**
+ * @param string $offset
+ * @param string $value
+ */
+ public function offsetSet($offset, $value)
+ {
+ // todo maybe support?
+ throw new Exception('Setting an option value via array syntax is not permitted');
+ }
+
+ /**
+ * @param string $offset
+ */
+ public function offsetUnset($offset)
+ {
+ $this->options[$offset]->setValue(null);
+ }
-// class Rule
-// {
-// const INT = 1;
-// const FLOAT = 2;
+ // END ARRAYACCESS METHODS
-// // function anInt($val)
-// // {
-// // return is_numeric($val);
-// // }
-// }
+}
View
40 src/Commando/Option.php
@@ -9,6 +9,7 @@ class Option
$name, /* string optional name of argument */
// $index, /* int */
$description, /* string */
+ $required = false, /* bool */
$boolean = false, /* bool */
$type, /* int see constants */
$rule, /* closure|regex|int */
@@ -58,7 +59,7 @@ public function setDescription($description)
}
/**
- * @param closure|string $rule regex, closure
+ * @param bool $bool
* @return Option
*/
public function setBoolean($bool = true)
@@ -68,6 +69,16 @@ public function setBoolean($bool = true)
}
/**
+ * @param bool $bool required?
+ * @return Option
+ */
+ public function setRequired($bool = true)
+ {
+ $this->required = $bool;
+ return $this;
+ }
+
+ /**
* @param closure|string $rule regex, closure
* @return Option
*/
@@ -104,6 +115,9 @@ public function map($value)
}
+ /**
+ * @return bool
+ */
public function validate($value)
{
if (!is_callable($this->rule))
@@ -115,26 +129,50 @@ public function validate($value)
return call_user_func($this->rule, $value);
}
+ /**
+ * @return string|int name of the option
+ */
public function getName()
{
return $this->name;
}
+
+ /**
+ * @return mixed value of the option
+ */
public function getValue()
{
return $this->value;
}
+ /**
+ * @return array list of aliases
+ */
public function getAliases()
{
return $this->aliases;
}
+ /**
+ * @return bool is this option a boolean
+ */
public function isBoolean()
{
return $this->boolean;
}
+ /**
+ * @return bool is this option required?
+ */
+ public function isRequired()
+ {
+ return $this->required;
+ }
+
+ /**
+ * @param mixed value for this option (set on the command line)
+ */
public function setValue($value)
{
// boolean check
View
81 tests/Commando/CommandoTest.php
@@ -9,7 +9,82 @@
class CommandoTest extends \PHPUnit_Framework_TestCase
{
- public function testCommano() {
- //new Commando;
- }
+
+ public function testCommandoAnon()
+ {
+ $tokens = array('filename', 'arg1', 'arg2', 'arg3');
+ $cmd = new Commando($tokens);
+ $this->assertEquals($tokens[1], $cmd[0]);
+ }
+
+ public function testCommandoFlag()
+ {
+ // Single flag
+ $tokens = array('filename', '-f', 'val');
+ $cmd = new Commando($tokens);
+ $cmd->option('f');
+ $this->assertEquals($tokens[2], $cmd['f']);
+
+ // Single alias
+ $tokens = array('filename', '--foo', 'val');
+ $cmd = new Commando($tokens);
+ $cmd->option('f')->alias('foo');
+ $this->assertEquals($tokens[2], $cmd['f']);
+ $this->assertEquals($tokens[2], $cmd['foo']);
+
+ // Multiple flags
+ $tokens = array('filename', '-f', 'val', '-g', 'val2');
+ $cmd = new Commando($tokens);
+ $cmd->option('f')->option('g');
+ $this->assertEquals($tokens[2], $cmd['f']);
+ $this->assertEquals($tokens[4], $cmd['g']);
+
+ // Single flag with anonnymous argument
+ $tokens = array('filename', '-f', 'val', 'arg1');
+ $cmd = new Commando($tokens);
+ $cmd->option('f')->option();
+ $this->assertEquals($tokens[3], $cmd[0]);
+
+ // Single flag with anonnymous argument
+ $tokens = array('filename', '-f', 'val', 'arg1');
+ $cmd = new Commando($tokens);
+ $cmd->option('f');
+ $this->assertEquals($tokens[3], $cmd[0]);
+ }
+
+ public function testImplicitAndExplicitParse()
+ {
+ // Implicit
+ $tokens = array('filename', 'arg1', 'arg2', 'arg3');
+ $cmd = new Commando($tokens);
+ $this->assertFalse($cmd->isParsed());
+ $val = $cmd[0];
+ $this->assertTrue($cmd->isParsed());
+
+ // Explicit
+ $cmd = new Commando($tokens);
+ $this->assertFalse($cmd->isParsed());
+ $cmd->parse();
+ $this->assertTrue($cmd->isParsed());
+ }
+
+ // Test retrieving a previously defined option via option($name)
+ public function testRevtrievingOption()
+ {
+ // Short flag
+ $tokens = array('filename', '-f', 'val');
+ $cmd = new Commando($tokens);
+ $cmd->option('f')->require();
+ $this->assertTrue($cmd->getOption('f')->isRequired());
+ $cmd->option('f')->require(false);
+ $this->assertFalse($cmd->getOption('f')->isRequired());
+
+ // Annonymous
+ // $tokens = array('filename', 'arg1', 'arg2', 'arg3');
+ // $cmd = new Commando($tokens);
+ // $cmd->option()->require();
+ // $this->assertTrue($cmd->option(0)->isRequired());
+ // $cmd->option(0)->setRequired(false);
+ // $this->assertFalse($cmd->option(0)->isRequired());
+ }
}
View
2 tests/Commando/OptionTest.php
@@ -58,7 +58,6 @@ public function testSetValue($val)
*/
public function testMap($val)
{
-
$option = new Option('f');
$option->setMap(function($value) {
return $value . $value;
@@ -70,7 +69,6 @@ public function testMap($val)
public function testRule()
{
-
$option = new Option('f');
$option->setRule(function($value) {
return is_numeric($value);

0 comments on commit aa4a3b7

Please sign in to comment.
Something went wrong with that request. Please try again.