Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 107 |
|
0.00% |
0 / 15 |
CRAP | |
0.00% |
0 / 1 |
SpecialMathStatus | |
0.00% |
0 / 107 |
|
0.00% |
0 / 15 |
812 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
42 | |||
runNativeTest | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
runMathMLTest | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
2 | |||
runMathLaTeXMLTest | |
0.00% |
0 / 4 |
|
0.00% |
0 / 1 |
2 | |||
testSpecialCaseText | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
2 | |||
testMathMLIntegration | |
0.00% |
0 / 10 |
|
0.00% |
0 / 1 |
2 | |||
testPmmlInput | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
testLaTeXMLIntegration | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
testLaTeXMLLinebreak | |
0.00% |
0 / 13 |
|
0.00% |
0 / 1 |
6 | |||
assertTrue | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
assertContains | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
6 | |||
assertEquals | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
30 | |||
printDiff | |
0.00% |
0 / 6 |
|
0.00% |
0 / 1 |
6 | |||
getGroupName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\Math; |
4 | |
5 | use ExtensionRegistry; |
6 | use MediaWiki\Extension\Math\Render\RendererFactory; |
7 | use MediaWiki\Extension\Math\Widget\MathTestInputForm; |
8 | use MediaWiki\Logger\LoggerFactory; |
9 | use MediaWiki\SpecialPage\SpecialPage; |
10 | use Psr\Log\LoggerInterface; |
11 | |
12 | /** |
13 | * MediaWiki math extension |
14 | * |
15 | * @copyright 2002-2015 Tomasz Wegrzanowski, Brion Vibber, Moritz Schubotz, |
16 | * and other MediaWiki contributors |
17 | * @license GPL-2.0-or-later |
18 | * @author Moritz Schubotz |
19 | */ |
20 | class SpecialMathStatus extends SpecialPage { |
21 | /** @var LoggerInterface */ |
22 | private $logger; |
23 | |
24 | /** @var MathConfig */ |
25 | private $mathConfig; |
26 | |
27 | /** @var RendererFactory */ |
28 | private $rendererFactory; |
29 | |
30 | public function __construct( |
31 | MathConfig $mathConfig, |
32 | RendererFactory $rendererFactory |
33 | ) { |
34 | parent::__construct( 'MathStatus', 'purge' ); |
35 | |
36 | $this->mathConfig = $mathConfig; |
37 | $this->rendererFactory = $rendererFactory; |
38 | $this->logger = LoggerFactory::getInstance( 'Math' ); |
39 | } |
40 | |
41 | /** |
42 | * @param null|string $query |
43 | */ |
44 | public function execute( $query ) { |
45 | $this->setHeaders(); |
46 | |
47 | $out = $this->getOutput(); |
48 | $enabledMathModes = $this->mathConfig->getValidRenderingModeNames(); |
49 | $req = $this->getRequest(); |
50 | $tex = $req->getText( 'wptex' ); |
51 | |
52 | if ( $tex === '' ) { |
53 | $out->addWikiMsg( 'math-status-introduction', count( $enabledMathModes ) ); |
54 | |
55 | foreach ( $enabledMathModes as $modeNr => $modeName ) { |
56 | $out->wrapWikiMsg( '=== $1 ===', $modeName ); |
57 | switch ( $modeNr ) { |
58 | case MathConfig::MODE_MATHML: |
59 | $this->runMathMLTest( $modeName ); |
60 | break; |
61 | case MathConfig::MODE_LATEXML: |
62 | $this->runMathLaTeXMLTest( $modeName ); |
63 | break; |
64 | case MathConfig::MODE_NATIVE_MML: |
65 | $this->runNativeTest( $modeName ); |
66 | } |
67 | } |
68 | } |
69 | |
70 | $form = new MathTestInputForm( $this, $enabledMathModes, $this->rendererFactory ); |
71 | $form->show(); |
72 | } |
73 | |
74 | private function runNativeTest( $modeName ) { |
75 | $this->getOutput()->addWikiMsgArray( 'math-test-start', [ $modeName ] ); |
76 | $renderer = $this->rendererFactory->getRenderer( "a+b", [], MathConfig::MODE_NATIVE_MML ); |
77 | $this->assertTrue( $renderer->render(), "Rendering of a+b in $modeName" ); |
78 | $real = str_replace( "\n", '', $renderer->getHtmlOutput() ); |
79 | $expected = '<mo>+</mo>'; |
80 | $this->assertContains( $expected, $real, "Checking the presence of '+' in the MathML output" ); |
81 | $this->getOutput()->addWikiMsgArray( 'math-test-end', [ $modeName ] ); |
82 | } |
83 | |
84 | private function runMathMLTest( $modeName ) { |
85 | $this->getOutput()->addWikiMsgArray( 'math-test-start', [ $modeName ] ); |
86 | $this->testSpecialCaseText(); |
87 | $this->testMathMLIntegration(); |
88 | $this->testPmmlInput(); |
89 | $this->getOutput()->addWikiMsgArray( 'math-test-end', [ $modeName ] ); |
90 | } |
91 | |
92 | private function runMathLaTeXMLTest( $modeName ) { |
93 | $this->getOutput()->addWikiMsgArray( 'math-test-start', [ $modeName ] ); |
94 | $this->testLaTeXMLIntegration(); |
95 | $this->testLaTeXMLLinebreak(); |
96 | $this->getOutput()->addWikiMsgArray( 'math-test-end', [ $modeName ] ); |
97 | } |
98 | |
99 | public function testSpecialCaseText() { |
100 | $renderer = $this->rendererFactory->getRenderer( 'x^2+\text{a sample Text}', [], MathConfig::MODE_MATHML ); |
101 | $expected = 'a sample Text</mtext>'; |
102 | $this->assertTrue( $renderer->render(), 'Rendering the input "x^2+\text{a sample Text}"' ); |
103 | $this->assertContains( |
104 | $expected, $renderer->getHtmlOutput(), 'Comparing to the reference rendering' |
105 | ); |
106 | } |
107 | |
108 | /** |
109 | * Checks the basic functionality |
110 | * i.e. if the span element is generated right. |
111 | */ |
112 | public function testMathMLIntegration() { |
113 | $renderer = $this->rendererFactory->getRenderer( "a+b", [], MathConfig::MODE_MATHML ); |
114 | $this->assertTrue( $renderer->render(), "Rendering of a+b in plain MathML mode" ); |
115 | $real = str_replace( "\n", '', $renderer->getHtmlOutput() ); |
116 | $expected = '<mo>+</mo>'; |
117 | $this->assertContains( $expected, $real, "Checking the presence of '+' in the MathML output" ); |
118 | $this->assertContains( |
119 | '<svg xmlns:xlink="http://www.w3.org/1999/xlink" ', |
120 | $renderer->getSvg(), |
121 | "Check that the generated SVG image contains the xlink namespace" |
122 | ); |
123 | } |
124 | |
125 | /** |
126 | * Checks the experimental option to 'render' MathML input |
127 | */ |
128 | public function testPmmlInput() { |
129 | // sample from 'Navajo Coal Combustion and Respiratory Health Near Shiprock, |
130 | // New Mexico' in ''Journal of Environmental and Public Health'' , vol. 2010p. |
131 | // authors Joseph E. Bunnell; Linda V. Garcia; Jill M. Furst; |
132 | // Harry Lerch; Ricardo A. Olea; Stephen E. Suitt; Allan Kolker |
133 | // phpcs:ignore Generic.Files.LineLength.TooLong |
134 | $inputSample = '<msub> <mrow> <mi> P</mi> </mrow> <mrow> <mi> i</mi> <mi> j</mi> </mrow> </msub> <mo> =</mo> <mfrac> <mrow> <mn> 100</mn> <msub> <mrow> <mi> d</mi> </mrow> <mrow> <mi> i</mi> <mi> j</mi> </mrow> </msub> </mrow> <mrow> <mn> 6.75</mn> <msub> <mrow> <mi> r</mi> </mrow> <mrow> <mi> j</mi> </mrow> </msub> </mrow> </mfrac> <mo> ,</mo> </math>'; |
135 | $attribs = [ 'type' => 'pmml' ]; |
136 | $renderer = $this->rendererFactory->getRenderer( $inputSample, $attribs, MathConfig::MODE_MATHML ); |
137 | $this->assertEquals( 'pmml', $renderer->getInputType(), 'Checking if MathML input is supported' ); |
138 | $this->assertTrue( $renderer->render(), 'Rendering Presentation MathML sample' ); |
139 | $real = $renderer->getHtmlOutput(); |
140 | $this->assertContains( 'mode=mathml', $real, 'Checking if the link to SVG image is in correct mode' ); |
141 | } |
142 | |
143 | /** |
144 | * Checks the basic functionality |
145 | * i.e. if the span element is generated right. |
146 | */ |
147 | public function testLaTeXMLIntegration() { |
148 | $renderer = $this->rendererFactory->getRenderer( "a+b", [], MathConfig::MODE_LATEXML ); |
149 | $this->assertTrue( $renderer->render(), "Rendering of a+b in LaTeXML mode" ); |
150 | // phpcs:ignore Generic.Files.LineLength.TooLong |
151 | $expected = '<math xmlns="http://www.w3.org/1998/Math/MathML" '; |
152 | $real = preg_replace( "/\n\\s*/", '', $renderer->getHtmlOutput() ); |
153 | $this->assertContains( $expected, $real, |
154 | "Comparing the output to the MathML reference rendering" . |
155 | $renderer->getLastError() ); |
156 | } |
157 | |
158 | /** |
159 | * Checks LaTeXML line break functionality |
160 | * i.e. if a long line contains a mtr element. |
161 | * http://www.w3.org/TR/REC-MathML/chap3_5.html#sec3.5.2 |
162 | */ |
163 | public function testLaTeXMLLinebreak() { |
164 | global $wgMathDefaultLaTeXMLSetting; |
165 | $tex = ''; |
166 | $testMax = ceil( $wgMathDefaultLaTeXMLSetting[ 'linelength' ] / 2 ); |
167 | for ( $i = 0; $i < $testMax; $i++ ) { |
168 | $tex .= "$i+"; |
169 | } |
170 | $tex .= $testMax; |
171 | $renderer = new MathLaTeXML( $tex, [ 'display' => 'linebreak' ] ); |
172 | $renderer->setPurge(); |
173 | $this->assertTrue( $renderer->render(), "Rendering of linebreak test in LaTeXML mode" ); |
174 | $expected = 'mtr'; |
175 | $real = preg_replace( "/\n\\s*/", '', $renderer->getHtmlOutput() ); |
176 | $this->assertContains( $expected, $real, "Checking for linebreak" . |
177 | $renderer->getLastError() ); |
178 | } |
179 | |
180 | private function assertTrue( $expression, $message = '' ) { |
181 | if ( $expression ) { |
182 | $this->getOutput()->addWikiMsgArray( 'math-test-success', $message ); |
183 | return true; |
184 | } else { |
185 | $this->getOutput()->addWikiMsgArray( 'math-test-fail', $message ); |
186 | return false; |
187 | } |
188 | } |
189 | |
190 | private function assertContains( $expected, $real, $message = '' ) { |
191 | if ( !$this->assertTrue( strpos( $real, $expected ) !== false, $message ) ) { |
192 | $this->printDiff( $expected, $real, 'math-test-contains-diff' ); |
193 | } |
194 | } |
195 | |
196 | private function assertEquals( $expected, $real, $message = '' ) { |
197 | if ( is_array( $expected ) ) { |
198 | foreach ( $expected as $alternative ) { |
199 | if ( $alternative === $real ) { |
200 | $this->getOutput()->addWikiMsgArray( 'math-test-success', $message ); |
201 | return true; |
202 | } |
203 | } |
204 | // non of the alternatives matched |
205 | $this->getOutput()->addWikiMsgArray( 'math-test-fail', $message ); |
206 | return false; |
207 | } |
208 | if ( !$this->assertTrue( $expected === $real, $message ) ) { |
209 | $this->printDiff( $expected, $real, 'math-test-equals-diff' ); |
210 | return false; |
211 | } |
212 | return true; |
213 | } |
214 | |
215 | private function printDiff( $expected, $real, $message = '' ) { |
216 | if ( ExtensionRegistry::getInstance()->isLoaded( "SyntaxHighlight" ) ) { |
217 | $expected = "<syntaxhighlight lang=\"xml\">$expected</syntaxhighlight>"; |
218 | $real = "<syntaxhighlight lang=\"xml\">$real</syntaxhighlight>"; |
219 | $this->getOutput()->addWikiMsgArray( $message, [ $real, $expected ] ); |
220 | } else { |
221 | $this->logger->warning( 'Can not display expected and real value.' . |
222 | 'SyntaxHighlight is not installed.' ); |
223 | } |
224 | } |
225 | |
226 | protected function getGroupName() { |
227 | return 'other'; |
228 | } |
229 | } |