gplx/mediawiki/extensions/SemanticMediaWiki/tests/phpunit/SQLStore/QueryEngine/ConditionBuilderTest.php

313 lines
7.8 KiB
PHP

<?php
namespace SMW\Tests\SQLStore\QueryEngine;
use SMW\DIWikiPage;
use SMW\Query\Language\ClassDescription;
use SMW\Query\Language\Disjunction;
use SMW\Query\Language\NamespaceDescription;
use SMW\SQLStore\QueryEngine\ConditionBuilder;
use SMW\SQLStore\QueryEngine\DescriptionInterpreterFactory;
use SMW\SQLStore\QueryEngine\QuerySegment;
use SMW\Tests\PHPUnitCompat;
use SMW\Tests\TestEnvironment;
use SMW\Tests\Utils\Validators\QuerySegmentValidator;
/**
* @covers \SMW\SQLStore\QueryEngine\ConditionBuilder
* @group semantic-mediawiki
*
* @license GPL-2.0-or-later
* @since 2.2
*
* @author mwjames
*/
class ConditionBuilderTest extends \PHPUnit\Framework\TestCase {
use PHPUnitCompat;
private $store;
private $connection;
private $orderCondition;
private $circularReferenceGuard;
private $descriptionInterpreterFactory;
private QuerySegmentValidator $querySegmentValidator;
protected function setUp(): void {
parent::setUp();
$this->store = $this->getMockBuilder( '\SMW\SQLStore\SQLStore' )
->disableOriginalConstructor()
->getMock();
$this->connection = $this->getMockBuilder( '\SMW\MediaWiki\Connection\Database' )
->disableOriginalConstructor()
->getMock();
$this->store->expects( $this->any() )
->method( 'getConnection' )
->willReturn( $this->connection );
$this->orderCondition = $this->getMockBuilder( '\SMW\SQLStore\QueryEngine\OrderCondition' )
->disableOriginalConstructor()
->getMock();
$this->circularReferenceGuard = $this->getMockBuilder( '\SMW\Utils\CircularReferenceGuard' )
->disableOriginalConstructor()
->getMock();
$this->descriptionInterpreterFactory = new DescriptionInterpreterFactory(
$this->store,
$this->circularReferenceGuard
);
$testEnvironment = new TestEnvironment();
$this->querySegmentValidator = $testEnvironment->getUtilityFactory()->newValidatorFactory()->newQuerySegmentValidator();
}
public function testCanConstruct() {
$descriptionInterpreterFactory = $this->getMockBuilder( '\SMW\SQLStore\QueryEngine\DescriptionInterpreterFactory' )
->disableOriginalConstructor()
->getMock();
$this->assertInstanceOf(
ConditionBuilder::class,
new ConditionBuilder( $this->store, $this->orderCondition, $descriptionInterpreterFactory, $this->circularReferenceGuard )
);
}
public function testBuildCondition() {
$description = $this->getMockBuilder( '\SMW\Query\Language\Description' )
->disableOriginalConstructor()
->getMock();
$query = $this->getMockBuilder( '\SMWQuery' )
->disableOriginalConstructor()
->getMock();
$query->expects( $this->atLeastOnce() )
->method( 'getDescription' )
->willReturn( $description );
$this->orderCondition->expects( $this->once() )
->method( 'addConditions' );
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$instance->buildCondition( $query );
}
public function testNamespaceDescription() {
$description = new NamespaceDescription( NS_HELP );
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$instance->buildFromDescription( $description );
$expected = new \stdClass;
$expected->type = 1;
$expected->where = "t0.smw_namespace=";
$this->assertSame( 0, $instance->getLastQuerySegmentId() );
$this->assertEmpty( $instance->getErrors() );
$this->querySegmentValidator->assertThatContainerContains(
$expected,
$instance->getQuerySegmentList()
);
}
public function testDisjunctiveNamespaceDescription() {
$description = new Disjunction();
$description->addDescription( new NamespaceDescription( NS_HELP ) );
$description->addDescription( new NamespaceDescription( NS_MAIN ) );
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$instance->buildFromDescription( $description );
$expectedDisjunction = new \stdClass;
$expectedDisjunction->type = 3;
$expectedHelpNs = new \stdClass;
$expectedHelpNs->type = 1;
$expectedHelpNs->where = "t1.smw_namespace=";
$expectedMainNs = new \stdClass;
$expectedMainNs->type = 1;
$expectedMainNs->where = "t2.smw_namespace=";
$this->assertSame(
0,
$instance->getLastQuerySegmentId()
);
$this->assertEmpty(
$instance->getErrors()
);
$expected = [
$expectedDisjunction,
$expectedHelpNs,
$expectedMainNs
];
$this->querySegmentValidator->assertThatContainerContains(
$expected,
$instance->getQuerySegmentList()
);
}
public function testClassDescription() {
$objectIds = $this->getMockBuilder( '\stdClass' )
->setMethods( [ 'getSMWPageID' ] )
->getMock();
$objectIds->expects( $this->any() )
->method( 'getSMWPageID' )
->willReturn( 42 );
$this->store->expects( $this->once() )
->method( 'getObjectIds' )
->willReturn( $objectIds );
$description = new ClassDescription( new DIWikiPage( 'Foo', NS_CATEGORY ) );
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$instance->buildFromDescription( $description );
$expectedClass = new \stdClass;
$expectedClass->type = 1;
$expectedClass->alias = "t0";
$expectedClass->queryNumber = 0;
$expectedHierarchy = new \stdClass;
$expectedHierarchy->type = 5;
$expectedHierarchy->joinfield = [ 0 => 42 ];
$expectedHierarchy->alias = "t1";
$expectedHierarchy->queryNumber = 1;
$this->assertSame(
0,
$instance->getLastQuerySegmentId()
);
$this->assertEmpty(
$instance->getErrors()
);
$expected = [
$expectedClass,
$expectedHierarchy
];
$this->querySegmentValidator->assertThatContainerContains(
$expected,
$instance->getQuerySegmentList()
);
}
public function testGivenNonInteger_getQuerySegmentThrowsException() {
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$this->expectException( 'InvalidArgumentException' );
$instance->findQuerySegment( null );
}
public function testGivenUnknownId_getQuerySegmentThrowsException() {
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$this->expectException( 'OutOfBoundsException' );
$instance->findQuerySegment( 1 );
}
public function testGivenKnownId_getQuerySegmentReturnsCorrectPart() {
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$querySegment = new QuerySegment();
$instance->addQuerySegment( $querySegment );
$this->assertSame(
$querySegment,
$instance->findQuerySegment( $querySegment->queryNumber )
);
}
public function testWhenNoQuerySegments_getQuerySegmentListReturnsEmptyArray() {
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$this->assertSame(
[],
$instance->getQuerySegmentList()
);
}
public function testWhenSomeQuerySegments_getQuerySegmentListReturnsThemAll() {
$instance = new ConditionBuilder(
$this->store,
$this->orderCondition,
$this->descriptionInterpreterFactory,
$this->circularReferenceGuard
);
$firstQuerySegment = new QuerySegment();
$instance->addQuerySegment( $firstQuerySegment );
$secondQuerySegment = new QuerySegment();
$instance->addQuerySegment( $secondQuerySegment );
$expected = [
0 => $firstQuerySegment,
1 => $secondQuerySegment
];
$this->assertSame(
$expected,
$instance->getQuerySegmentList()
);
}
}