00001 <?php
00002
00006 class Parser_DiffTest
00007 {
00008 var $parsers, $conf;
00009 var $shortOutput = false;
00010
00011 var $dfUniqPrefix;
00012
00013 function __construct( $conf ) {
00014 if ( !isset( $conf['parsers'] ) ) {
00015 throw new MWException( __METHOD__ . ': no parsers specified' );
00016 }
00017 $this->conf = $conf;
00018 $this->dtUniqPrefix = "\x7fUNIQ" . Parser::getRandomString();
00019 }
00020
00021 function init() {
00022 if ( !is_null( $this->parsers ) ) {
00023 return;
00024 }
00025
00026 global $wgHooks;
00027 static $doneHook = false;
00028 if ( !$doneHook ) {
00029 $doneHook = true;
00030 $wgHooks['ParserClearState'][] = array( $this, 'onClearState' );
00031 }
00032 if ( isset( $this->conf['shortOutput'] ) ) {
00033 $this->shortOutput = $this->conf['shortOutput'];
00034 }
00035
00036 foreach ( $this->conf['parsers'] as $i => $parserConf ) {
00037 if ( !is_array( $parserConf ) ) {
00038 $class = $parserConf;
00039 $parserConf = array( 'class' => $parserConf );
00040 } else {
00041 $class = $parserConf['class'];
00042 }
00043 $this->parsers[$i] = new $class( $parserConf );
00044 }
00045 }
00046
00047 function __call( $name, $args ) {
00048 $this->init();
00049 $results = array();
00050 $mismatch = false;
00051 $lastResult = null;
00052 $first = true;
00053 foreach ( $this->parsers as $i => $parser ) {
00054 $currentResult = call_user_func_array( array( &$this->parsers[$i], $name ), $args );
00055 if ( $first ) {
00056 $first = false;
00057 } else {
00058 if ( is_object( $lastResult ) ) {
00059 if ( $lastResult != $currentResult ) {
00060 $mismatch = true;
00061 }
00062 } else {
00063 if ( $lastResult !== $currentResult ) {
00064 $mismatch = true;
00065 }
00066 }
00067 }
00068 $results[$i] = $currentResult;
00069 $lastResult = $currentResult;
00070 }
00071 if ( $mismatch ) {
00072 if ( count( $results ) == 2 ) {
00073 $resultsList = array();
00074 foreach ( $this->parsers as $i => $parser ) {
00075 $resultsList[] = var_export( $results[$i], true );
00076 }
00077 $diff = wfDiff( $resultsList[0], $resultsList[1] );
00078 } else {
00079 $diff = '[too many parsers]';
00080 }
00081 $msg = "Parser_DiffTest: results mismatch on call to $name\n";
00082 if ( !$this->shortOutput ) {
00083 $msg .= 'Arguments: ' . $this->formatArray( $args ) . "\n";
00084 }
00085 $msg .= 'Results: ' . $this->formatArray( $results ) . "\n" .
00086 "Diff: $diff\n";
00087 throw new MWException( $msg );
00088 }
00089 return $lastResult;
00090 }
00091
00092 function formatArray( $array ) {
00093 if ( $this->shortOutput ) {
00094 foreach ( $array as $key => $value ) {
00095 if ( $value instanceof ParserOutput ) {
00096 $array[$key] = "ParserOutput: {$value->getText()}";
00097 }
00098 }
00099 }
00100 return var_export( $array, true );
00101 }
00102
00103 function setFunctionHook( $id, $callback, $flags = 0 ) {
00104 $this->init();
00105 foreach ( $this->parsers as $i => $parser ) {
00106 $parser->setFunctionHook( $id, $callback, $flags );
00107 }
00108 }
00109
00110 function onClearState( &$parser ) {
00111
00112 $parser->mUniqPrefix = $this->dtUniqPrefix;
00113 return true;
00114 }
00115 }