* Added file description headers
[lhc/web/wiklou.git] / includes / parser / Parser_DiffTest.php
1 <?php
2 /**
3 * Fake parser that output the difference of two different parsers
4 *
5 * @file
6 */
7
8 /**
9 * @ingroup Parser
10 */
11 class Parser_DiffTest
12 {
13 var $parsers, $conf;
14 var $shortOutput = false;
15
16 var $dfUniqPrefix;
17
18 function __construct( $conf ) {
19 if ( !isset( $conf['parsers'] ) ) {
20 throw new MWException( __METHOD__ . ': no parsers specified' );
21 }
22 $this->conf = $conf;
23 $this->dtUniqPrefix = "\x7fUNIQ" . Parser::getRandomString();
24 }
25
26 function init() {
27 if ( !is_null( $this->parsers ) ) {
28 return;
29 }
30
31 global $wgHooks;
32 static $doneHook = false;
33 if ( !$doneHook ) {
34 $doneHook = true;
35 $wgHooks['ParserClearState'][] = array( $this, 'onClearState' );
36 }
37 if ( isset( $this->conf['shortOutput'] ) ) {
38 $this->shortOutput = $this->conf['shortOutput'];
39 }
40
41 foreach ( $this->conf['parsers'] as $i => $parserConf ) {
42 if ( !is_array( $parserConf ) ) {
43 $class = $parserConf;
44 $parserConf = array( 'class' => $parserConf );
45 } else {
46 $class = $parserConf['class'];
47 }
48 $this->parsers[$i] = new $class( $parserConf );
49 }
50 }
51
52 function __call( $name, $args ) {
53 $this->init();
54 $results = array();
55 $mismatch = false;
56 $lastResult = null;
57 $first = true;
58 foreach ( $this->parsers as $i => $parser ) {
59 $currentResult = call_user_func_array( array( &$this->parsers[$i], $name ), $args );
60 if ( $first ) {
61 $first = false;
62 } else {
63 if ( is_object( $lastResult ) ) {
64 if ( $lastResult != $currentResult ) {
65 $mismatch = true;
66 }
67 } else {
68 if ( $lastResult !== $currentResult ) {
69 $mismatch = true;
70 }
71 }
72 }
73 $results[$i] = $currentResult;
74 $lastResult = $currentResult;
75 }
76 if ( $mismatch ) {
77 if ( count( $results ) == 2 ) {
78 $resultsList = array();
79 foreach ( $this->parsers as $i => $parser ) {
80 $resultsList[] = var_export( $results[$i], true );
81 }
82 $diff = wfDiff( $resultsList[0], $resultsList[1] );
83 } else {
84 $diff = '[too many parsers]';
85 }
86 $msg = "Parser_DiffTest: results mismatch on call to $name\n";
87 if ( !$this->shortOutput ) {
88 $msg .= 'Arguments: ' . $this->formatArray( $args ) . "\n";
89 }
90 $msg .= 'Results: ' . $this->formatArray( $results ) . "\n" .
91 "Diff: $diff\n";
92 throw new MWException( $msg );
93 }
94 return $lastResult;
95 }
96
97 function formatArray( $array ) {
98 if ( $this->shortOutput ) {
99 foreach ( $array as $key => $value ) {
100 if ( $value instanceof ParserOutput ) {
101 $array[$key] = "ParserOutput: {$value->getText()}";
102 }
103 }
104 }
105 return var_export( $array, true );
106 }
107
108 function setFunctionHook( $id, $callback, $flags = 0 ) {
109 $this->init();
110 foreach ( $this->parsers as $i => $parser ) {
111 $parser->setFunctionHook( $id, $callback, $flags );
112 }
113 }
114
115 function onClearState( &$parser ) {
116 // hack marker prefixes to get identical output
117 $parser->mUniqPrefix = $this->dtUniqPrefix;
118 return true;
119 }
120 }