2020-05-11 15:52:06 +00:00
|
|
|
<?php
|
|
|
|
|
2020-05-14 22:44:49 +00:00
|
|
|
namespace MediaWiki\Extension\DiscussionTools\Tests;
|
|
|
|
|
|
|
|
use MediaWiki\Extension\DiscussionTools\CommentParser;
|
2020-05-11 15:52:06 +00:00
|
|
|
use MediaWiki\MediaWikiServices;
|
2021-07-29 02:16:15 +00:00
|
|
|
use Wikimedia\Parsoid\DOM\Document;
|
2020-07-30 23:34:56 +00:00
|
|
|
use Wikimedia\Parsoid\Utils\DOMCompat;
|
2020-06-16 20:13:31 +00:00
|
|
|
use Wikimedia\Parsoid\Utils\DOMUtils;
|
2020-05-11 15:52:06 +00:00
|
|
|
|
2021-02-02 14:12:51 +00:00
|
|
|
trait TestUtils {
|
2020-05-11 15:52:06 +00:00
|
|
|
|
|
|
|
/**
|
2021-07-29 02:16:15 +00:00
|
|
|
* Create a Document from a string
|
2020-05-11 15:52:06 +00:00
|
|
|
*
|
|
|
|
* @param string $html
|
2021-07-29 02:16:15 +00:00
|
|
|
* @return Document
|
2020-05-11 15:52:06 +00:00
|
|
|
*/
|
2021-07-29 02:16:15 +00:00
|
|
|
protected static function createDocument( string $html ): Document {
|
2020-06-16 20:13:31 +00:00
|
|
|
$doc = DOMUtils::parseHTML( $html );
|
2020-05-11 15:52:06 +00:00
|
|
|
return $doc;
|
|
|
|
}
|
|
|
|
|
2021-02-27 00:15:42 +00:00
|
|
|
/**
|
|
|
|
* Get text from path
|
|
|
|
*
|
|
|
|
* @param string $relativePath
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-07-22 07:25:13 +00:00
|
|
|
protected static function getText( string $relativePath ): string {
|
2021-02-27 00:15:42 +00:00
|
|
|
return file_get_contents( __DIR__ . '/../' . $relativePath );
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Write text to path
|
|
|
|
*
|
|
|
|
* @param string $relativePath
|
|
|
|
* @param string $text
|
|
|
|
*/
|
2021-07-22 07:25:13 +00:00
|
|
|
protected static function overwriteTextFile( string $relativePath, string $text ): void {
|
2021-02-27 00:15:42 +00:00
|
|
|
file_put_contents( __DIR__ . '/../' . $relativePath, $text );
|
|
|
|
}
|
|
|
|
|
2020-05-11 15:52:06 +00:00
|
|
|
/**
|
|
|
|
* Get parsed JSON from path
|
|
|
|
*
|
|
|
|
* @param string $relativePath
|
2020-05-19 19:01:03 +00:00
|
|
|
* @param bool $assoc See json_decode()
|
2020-05-11 15:52:06 +00:00
|
|
|
* @return array
|
|
|
|
*/
|
2021-07-22 07:25:13 +00:00
|
|
|
protected static function getJson( string $relativePath, bool $assoc = true ): array {
|
2020-05-11 15:52:06 +00:00
|
|
|
$json = json_decode(
|
2020-05-18 20:07:00 +00:00
|
|
|
file_get_contents( __DIR__ . '/' . $relativePath ),
|
2020-05-19 19:01:03 +00:00
|
|
|
$assoc
|
2020-05-11 15:52:06 +00:00
|
|
|
);
|
|
|
|
return $json;
|
|
|
|
}
|
|
|
|
|
2020-07-30 23:34:56 +00:00
|
|
|
/**
|
|
|
|
* Write JSON to path
|
|
|
|
*
|
|
|
|
* @param string $relativePath
|
|
|
|
* @param array $data
|
|
|
|
*/
|
2021-07-22 07:25:13 +00:00
|
|
|
protected static function overwriteJsonFile( string $relativePath, array $data ): void {
|
2020-07-30 23:34:56 +00:00
|
|
|
$json = json_encode( $data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
|
2021-01-26 23:55:15 +00:00
|
|
|
// Tabs instead of 4 spaces
|
|
|
|
$json = preg_replace( '/(?:\G|^) {4}/m', "\t", $json );
|
2020-07-30 23:34:56 +00:00
|
|
|
file_put_contents( __DIR__ . '/' . $relativePath, $json . "\n" );
|
|
|
|
}
|
|
|
|
|
2020-05-11 15:52:06 +00:00
|
|
|
/**
|
|
|
|
* Get HTML from path
|
|
|
|
*
|
|
|
|
* @param string $relativePath
|
|
|
|
* @return string
|
|
|
|
*/
|
2021-07-22 07:25:13 +00:00
|
|
|
protected static function getHtml( string $relativePath ): string {
|
2020-05-18 20:07:00 +00:00
|
|
|
$html = file_get_contents( __DIR__ . '/../' . $relativePath );
|
2020-05-11 15:52:06 +00:00
|
|
|
|
|
|
|
// Remove all but the body tags from full Parsoid docs
|
|
|
|
if ( strpos( $html, '<body' ) !== false ) {
|
2020-07-30 23:34:56 +00:00
|
|
|
preg_match( '`(<body[^>]*>)(.*)(</body>)`s', $html, $match );
|
|
|
|
$html = "<div>$match[2]</div>";
|
2020-05-11 15:52:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return $html;
|
|
|
|
}
|
|
|
|
|
2020-07-30 23:34:56 +00:00
|
|
|
/**
|
|
|
|
* Write HTML to path
|
|
|
|
*
|
|
|
|
* @param string $relPath
|
2021-07-29 02:16:15 +00:00
|
|
|
* @param Document $doc
|
2020-07-30 23:34:56 +00:00
|
|
|
* @param string $origRelPath
|
|
|
|
*/
|
2021-07-29 02:16:15 +00:00
|
|
|
protected static function overwriteHtmlFile( string $relPath, Document $doc, string $origRelPath ): void {
|
2020-07-30 23:34:56 +00:00
|
|
|
// Do not use $doc->saveHtml(), it outputs an awful soup of HTML entities for documents with
|
|
|
|
// non-ASCII characters
|
2020-08-10 21:31:49 +00:00
|
|
|
$html = file_get_contents( __DIR__ . '/../' . $origRelPath );
|
2020-07-30 23:34:56 +00:00
|
|
|
|
|
|
|
// Replace the body tag only in full Parsoid docs
|
|
|
|
if ( strpos( $html, '<body' ) !== false ) {
|
2021-08-02 13:45:39 +00:00
|
|
|
$innerHtml = DOMCompat::getInnerHTML( DOMCompat::getBody( $doc )->firstChild );
|
2020-07-30 23:34:56 +00:00
|
|
|
$html = preg_replace(
|
|
|
|
'`(<body[^>]*>)(.*)(</body>)`s',
|
|
|
|
// Quote \ and $ in the replacement text
|
|
|
|
'$1' . strtr( $innerHtml, [ '\\' => '\\\\', '$' => '\\$' ] ) . '$3',
|
|
|
|
$html
|
|
|
|
);
|
|
|
|
} else {
|
2021-08-02 13:45:39 +00:00
|
|
|
$html = DOMCompat::getInnerHTML( DOMCompat::getBody( $doc ) );
|
2020-07-30 23:34:56 +00:00
|
|
|
}
|
|
|
|
|
2020-08-10 21:31:49 +00:00
|
|
|
file_put_contents( __DIR__ . '/../' . $relPath, $html );
|
2020-07-30 23:34:56 +00:00
|
|
|
}
|
|
|
|
|
2020-05-11 15:52:06 +00:00
|
|
|
/**
|
2020-10-14 20:14:59 +00:00
|
|
|
* Create a comment parser
|
2020-05-11 15:52:06 +00:00
|
|
|
*
|
|
|
|
* @param array $data
|
2020-05-14 22:44:49 +00:00
|
|
|
* @return CommentParser
|
2020-05-11 15:52:06 +00:00
|
|
|
*/
|
Change CommentParser into a service
Goal:
-----
To have a method like CommentParser::parse(), which just takes a node
to parse and a title and returns plain data, so that we don't need to
keep track of the config to construct a CommentParser object (the
required config like content language is provided by services) and
we don't need to keep that object around after parsing.
Changes:
--------
CommentParser.php:
* …is now a service. Constructor only takes services as arguments.
The node and title are passed to a new parse() method.
* parse() should return plain data, but I split this part to a separate
patch for ease of review: I49bfe019aa460651447fd383f73eafa9d7180a92.
* CommentParser still cheats and accesses global state in a few places,
e.g. calling Title::makeTitleSafe or CommentUtils::getTitleFromUrl,
so we can't turn its tests into true unit tests. This work is left
for future commits.
LanguageData.php:
* …is now a service, instead of a static class.
Parser.js:
* …is not a real service, but it's changed to behave in a similar way.
Constructor takes only the required config as argument,
and node and title are instead passed to a new parse() method.
CommentParserTest.php:
parser.test.js:
* Can be simplified, now that we don't need a useless node and title
to test internal methods that don't use them.
testUtils.js:
* Can be simplified, now that we don't need to override internal
ResourceLoader stuff just to change the parser config.
Change-Id: Iadb7757debe000025e52770ca51ebcf24ca8ee66
2022-02-19 02:43:21 +00:00
|
|
|
public static function createParser( array $data ): CommentParser {
|
2020-05-11 15:52:06 +00:00
|
|
|
$services = MediaWikiServices::getInstance();
|
2020-05-14 22:44:49 +00:00
|
|
|
return new CommentParser(
|
2020-05-11 15:52:06 +00:00
|
|
|
$services->getContentLanguage(),
|
|
|
|
$services->getMainConfig(),
|
Change CommentParser into a service
Goal:
-----
To have a method like CommentParser::parse(), which just takes a node
to parse and a title and returns plain data, so that we don't need to
keep track of the config to construct a CommentParser object (the
required config like content language is provided by services) and
we don't need to keep that object around after parsing.
Changes:
--------
CommentParser.php:
* …is now a service. Constructor only takes services as arguments.
The node and title are passed to a new parse() method.
* parse() should return plain data, but I split this part to a separate
patch for ease of review: I49bfe019aa460651447fd383f73eafa9d7180a92.
* CommentParser still cheats and accesses global state in a few places,
e.g. calling Title::makeTitleSafe or CommentUtils::getTitleFromUrl,
so we can't turn its tests into true unit tests. This work is left
for future commits.
LanguageData.php:
* …is now a service, instead of a static class.
Parser.js:
* …is not a real service, but it's changed to behave in a similar way.
Constructor takes only the required config as argument,
and node and title are instead passed to a new parse() method.
CommentParserTest.php:
parser.test.js:
* Can be simplified, now that we don't need a useless node and title
to test internal methods that don't use them.
testUtils.js:
* Can be simplified, now that we don't need to override internal
ResourceLoader stuff just to change the parser config.
Change-Id: Iadb7757debe000025e52770ca51ebcf24ca8ee66
2022-02-19 02:43:21 +00:00
|
|
|
new MockLanguageData( $data )
|
2020-05-11 15:52:06 +00:00
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|