gplx/mediawiki/extensions/SemanticMediaWiki/tests/phpunit/Utils/JSONScript/ParserTestCaseProcessor.php

283 lines
7.0 KiB
PHP

<?php
namespace SMW\Tests\Utils\JSONScript;
use Article;
use MediaWiki\Context\RequestContext;
use MediaWiki\User\User;
use MediaWikiIntegrationTestCase;
use RuntimeException;
use SMW\DIWikiPage;
use SMW\SerializerFactory;
use SMW\Services\ServicesFactory;
use SMW\Services\ServicesFactory as ApplicationFactory;
use SMW\Store;
use SMW\Tests\Utils\PageReader;
use SMW\Tests\Utils\UtilityFactory;
use SMW\Tests\Utils\Validators\IncomingSemanticDataValidator;
use SMW\Tests\Utils\Validators\SemanticDataValidator;
use SMW\Tests\Utils\Validators\StringValidator;
/**
* @group semantic-mediawiki
* @group Database
* @group medium
*
* @license GPL-2.0-or-later
* @since 2.3
*
* @author mwjames
*/
class ParserTestCaseProcessor extends MediaWikiIntegrationTestCase {
/**
* @var Store
*/
private $store;
/**
* @var SemanticDataValidator
*/
private $semanticDataValidator;
/**
* @var IncomingSemanticDataValidator
*/
private $incomingSemanticDataValidator;
/**
* @var StringValidator
*/
private $stringValidator;
/**
* @var PageReader
*/
private $pageReader;
/**
* @var User
*/
private $superUser;
/**
* @var SerializerFactory
*/
private $serializerFactory;
/**
* @var bool
*/
private $debug = false;
/**
* @param Store
* @param SemanticDataValidator
* @param IncomingSemanticDataValidator
* @param StringValidator
*/
public function __construct( $store, $semanticDataValidator, $incomingSemanticDataValidator, $stringValidator ) {
$this->store = $store;
$this->semanticDataValidator = $semanticDataValidator;
$this->incomingSemanticDataValidator = $incomingSemanticDataValidator;
$this->stringValidator = $stringValidator;
$this->pageReader = UtilityFactory::getInstance()->newPageReader();
$this->superUser = UtilityFactory::getInstance()->newMockSuperUser();
$this->serializerFactory = ApplicationFactory::getInstance()->newSerializerFactory();
}
/**
* @since 2.2
*
* @param bool $debugMode
*/
public function setDebugMode( $debugMode ) {
$this->debug = $debugMode;
}
/**
* @since 2.2
*
* @param array $case
*/
public function process( array $case ) {
if ( !isset( $case['subject'] ) ) {
return;
}
$this->assertSemanticDataForCase(
$case
);
$this->assertTextFromParserOutputForCase(
$case
);
$this->assertTextFromParsedMsgForCase(
$case
);
}
private function assertSemanticDataForCase( $case ) {
// Allows for data to be re-read from the DB instead of being fetched
// from the store-id-cache
if ( isset( $case['store']['clear-cache'] ) && $case['store']['clear-cache'] ) {
$this->store->clear();
}
if ( !isset( $case['assert-store'] ) || !isset( $case['assert-store']['semantic-data'] ) ) {
return;
}
$subject = $this->getSubjectFrom( $case, false );
$semanticData = $this->store->getSemanticData( $subject );
if ( $this->debug ) {
print_r(
$this->serializerFactory->newSemanticDataSerializer()->serialize( $semanticData )
);
}
if ( isset( $case['errors'] ) && $case['errors'] !== [] ) {
$this->assertNotEmpty(
$semanticData->getErrors()
);
}
$this->semanticDataValidator->assertThatPropertiesAreSet(
$case['assert-store']['semantic-data'],
$semanticData,
$case['about']
);
if ( !isset( $case['assert-store']['semantic-data']['incoming'] ) ) {
return;
}
$this->incomingSemanticDataValidator->assertThatIncomingDataAreSet(
$case['assert-store']['semantic-data']['incoming'],
$subject,
$case['about']
);
}
private function assertTextFromParserOutputForCase( $case ) {
if ( !isset( $case['assert-output'] ) ) {
return;
}
$title = $this->getSubjectFrom( $case )->getTitle();
$parserOutput = $this->pageReader->getParserOutputFromEdit(
$title
);
if ( isset( $case['assert-output']['onOutputPage'] ) && $case['assert-output']['onOutputPage'] ) {
$context = new RequestContext();
$context->setTitle( $title );
// Ensures the OutputPageBeforeHTML hook is run
$context->getOutput()->addParserOutput( $parserOutput );
$output = $context->getOutput()->getHtml();
} elseif ( isset( $case['assert-output']['onPageView'] ) ) {
$parameters = isset( $case['assert-output']['onPageView']['parameters'] ) ? $case['assert-output']['onPageView']['parameters'] : [];
$context = RequestContext::newExtraneousContext(
$title,
$parameters
);
// Avoid "... PermissionsError: The action you have requested is
// limited to users in the group ..."
$context->setUser( $this->superUser );
Article::newFromTitle( $title, $context )->view();
$output = $context->getOutput()->getHtml();
} else {
$output = $parserOutput->getText();
}
if ( isset( $case['assert-output']['include-head-items'] ) && $case['assert-output']['include-head-items'] ) {
$output .= '<include-head-items>' . implode( '', $parserOutput->getHeadItems() ) . '</include-head-items>';
}
// Strip HTML comments
$output = preg_replace( '/<!--(.*)-->/Uis', '', $output );
if ( isset( $case['assert-output']['to-contain'] ) ) {
$contains = $case['assert-output']['to-contain'];
// Concatenate to a string to ensure we keep the sequence as entered
// while adding .* to signal that anything goes between them except
// for the string expected to be asserted
if ( isset( $case['assert-output']['in-sequence' ] ) && is_array( $contains ) ) {
$contains = implode( '.*', $contains );
}
$this->stringValidator->assertThatStringContains(
$contains,
$output,
$case['about']
);
}
if ( isset( $case['assert-output']['not-contain'] ) ) {
$this->stringValidator->assertThatStringNotContains(
$case['assert-output']['not-contain'],
$output,
$case['about']
);
}
}
private function assertTextFromParsedMsgForCase( $case ) {
if ( !isset( $case['assert-msgoutput'] ) ) {
return;
}
$mediaWikiNsContentReader = ServicesFactory::getInstance()->create( 'MediaWikiNsContentReader' );
$mediaWikiNsContentReader->skipMessageCache();
$text = $mediaWikiNsContentReader->read( $case['subject'] );
$text = wfMessage( 'smw-parse', $text )->parse();
if ( isset( $case['assert-msgoutput']['to-contain'] ) ) {
$this->stringValidator->assertThatStringContains(
$case['assert-msgoutput']['to-contain'],
$text,
$case['about']
);
}
if ( isset( $case['assert-msgoutput']['not-contain'] ) ) {
$this->stringValidator->assertThatStringNotContains(
$case['assert-msgoutput']['not-contain'],
$text,
$case['about']
);
}
}
private function getSubjectFrom( $case, $checkExists = true ) {
$subject = DIWikiPage::newFromText(
$case['subject'],
isset( $case['namespace'] ) ? constant( $case['namespace'] ) : NS_MAIN
);
$title = $subject->getTitle();
if ( $subject->getNamespace() === SMW_NS_PROPERTY ) {
$checkExists = false;
}
if ( $title === null ) {
throw new RuntimeException( 'Could not create Title object for subject page "' . $case['subject'] . '".' );
}
if ( $checkExists && !$title->exists() ) {
throw new RuntimeException( 'Subject page "' . $case['subject'] . '" does not exist.' );
}
return $subject;
}
}