mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/Math
synced 2024-11-30 18:35:12 +00:00
Add Full-Coverage Test TexVC-MMLGeneration for Mathoid-LateXML
* Implemented multiple-column generation for the HTML-Generator * Items can be skipped in test by defining index Bug: T327386 Change-Id: I13148d58246ddcc1f2e6dcd14fa5b4255a1fb8e7
This commit is contained in:
parent
8ca418578c
commit
ada1d6e3db
123
tests/phpunit/unit/TexVC/MMLFullCoverageTest.php
Normal file
123
tests/phpunit/unit/TexVC/MMLFullCoverageTest.php
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
<?php
|
||||||
|
namespace MediaWiki\Extension\Math\TexVC;
|
||||||
|
|
||||||
|
use InvalidArgumentException;
|
||||||
|
use MediaWiki\Extension\Math\TexVC\MMLmappings\Util\MMLTestUtil;
|
||||||
|
use MediaWiki\Extension\Math\TexVC\MMLmappings\Util\MMLTestUtilHTML;
|
||||||
|
|
||||||
|
use MediaWikiUnitTestCase;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a test which checks the TexVC (LaTeX to MathML) converter capabilities
|
||||||
|
* It uses the Full-Coverage definition of tests from:
|
||||||
|
* https://www.mediawiki.org/wiki/Extension:Math/CoverageTest
|
||||||
|
*
|
||||||
|
* The json test-files for this can be updated with:
|
||||||
|
* 'MathSearch-Extension/maintenance/UpdateMath.php --mode mathml --exportmml /var/www/html/extensions/MathSearch'
|
||||||
|
*
|
||||||
|
* WIP:
|
||||||
|
* Currently this is just checking that texVC can generate MathML
|
||||||
|
* for the specified tests, not how the MathML looks like.
|
||||||
|
*
|
||||||
|
* @covers \MediaWiki\Extension\Math\TexVC\TexVC
|
||||||
|
* @group stub
|
||||||
|
*/
|
||||||
|
final class MMLFullCoverageTest extends MediaWikiUnitTestCase {
|
||||||
|
private static $FILENAMELATEXML = __DIR__ . "/mmlRes-latexml-FullCoverage.json";
|
||||||
|
private static $FILENAMEMATHOID = __DIR__ . "/mmlRes-mathml-FullCoverage.json";
|
||||||
|
private static $APPLYFILTER = false;
|
||||||
|
private static $FILTERSTART = 0;
|
||||||
|
private static $FILTERLENGTH = 60;
|
||||||
|
private static $GENERATEHTML = true;
|
||||||
|
private static $GENERATEDHTMLFILE = __DIR__ . "/MMLFullCoverageTest-Output.html";
|
||||||
|
private static $SKIPPEDINDICES = [ 0,58, 380, 388 ];
|
||||||
|
|
||||||
|
private static $FILTERMML = true;
|
||||||
|
|
||||||
|
public static function setUpBeforeClass(): void {
|
||||||
|
MMLTestUtilHTML::generateHTMLstart( self::$GENERATEDHTMLFILE, [ "name","TeX-Input","MathML(LaTeXML)",
|
||||||
|
"MathML(Mathoid)", "MathML(TexVC)" ], self::$GENERATEHTML );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function tearDownAfterClass(): void {
|
||||||
|
MMLTestUtilHTML::generateHTMLEnd( self::$GENERATEDHTMLFILE, self::$GENERATEHTML );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider provideTestCases
|
||||||
|
*/
|
||||||
|
public function testTexVC( $title, $tc ) {
|
||||||
|
$texVC = new TexVC();
|
||||||
|
|
||||||
|
if ( in_array( $tc->ctr, self::$SKIPPEDINDICES ) ) {
|
||||||
|
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, [ $tc->ctr, $tc->tex,
|
||||||
|
"skipped", "skipped", "skipped" ], false, self::$GENERATEHTML );
|
||||||
|
$this->assertTrue( true );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
# Fetch result from TexVC(PHP)
|
||||||
|
$resultT = $texVC->check( $tc->tex, [
|
||||||
|
'debug' => false,
|
||||||
|
'usemathrm' => $tc->usemathrm ?? false,
|
||||||
|
'oldtexvc' => $tc->oldtexvc ?? false
|
||||||
|
] );
|
||||||
|
|
||||||
|
$mml_latexml = self::$FILTERMML ? self::loadXMLandDeleteAttrs( $tc->mml_latexml ) : $tc->mml_latexml;
|
||||||
|
$mathMLtexVC = MMLTestUtil::getMMLwrapped( $resultT["input"] );
|
||||||
|
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, [ $tc->ctr, $tc->tex, $mml_latexml,
|
||||||
|
$tc->mml_mathoid, $mathMLtexVC ], false, self::$GENERATEHTML );
|
||||||
|
$this->assertTrue( true );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes some attributes from the mathml which are not necessary for comparisons.
|
||||||
|
* @param string $mml mathml as string
|
||||||
|
* @return bool|string false if problem, mathml as xml string without the specified attributes if ok
|
||||||
|
*/
|
||||||
|
public static function loadXMLandDeleteAttrs( $mml ) {
|
||||||
|
$xml = simplexml_load_string( $mml );
|
||||||
|
self::unsetAttrs( $xml );
|
||||||
|
// Recursive call deleting attributes
|
||||||
|
self::deleteAttributes( $xml );
|
||||||
|
return $xml->asXML();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function deleteAttributes( &$xml ) {
|
||||||
|
foreach ( $xml as $node ) {
|
||||||
|
self::unsetAttrs( $node );
|
||||||
|
self::deleteAttributes( $node );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function unsetAttrs( $node ): void {
|
||||||
|
$attrs = $node->attributes();
|
||||||
|
unset( $attrs['id'] );
|
||||||
|
unset( $attrs['xref'] );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function provideTestCases() {
|
||||||
|
$resMathoid = MMLTestUtil::getJSON( self::$FILENAMEMATHOID );
|
||||||
|
$resLaTeXML = MMLTestUtil::getJSON( self::$FILENAMELATEXML );
|
||||||
|
if ( count( $resMathoid ) != count( $resLaTeXML ) ) {
|
||||||
|
throw new InvalidArgumentException( "Test files dont have the same number of entries." );
|
||||||
|
}
|
||||||
|
$f = [];
|
||||||
|
// Adding running indices for location of tests.
|
||||||
|
foreach ( $resMathoid as $index => $tcMathoid ) {
|
||||||
|
$tcLaTeXML = $resLaTeXML[$index];
|
||||||
|
$tc = [
|
||||||
|
"ctr" => $index,
|
||||||
|
"tex" => $tcMathoid->tex,
|
||||||
|
"type" => $tcMathoid->type,
|
||||||
|
"mml_mathoid" => $tcMathoid->mml,
|
||||||
|
"mml_latexml" => $tcLaTeXML->mml,
|
||||||
|
];
|
||||||
|
array_push( $f, [ "title N/A", (object)$tc ] );
|
||||||
|
}
|
||||||
|
// Filtering results by index if necessary
|
||||||
|
if ( self::$APPLYFILTER ) {
|
||||||
|
$f = array_slice( $f, self::$FILTERSTART, self::$FILTERLENGTH );
|
||||||
|
}
|
||||||
|
return $f;
|
||||||
|
}
|
||||||
|
}
|
|
@ -156,12 +156,12 @@ class MMLGenerationTest extends MediaWikiUnitTestCase {
|
||||||
$resMML3latexml = $mmlLatexML[$input] ?? "merror";
|
$resMML3latexml = $mmlLatexML[$input] ?? "merror";
|
||||||
if ( str_contains( $resMML3latexml, "merror" ) ) {
|
if ( str_contains( $resMML3latexml, "merror" ) ) {
|
||||||
$errorMessage = "Error Rendering in MathJax";
|
$errorMessage = "Error Rendering in MathJax";
|
||||||
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, $title, $input, $errorMessage,
|
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, [ $title, $input, $errorMessage,
|
||||||
$mathMLtexVC, false, self::$GENERATEHTML );
|
$mathMLtexVC ], false, self::$GENERATEHTML );
|
||||||
$this->assertTrue( true );
|
$this->assertTrue( true );
|
||||||
} else {
|
} else {
|
||||||
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, $title, $input, $resMML3latexml,
|
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, [ $title, $input, $resMML3latexml,
|
||||||
$mathMLtexVC, false, self::$GENERATEHTML );
|
$mathMLtexVC ], false, self::$GENERATEHTML );
|
||||||
$resMML3latexml = $resMML3latexml ?: "<math> no MML3 from Lookup </math>";
|
$resMML3latexml = $resMML3latexml ?: "<math> no MML3 from Lookup </math>";
|
||||||
if ( !self::$SKIPXMLVALIDATION ) {
|
if ( !self::$SKIPXMLVALIDATION ) {
|
||||||
$this->assertXmlStringEqualsXmlString( $resMML3latexml, $mathMLtexVC );
|
$this->assertXmlStringEqualsXmlString( $resMML3latexml, $mathMLtexVC );
|
||||||
|
@ -172,7 +172,8 @@ class MMLGenerationTest extends MediaWikiUnitTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setUpBeforeClass(): void {
|
public static function setUpBeforeClass(): void {
|
||||||
MMLTestUtilHTML::generateHTMLstart( self::$GENERATEDHTMLFILE, "MathML(MathJax3)", self::$GENERATEHTML );
|
MMLTestUtilHTML::generateHTMLstart( self::$GENERATEDHTMLFILE, [ "name","Tex-Input",
|
||||||
|
"MathML(MathJax3)","MathML(TexVC)" ], self::$GENERATEHTML );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function tearDownAfterClass(): void {
|
public static function tearDownAfterClass(): void {
|
||||||
|
|
|
@ -22,7 +22,7 @@ final class MMLGenerationTest2 extends MediaWikiUnitTestCase {
|
||||||
private static $FILTERSTART = 0;
|
private static $FILTERSTART = 0;
|
||||||
private static $FILTERLENGTH = 1;
|
private static $FILTERLENGTH = 1;
|
||||||
|
|
||||||
private static $GENERATEHTML = true;
|
private static $GENERATEHTML = false;
|
||||||
private static $GENERATEDHTMLFILE = __DIR__ . "/MMLGenerationTest2-Output.html";
|
private static $GENERATEDHTMLFILE = __DIR__ . "/MMLGenerationTest2-Output.html";
|
||||||
|
|
||||||
protected function setUp(): void {
|
protected function setUp(): void {
|
||||||
|
@ -34,7 +34,8 @@ final class MMLGenerationTest2 extends MediaWikiUnitTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function setUpBeforeClass(): void {
|
public static function setUpBeforeClass(): void {
|
||||||
MMLTestUtilHTML::generateHTMLstart( self::$GENERATEDHTMLFILE, self::$GENERATEHTML );
|
MMLTestUtilHTML::generateHTMLstart( self::$GENERATEDHTMLFILE, [ "name","Tex-Input",
|
||||||
|
"MathML(MathJax3)","MathML(TexVC)" ], self::$GENERATEHTML );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function tearDownAfterClass(): void {
|
public static function tearDownAfterClass(): void {
|
||||||
|
@ -48,8 +49,8 @@ final class MMLGenerationTest2 extends MediaWikiUnitTestCase {
|
||||||
$texVC = new TexVC();
|
$texVC = new TexVC();
|
||||||
|
|
||||||
if ( $tc->skipped ?? false ) {
|
if ( $tc->skipped ?? false ) {
|
||||||
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, $tc->ctr, $tc->input,
|
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, [ $tc->ctr, $tc->input,
|
||||||
"skipped", "skipped", false, self::$GENERATEHTML );
|
"skipped", "skipped" ], false, self::$GENERATEHTML );
|
||||||
$this->assertTrue( true );
|
$this->assertTrue( true );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -60,8 +61,8 @@ final class MMLGenerationTest2 extends MediaWikiUnitTestCase {
|
||||||
'oldtexvc' => $tc->oldtexvc ?? false
|
'oldtexvc' => $tc->oldtexvc ?? false
|
||||||
] );
|
] );
|
||||||
$mathMLtexVC = MMLTestUtil::getMMLwrapped( $resultT["input"] );
|
$mathMLtexVC = MMLTestUtil::getMMLwrapped( $resultT["input"] );
|
||||||
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, $tc->ctr, $tc->input, "tbd",
|
MMLTestUtilHTML::generateHTMLtableRow( self::$GENERATEDHTMLFILE, [ $tc->ctr, $tc->input, "tbd",
|
||||||
$mathMLtexVC, false, self::$GENERATEHTML );
|
$mathMLtexVC ], false, self::$GENERATEHTML );
|
||||||
$this->assertTrue( true );
|
$this->assertTrue( true );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,78 +27,80 @@ class MMLTestUtilHTML {
|
||||||
fclose( $file );
|
fclose( $file );
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function generateHTMLtableRow( $filePath, $id, $inputTex, $mmlMj3, $mmlGen,
|
public static function generateHTMLtableRow( $filePath, $rows, $bold = false, $active = true ) {
|
||||||
$bold = false, $active = true ) {
|
|
||||||
if ( !$active ) {
|
if ( !$active ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
$file = fopen( $filePath, 'a' );
|
$file = fopen( $filePath, 'a' );
|
||||||
|
|
||||||
$stringData = "<tr>"
|
$stringData = "<tr>";
|
||||||
. self::generateHTMLtableItem( $id, $bold )
|
foreach ( $rows as $row ) {
|
||||||
. self::generateHTMLtableItem( $inputTex, $bold )
|
$stringData .= self::generateHTMLtableItem( $row, $bold );
|
||||||
. self::generateHTMLtableItem( $mmlMj3, $bold )
|
}
|
||||||
. self::generateHTMLtableItem( $mmlGen, $bold ) .
|
$stringData .= "</tr>";
|
||||||
"</tr>";
|
|
||||||
|
|
||||||
fwrite( $file, $stringData );
|
fwrite( $file, $stringData );
|
||||||
|
|
||||||
fclose( $file ); // tbd only open close once for all tests
|
fclose( $file ); // tbd only open close once for all tests
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function generateHTMLstart( $filePath, $name, $active = true ) {
|
public static function generateHTMLstart( $filePath, $headrows = [ "name","Tex-Input",
|
||||||
|
"MathML(MathJax3)","MathML(TexVC)" ], $active = true ) {
|
||||||
if ( !$active ) {
|
if ( !$active ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$htmlRows = "";
|
||||||
|
foreach ( $headrows as $header ) {
|
||||||
|
$htmlRows .= "<th class=\"tg-0lax\"><b>" . $header . "</b></th>";
|
||||||
|
}
|
||||||
|
|
||||||
$file = fopen( $filePath, 'w' ); // or die("error");
|
$file = fopen( $filePath, 'w' ); // or die("error");
|
||||||
$stringData = /** @lang HTML */
|
$stringData = /** @lang HTML */
|
||||||
<<<HTML
|
<<<HTML
|
||||||
<style>
|
<!DOCTYPE html>
|
||||||
.tg {
|
<html lang="en">
|
||||||
border-collapse: collapse;
|
<head>
|
||||||
border-spacing: 0;
|
<meta charset="utf-8">
|
||||||
}
|
</head>
|
||||||
|
<style>
|
||||||
.tg td {
|
.tg {
|
||||||
border-color: black;
|
border-collapse: collapse;
|
||||||
border-style: solid;
|
border-spacing: 0;
|
||||||
border-width: 1px;
|
}
|
||||||
font-family: Arial, sans-serif;
|
.tg td {
|
||||||
font-size: 14px;
|
border-color: black;
|
||||||
overflow: hidden;
|
border-style: solid;
|
||||||
padding: 10px 5px;
|
border-width: 1px;
|
||||||
word-break: normal;
|
font-family: Arial, sans-serif;
|
||||||
}
|
font-size: 14px;
|
||||||
|
overflow: hidden;
|
||||||
.tg th {
|
padding: 10px 5px;
|
||||||
border-color: black;
|
word-break: normal;
|
||||||
border-style: solid;
|
}
|
||||||
border-width: 1px;
|
.tg th {
|
||||||
font-family: Arial,
|
border-color: black;
|
||||||
sans-serif;
|
border-style: solid;
|
||||||
font-size: 14px;
|
border-width: 1px;
|
||||||
font-weight: normal;
|
font-family: Arial,
|
||||||
overflow: hidden;
|
sans-serif;
|
||||||
padding: 10px 5px;
|
font-size: 14px;
|
||||||
word-break: normal;
|
font-weight: normal;
|
||||||
}
|
overflow: hidden;
|
||||||
|
padding: 10px 5px;
|
||||||
.tg .tg-0lax {
|
word-break: normal;
|
||||||
text-align: left;
|
}
|
||||||
vertical-align: top
|
.tg .tg-0lax {
|
||||||
}
|
text-align: left;
|
||||||
</style>
|
vertical-align: top
|
||||||
<table class="tg">
|
}
|
||||||
<thead>
|
</style>
|
||||||
<tr>
|
<table class="tg">
|
||||||
<th class="tg-0lax"><b>name</b></th>
|
<thead>
|
||||||
<th class="tg-0lax"><b>Tex-Input</b></th>
|
<tr>{$htmlRows}</tr>
|
||||||
<th class="tg-0lax"><b>MathML(MathJax3)</b></th>
|
</thead>
|
||||||
<th class="tg-0lax"><b>MathML(TexVC)</b></th>
|
<tbody>
|
||||||
</tr>
|
HTML;
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
HTML;
|
|
||||||
fwrite( $file, $stringData );
|
fwrite( $file, $stringData );
|
||||||
fclose( $file );
|
fclose( $file );
|
||||||
}
|
}
|
||||||
|
|
2122
tests/phpunit/unit/TexVC/mmlRes-latexml-FullCoverage.json
Normal file
2122
tests/phpunit/unit/TexVC/mmlRes-latexml-FullCoverage.json
Normal file
File diff suppressed because one or more lines are too long
2122
tests/phpunit/unit/TexVC/mmlRes-mathml-FullCoverage.json
Normal file
2122
tests/phpunit/unit/TexVC/mmlRes-mathml-FullCoverage.json
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue