OSDN Git Service

introduce SynopsisValidator class
authorscribu <mail@scribu.net>
Tue, 30 Jul 2013 00:55:57 +0000 (03:55 +0300)
committerscribu <mail@scribu.net>
Tue, 30 Jul 2013 01:11:40 +0000 (04:11 +0300)
php/WP_CLI/Dispatcher/Subcommand.php
php/WP_CLI/SynopsisParser.php
php/WP_CLI/SynopsisValidator.php [new file with mode: 0644]
tests/test-arg-validation.php

index 3203ef9..16d101e 100644 (file)
@@ -42,7 +42,7 @@ class Subcommand extends CompositeCommand {
                if ( !$synopsis )
                        return;
 
-               $parser = new \WP_CLI\SynopsisParser( $synopsis );
+               $parser = new \WP_CLI\SynopsisValidator( $synopsis );
                if ( !$parser->enough_positionals( $args ) ) {
                        $this->show_usage();
                        exit(1);
index eb5dc8e..3daf70d 100644 (file)
@@ -6,72 +6,6 @@ class SynopsisParser {
 
        private static $patterns = array();
 
-       private $params = array();
-
-       public function __construct( $synopsis ) {
-               $this->params = $this->parse( $synopsis );
-       }
-
-       public function enough_positionals( $args ) {
-               $positional = $this->query_params( array(
-                       'type' => 'positional',
-                       'flavour' => 'mandatory'
-               ) );
-
-               return count( $args ) >= count( $positional );
-       }
-
-       public function validate_assoc( &$assoc_args, $ignored_keys = array() ) {
-               $assoc = $this->query_params( array(
-                       'type' => 'assoc',
-               ) );
-
-               $errors = array(
-                       'fatal' => array(),
-                       'warning' => array()
-               );
-
-               foreach ( $assoc as $param ) {
-                       $key = $param['name'];
-
-                       if ( in_array( $key, $ignored_keys ) )
-                               continue;
-
-                       if ( !isset( $assoc_args[ $key ] ) ) {
-                               if ( 'mandatory' == $param['flavour'] ) {
-                                       $errors['fatal'][] = "missing --$key parameter";
-                               }
-                       } else {
-                               if ( true === $assoc_args[ $key ] ) {
-                                       $error_type = ( 'mandatory' == $param['flavour'] ) ? 'fatal' : 'warning';
-                                       $errors[ $error_type ][] = "--$key parameter needs a value";
-
-                                       unset( $assoc_args[ $key ] );
-                               }
-                       }
-               }
-
-               return $errors;
-       }
-
-       public function unknown_assoc( $assoc_args ) {
-               $generic = $this->query_params( array(
-                       'type' => 'generic',
-               ) );
-
-               if ( count( $generic ) )
-                       return array();
-
-               $known_assoc = array();
-
-               foreach ( $this->params as $param ) {
-                       if ( in_array( $param['type'], array( 'assoc', 'flag' ) ) )
-                               $known_assoc[] = $param['name'];
-               }
-
-               return array_diff( array_keys( $assoc_args ), $known_assoc );
-       }
-
        /**
         * @param string
         * @return array List of parameters
@@ -134,34 +68,5 @@ class SynopsisParser {
                        }
                }
        }
-
-       /**
-        * Filters a list of associatve arrays, based on a set of key => value arguments.
-        *
-        * @param array $args An array of key => value arguments to match against
-        * @param string $operator
-        * @return array
-        */
-       private function query_params( $args, $operator = 'AND' ) {
-               $operator = strtoupper( $operator );
-               $count = count( $args );
-               $filtered = array();
-
-               foreach ( $this->params as $key => $to_match ) {
-                       $matched = 0;
-                       foreach ( $args as $m_key => $m_value ) {
-                               if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] )
-                                       $matched++;
-                       }
-
-                       if (   ( 'AND' == $operator && $matched == $count )
-                               || ( 'OR' == $operator && $matched > 0 )
-                               || ( 'NOT' == $operator && 0 == $matched ) ) {
-                                       $filtered[$key] = $to_match;
-                               }
-               }
-
-               return $filtered;
-       }
 }
 
diff --git a/php/WP_CLI/SynopsisValidator.php b/php/WP_CLI/SynopsisValidator.php
new file mode 100644 (file)
index 0000000..597d89b
--- /dev/null
@@ -0,0 +1,105 @@
+<?php
+
+namespace WP_CLI;
+
+/**
+ * Checks if the list of parameters matches the specification defined in the synopsis.
+ */
+class SynopsisValidator {
+
+       private $spec = array();
+
+       public function __construct( $synopsis ) {
+               $this->spec = SynopsisParser::parse( $synopsis );
+       }
+
+       public function enough_positionals( $args ) {
+               $positional = $this->query_spec( array(
+                       'type' => 'positional',
+                       'flavour' => 'mandatory'
+               ) );
+
+               return count( $args ) >= count( $positional );
+       }
+
+       public function validate_assoc( &$assoc_args, $ignored_keys = array() ) {
+               $assoc = $this->query_spec( array(
+                       'type' => 'assoc',
+               ) );
+
+               $errors = array(
+                       'fatal' => array(),
+                       'warning' => array()
+               );
+
+               foreach ( $assoc as $param ) {
+                       $key = $param['name'];
+
+                       if ( in_array( $key, $ignored_keys ) )
+                               continue;
+
+                       if ( !isset( $assoc_args[ $key ] ) ) {
+                               if ( 'mandatory' == $param['flavour'] ) {
+                                       $errors['fatal'][] = "missing --$key parameter";
+                               }
+                       } else {
+                               if ( true === $assoc_args[ $key ] ) {
+                                       $error_type = ( 'mandatory' == $param['flavour'] ) ? 'fatal' : 'warning';
+                                       $errors[ $error_type ][] = "--$key parameter needs a value";
+
+                                       unset( $assoc_args[ $key ] );
+                               }
+                       }
+               }
+
+               return $errors;
+       }
+
+       public function unknown_assoc( $assoc_args ) {
+               $generic = $this->query_spec( array(
+                       'type' => 'generic',
+               ) );
+
+               if ( count( $generic ) )
+                       return array();
+
+               $known_assoc = array();
+
+               foreach ( $this->spec as $param ) {
+                       if ( in_array( $param['type'], array( 'assoc', 'flag' ) ) )
+                               $known_assoc[] = $param['name'];
+               }
+
+               return array_diff( array_keys( $assoc_args ), $known_assoc );
+       }
+
+       /**
+        * Filters a list of associatve arrays, based on a set of key => value arguments.
+        *
+        * @param array $args An array of key => value arguments to match against
+        * @param string $operator
+        * @return array
+        */
+       private function query_spec( $args, $operator = 'AND' ) {
+               $operator = strtoupper( $operator );
+               $count = count( $args );
+               $filtered = array();
+
+               foreach ( $this->spec as $key => $to_match ) {
+                       $matched = 0;
+                       foreach ( $args as $m_key => $m_value ) {
+                               if ( array_key_exists( $m_key, $to_match ) && $m_value == $to_match[ $m_key ] )
+                                       $matched++;
+                       }
+
+                       if (   ( 'AND' == $operator && $matched == $count )
+                               || ( 'OR' == $operator && $matched > 0 )
+                               || ( 'NOT' == $operator && 0 == $matched ) ) {
+                                       $filtered[$key] = $to_match;
+                               }
+               }
+
+               return $filtered;
+       }
+}
+
index 8875891..f579823 100644 (file)
@@ -1,11 +1,11 @@
 <?php
 
-use WP_CLI\SynopsisParser;
+use WP_CLI\SynopsisValidator;
 
 class ArgValidationTests extends PHPUnit_Framework_TestCase {
 
        function testMissingPositional() {
-               $parser = new SynopsisParser( '<foo> <bar> [<baz>]' );
+               $parser = new SynopsisValidator( '<foo> <bar> [<baz>]' );
 
                $this->assertFalse( $parser->enough_positionals( array() ) );
                $this->assertTrue( $parser->enough_positionals( array( 1, 2 ) ) );
@@ -13,7 +13,7 @@ class ArgValidationTests extends PHPUnit_Framework_TestCase {
        }
 
        function testRepeatingPositional() {
-               $parser = new SynopsisParser( '<foo> [<bar>...]' );
+               $parser = new SynopsisValidator( '<foo> [<bar>...]' );
 
                $this->assertFalse( $parser->enough_positionals( array() ) );
                $this->assertTrue( $parser->enough_positionals( array( 1 ) ) );
@@ -21,14 +21,14 @@ class ArgValidationTests extends PHPUnit_Framework_TestCase {
        }
 
        function testUnknownAssocEmpty() {
-               $parser = new SynopsisParser( '' );
+               $parser = new SynopsisValidator( '' );
 
                $assoc_args = array( 'foo' => true, 'bar' => false );
                $this->assertEquals( array_keys( $assoc_args ), $parser->unknown_assoc( $assoc_args ) );
        }
 
        function testUnknownAssoc() {
-               $parser = new SynopsisParser( '--type=<type> [--brand=<brand>] [--flag]' );
+               $parser = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' );
 
                $assoc_args = array( 'type' => 'analog', 'brand' => true, 'flag' => true );
                $this->assertEmpty( $parser->unknown_assoc( $assoc_args ) );
@@ -38,7 +38,7 @@ class ArgValidationTests extends PHPUnit_Framework_TestCase {
        }
 
        function testMissingAssoc() {
-               $parser = new SynopsisParser( '--type=<type> [--brand=<brand>] [--flag]' );
+               $parser = new SynopsisValidator( '--type=<type> [--brand=<brand>] [--flag]' );
 
                $assoc_args = array( 'brand' => true, 'flag' => true );
                $errors = $parser->validate_assoc( $assoc_args );