MediaWiki  REL1_22
Parser_DiffTest.php
Go to the documentation of this file.
00001 <?php
00027 class Parser_DiffTest
00028 {
00029     var $parsers, $conf;
00030     var $shortOutput = false;
00031 
00032     var $dtUniqPrefix;
00033 
00034     function __construct( $conf ) {
00035         if ( !isset( $conf['parsers'] ) ) {
00036             throw new MWException( __METHOD__ . ': no parsers specified' );
00037         }
00038         $this->conf = $conf;
00039     }
00040 
00041     function init() {
00042         if ( !is_null( $this->parsers ) ) {
00043             return;
00044         }
00045 
00046         global $wgHooks;
00047         static $doneHook = false;
00048         if ( !$doneHook ) {
00049             $doneHook = true;
00050             $wgHooks['ParserClearState'][] = array( $this, 'onClearState' );
00051         }
00052         if ( isset( $this->conf['shortOutput'] ) ) {
00053             $this->shortOutput = $this->conf['shortOutput'];
00054         }
00055 
00056         foreach ( $this->conf['parsers'] as $i => $parserConf ) {
00057             if ( !is_array( $parserConf ) ) {
00058                 $class = $parserConf;
00059                 $parserConf = array( 'class' => $parserConf );
00060             } else {
00061                 $class = $parserConf['class'];
00062             }
00063             $this->parsers[$i] = new $class( $parserConf );
00064         }
00065     }
00066 
00067     function __call( $name, $args ) {
00068         $this->init();
00069         $results = array();
00070         $mismatch = false;
00071         $lastResult = null;
00072         $first = true;
00073         foreach ( $this->parsers as $i => $parser ) {
00074             $currentResult = call_user_func_array( array( &$this->parsers[$i], $name ), $args );
00075             if ( $first ) {
00076                 $first = false;
00077             } else {
00078                 if ( is_object( $lastResult ) ) {
00079                     if ( $lastResult != $currentResult ) {
00080                         $mismatch = true;
00081                     }
00082                 } else {
00083                     if ( $lastResult !== $currentResult ) {
00084                         $mismatch = true;
00085                     }
00086                 }
00087             }
00088             $results[$i] = $currentResult;
00089             $lastResult = $currentResult;
00090         }
00091         if ( $mismatch ) {
00092             if ( count( $results ) == 2 ) {
00093                 $resultsList = array();
00094                 foreach ( $this->parsers as $i => $parser ) {
00095                     $resultsList[] = var_export( $results[$i], true );
00096                 }
00097                 $diff = wfDiff( $resultsList[0], $resultsList[1] );
00098             } else {
00099                 $diff = '[too many parsers]';
00100             }
00101             $msg = "Parser_DiffTest: results mismatch on call to $name\n";
00102             if ( !$this->shortOutput ) {
00103                 $msg .= 'Arguments: ' . $this->formatArray( $args ) . "\n";
00104             }
00105             $msg .= 'Results: ' . $this->formatArray( $results ) . "\n" .
00106                 "Diff: $diff\n";
00107             throw new MWException( $msg );
00108         }
00109         return $lastResult;
00110     }
00111 
00112     function formatArray( $array ) {
00113         if ( $this->shortOutput ) {
00114             foreach ( $array as $key => $value ) {
00115                 if ( $value instanceof ParserOutput ) {
00116                     $array[$key] = "ParserOutput: {$value->getText()}";
00117                 }
00118             }
00119         }
00120         return var_export( $array, true );
00121     }
00122 
00123     function setFunctionHook( $id, $callback, $flags = 0 ) {
00124         $this->init();
00125         foreach ( $this->parsers as $parser ) {
00126             $parser->setFunctionHook( $id, $callback, $flags );
00127         }
00128     }
00129 
00134     function onClearState( &$parser ) {
00135         // hack marker prefixes to get identical output
00136         if ( !isset( $this->dtUniqPrefix ) ) {
00137             $this->dtUniqPrefix = $parser->uniqPrefix();
00138         } else {
00139             $parser->mUniqPrefix = $this->dtUniqPrefix;
00140         }
00141         return true;
00142     }
00143 }