From f63eaeac2358f828bad95a5c7ed48c24cd8cf6cd Mon Sep 17 00:00:00 2001 From: physikerwelt Date: Sat, 28 Nov 2015 10:24:54 +0100 Subject: [PATCH] Restbase based texvc input check This change only connects the restbase and the mathinput interfaces but does not change any functionality. Change-Id: I3a23e5008c26c5f14ad842dcb5d22906a8aff33c --- MathInputCheckRestbase.php | 76 +++++++++++++++++++ extension.json | 1 + tests/MathInputCheckRestbaseTest.php | 106 +++++++++++++++++++++++++++ 3 files changed, 183 insertions(+) create mode 100644 MathInputCheckRestbase.php create mode 100644 tests/MathInputCheckRestbaseTest.php diff --git a/MathInputCheckRestbase.php b/MathInputCheckRestbase.php new file mode 100644 index 0000000..bf17b64 --- /dev/null +++ b/MathInputCheckRestbase.php @@ -0,0 +1,76 @@ +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 ); + } + +} diff --git a/extension.json b/extension.json index 21c4067..20d87fe 100644 --- a/extension.json +++ b/extension.json @@ -22,6 +22,7 @@ "MathLaTeXML": "MathLaTeXML.php", "MathInputCheck": "MathInputCheck.php", "MathInputCheckTexvc": "MathInputCheckTexvc.php", + "MathInputCheckRestbase": "MathInputCheckRestbase.php", "SpecialMathShowImage": "SpecialMathShowImage.php", "SpecialMathStatus": "SpecialMathStatus.php" }, diff --git a/tests/MathInputCheckRestbaseTest.php b/tests/MathInputCheckRestbaseTest.php new file mode 100644 index 0000000..359dbeb --- /dev/null +++ b/tests/MathInputCheckRestbaseTest.php @@ -0,0 +1,106 @@ +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() ); + } + +}