360 lines
11 KiB
PHP
360 lines
11 KiB
PHP
<?php
|
|
|
|
namespace SMW\Tests\Query\Parser;
|
|
|
|
use SMW\DIProperty;
|
|
use SMW\DIWikiPage;
|
|
use SMW\Query\DescriptionFactory;
|
|
use SMW\Query\Parser\DescriptionProcessor;
|
|
use SMW\Query\Parser\LegacyParser as QueryParser;
|
|
use SMW\Query\Parser\Tokenizer;
|
|
use SMW\Query\QueryToken;
|
|
use SMW\Tests\TestEnvironment;
|
|
|
|
/**
|
|
* @covers \SMW\Query\Parser\LegacyParser
|
|
* @group semantic-mediawiki
|
|
*
|
|
* @license GPL-2.0-or-later
|
|
* @since 3.0
|
|
*
|
|
* @author mwjames
|
|
*/
|
|
class LegacyParserTest extends \PHPUnit\Framework\TestCase {
|
|
|
|
private $testEnvironment;
|
|
private $descriptionFactory;
|
|
private $queryParser;
|
|
|
|
protected function setUp(): void {
|
|
parent::setUp();
|
|
|
|
$this->testEnvironment = new TestEnvironment();
|
|
$this->descriptionFactory = new DescriptionFactory();
|
|
|
|
$store = $this->getMockBuilder( '\SMW\Store' )
|
|
->disableOriginalConstructor()
|
|
->getMockForAbstractClass();
|
|
|
|
$this->testEnvironment->registerObject( 'Store', $store );
|
|
|
|
$this->queryParser = new QueryParser(
|
|
new DescriptionProcessor(),
|
|
new Tokenizer(),
|
|
new QueryToken()
|
|
);
|
|
}
|
|
|
|
protected function tearDown(): void {
|
|
$this->testEnvironment->tearDown();
|
|
parent::tearDown();
|
|
}
|
|
|
|
public function testCanConstruct() {
|
|
$descriptionProcessor = $this->getMockBuilder( '\SMW\Query\Parser\DescriptionProcessor' )
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
|
|
$tokenizer = $this->getMockBuilder( '\SMW\Query\Parser\Tokenizer' )
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
|
|
$queryToken = $this->getMockBuilder( '\SMW\Query\QueryToken' )
|
|
->disableOriginalConstructor()
|
|
->getMock();
|
|
|
|
$this->assertInstanceOf(
|
|
'\SMW\Query\Parser',
|
|
new QueryParser( $descriptionProcessor, $tokenizer, $queryToken )
|
|
);
|
|
}
|
|
|
|
public function testCreateCondition() {
|
|
$this->assertEquals(
|
|
'[[Foo::Bar]]',
|
|
$this->queryParser->createCondition( 'Foo', 'Bar' )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
'[[Foo::Bar]]',
|
|
$this->queryParser->createCondition( new DIProperty( 'Foo' ), 'Bar' )
|
|
);
|
|
}
|
|
|
|
public function testPropertyWildardDescription() {
|
|
$description = $this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'Foo' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newThingDescription()
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Foo::+]]' )
|
|
);
|
|
}
|
|
|
|
public function testNamespaceWildardDescription() {
|
|
$description = $this->descriptionFactory->newNamespaceDescription(
|
|
NS_MAIN
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[:+]]' )
|
|
);
|
|
}
|
|
|
|
public function testPageDescription() {
|
|
$description = $this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'Foo', NS_MAIN, '' )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Foo]]' )
|
|
);
|
|
}
|
|
|
|
public function testPropertyNotEqualValueDescription() {
|
|
$description = $this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'Has foo' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'Bar', NS_MAIN, '' ),
|
|
DIProperty::newFromUserLabel( 'Has foo' )->setPropertyTypeId( '_wpg' ),
|
|
SMW_CMP_NEQ
|
|
)
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Has foo::!Bar]]' )
|
|
);
|
|
}
|
|
|
|
public function testInversePropertyDescription() {
|
|
$description = $this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'Has foo', true )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'Bar', NS_MAIN, '' ),
|
|
DIProperty::newFromUserLabel( 'Has foo', true )->setPropertyTypeId( '_wpg' ),
|
|
SMW_CMP_EQ
|
|
)
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[-Has foo::Bar]]' )
|
|
);
|
|
}
|
|
|
|
public function testConjunctionForCategoryPropertyValueGreaterThanOrEqualLessThanOrEqual() {
|
|
$someGreaterThanOrEqualProperty = $this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'A', NS_MAIN, '' ),
|
|
DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ), SMW_CMP_GEQ )
|
|
);
|
|
|
|
$someLessThanOrEqualProperty = $this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'D', NS_MAIN, '' ),
|
|
DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), SMW_CMP_LEQ )
|
|
);
|
|
|
|
$classDescription = $this->descriptionFactory->newClassDescription(
|
|
new DIWikiPage( 'Foo', NS_CATEGORY, '' )
|
|
);
|
|
|
|
$description = $this->descriptionFactory->newConjunction();
|
|
$description->addDescription( $classDescription );
|
|
$description->addDescription( $someGreaterThanOrEqualProperty );
|
|
$description->addDescription( $someLessThanOrEqualProperty );
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Category:Foo]] [[One::>A]] [[Two::<D]]' )
|
|
);
|
|
}
|
|
|
|
public function testConjunctionForCategoryPropertyChainDescription() {
|
|
$someProperty = $this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'Bar', NS_MAIN, '' ),
|
|
DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), SMW_CMP_EQ
|
|
)
|
|
)
|
|
);
|
|
|
|
$classDescription = $this->descriptionFactory->newClassDescription(
|
|
new DIWikiPage( 'Foo', NS_CATEGORY, '' )
|
|
);
|
|
|
|
$description = $this->descriptionFactory->newConjunction();
|
|
$description->addDescription( $classDescription );
|
|
$description->addDescription( $someProperty );
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Category:Foo]] [[One.Two::Bar]]' )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Category:Foo]] [[One::<q>[[Two::Bar]]</q>]]' )
|
|
);
|
|
}
|
|
|
|
public function testDisjunctionForCategoryPropertyChainDescription() {
|
|
$someProperty = $this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'Bar', NS_MAIN, '' ),
|
|
DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), SMW_CMP_EQ
|
|
)
|
|
)
|
|
);
|
|
|
|
$classDescription = $this->descriptionFactory->newClassDescription(
|
|
new DIWikiPage( 'Foo', NS_CATEGORY, '' )
|
|
);
|
|
|
|
$description = $this->descriptionFactory->newDisjunction();
|
|
$description->addDescription( $classDescription );
|
|
$description->addDescription( $someProperty );
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Category:Foo]] OR [[One.Two::Bar]]' )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Category:Foo]] OR [[One::<q>[[Two::Bar]]</q>]]' )
|
|
);
|
|
}
|
|
|
|
public function testDisjunctionForCategoryChainDescription() {
|
|
$classFooDescription = $this->descriptionFactory->newClassDescription(
|
|
new DIWikiPage( 'Foo', NS_CATEGORY, '' )
|
|
);
|
|
|
|
$classBarDescription = $this->descriptionFactory->newClassDescription(
|
|
new DIWikiPage( 'Bar', NS_CATEGORY, '' )
|
|
);
|
|
|
|
$description = $this->descriptionFactory->newDisjunction();
|
|
$description->addDescription( $classFooDescription );
|
|
$description->addDescription( $classBarDescription );
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Category:Foo||Bar]]' )
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[Category:Foo]] OR [[Category:Bar]]' )
|
|
);
|
|
}
|
|
|
|
public function testCombinedSubobjectPropertyChainDescription() {
|
|
$description = $this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'One' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( '_SOBJ' )->setPropertyTypeId( '__sob' ),
|
|
$this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'Bar', NS_MAIN, '' ),
|
|
DIProperty::newFromUserLabel( 'Two' )->setPropertyTypeId( '_wpg' ), SMW_CMP_EQ
|
|
)
|
|
)
|
|
)
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[One.Has subobject.Two::Bar]]' )
|
|
);
|
|
}
|
|
|
|
public function testSubqueryDisjunction() {
|
|
$property = new DIProperty( 'HasSomeProperty' );
|
|
$property->setPropertyTypeId( '_wpg' );
|
|
|
|
$disjunction = $this->descriptionFactory->newDisjunction( [
|
|
$this->descriptionFactory->newValueDescription( new DIWikiPage( 'Foo', NS_MAIN ), $property ),
|
|
$this->descriptionFactory->newValueDescription( new DIWikiPage( 'Bar', NS_MAIN ), $property )
|
|
] );
|
|
|
|
$description = $this->descriptionFactory->newSomeProperty(
|
|
$property,
|
|
$disjunction
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[HasSomeProperty::Foo||Bar]]' )
|
|
);
|
|
}
|
|
|
|
public function testNestedPropertyConjunction() {
|
|
$property = DIProperty::newFromUserLabel( 'Born in' );
|
|
$property->setPropertyTypeId( '_wpg' );
|
|
|
|
$conjunction = $this->descriptionFactory->newConjunction( [
|
|
$this->descriptionFactory->newClassDescription( new DIWikiPage( 'City', NS_CATEGORY ) ),
|
|
$this->descriptionFactory->newSomeProperty(
|
|
DIProperty::newFromUserLabel( 'Located in' )->setPropertyTypeId( '_wpg' ),
|
|
$this->descriptionFactory->newValueDescription(
|
|
new DIWikiPage( 'Outback', NS_MAIN ),
|
|
DIProperty::newFromUserLabel( 'Located in' )->setPropertyTypeId( '_wpg' ) )
|
|
)
|
|
]
|
|
);
|
|
|
|
$description = $this->descriptionFactory->newSomeProperty(
|
|
$property,
|
|
$conjunction
|
|
);
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '[[born in::<q>[[Category:City]] [[located in::Outback]]</q>]]' )
|
|
);
|
|
}
|
|
|
|
public function testRestrictedDefaultNamespace() {
|
|
$property = DIProperty::newFromUserLabel( 'Foo' );
|
|
$property->setPropertyTypeId( '_wpg' );
|
|
|
|
$description = $this->descriptionFactory->newSomeProperty(
|
|
$property,
|
|
$this->descriptionFactory->newValueDescription( new DIWikiPage( 'Bar', NS_MAIN ), $property )
|
|
);
|
|
|
|
$description = $this->descriptionFactory->newConjunction( [
|
|
$description,
|
|
$this->descriptionFactory->newNamespaceDescription( NS_MAIN )
|
|
] );
|
|
|
|
$this->queryParser->setDefaultNamespaces( [ NS_MAIN ] );
|
|
|
|
$this->assertEquals(
|
|
$description,
|
|
$this->queryParser->getQueryDescription( '<q>[[Foo::Bar]]</q>[[:+]]' )
|
|
);
|
|
|
|
$this->assertEmpty(
|
|
$this->queryParser->getErrors()
|
|
);
|
|
}
|
|
|
|
}
|