Coverage tests for the Math extension
* Include generated tests for a better test coverage of the Math extension. * Compiles texvc in testsuite (if required) * Test generator now included * Replaces the old parser tests * Fixes whitspace issues Bug: 61090 Change-Id: Iff7eeb5ee72137492c3f6659e4d4d106e5715586
This commit is contained in:
parent
02477fa877
commit
94b035b26a
|
@ -21,7 +21,7 @@ class MathHooks {
|
|||
|
||||
// To be independent of the MediaWiki core version,
|
||||
// we check if the core caching logic for math is still available.
|
||||
if ( ! is_callable( 'ParserOptions::getMath' ) && in_array( 'math', $forOptions) ) {
|
||||
if ( ! is_callable( 'ParserOptions::getMath' ) && in_array( 'math', $forOptions ) ) {
|
||||
if ( $user === false ) {
|
||||
$user = $wgUser;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class MathHooks {
|
|||
) {
|
||||
// The math part of cache key starts with "math=" followed by a star or a number for the math mode
|
||||
// and the optional letter j that indicates if clientside MathJax rendering is used.
|
||||
if ( preg_match( '/(^|!)' . self::mathCacheKey.'[*\d]m?(!|$)/', $confstr ) ) {
|
||||
if ( preg_match( '/(^|!)' . self::mathCacheKey . '[*\d]m?(!|$)/', $confstr ) ) {
|
||||
$confstr = preg_replace(
|
||||
'/(^|!)' . self::mathCacheKey . '[*\d]m?(!|$)/',
|
||||
'\1' . self::mathCacheKey . $mathOption . '\2',
|
||||
|
@ -235,22 +235,6 @@ class MathHooks {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Hack to fake a default $wgMathPath value so parser test output
|
||||
* that renders to images doesn't vary by who runs it.
|
||||
*
|
||||
* @global string $wgMathPath
|
||||
* @param Parser $parser
|
||||
* @return bool
|
||||
*/
|
||||
static function onParserTestParser( &$parser ) {
|
||||
global $wgMathPath;
|
||||
|
||||
$wgMathPath = '/images/math';
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Links to the unit test files for the test cases.
|
||||
*
|
||||
|
|
1
Math.php
1
Math.php
|
@ -150,7 +150,6 @@ $wgHooks['ParserFirstCallInit'][] = 'MathHooks::onParserFirstCallInit';
|
|||
$wgHooks['GetPreferences'][] = 'MathHooks::onGetPreferences';
|
||||
$wgHooks['LoadExtensionSchemaUpdates'][] = 'MathHooks::onLoadExtensionSchemaUpdates';
|
||||
$wgHooks['ParserTestTables'][] = 'MathHooks::onParserTestTables';
|
||||
$wgHooks['ParserTestParser'][] = 'MathHooks::onParserTestParser';
|
||||
$wgHooks['UnitTestsList'][] = 'MathHooks::onRegisterUnitTests';
|
||||
$wgHooks['PageRenderingHash'][] = 'MathHooks::onPageRenderingHash';
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ class MathInputCheckTexvc extends MathInputCheck {
|
|||
* Converts an error returned by texvc to a localized exception
|
||||
*
|
||||
* @param string $texvcResult error result returned by texvc
|
||||
* @param bool|MathRenderer $errorRenderer
|
||||
* @return string
|
||||
*/
|
||||
public function convertTexvcError( $texvcResult, $errorRenderer = false ) {
|
||||
$texvcStatus = substr( $texvcResult, 0, 1 );
|
||||
|
@ -22,7 +24,7 @@ class MathInputCheckTexvc extends MathInputCheck {
|
|||
$errorRenderer = new MathSource( $this->inputTeX );
|
||||
}
|
||||
|
||||
switch ($texvcStatus) {
|
||||
switch ( $texvcStatus ) {
|
||||
case 'E':
|
||||
$errMsg = $errorRenderer->getError( 'math_lexing_error' );
|
||||
break;
|
||||
|
@ -69,14 +71,14 @@ class MathInputCheckTexvc extends MathInputCheck {
|
|||
|
||||
if ( wfIsWindows() ) {
|
||||
# Invoke it within cygwin sh, because texvc expects sh features in its default shell
|
||||
$cmd = 'sh -c ' . wfEscapeShellArg($cmd);
|
||||
$cmd = 'sh -c ' . wfEscapeShellArg( $cmd );
|
||||
}
|
||||
|
||||
wfDebugLog( 'Math', "TeX check command: $cmd\n" );
|
||||
$contents = wfShellExec( $cmd );
|
||||
wfDebugLog( 'Math', "TeX check result:\n $contents\n---\n" );
|
||||
|
||||
if ( strlen($contents) === 0 ) {
|
||||
if ( strlen( $contents ) === 0 ) {
|
||||
wfDebugLog( 'Math', "TeX check output was empty. \n" );
|
||||
$this->lastError = MathRenderer::getError( 'math_unknown_error' );
|
||||
|
||||
|
|
|
@ -23,14 +23,14 @@ class MathLaTeXML extends MathRenderer {
|
|||
* @param (string|array) $array
|
||||
* @return string
|
||||
*/
|
||||
public function serializeSettings($array){
|
||||
if(!is_array($array)){
|
||||
public function serializeSettings( $array ) {
|
||||
if ( !is_array( $array ) ) {
|
||||
return $array;
|
||||
} else {
|
||||
//removes the [1] [2]... for the unnamed subarrays since LaTeXML
|
||||
//assigns multiple values to one key e.g.
|
||||
//preload=amsmath.sty&preload=amsthm.sty&preload=amstext.sty
|
||||
return preg_replace('|\%5B\d+\%5D|', '', wfArrayToCgi($array)) ;
|
||||
// removes the [1] [2]... for the unnamed subarrays since LaTeXML
|
||||
// assigns multiple values to one key e.g.
|
||||
// preload=amsmath.sty&preload=amsthm.sty&preload=amstext.sty
|
||||
return preg_replace( '|\%5B\d+\%5D|', '', wfArrayToCgi( $array ) ) ;
|
||||
}
|
||||
}
|
||||
/**
|
||||
|
@ -184,8 +184,8 @@ class MathLaTeXML extends MathRenderer {
|
|||
*/
|
||||
public function getPostData() {
|
||||
$texcmd = urlencode( $this->tex );
|
||||
$settings = $this->serializeSettings($this->getLaTeXMLSettings());
|
||||
return $settings. '&tex=' . $texcmd;
|
||||
$settings = $this->serializeSettings( $this->getLaTeXMLSettings() );
|
||||
return $settings . '&tex=' . $texcmd;
|
||||
}
|
||||
/**
|
||||
* Does the actual web request to convert TeX to MathML.
|
||||
|
@ -269,8 +269,9 @@ class MathLaTeXML extends MathRenderer {
|
|||
|
||||
/**
|
||||
* Embeds the MathML-XML element in a HTML span element with class tex
|
||||
* @param string $mml: the MathML string
|
||||
* @param string $tagId: optional tagID for references like (pagename#equation2)
|
||||
* @param string $mml : the MathML string
|
||||
* @param string $tagId : optional tagID for references like (pagename#equation2)
|
||||
* @param bool $attribs
|
||||
* @return html element with rendered math
|
||||
*/
|
||||
public static function embedMathML( $mml, $tagId = '', $attribs = false ) {
|
||||
|
|
|
@ -38,7 +38,7 @@ abstract class MathRenderer {
|
|||
protected $mathml = '';
|
||||
protected $conservativeness = 0;
|
||||
protected $params = '';
|
||||
//STATE OF THE CLASS INSTANCE
|
||||
// STATE OF THE CLASS INSTANCE
|
||||
/** @var boolean has variable tex been security-checked */
|
||||
protected $texSecure = false;
|
||||
protected $changed = false;
|
||||
|
@ -117,7 +117,7 @@ abstract class MathRenderer {
|
|||
* Returns an internationalized HTML error string
|
||||
*
|
||||
* @param string $msg message key for specific error
|
||||
* @param Varargs $parameters (optional) zero or more message parameters for specific error
|
||||
* @internal param \Varargs $parameters (optional) zero or more message parameters for specific error
|
||||
* @return string HTML error string
|
||||
*/
|
||||
public function getError( $msg /*, ... */ ) {
|
||||
|
@ -206,7 +206,7 @@ abstract class MathRenderer {
|
|||
public function writeToDatabase( $dbw = null ) {
|
||||
# Now save it back to the DB:
|
||||
if ( !wfReadOnly() ) {
|
||||
$dbw = $dbw ?: wfGetDB( DB_MASTER );
|
||||
$dbw = $dbw ? : wfGetDB( DB_MASTER );
|
||||
wfDebugLog( "Math", 'store entry for $' . $this->tex . '$ in database (hash:' . bin2hex( $this->hash ) . ")\n" );
|
||||
$outArray = $this->dbOutArray();
|
||||
$dbw->onTransactionIdle(
|
||||
|
@ -221,7 +221,6 @@ abstract class MathRenderer {
|
|||
* @return array
|
||||
*/
|
||||
private function dbOutArray() {
|
||||
global $wgDebugMath;
|
||||
$dbr = wfGetDB( DB_SLAVE );
|
||||
if ( $this->hash ) {
|
||||
$outmd5_sql = $dbr->encodeBlob( pack( 'H32', $this->hash ) );
|
||||
|
@ -411,6 +410,7 @@ abstract class MathRenderer {
|
|||
/**
|
||||
* Sets purge. If set to true the render is forced to rerender and must not
|
||||
* use a cached version.
|
||||
* @param bool $purge
|
||||
* @return boolean
|
||||
*/
|
||||
function setPurge( $purge = true ) {
|
||||
|
@ -433,7 +433,7 @@ abstract class MathRenderer {
|
|||
public function checkTex() {
|
||||
if ( !$this->texSecure ) {
|
||||
$checker = new MathInputCheckTexvc( $this->userInputTex );
|
||||
if ( $checker->isValid() ){
|
||||
if ( $checker->isValid() ) {
|
||||
$this->setTex( $checker->getValidTex() );
|
||||
$this->texSecure = true;
|
||||
return true;
|
||||
|
@ -441,13 +441,15 @@ abstract class MathRenderer {
|
|||
$this->lastError = $checker->getError();
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string original tex string specified by the user
|
||||
*/
|
||||
public function getUserInputTex(){
|
||||
public function getUserInputTex() {
|
||||
return $this->userInputTex;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ class MathTexvc extends MathRenderer {
|
|||
public function getHashPath() {
|
||||
$path = $this->getBackend()->getRootStoragePath() .
|
||||
'/math-render/' . $this->getHashSubPath();
|
||||
wfDebugLog("Math", "TeX: getHashPath, hash is: {$this->getHash()}, path is: $path\n" );
|
||||
wfDebugLog( "Math", "TeX: getHashPath, hash is: {$this->getHash()}, path is: $path\n" );
|
||||
return $path;
|
||||
}
|
||||
|
||||
|
@ -98,6 +98,7 @@ class MathTexvc extends MathRenderer {
|
|||
* Converts an error returned by texvc to a localized exception
|
||||
*
|
||||
* @param string $texvcResult error result returned by texvc
|
||||
* @return string
|
||||
*/
|
||||
public function convertTexvcError( $texvcResult ) {
|
||||
$errorConverter = new MathInputCheckTexvc();
|
||||
|
@ -233,7 +234,7 @@ class MathTexvc extends MathRenderer {
|
|||
unset( $wgHooks['ParserAfterParse']['FlushMathBackend'] );
|
||||
$backend->doQuickOperations( $backend->mathBufferedWrites );
|
||||
unset( $backend->mathBufferedWrites );
|
||||
};
|
||||
} ;
|
||||
}
|
||||
$backend->mathBufferedWrites[] = array(
|
||||
'op' => 'store',
|
||||
|
@ -261,7 +262,7 @@ class MathTexvc extends MathRenderer {
|
|||
$backend = new FSFileBackend( array(
|
||||
'name' => 'math-backend',
|
||||
'wikiId' => wfWikiId(),
|
||||
'lockManager' => new NullLockManager(array() ),
|
||||
'lockManager' => new NullLockManager( array() ),
|
||||
'containerPaths' => array( 'math-render' => $wgMathDirectory ),
|
||||
'fileMode' => 0777
|
||||
) );
|
||||
|
|
|
@ -0,0 +1,96 @@
|
|||
<?php
|
||||
/**
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
* http://www.gnu.org/copyleft/gpl.html
|
||||
*
|
||||
* @ingroup Maintenance
|
||||
*/
|
||||
|
||||
require_once( dirname( __FILE__ ) . '/../../../maintenance/Maintenance.php' );
|
||||
|
||||
class MathGenerateTests extends Maintenance
|
||||
{
|
||||
const REFERENCE_PAGE = 'mediawikiwiki:Extension:Math/CoverageTest';
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
parent::__construct();
|
||||
$this->mDescription = 'Rebuilds the MathCoverage tests';
|
||||
$this->addArg( 'page', "The page ues for the testset generation.", false );
|
||||
$this->addOption( 'offset', "If set the first n equations on the page are skipped", false, true, "o" );
|
||||
$this->addOption( 'length', "If set the only n equations were processed", false, true, "l" );
|
||||
$this->addOption( 'user', "User with rights to view the page", false, true, "u" );
|
||||
|
||||
}
|
||||
|
||||
private static function getMathTagsFromPage( $titleString )
|
||||
{
|
||||
global $wgEnableScaryTranscluding;
|
||||
$title = Title::newFromText( $titleString );
|
||||
if ( $title->exists() ) {
|
||||
$article = new Article( $title );
|
||||
$wikiText = $article->getPage()->getContent()->getNativeData();
|
||||
} else {
|
||||
if ( $title == self::REFERENCE_PAGE ) {
|
||||
$wgEnableScaryTranscluding = true;
|
||||
$parser = new Parser();
|
||||
$wikiText = $parser->interwikiTransclude( $title, 'raw' );
|
||||
} else {
|
||||
return 'Page does not exist';
|
||||
}
|
||||
}
|
||||
// TODO: find a better way to extract math elements from a page
|
||||
|
||||
$wikiText = Sanitizer::removeHTMLcomments( $wikiText );
|
||||
$wikiText = preg_replace( '#<nowiki>(.*)</nowiki>#', '', $wikiText );
|
||||
preg_match_all( "#<math>(.*?)</math>#s", $wikiText, $math );
|
||||
// TODO: Find a way to specify a key e.g '\nRenderTest:(.?)#<math>(.*?)</math>#s\n'
|
||||
// leads to array('\1'->'\2') with \1 eg Bug 2345 and \2 the math content
|
||||
return $math[1];
|
||||
|
||||
}
|
||||
|
||||
public function execute()
|
||||
{
|
||||
global $wgUser;
|
||||
$parserTests = array();
|
||||
$page = $this->getArg( 0, self::REFERENCE_PAGE );
|
||||
$offset = $this->getOption( 'offset', 0 );
|
||||
$length = $this->getOption( 'length', PHP_INT_MAX );
|
||||
$userName = $this->getOption( 'user', 'Maintenance script' );
|
||||
$wgUser = User::newFromName( $userName );
|
||||
$allEquations = self::getMathTagsFromPage( $page );
|
||||
if ( !is_array( $allEquations ) ) {
|
||||
echo "Could not get equations from page '$page'\n";
|
||||
echo $allEquations . PHP_EOL;
|
||||
return;
|
||||
} else {
|
||||
echo 'got ' . count( $allEquations ) . " math tags. Start processing.";
|
||||
}
|
||||
$i = 0;
|
||||
foreach ( array_slice( $allEquations, $offset, $length, true ) as $input ) {
|
||||
$output = MathRenderer::renderMath( $input, array(), MW_MATH_PNG );
|
||||
$parserTests[] = array( (string)$input, $output );
|
||||
$i++;
|
||||
echo '.';
|
||||
}
|
||||
echo "Generated $i tests\n";
|
||||
file_put_contents( dirname( __FILE__ ) . '/../tests/ParserTest.data', serialize( $parserTests ) );
|
||||
}
|
||||
}
|
||||
|
||||
$maintClass = "MathGenerateTests";
|
||||
require_once( RUN_MAINTENANCE_IF_MAIN );
|
|
@ -7,196 +7,3 @@ pst
|
|||
!!result
|
||||
<!-- <math>data</math> -->
|
||||
!!end
|
||||
|
||||
#!! test
|
||||
#BUG 1887: A <math> with a thumbnail- we don't render math in the parsertests by default,
|
||||
#so math is not stripped and turns up as escaped <math> tags.
|
||||
#!! input
|
||||
#[[Image:foobar.jpg|thumb|<math>2+2</math>]]
|
||||
#!! result
|
||||
#<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/3/3a/Foobar.jpg" width="180" height="20" class="thumbimage" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><math>2+2</math></div></div></div>
|
||||
#
|
||||
#!! end
|
||||
|
||||
!! test
|
||||
BUG 1887, part 2: A <math> with a thumbnail- math enabled
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
[[Image:foobar.jpg|thumb|<math>2+2</math>]]
|
||||
!! result
|
||||
<div class="thumb tright"><div class="thumbinner" style="width:182px;"><a href="/wiki/File:Foobar.jpg" class="image"><img alt="" src="http://example.com/images/thumb/3/3a/Foobar.jpg/180px-Foobar.jpg" width="180" height="20" class="thumbimage" srcset="http://example.com/images/thumb/3/3a/Foobar.jpg/270px-Foobar.jpg 1.5x, http://example.com/images/thumb/3/3a/Foobar.jpg/360px-Foobar.jpg 2x" /></a> <div class="thumbcaption"><div class="magnify"><a href="/wiki/File:Foobar.jpg" class="internal" title="Enlarge"><img src="/skins/common/images/magnify-clip.png" width="15" height="11" alt="" /></a></div><img class="tex" alt="2+2" src="/images/math/f/a/5/fa50b8b616463173474302ca3e63586b.png" /></div></div></div>
|
||||
|
||||
!! end
|
||||
|
||||
#!! test
|
||||
#Math section safety when disabled
|
||||
#!! input
|
||||
#<math><script>alert(document.cookies);</script></math>
|
||||
#!! result
|
||||
#<p><math><script>alert(document.cookies);</script></math>
|
||||
#</p>
|
||||
#!! end
|
||||
|
||||
!! test
|
||||
BUG 26380: Add \widetilde support to match \widehat
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\widehat{x}</math>
|
||||
<math>\widetilde{x}</math>
|
||||
!! result
|
||||
<p><img class="tex" alt="\widehat{x}" src="/images/math/9/9/8/998309e831dfb051f233c92b4b8a825b.png" />
|
||||
<img class="tex" alt="\widetilde{x}" src="/images/math/e/9/e/e9e91996778a6d6f5cdf4cc951955206.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 27324: Euro symbol for math
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\euro 200</math>
|
||||
<math>\geneuro</math>
|
||||
<math>\geneuronarrow</math>
|
||||
<math>\geneurowide</math>
|
||||
<math>\officialeuro</math>
|
||||
!! result
|
||||
<p><img class="tex" alt="\euro 200" src="/images/math/1/8/8/18867d4c568a19ae7b2388346e504ec3.png" />
|
||||
<img class="tex" alt="\geneuro" src="/images/math/9/8/b/98b63c235ee187a38267e0e170b10e9d.png" />
|
||||
<img class="tex" alt="\geneuronarrow" src="/images/math/a/a/4/aa4a1ed370f4ee705c6930384bf89502.png" />
|
||||
<img class="tex" alt="\geneurowide" src="/images/math/4/4/0/4404468e6187fb04e4f7e1f15e550825.png" />
|
||||
<img class="tex" alt="\officialeuro" src="/images/math/d/7/0/d708de0eed23dbd6f02b99ea9073547b.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 27754: Archaic Greek letters for math (may require texlive-lang-greek)
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\digamma</math><!-- Lowercase digamma was already available -->
|
||||
<math>\Coppa\coppa\varcoppa</math>
|
||||
<math>\Digamma</math>
|
||||
<math>\Koppa\koppa</math>
|
||||
<math>\Sampi\sampi</math>
|
||||
<math>\Stigma\stigma\varstigma</math>
|
||||
!! result
|
||||
<p><img class="tex" alt="\digamma" src="/images/math/2/f/0/2f057b6e514c8ca2d9cf9a3e549f8865.png" />
|
||||
<img class="tex" alt="\Coppa\coppa\varcoppa" src="/images/math/8/3/0/8308ee5003aa36112414cad8ef874f85.png" />
|
||||
<img class="tex" alt="\Digamma" src="/images/math/5/c/f/5cfd6e5df6c87798542dca2e22c1e7cb.png" />
|
||||
<img class="tex" alt="\Koppa\koppa" src="/images/math/5/2/5/52593a0cdac178d165985ac014788b97.png" />
|
||||
<img class="tex" alt="\Sampi\sampi" src="/images/math/e/9/d/e9dabb19e4c27bf23d3c2a3629474562.png" />
|
||||
<img class="tex" alt="\Stigma\stigma\varstigma" src="/images/math/7/b/9/7b9233276816994a33a5e968202cef6e.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 19547: Apostrophe / single quotes in math \text{...}
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\text{next years}</math>
|
||||
<math>\text{next year's}</math>
|
||||
<math>\text{`next' year}</math>
|
||||
!! result
|
||||
<p><img class="tex" alt="\text{next years}" src="/images/math/6/6/9/6691dbc0b36631a68b78dd5ace256d80.png" />
|
||||
<img class="tex" alt="\text{next year's}" src="/images/math/2/3/6/236fd262b1976d04bc0e7a969d61aede.png" />
|
||||
<img class="tex" alt="\text{`next' year}" src="/images/math/0/5/8/05854b483a833f067cb6ae72319b44bc.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 6722: Spacing fix for functions in math HTML output
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\sin x</math>
|
||||
<math>\sin(x)</math>
|
||||
<math>\sin{x}</math>
|
||||
|
||||
<math>\sin x \,</math>
|
||||
<math>\sin(x) \,</math>
|
||||
<math>\sin{x} \,</math>
|
||||
!!result
|
||||
<p><img class="tex" alt="\sin x" src="/images/math/c/d/b/cdba58911c590ced3e2435dfa39f6873.png" />
|
||||
<img class="tex" alt="\sin(x)" src="/images/math/3/e/2/3e21673ce6c9b09f9ec50b7237248576.png" />
|
||||
<img class="tex" alt="\sin{x}" src="/images/math/f/b/5/fb5551723991d4dcb974a23c162ae813.png" />
|
||||
</p><p><img class="tex" alt="\sin x \," src="/images/math/7/6/a/76a8e1a01bd233c1e4e16d63b2bbf939.png" />
|
||||
<img class="tex" alt="\sin(x) \," src="/images/math/1/6/c/16c69b0a3658d3b398f72c518d869a03.png" />
|
||||
<img class="tex" alt="\sin{x} \," src="/images/math/8/3/9/839639707da39f691e702c2399cbf943.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 18912: Add \sen function for Spanish sin to math
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\sen x</math>
|
||||
<math>\sen(x)</math>
|
||||
<math>\sen{x}</math>
|
||||
|
||||
<math>\sen x \,</math>
|
||||
<math>\sen(x) \,</math>
|
||||
<math>\sen{x} \,</math>
|
||||
!! result
|
||||
<p><img class="tex" alt="\sen x" src="/images/math/f/b/8/fb82a78d580396c62cecb4cf018f3769.png" />
|
||||
<img class="tex" alt="\sen(x)" src="/images/math/8/3/a/83a10e6756c8e59055178dc1f593130a.png" />
|
||||
<img class="tex" alt="\sen{x}" src="/images/math/0/4/f/04fde4f7a7e478015066f378050b1979.png" />
|
||||
</p><p><img class="tex" alt="\sen x \," src="/images/math/0/a/c/0ac592b8f31b4698766c50c532f446a7.png" />
|
||||
<img class="tex" alt="\sen(x) \," src="/images/math/b/b/5/bb5469d24fcdd52aa60cb9ee90ba697d.png" />
|
||||
<img class="tex" alt="\sen{x} \," src="/images/math/d/4/8/d4882a4bcf5db1da3e30d905da8b394e.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 18912: \operatorname{sen} x gets wrong spacing in math
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\operatorname{sen}</math>
|
||||
!! result
|
||||
<p><img class="tex" alt="\operatorname{sen}" src="/images/math/f/a/9/fa9660c7eb053ca8d3c9a87fa86635d9.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 31442: Multiple math accents without braces fails to parse
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\dot \vec B</math>
|
||||
!! result
|
||||
<p><img class="tex" alt="\dot \vec B" src="/images/math/e/6/4/e64939568ecb506a86a392373cec0458.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 31442: Math accents with math font fail to parse if braces not used
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math>\tilde \mathcal{M}</math>
|
||||
!! result
|
||||
<p><img class="tex" alt="\tilde \mathcal{M}" src="/images/math/5/5/0/55072ce6ef8c840c4b7687bd8a028bde.png" />
|
||||
</p>
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 31824: Empty math tag returns uniq
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math></math>
|
||||
!! result
|
||||
!! end
|
||||
|
||||
!! test
|
||||
BUG 31824: Empty math tag returns uniq
|
||||
!! options
|
||||
texvc
|
||||
!! input
|
||||
<math> </math>
|
||||
!! result
|
||||
!! end
|
||||
|
|
|
@ -0,0 +1,86 @@
|
|||
<?php
|
||||
/**
|
||||
* PHPUnit tests to test the wide range of all typical use cases for formulae at Wikipedia.
|
||||
* To generate the page https://www.mediawiki.org/wiki/Extension:Math/CoverageTest is used to
|
||||
* generate the test data.
|
||||
* The testData is generated by the maintenance script Math/maintenance/MathGenerateTests.php.
|
||||
* To update the test data locally with vagrant the following procedure is recommended:
|
||||
*
|
||||
* 1. copy the source from https://www.mediawiki.org/wiki/Extension:Math/CoverageTest to a new page e.g.
|
||||
* MathTest at your local vagrant instance
|
||||
* 2. run <code>php MathGenerateTests.php MathTest</code> in the maitenance folder of the Math extension.
|
||||
* 3. Test local e.g. via
|
||||
* <code>sudo php /vagrant/mediawiki/tests/phpunit/phpunit.php /vagrant/mediawiki/extensions/Math/tests/MathCoverageTest.php</code>
|
||||
* (If you don't use sudo you might have problems with the permissions set at vagrant.)
|
||||
*
|
||||
* @group Extensions
|
||||
* @group Math
|
||||
*/
|
||||
class MathCoverageTest extends MediaWikiTestCase {
|
||||
protected static $hasTexvc;
|
||||
protected static $texvcPath;
|
||||
|
||||
public static function setUpBeforeClass() {
|
||||
global $wgTexvc;
|
||||
|
||||
if ( is_executable( $wgTexvc ) ) {
|
||||
wfDebugLog( __CLASS__, " using build in texvc from "
|
||||
. "\$wgMathTexvcCheckExecutable = $wgTexvc" );
|
||||
# Using build-in
|
||||
self::$hasTexvc = true;
|
||||
self::$texvcPath = $wgTexvc;
|
||||
} else {
|
||||
# Attempt to compile
|
||||
wfDebugLog( __CLASS__, " compiling texvc..." );
|
||||
$cmd = 'cd ' . dirname( __DIR__ ) . '/math; make --always-make 2>&1';
|
||||
wfShellExec( $cmd, $retval );
|
||||
if ( $retval === 0 ) {
|
||||
self::$hasTexvc = true;
|
||||
self::$texvcPath = dirname( __DIR__ ) . '/math/texvc';
|
||||
wfDebugLog( __CLASS__, ' compiled texvc at ' . self::$texvcPath );
|
||||
} else {
|
||||
wfDebugLog( __CLASS__, ' ocaml not available or compilation of texvc failed' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
*/
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
|
||||
if ( ! self::$hasTexvc ) {
|
||||
$this->markTestSkipped( "No texvc installed on server" );
|
||||
} else {
|
||||
$this->setMwGlobals( 'wgTexvc',
|
||||
self::$texvcPath );
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Loops over all test cases provided by the provider function.
|
||||
* Compares each the rendering result of each input with the expected output.
|
||||
* @dataProvider testProvider
|
||||
*/
|
||||
public function testCoverage( $input, $output )
|
||||
{
|
||||
// TODO: Make rendering mode configurable
|
||||
// TODO: Provide test-ids
|
||||
// TODO: Link to the wikipage that contains the reference rendering
|
||||
$this->assertEquals( $this->normalize( $output ), $this->normalize( MathRenderer::renderMath( $input , array(), MW_MATH_PNG ) ), "Failed to render $input" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the test-data from the file ParserTest.data
|
||||
* @return array($input, $output) where $input is the test input string and $output is the rendered html5-output string
|
||||
*/
|
||||
public function testProvider()
|
||||
{
|
||||
return unserialize( file_get_contents( dirname( __FILE__ ) . '/ParserTest.data' ) );
|
||||
}
|
||||
|
||||
private function normalize( $input ) {
|
||||
return preg_replace( '#src="(.*?)/(([a-f]|\d)*).png"#', 'src="\2.png"', $input );
|
||||
}
|
||||
}
|
|
@ -63,7 +63,6 @@ class MathDatabaseTest extends MediaWikiTestCase {
|
|||
public function testDBBasics() {
|
||||
// ;
|
||||
$this->setValues();
|
||||
$wgDebugMath = false;
|
||||
|
||||
$this->renderer->writeToDatabase();
|
||||
|
||||
|
@ -83,7 +82,7 @@ class MathDatabaseTest extends MediaWikiTestCase {
|
|||
* @covers MathHooks::onLoadExtensionSchemaUpdates
|
||||
*/
|
||||
public function testBasicCreateTable() {
|
||||
if( $this->db->getType() === 'sqlite' ) {
|
||||
if ( $this->db->getType() === 'sqlite' ) {
|
||||
$this->markTestSkipped( "SQLite has global indices. We cannot " .
|
||||
"create the `unitest_math` table, its math_inputhash index " .
|
||||
"would conflict with the one from the real `math` table."
|
||||
|
|
|
@ -26,7 +26,7 @@ class MathInputCheckTest extends MediaWikiTestCase
|
|||
*/
|
||||
public function testGetValidTex() {
|
||||
$InputCheck = $this->getMockBuilder( 'MathInputCheck' )
|
||||
->setConstructorArgs(array('some tex input'))
|
||||
->setConstructorArgs( array( 'some tex input' ) )
|
||||
->getMock();
|
||||
$this->assertNull( $InputCheck->getValidTex() );
|
||||
}
|
||||
|
|
|
@ -26,8 +26,8 @@ class MathInputCheckTexvcTest extends MediaWikiTestCase {
|
|||
} else {
|
||||
# Attempt to compile
|
||||
wfDebugLog( __CLASS__, " compiling texvccheck..." );
|
||||
$cmd = 'cd ' . dirname(__DIR__) . '/texvccheck; make --always-make 2>&1';
|
||||
$stdout = wfShellExec( $cmd, $retval );
|
||||
$cmd = 'cd ' . dirname( __DIR__ ) . '/texvccheck; make --always-make 2>&1';
|
||||
wfShellExec( $cmd, $retval );
|
||||
if ( $retval === 0 ) {
|
||||
self::$hasTexvccheck = true;
|
||||
self::$texvccheckPath = dirname( __DIR__ ) . '/texvccheck/texvccheck';
|
||||
|
@ -43,7 +43,6 @@ class MathInputCheckTexvcTest extends MediaWikiTestCase {
|
|||
* This method is called before a test is executed.
|
||||
*/
|
||||
protected function setUp() {
|
||||
global $wgMathTexvcCheckExecutable;
|
||||
parent::setUp();
|
||||
$this->BadObject = new MathInputCheckTexvc( '\newcommand{\text{do evil things}}' );
|
||||
$this->GoodObject = new MathInputCheckTexvc( '\sin\left(\frac12x\right)' );
|
||||
|
@ -72,7 +71,7 @@ class MathInputCheckTexvcTest extends MediaWikiTestCase {
|
|||
$maxAvgTime = .001;
|
||||
$tstart = microtime( true );
|
||||
|
||||
for ($i = 1; $i <= $numberOfRuns; $i++){
|
||||
for ( $i = 1; $i <= $numberOfRuns; $i++ ) {
|
||||
is_executable( $wgMathTexvcCheckExecutable );
|
||||
}
|
||||
|
||||
|
@ -97,7 +96,7 @@ class MathInputCheckTexvcTest extends MediaWikiTestCase {
|
|||
$this->GoodObject->isValid();
|
||||
$this->assertNull( $this->GoodObject->getError() );
|
||||
$expectedMessage = wfMessage( 'math_unknown_function', '\newcommand' )->inContentLanguage()->escaped();
|
||||
$this->assertContains( $expectedMessage , $this->BadObject->getError());
|
||||
$this->assertContains( $expectedMessage , $this->BadObject->getError() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -142,7 +141,7 @@ class MathInputCheckTexvcTest extends MediaWikiTestCase {
|
|||
*/
|
||||
public function testConvertTexvcError() {
|
||||
$texvc = $this->getMockBuilder( 'MathInputCheckTexvc' )
|
||||
->setMethods(NULL)
|
||||
->setMethods( NULL )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
|
|
|
@ -111,14 +111,14 @@ class MathLaTeXMLTest extends MediaWikiTestCase {
|
|||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$sampleSettings = array(
|
||||
'k1'=>'v1',
|
||||
'k2&='=>'v2 + & *üö',
|
||||
'k1' => 'v1',
|
||||
'k2&=' => 'v2 + & *üö',
|
||||
'k3' => array(
|
||||
'v3A', 'v3b'
|
||||
));
|
||||
) );
|
||||
$expected = 'k1=v1&k2%26%3D=v2+%2B+%26+%2A%C3%BC%C3%B6&k3=v3A&k3=v3b';
|
||||
$this->assertEquals( $expected,$renderer->serializeSettings($sampleSettings), 'test serialization of array settings' );
|
||||
$this->assertEquals( $expected,$renderer->serializeSettings($expected), 'test serialization of a string setting' );
|
||||
$this->assertEquals( $expected, $renderer->serializeSettings( $sampleSettings ), 'test serialization of array settings' );
|
||||
$this->assertEquals( $expected, $renderer->serializeSettings( $expected ), 'test serialization of a string setting' );
|
||||
}
|
||||
/**
|
||||
* Checks the basic functionallity
|
||||
|
|
|
@ -17,7 +17,7 @@ class MathRendererTest extends MediaWikiTestCase {
|
|||
$this->assertEquals( MathDatabaseTest::SOME_TEX, $renderer->getTex()
|
||||
, "test getTex" );
|
||||
$this->assertEquals( $renderer->isChanged(), false
|
||||
, "test if changed is initially false");
|
||||
, "test if changed is initially false" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,13 +58,13 @@ class MathRendererTest extends MediaWikiTestCase {
|
|||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
$this->assertEquals( $renderer->isChanged(), false
|
||||
, "test if changed is initially false");
|
||||
$renderer->setHash('0000');
|
||||
, "test if changed is initially false" );
|
||||
$renderer->setHash( '0000' );
|
||||
$this->assertEquals( $renderer->isChanged(), true
|
||||
, "assumes that changing a hash sets changed to true");
|
||||
, "assumes that changing a hash sets changed to true" );
|
||||
}
|
||||
|
||||
public function testSetPurge(){
|
||||
public function testSetPurge() {
|
||||
$renderer = $this->getMockBuilder( 'MathRenderer' )
|
||||
->setMethods( array( 'render' ) )
|
||||
->disableOriginalConstructor()
|
||||
|
|
|
@ -9,19 +9,19 @@ class MathSourceTest extends MediaWikiTestCase {
|
|||
* Checks the basic functionallity
|
||||
* i.e. if the span element is generated right.
|
||||
*/
|
||||
public function testBasics(){
|
||||
$real=MathRenderer::renderMath("a+b",array(),MW_MATH_SOURCE);
|
||||
$this->assertEquals('<span class="tex" dir="ltr">$ a+b $</span>', $real
|
||||
, "Rendering of a+b in plain Text mode");
|
||||
public function testBasics() {
|
||||
$real = MathRenderer::renderMath( "a+b", array(), MW_MATH_SOURCE );
|
||||
$this->assertEquals( '<span class="tex" dir="ltr">$ a+b $</span>', $real
|
||||
, "Rendering of a+b in plain Text mode" );
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if newlines are converted to spaces correctly.
|
||||
*/
|
||||
public function testNewLines(){
|
||||
$real=MathRenderer::renderMath("a\n b",array(),MW_MATH_SOURCE);
|
||||
$this->assertSame('<span class="tex" dir="ltr">$ a b $</span>', $real
|
||||
, "converting newlines to spaces");
|
||||
public function testNewLines() {
|
||||
$real = MathRenderer::renderMath( "a\n b", array(), MW_MATH_SOURCE );
|
||||
$this->assertSame( '<span class="tex" dir="ltr">$ a b $</span>', $real
|
||||
, "converting newlines to spaces" );
|
||||
}
|
||||
|
||||
}
|
|
@ -122,7 +122,7 @@ class MathTexvcTest extends MediaWikiTestCase {
|
|||
*/
|
||||
public function testConvertTexvcError() {
|
||||
$texvc = $this->getMockBuilder( 'MathTexvc' )
|
||||
->setMethods(NULL)
|
||||
->setMethods( NULL )
|
||||
->disableOriginalConstructor()
|
||||
->getMock();
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue