Support >2 and JSON-formatted options in parser tests.
authorC. Scott Ananian <cscott@cscott.net>
Wed, 19 Feb 2014 17:14:08 +0000 (07:14 -1000)
committerC. Scott Ananian <cscott@cscott.net>
Wed, 19 Feb 2014 17:50:47 +0000 (07:50 -1000)
The parserTests options handling had a regex capture bug which caused
it to discard all but the first and last option values.  Fix this (by
separating value splitting from key/value capture).

Add support for JSON-valued options, which parsoid would like to begin
using.  Add support for backslash escapes in quoted strings.

Change-Id: I69323bb44b7a481bad6f490d0773a984239c0b9c

tests/parser/parserTest.inc

index 39fa09e..55e93e2 100644 (file)
@@ -642,48 +642,65 @@ class ParserTest {
                // foo="bar baz"
                // foo=[[bar baz]]
                // foo=bar,"baz quux"
-               $regex = '/\b
-                       ([\w-]+)                                                # Key
-                       \b
-                       (?:\s*
-                               =                                               # First sub-value
-                               \s*
-                               (
-                                       "
-                                               [^"]*                   # Quoted val
-                                       "
+               // foo={...json...}
+               $defs = '(?(DEFINE)
+                       (?<qstr>                                        # Quoted string
+                               "
+                               (?:[^\\\\"] | \\\\.)*
+                               "
+                       )
+                       (?<json>
+                               \{              # Open bracket
+                               (?:
+                                       [^"{}] |                                # Not a quoted string or object, or
+                                       (?&qstr) |                              # A quoted string, or
+                                       (?&json)                                # A json object (recursively)
+                               )*
+                               \}              # Close bracket
+                       )
+            (?<value>
+                               (?:
+                                       (?&qstr)                        # Quoted val
                                |
                                        \[\[
                                                [^]]*                   # Link target
                                        \]\]
                                |
                                        [\w-]+                          # Plain word
+                               |
+                                       (?&json)                        # JSON object
+                               )
+                       )
+               )';
+               $regex = '/'.$defs.'\b
+                       (?<k>[\w-]+)                            # Key
+                       \b
+                       (?:\s*
+                               =                                               # First sub-value
+                               \s*
+                               (?<v>
+                                       (?&value)
+                                       (?:\s*
+                                               ,                               # Sub-vals 1..N
+                                               \s*
+                                               (?&value)
+                                       )*
                                )
-                               (?:\s*
-                                       ,                                       # Sub-vals 1..N
-                                       \s*
-                                       (
-                                               "[^"]*"                 # Quoted val
-                                       |
-                                               \[\[[^]]*\]\]   # Link target
-                                       |
-                                               [\w-]+                  # Plain word
-                                       )
-                               )*
                        )?
                        /x';
+               $valueregex = '/'.$defs.'(?&value)/x';
 
                if ( preg_match_all( $regex, $instring, $matches, PREG_SET_ORDER ) ) {
                        foreach ( $matches as $bits ) {
-                               array_shift( $bits );
-                               $key = strtolower( array_shift( $bits ) );
-                               if ( count( $bits ) == 0 ) {
+                               $key = strtolower( $bits[ 'k' ] );
+                               if ( !isset( $bits[ 'v' ] ) ) {
                                        $opts[$key] = true;
-                               } elseif ( count( $bits ) == 1 ) {
-                                       $opts[$key] = $this->cleanupOption( array_shift( $bits ) );
                                } else {
-                                       // Array!
-                                       $opts[$key] = array_map( array( $this, 'cleanupOption' ), $bits );
+                                       preg_match_all( $valueregex, $bits[ 'v' ], $vmatches );
+                                       $opts[$key] = array_map( array( $this, 'cleanupOption' ), $vmatches[0] );
+                                       if ( count( $opts[$key] ) == 1 ) {
+                                               $opts[$key] = $opts[$key][0];
+                                       }
                                }
                        }
                }
@@ -692,12 +709,16 @@ class ParserTest {
 
        private function cleanupOption( $opt ) {
                if ( substr( $opt, 0, 1 ) == '"' ) {
-                       return substr( $opt, 1, -1 );
+                       return stripcslashes( substr( $opt, 1, -1 ) );
                }
 
                if ( substr( $opt, 0, 2 ) == '[[' ) {
                        return substr( $opt, 2, -2 );
                }
+
+               if ( substr( $opt, 0, 1 ) == '{' ) {
+                       return FormatJson::decode( $opt, true );
+               }
                return $opt;
        }