Restbase based texvc input check

This change only connects the restbase and the mathinput interfaces
but does not change any functionality.

Change-Id: I3a23e5008c26c5f14ad842dcb5d22906a8aff33c
This commit is contained in:
physikerwelt 2015-11-28 10:24:54 +01:00 committed by Mobrovac
parent c66a85f143
commit f63eaeac23
3 changed files with 183 additions and 0 deletions

View File

@ -0,0 +1,76 @@
<?php
/**
* MediaWiki math extension
*
* (c) 2002-2015 Tomasz Wegrzanowski, Brion Vibber, Moritz Schubotz,
* and other MediaWiki contributors
* GPLv2 license; info in main package.
*
* @author Moritz Schubotz
*/
use MediaWiki\Logger\LoggerFactory;
class MathInputCheckRestbase extends MathInputCheck {
private $restbaseInterface;
/**
* Default constructor
* (performs no checking)
* @param string $tex the TeX input string to be checked
* @param bool $displayStyle
*/
public function __construct( $tex = '', $displayStyle = true ) {
parent::__construct( $tex );
$this->restbaseInterface = new MathRestbaseInterface( $tex, $displayStyle );
}
/**
* @see https://phabricator.wikimedia.org/T119300
* @param stdClass $e
* @param MathRenderer $errorRenderer
* @return string
*/
public function errorObjectToHtml( stdClass $e, $errorRenderer = null ) {
if ( $errorRenderer === null ) {
$errorRenderer = new MathSource( $this->inputTeX );
}
if ( isset( $e->error->message ) ){
if ( $e->error->message === 'Illegal TeX function' ) {
return $errorRenderer->getError( 'math_unknown_function', $e->error->found );
}
return $errorRenderer->getError( 'math_syntax_error' );
}
return $errorRenderer->getError( 'math_unknown_error' );
}
/**
* @return boolean
*/
public function isValid() {
return $this->restbaseInterface->checkTeX();
}
/**
* Some TeX checking programs may return
* a modified tex string after having checked it.
* You can get the altered tex string with this method
* @return string A valid Tex string
*/
public function getValidTex() {
return $this->restbaseInterface->getCheckedTex();
}
/**
* Returns the string of the last error.
* @return string
*/
public function getError() {
$err = $this->restbaseInterface->getError();
if ( $err === null ){
return null;
}
return $this->errorObjectToHtml( $err );
}
}

View File

@ -22,6 +22,7 @@
"MathLaTeXML": "MathLaTeXML.php",
"MathInputCheck": "MathInputCheck.php",
"MathInputCheckTexvc": "MathInputCheckTexvc.php",
"MathInputCheckRestbase": "MathInputCheckRestbase.php",
"SpecialMathShowImage": "SpecialMathShowImage.php",
"SpecialMathStatus": "SpecialMathStatus.php"
},

View File

@ -0,0 +1,106 @@
<?php
/**
* @group Math
*/
class MathInputCheckRestbaseTest extends MediaWikiTestCase {
protected static $hasRestbase;
/** @var MathInputCheckRestbase */
protected $BadObject;
/** @var MathInputCheckRestbase */
protected $GoodObject;
public static function setUpBeforeClass() {
$rbi = new MathRestbaseInterface();
self::$hasRestbase = $rbi->checkBackend( true );
}
/**
* 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::$hasRestbase ) {
$this->markTestSkipped( "Can not connect to Restbase Math interface." );
}
$this->BadObject = new MathInputCheckRestbase( '\newcommand{\text{do evil things}}' );
$this->GoodObject = new MathInputCheckRestbase( '\sin\left(\frac12x\right)' );
}
/**
* @covers MathInputCheckRestbase::getError
*/
public function testGetError() {
$this->assertNull( $this->GoodObject->getError() );
$this->assertNull( $this->BadObject->getError() );
$this->BadObject->isValid();
$this->GoodObject->isValid();
$this->assertNull( $this->GoodObject->getError() );
$expectedMessage = wfMessage(
'math_unknown_function', '\newcommand'
)->inContentLanguage()->escaped();
$this->assertContains( $expectedMessage, $this->BadObject->getError() );
}
/**
* @covers MathInputCheckRestbase::getError
*/
public function testErrorSyntax() {
$o = new MathInputCheckRestbase( '\left(' );
$this->assertFalse( $o->isValid() );
$expectedMessage = wfMessage( 'math_syntax_error' )->inContentLanguage()->escaped();
$this->assertContains( $expectedMessage, $o->getError() );
}
/**
* @covers MathInputCheckRestbase::getError
*/
public function testErrorLexing() {
$o = new MathInputCheckRestbase( "\x61\xCC\x81" );
$this->assertFalse( $o->isValid() );
// Lexical errors are no longer supported. The new error message
// Expected "-", "[", "\\\\",
// "\\\\begin", "\\\\begin{", "]", "^", "_", "{", [ \\t\\n\\r], [%$], [().], [,:;?!\\\'],
// [-+*=], [0-9], [><~], [\\/|] or [a-zA-Z] but "\\u0301" found.
// is more expressive anyhow.
$expectedMessage = wfMessage( 'math_syntax_error' )->inContentLanguage()->escaped();
$this->assertContains( $expectedMessage, $o->getError() );
}
/**
* @covers MathInputCheckRestbase::isValid
*/
public function testIsValid() {
$this->assertFalse( $this->BadObject->isValid() );
$this->assertTrue( $this->GoodObject->isValid() );
}
/**
* @covers MathInputCheckRestbase::getValidTex
*/
public function testGetValidTex() {
$this->assertNull( $this->GoodObject->getValidTex() );
$this->assertNull( $this->BadObject->getValidTex() );
$this->BadObject->isValid();
$this->GoodObject->isValid();
$this->assertNull( $this->BadObject->getValidTex() );
// Note that texvcjs has slightly diverged from texvc and enforces brackets for function
// arguments. Also the double space between frac and the arg has ben reduce to a single space.
$this->assertEquals( $this->GoodObject->getValidTex(), '\\sin \\left({\\frac {1}{2}}x\\right)' );
}
/**
* Test corner cases of texvccheck conversion
* @covers MathInputCheckTexvc::getValidTex
*/
public function testGetValidTexCornerCases() {
$Object = new MathInputCheckTexvc( '\reals' );
$Object->isValid();
$this->assertEquals( "\\mathbb{R} ", $Object->getValidTex() );
$Object = new MathInputCheckTexvc( '\lbrack' ); // Bug: 54624
$Object->isValid();
$this->assertEquals( '\\lbrack ', $Object->getValidTex() );
}
}